void wormhit(struct monst *mtmp) { int tmp = mtmp->wormno; struct wseg *wtmp; if (!tmp) /* worm without tail */ return; for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg) hitu(mtmp, 1); }
int wiz_hit(struct monst *mtmp) { /* if we have stolen or found the amulet, we disappear */ if(mtmp->minvent && mtmp->minvent->olet == AMULET_SYM && mtmp->minvent->spe == 0) { /* vanish -- very primitive */ fall_down(mtmp); return(1); } /* if it is lying around someplace, we teleport to it */ if(!carrying(AMULET_OF_YENDOR)) { struct obj *otmp; for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp->olet == AMULET_SYM && !otmp->spe) { if((u.ux != otmp->ox || u.uy != otmp->oy) && !m_at(otmp->ox, otmp->oy)) { /* teleport to it and pick it up */ mtmp->mx = otmp->ox; mtmp->my = otmp->oy; freeobj(otmp); mpickobj(mtmp, otmp); pmon(mtmp); return(0); } goto hithim; } return(0); /* we don't know where it is */ } hithim: if(rn2(2)) { /* hit - perhaps steal */ /* if hit 1/20 chance of stealing amulet & vanish - amulet is on level 26 again. */ if(hitu(mtmp, d(mtmp->data->damn,mtmp->data->damd)) && !rn2(20) && stealamulet(mtmp)) ; } else inrange(mtmp); /* try magic */ return(0); }
/* return 0 (no move), 1 (move) or 2 (dead) */ int dog_move(struct monst *mtmp, int after) { int nx, ny, omx, omy, appr, nearer, j; int udist, chi, i, whappr; struct monst *mtmp2; struct permonst *mdat = mtmp->data; struct edog *edog = EDOG(mtmp); struct obj *obj; struct trap *trap; xchar cnt, chcnt, nix, niy; schar dogroom, uroom; xchar gx, gy, gtyp, otyp; /* current goal */ coord poss[9]; int info[9]; #define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy)) #define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy)) if(moves <= edog->eattime) return(0); /* dog is still eating */ omx = mtmp->mx; omy = mtmp->my; whappr = (moves - EDOG(mtmp)->whistletime < 5); if(moves > edog->hungrytime + 500 && !mtmp->mconf){ mtmp->mconf = 1; mtmp->mhpmax /= 3; if(mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; if(cansee(omx,omy)) pline("%s is confused from hunger.", Monnam(mtmp)); else pline("You feel worried about %s.", monnam(mtmp)); } else if(moves > edog->hungrytime + 750 || mtmp->mhp < 1){ if(cansee(omx,omy)) pline("%s dies from hunger.", Monnam(mtmp)); else pline("You have a sad feeling for a moment, then it passes."); mondied(mtmp); return(2); } dogroom = inroom(omx,omy); uroom = inroom(u.ux,u.uy); udist = dist(omx,omy); /* maybe we tamed him while being swallowed --jgm */ if(!udist) return(0); /* if we are carrying sth then we drop it (perhaps near @) */ /* Note: if apport == 1 then our behaviour is independent of udist */ if(mtmp->minvent){ if(!rn2(udist) || !rn2((int) edog->apport)) if(rn2(10) < edog->apport){ relobj(mtmp, (int) mtmp->minvis); if(edog->apport > 1) edog->apport--; edog->dropdist = udist; /* hpscdi!jon */ edog->droptime = moves; } } else { if ((obj = o_at(omx,omy))) if(!strchr("0_", obj->olet)){ if((otyp = dogfood(obj)) <= CADAVER){ nix = omx; niy = omy; goto eatobj; } if (obj->owt < 10*mtmp->data->mlevel) if (rn2(20) < edog->apport+3) if (rn2(udist) || !rn2((int) edog->apport)){ freeobj(obj); unpobj(obj); /* if(levl[omx][omy].scrsym == obj->olet) newsym(omx,omy); */ mpickobj(mtmp,obj); } } } /* first we look for food */ gtyp = UNDEF; /* no goal as yet */ gx = gy = 0; for(obj = fobj; obj; obj = obj->nobj) { otyp = dogfood(obj); if(otyp > gtyp || otyp == UNDEF) continue; if(inroom(obj->ox,obj->oy) != dogroom) continue; if(otyp < MANFOOD && (dogroom >= 0 || DDIST(obj->ox,obj->oy) < 10)) { if(otyp < gtyp || (otyp == gtyp && DDIST(obj->ox,obj->oy) < DDIST(gx,gy))){ gx = obj->ox; gy = obj->oy; gtyp = otyp; } } else if(gtyp == UNDEF && dogroom >= 0 && uroom == dogroom && !mtmp->minvent && edog->apport > rn2(8)){ gx = obj->ox; gy = obj->oy; gtyp = APPORT; } } if(gtyp == UNDEF || (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)){ if(dogroom < 0 || dogroom == uroom){ gx = u.ux; gy = u.uy; #ifndef QUEST } else { int tmp = rooms[(int)dogroom].fdoor; cnt = rooms[(int)dogroom].doorct; gx = gy = FAR; /* random, far away */ while(cnt--){ if(dist(gx,gy) > dist(doors[tmp].x, doors[tmp].y)){ gx = doors[tmp].x; gy = doors[tmp].y; } tmp++; } /* here gx == FAR e.g. when dog is in a vault */ if(gx == FAR || (gx == omx && gy == omy)){ gx = u.ux; gy = u.uy; } #endif /* QUEST */ } appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0; if(after && udist <= 4 && gx == u.ux && gy == u.uy) return(0); if(udist > 1){ if (!IS_ROOM(levl[(int)u.ux][(int)u.uy].typ) || !rn2(4) || whappr || (mtmp->minvent && rn2((int) edog->apport))) appr = 1; } /* if you have dog food he'll follow you more closely */ if (appr == 0) { obj = invent; while(obj){ if(obj->otyp == TRIPE_RATION){ appr = 1; break; } obj = obj->nobj; } } } else appr = 1; /* gtyp != UNDEF */ if(mtmp->mconf) appr = 0; if(gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)){ coord *cp; cp = gettrack(omx,omy); if(cp){ gx = cp->x; gy = cp->y; } } nix = omx; niy = omy; cnt = mfndpos(mtmp,poss,info,ALLOW_M | ALLOW_TRAPS); chcnt = 0; chi = -1; for(i=0; i<cnt; i++){ nx = poss[i].x; ny = poss[i].y; if(info[i] & ALLOW_M){ mtmp2 = m_at(nx,ny); if(mtmp2->data->mlevel >= mdat->mlevel+2 || mtmp2->data->mlet == 'c') continue; if(after) return(0); /* hit only once each move */ if(hitmm(mtmp, mtmp2) == 1 && rn2(4) && mtmp2->mlstmv != moves && hitmm(mtmp2,mtmp) == 2) return(2); return(0); } /* dog avoids traps */ /* but perhaps we have to pass a trap in order to follow @ */ if((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))){ if(!trap->tseen && rn2(40)) continue; if(rn2(10)) continue; } /* dog eschewes cursed objects */ /* but likes dog food */ obj = fobj; while(obj){ if(obj->ox != nx || obj->oy != ny) goto nextobj; if(obj->cursed) goto nxti; if(obj->olet == FOOD_SYM && (otyp = dogfood(obj)) < MANFOOD && (otyp < ACCFOOD || edog->hungrytime <= moves)){ /* Note: our dog likes the food so much that he might eat it even when it conceals a cursed object */ nix = nx; niy = ny; chi = i; eatobj: edog->eattime = moves + obj->quan * objects[obj->otyp].oc_delay; if(edog->hungrytime < moves) edog->hungrytime = moves; edog->hungrytime += 5*obj->quan * objects[obj->otyp].nutrition; mtmp->mconf = 0; if(cansee(nix,niy)) pline("%s ate %s.", Monnam(mtmp), doname(obj)); /* perhaps this was a reward */ if(otyp != CADAVER) edog->apport += 200/(edog->dropdist+moves-edog->droptime); delobj(obj); goto newdogpos; } nextobj: obj = obj->nobj; } for(j=0; j<MTSZ && j<cnt-1; j++) if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) if(rn2(4*(cnt-j))) goto nxti; /* Some stupid C compilers cannot compute the whole expression at once. */ nearer = GDIST(nx,ny); nearer -= GDIST(nix,niy); nearer *= appr; if((nearer == 0 && !rn2(++chcnt)) || nearer<0 || (nearer > 0 && !whappr && ((omx == nix && omy == niy && !rn2(3)) || !rn2(12)) )){ nix = nx; niy = ny; if(nearer < 0) chcnt = 0; chi = i; } nxti: ; } newdogpos: if(nix != omx || niy != omy){ if(info[chi] & ALLOW_U){ (void) hitu(mtmp, d(mdat->damn, mdat->damd)+1); return(0); } mtmp->mx = nix; mtmp->my = niy; for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1]; mtmp->mtrack[0].x = omx; mtmp->mtrack[0].y = omy; } if(mintrap(mtmp) == 2) /* he died */ return(2); pmon(mtmp); return(1); }
/* * shk_move: return 1: he moved 0: he didnt -1: let m_move do it */ int shk_move(struct monst *shkp) { struct monst *mtmp; struct permonst *mdat = shkp->data; xchar gx, gy, omx, omy, nx, ny, nix, niy; schar appr, i; int udist; int z; schar shkroom, chi, chcnt, cnt; boolean uondoor = 0, satdoor, avoid = 0, badinv; coord poss[9]; int info[9]; struct obj *ib = NULL; omx = shkp->mx; omy = shkp->my; if ((udist = dist(omx, omy)) < 3) { if (ANGRY(shkp)) { hitu(shkp, d(mdat->damn, mdat->damd) + 1); return (0); } if (ESHK(shkp)->following) { if (strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)) { pline("Hello %s! I was looking for %s.", plname, ESHK(shkp)->customer); ESHK(shkp)->following = 0; return (0); } if (!ESHK(shkp)->robbed) { /* impossible? */ ESHK(shkp)->following = 0; return (0); } if (moves > followmsg + 4) { pline("Hello %s! Didn't you forget to pay?", plname); followmsg = moves; } if (udist < 2) return (0); } } shkroom = inroom(omx, omy); appr = 1; gx = ESHK(shkp)->shk.x; gy = ESHK(shkp)->shk.y; satdoor = (gx == omx && gy == omy); if (ESHK(shkp)->following || ((z = holetime()) >= 0 && z * z <= udist)) { gx = u.ux; gy = u.uy; if (shkroom < 0 || shkroom != inroom(u.ux, u.uy)) if (udist > 4) return (-1); /* leave it to m_move */ } else if (ANGRY(shkp)) { long saveBlind = Blind; Blind = 0; if (shkp->mcansee && !Invis && cansee(omx, omy)) { gx = u.ux; gy = u.uy; } Blind = saveBlind; avoid = FALSE; } else { #define GDIST(x, y) ((x - gx) * (x - gx) + (y - gy) * (y - gy)) if (Invis) avoid = FALSE; else { uondoor = (u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y); if (uondoor) { if (ESHK(shkp)->billct) pline("Hello %s! Will you please pay before leaving?", plname); badinv = (carrying(PICK_AXE) || carrying(ICE_BOX)); if (satdoor && badinv) return (0); avoid = !badinv; } else { avoid = (u.uinshop && dist(gx, gy) > 8); badinv = FALSE; } if (((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid) && GDIST(omx, omy) < 3) { if (!badinv && !online(omx, omy)) return (0); if (satdoor) appr = gx = gy = 0; } } } if (omx == gx && omy == gy) return (0); if (shkp->mconf) { avoid = FALSE; appr = 0; } nix = omx; niy = omy; cnt = mfndpos(shkp, poss, info, ALLOW_SSM); if (avoid && uondoor) { /* perhaps we cannot avoid him */ for (i = 0; i < cnt; i++) if (!(info[i] & NOTONL)) goto notonl_ok; avoid = FALSE; notonl_ok: ; } chi = -1; chcnt = 0; for (i = 0; i < cnt; i++) { nx = poss[i].x; ny = poss[i].y; if (levl[nx][ny].typ == ROOM || shkroom != ESHK(shkp)->shoproom || ESHK(shkp)->following) { #ifdef STUPID /* cater for stupid compilers */ int zz; #endif /* STUPID */ if (uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) { nix = nx; niy = ny; chi = i; break; } if (avoid && (info[i] & NOTONL)) continue; if ((!appr && !rn2(++chcnt)) || #ifdef STUPID (appr && (zz = GDIST(nix, niy)) && zz > GDIST(nx, ny)) #else (appr && GDIST(nx, ny) < GDIST(nix, niy)) #endif /* STUPID */ ) { nix = nx; niy = ny; chi = i; } } } if (nix != omx || niy != omy) { if (info[chi] & ALLOW_M) { mtmp = m_at(nix, niy); if (hitmm(shkp, mtmp) == 1 && rn2(3) && hitmm(mtmp, shkp) == 2) return (2); return (0); } else if (info[chi] & ALLOW_U) { hitu(shkp, d(mdat->damn, mdat->damd) + 1); return (0); } shkp->mx = nix; shkp->my = niy; pmon(shkp); if (ib) { freeobj(ib); mpickobj(shkp, ib); } return (1); } return (0); }
int m_move(struct monst *mtmp, int after) { struct monst *mtmp2; int nx = 0; int ny = 0; int omx; int omy; int appr; int nearer; int cnt; int i; int j; xchar gx; xchar gy; xchar nix; xchar niy; xchar chcnt; schar chi; boolean likegold = 0; boolean likegems = 0; boolean likeobjs = 0; /* Not strictly necessary: chi >= 0 will do */ schar mmoved = 0; coord poss[9]; int info[9]; if(mtmp->mtrapped != 0) { i = mintrap(mtmp); if(i == 2) { /* He died */ return 2; } if(i == 1) { /* Still in trap so didn't move */ return 0; } } if((mtmp->mhide != 0) && (o_at(mtmp->mx, mtmp->my) != NULL) && (rn2(10) != 0)) { /* Do not leave hiding place */ return 0; } /* My dog gets a special treatment */ if(mtmp->mtame != 0) { return dog_move(mtmp, after); } /* Likewise for shopkeeper */ if(mtmp->isshk != 0) { mmoved = shk_move(); if(mmoved == 1) { if(mintrap(mtmp) == 2) { /* He died */ return 2; } if(likegold != 0) { mpickgold(mtmp); } if(likegems != 0) { mpickgems(mtmp); } if(mtmp->mhide != 0) { mtmp->mundetected = 1; } } return mmoved; } /* And for the guard */ if(mtmp->isgd != 0) { mmoved = gd_move(); if(mmoved == 1) { if(mintrap(mtmp) == 2) { /* He died */ return 2; } if(likegold != 0) { mpickgold(mtmp); } if(likegems != 0) { mpickgems(mtmp); } if(mtmp->mhide != 0) { mtmp->mundetected = 1; } } return mmoved; } if((mtmp->data->mlet == 't') && (rn2(5) == 0)) { if(rn2(2) != 0) { mnexto(mtmp); } else { rloc(mtmp); } mmoved = 1; if(mmoved == 1) { if(mintrap(mtmp) == 2) { /* He died */ return 2; } if(likegold != 0) { mpickgold(mtmp); } if(likegems != 0) { mpickgems(mtmp); } if(mtmp->mhide != 0) { mtmp->mundetected = 1; } } return mmoved; } if((mtmp->data->mlet == 'D') && (mtmp->mcan == 0)) { inrange(mtmp); } if((Blind == 0) && (Confusion == 0) && (mtmp->data->mlet == 'U') && (mtmp->mcan == 0) && (cansee(mtmp->mx, mtmp->my) != 0) && (rn2(5) != 0)) { pline("%s's gaze has confused you!", Monnam(mtmp)); if(rn2(5) != 0) { mtmp->mcan = 1; } /* Timeout */ Confusion = d(3, 4); } if((mtmp->mflee == 0) && (u.uswallow != 0) && (u.ustuck != mtmp)) { return 1; } appr = 1; if(mtmp->mflee != 0) { appr = -1; } if((mtmp->mconf != 0) || (Invis != 0) || (mtmp->mcansee == 0) || ((index("Biy", mtmp->data->mlet) != 0) && (rn2(3) == 0))) { appr = 0; } omx = mtmp->mx; omy = mtmp->my; gx = u.ux; gy = u.uy; if((mtmp->data->mlet == 'L') && (appr == 1) && (mtmp->mgold > u.ugold)) { appr = -1; } #ifdef TRACK /* * Random criterion for 'smell' * should use mtmp->msmell */ if(('a' <= mtmp->data->mlet) && (mtmp->data->mlet <= 'z')) { coord *cp; schar mroom; mroom = inroom(omx, omy); if((mroom < 0) || (mroom != inroom(u.ux, u.uy))) { cp = gettrack(omx, omy); if(cp != 0) { gx = cp->x; gy = cp->y; } } } #endif /* Look for gold or jewels nearby */ if(index("LOD", mtmp->data->mlet) != NULL) { likegold = 1; } else { likegold = 0; } if(index("ODu", mtmp->data->mlet) != NULL) { likegems = 1; } else { likegems = 0; } likeobjs = mtmp->mhide; #define SRCHRADIUS 25 /* Not too far away */ xchar mind = SRCHRADIUS; int dd; if(likegold != 0) { struct gen *gold; for(gold = fgold; gold != NULL; gold = gold->ngen) { dd = DIST(omx, omy, gold->gx, gold->gy); if(dd < mind) { mind = dd; gx = gold->gx; gy = gold->gy; } } } if((likegems != 0) || (likeobjs != 0)) { struct obj *otmp; for(otmp = fobj; otmp != NULL; otmp = otmp->nobj) { if((likeobjs != 0) || (otmp->olet == GEM_SYM)) { if((mtmp->data->mlet != 'u') || (objects[otmp->otyp].g_val != 0)) { dd = DIST(omx, omy, otmp->ox, otmp->oy); if(dd < mind) { mind = dd; gx = otmp->ox; gy = otmp->oy; } } } } } if((mind < SRCHRADIUS) && (appr == -1)) { if(dist(omx, omy) < 10) { gx = u.ux; gy = u.uy; } else { appr = 1; } } nix = omx; niy = omy; if(mtmp->data->mlet == 'u') { cnt = mfndpos(mtmp, poss, info, NOTONL); } else { if(index(" VWZ", mtmp->data->mlet) != 0) { cnt = mfndpos(mtmp, poss, info, NOGARLIC); } else { cnt = mfndpos(mtmp, poss, info, ALLOW_TRAPS); } } /* ALLOW_ROCK for some monsters? */ chcnt = 0; chi = -1; for(i = 0; i < cnt; ++i) { nx = poss[i].x; nx = poss[i].y; for(j = 0; (j < MTSZ) && (j < (cnt - 1)); ++j) { if((nx == mtmp->mtrack[j].x) && (ny == mtmp->mtrack[j].y)) { if(rn2(4 * (cnt - j)) == 0) { #ifdef STUPID /* Some stupid compilers thing that is is too complicated */ int d1 = DIST(nx, ny, gx, gy); int d2 = DIST(nix, niy, gx, gy); if(d1 < d2) { nearer = 1; } else { nearer = 0; } #else if(DIST(nx, ny, gx, gy) < DIST(nix, niy, gx, gy)) { nearer = 1; } else { nearer = 0; } #endif if(((appr == 1) && (nearer != 0)) || ((appr == -1) && (nearer == 0)) || (mmoved == 0)) { nix = nx; niy = ny; chi = i; mmoved = 1; } else { if(appr == 0) { if(rn2(chcnt) == 0) { ++chcnt; nix = nx; niy = ny; chi = i; mmoved = 1; } else { ++chcnt; } } } } } } } if(mmoved != 0) { if((info[(int)chi] & ALLOW_M) != 0) { mtmp2 = m_at(nix, niy); if((hitmm(mtmp, mtmp2) == 1) && (rn2(4) != 0) && (hitmm(mtmp2, mtmp) == 2)) { return 2; } return 0; } if((info[(int)chi] & ALLOW_U) != 0) { hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd) + 1); return 0; } mtmp->mx = nix; mtmp->my = niy; for(j = MTSZ - 1; j > 0; --j) { mtmp->mtrack[j] = mtmp->mtrack[j - 1]; } mtmp->mtrack[0].x = omx; mtmp->mtrack[0].y = omy; #ifndef NOWORM if(mtmp->wormno != 0) { worm_move(mtmp); } #endif } else { if((mtmp->data->mlet == 'u') && (rn2(2) != 0)) { rloc(mtmp); return 0; } #ifndef NOWORM if(mtmp->wormno != 0) { worm_nomove(mtmp); } #endif } if(mmoved == 1) { if(mintrap(mtmp) == 2) { /* He died */ return 2; } if(likegold != 0) { mpickgold(mtmp); } if(likegems != 0) { mpickgems(mtmp); } if(mtmp->mhide != 0) { mtmp->mundetected = 1; } } pmon(mtmp); return mmoved; }
/* * mhitu: monster hits you * returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise */ bool mhitu(struct monst *mtmp) { struct permonst *mdat = mtmp->data; int tmp, ctmp; nomul(0); /* If swallowed, can only be affected by hissers and by u.ustuck */ if (u.uswallow) { if (mtmp != u.ustuck) { if (mdat->mlet == 'c' && !rn2(13)) { pline("Outside, you hear %s's hissing!", monnam(mtmp)); pline("%s gets turned to stone!", Monnam(u.ustuck)); pline("And the same fate befalls you."); done_in_by(mtmp); /* "notreached": not return(1); */ } return (0); } switch (mdat->mlet) { /* now mtmp == u.ustuck */ case ',': youswld(mtmp, (u.uac > 0) ? u.uac + 4 : 4, 5, "The trapper"); break; case '\'': youswld(mtmp, rnd(6), 7, "The lurker above"); break; case 'P': youswld(mtmp, d(2, 4), 12, "The purple worm"); break; default: /* This is not impossible! */ pline("The mysterious monster totally digests you."); u.uhp = 0; } if (u.uhp < 1) done_in_by(mtmp); return (0); } if (mdat->mlet == 'c' && Stoned) return (0); /* make eels visible the moment they hit/miss us */ if (mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx, mtmp->my)) { mtmp->minvis = 0; pmon(mtmp); } if (!strchr("1&DuxynNF", mdat->mlet)) tmp = hitu(mtmp, d(mdat->damn, mdat->damd)); else tmp = 0; if (strchr(UNDEAD, mdat->mlet) && midnight()) tmp += hitu(mtmp, d(mdat->damn, mdat->damd)); ctmp = tmp && !mtmp->mcan && (!uarm || objects[uarm->otyp].a_can < rnd(3) || !rn2(50)); switch (mdat->mlet) { case '1': if (wiz_hit(mtmp)) /* he disappeared */ return (1); break; case '&': if (!mtmp->cham && !mtmp->mcan && !rn2(13)) { makemon(PM_DEMON, u.ux, u.uy); } else { hitu(mtmp, d(2, 6)); hitu(mtmp, d(2, 6)); hitu(mtmp, rnd(3)); hitu(mtmp, rnd(3)); hitu(mtmp, rn1(4, 2)); } break; case ',': if (tmp) justswld(mtmp, "The trapper"); break; case '\'': if (tmp) justswld(mtmp, "The lurker above"); break; case ';': if (ctmp) { if (!u.ustuck && !rn2(10)) { pline("%s swings itself around you!", Monnam(mtmp)); u.ustuck = mtmp; } else if (u.ustuck == mtmp && levl[mtmp->mx][mtmp->my].typ == POOL) { pline("%s drowns you ...", Monnam(mtmp)); done("drowned"); } } break; case 'A': if (ctmp && rn2(2)) { if (Poison_resistance) pline("The sting doesn't seem to affect you."); else { pline("You feel weaker!"); losestr(1); } } break; case 'C': hitu(mtmp, rnd(6)); break; case 'c': if (!rn2(5)) { pline("You hear %s's hissing!", monnam(mtmp)); if (ctmp || !rn2(20) || (flags.moonphase == NEW_MOON && !carrying(DEAD_LIZARD))) Stoned = 5; } break; case 'D': if (rn2(6) || mtmp->mcan) { hitu(mtmp, d(3, 10)); hitu(mtmp, rnd(8)); hitu(mtmp, rnd(8)); break; } kludge("%s breathes fire!", "The dragon"); buzz(-1, mtmp->mx, mtmp->my, u.ux - mtmp->mx, u.uy - mtmp->my); break; case 'd': hitu(mtmp, d(2, (flags.moonphase == FULL_MOON) ? 3 : 4)); break; case 'e': hitu(mtmp, d(3, 6)); break; case 'F': if (mtmp->mcan) break; kludge("%s explodes!", "The freezing sphere"); if (Cold_resistance) pline("You don't seem affected by it."); else { xchar dn; if (17 - (u.ulevel / 2) > rnd(20)) { pline("You get blasted!"); dn = 6; } else { pline("You duck the blast..."); dn = 3; } losehp_m(d(dn, 6), mtmp); } mondead(mtmp); return (1); case 'g': if (ctmp && multi >= 0 && !rn2(3)) { kludge("You are frozen by %ss juices", "the cube'"); nomul(-rnd(10)); } break; case 'h': if (ctmp && multi >= 0 && !rn2(5)) { nomul(-rnd(10)); kludge("You are put to sleep by %ss bite!", "the homunculus'"); } break; case 'j': tmp = hitu(mtmp, rnd(3)); tmp &= hitu(mtmp, rnd(3)); if (tmp) { hitu(mtmp, rnd(4)); hitu(mtmp, rnd(4)); } break; case 'k': if ((hitu(mtmp, rnd(4)) || !rn2(3)) && ctmp) poisoned("bee's sting", mdat->mname); break; case 'L': if (tmp) stealgold(mtmp); break; case 'N': if (mtmp->mcan && !Blind) { pline("%s tries to seduce you, but you seem not interested.", Amonnam(mtmp, "plain")); if (rn2(3)) rloc(mtmp); } else if (steal(mtmp)) { rloc(mtmp); mtmp->mflee = 1; } break; case 'n': if (!uwep && !uarm && !uarmh && !uarms && !uarmg) { pline("%s hits! (I hope you don't mind)", Monnam(mtmp)); u.uhp += rnd(7); if (!rn2(7)) u.uhpmax++; if (u.uhp > u.uhpmax) u.uhp = u.uhpmax; flags.botl = 1; if (!rn2(50)) rloc(mtmp); } else { hitu(mtmp, d(2, 6)); hitu(mtmp, d(2, 6)); } break; case 'o': tmp = hitu(mtmp, rnd(6)); if (hitu(mtmp, rnd(6)) && tmp && /* hits with both paws */ !u.ustuck && rn2(2)) { u.ustuck = mtmp; kludge("%s has grabbed you!", "The owlbear"); u.uhp -= d(2, 8); } else if (u.ustuck == mtmp) { u.uhp -= d(2, 8); pline("You are being crushed."); } break; case 'P': if (ctmp && !rn2(4)) justswld(mtmp, "The purple worm"); else hitu(mtmp, d(2, 4)); break; case 'Q': hitu(mtmp, rnd(2)); hitu(mtmp, rnd(2)); break; case 'R': if (tmp && uarmh && !uarmh->rustfree && (int)uarmh->spe >= -1) { pline("Your helmet rusts!"); uarmh->spe--; } else if (ctmp && uarm && !uarm->rustfree && /* Mike Newton */ uarm->otyp < STUDDED_LEATHER_ARMOR && (int)uarm->spe >= -1) { pline("Your armor rusts!"); uarm->spe--; } break; case 'S': if (ctmp && !rn2(8)) poisoned("snake's bite", mdat->mname); break; case 's': if (tmp && !rn2(8)) poisoned("scorpion's sting", mdat->mname); hitu(mtmp, rnd(8)); hitu(mtmp, rnd(8)); break; case 'T': hitu(mtmp, rnd(6)); hitu(mtmp, rnd(6)); break; case 't': if (!rn2(5)) rloc(mtmp); break; case 'u': mtmp->mflee = 1; break; case 'U': hitu(mtmp, d(3, 4)); hitu(mtmp, d(3, 4)); break; case 'v': if (ctmp && !u.ustuck) u.ustuck = mtmp; break; case 'V': if (tmp) u.uhp -= 4; if (ctmp) losexp(); break; case 'W': if (ctmp) losexp(); break; #ifndef NOWORM case 'w': if (tmp) wormhit(mtmp); #endif /* NOWORM */ break; case 'X': hitu(mtmp, rnd(5)); hitu(mtmp, rnd(5)); hitu(mtmp, rnd(5)); break; case 'x': { long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; pline("%s pricks in your %s leg!", Monnam(mtmp), (side == RIGHT_SIDE) ? "right" : "left"); set_wounded_legs(side, rnd(50)); losehp_m(2, mtmp); break; } case 'y': if (mtmp->mcan) break; mondead(mtmp); if (!Blind) { pline("You are blinded by a blast of light!"); Blind = d(4, 12); seeoff(0); } return (1); case 'Y': hitu(mtmp, rnd(6)); break; } if (u.uhp < 1) done_in_by(mtmp); return (0); }