/* u.dx and u.dy must be set */ bool attack(struct monst *mtmp) { schar tmp; boolean malive = TRUE; struct permonst *mdat; mdat = mtmp->data; u_wipe_engr(3); /* andrew@orca: prevent unlimited pick-axe attacks */ if (mdat->mlet == 'L' && !mtmp->mfroz && !mtmp->msleep && !mtmp->mconf && mtmp->mcansee && !rn2(7) && (m_move(mtmp, 0) == 2 /* he died */ || /* he moved: */ mtmp->mx != u.ux + u.dx || mtmp->my != u.uy + u.dy)) return (FALSE); if (mtmp->mimic) { if (!u.ustuck && !mtmp->mflee) u.ustuck = mtmp; switch (levl[u.ux + u.dx][u.uy + u.dy].scrsym) { case '+': pline("The door actually was a Mimic."); break; case '$': pline("The chest was a Mimic!"); break; default: pline("Wait! That's a Mimic!"); } wakeup(mtmp); /* clears mtmp->mimic */ return (TRUE); } wakeup(mtmp); if (mtmp->mhide && mtmp->mundetected) { struct obj *obj; mtmp->mundetected = 0; if ((obj = o_at(mtmp->mx, mtmp->my)) && !Blind) pline("Wait! There's a %s hiding under %s!", mdat->mname, doname(obj)); return (TRUE); } tmp = u.uluck + u.ulevel + mdat->ac + abon(); if (uwep) { if (uwep->olet == WEAPON_SYM || uwep->otyp == PICK_AXE) tmp += uwep->spe; if (uwep->otyp == TWO_HANDED_SWORD) tmp -= 1; else if (uwep->otyp == DAGGER) tmp += 2; else if (uwep->otyp == CRYSKNIFE) tmp += 3; else if (uwep->otyp == SPEAR && strchr("XDne", mdat->mlet)) tmp += 2; } if (mtmp->msleep) { mtmp->msleep = 0; tmp += 2; } if (mtmp->mfroz) { tmp += 4; if (!rn2(10)) mtmp->mfroz = 0; } if (mtmp->mflee) tmp += 2; if (u.utrap) tmp -= 3; /* with a lot of luggage, your agility diminishes */ tmp -= (inv_weight() + 40) / 20; if (tmp <= rnd(20) && !u.uswallow) { if (Blind) pline("You miss it."); else pline("You miss %s.", monnam(mtmp)); } else { /* we hit the monster; be careful: it might die! */ if ((malive = hmon(mtmp, uwep, 0)) == TRUE) { /* monster still alive */ if (!rn2(25) && mtmp->mhp < mtmp->mhpmax / 2) { mtmp->mflee = 1; if (!rn2(3)) mtmp->mfleetim = rnd(100); if (u.ustuck == mtmp && !u.uswallow) u.ustuck = 0; } #ifndef NOWORM if (mtmp->wormno) cutworm(mtmp, u.ux + u.dx, u.uy + u.dy, uwep ? uwep->otyp : 0); #endif /* NOWORM */ } if (mdat->mlet == 'a') { if (rn2(2)) { pline("You are splashed by the blob's acid!"); losehp_m(rnd(6), mtmp); if (!rn2(30)) corrode_armor(); } if (!rn2(6)) corrode_weapon(); } } if (malive && mdat->mlet == 'E' && canseemon(mtmp) && !mtmp->mcan && rn2(3)) { if (mtmp->mcansee) { pline("You are frozen by the floating eye's gaze!"); nomul((u.ulevel > 6 || rn2(4)) ? rn1(20, -21) : -200); } else { pline("The blinded floating eye cannot defend itself."); if (!rn2(500)) if ((int)u.uluck > LUCKMIN) u.uluck--; } } return (TRUE); }
int dothrow() { struct obj *obj; struct monst *mon; int tmp; obj = getobj("#)", "throw"); /* it is also possible to throw food */ /* (or jewels, or iron balls ... ) */ if(!obj || !getdir(1)) /* ask "in what direction?" */ return(0); if(obj->owornmask & (W_ARMOR | W_RING)){ pline("You can't throw something you are wearing."); return(0); } u_wipe_engr(2); if(obj == uwep){ if(obj->cursed){ pline("Your weapon is welded to your hand."); return(1); } if(obj->quan > 1) setuwep(splitobj(obj, 1)); else setuwep((struct obj *) 0); } else if(obj->quan > 1) (void) splitobj(obj, 1); freeinv(obj); if(u.uswallow) { mon = u.ustuck; bhitpos.x = mon->mx; bhitpos.y = mon->my; } else if(u.dz) { if(u.dz < 0) { pline("%s hits the ceiling, then falls back on top of your head.", Doname(obj)); /* note: obj->quan == 1 */ if(obj->olet == POTION_SYM) potionhit(&youmonst, obj); else { if(uarmh) pline("Fortunately, you are wearing a helmet!"); losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object"); dropy(obj); } } else { pline("%s hits the floor.", Doname(obj)); if(obj->otyp == EXPENSIVE_CAMERA) { pline("It is shattered in a thousand pieces!"); obfree(obj, Null(obj)); } else if(obj->otyp == EGG) { pline("\"Splash!\""); obfree(obj, Null(obj)); } else if(obj->olet == POTION_SYM) { pline("The flask breaks, and you smell a peculiar odor ..."); potionbreathe(obj); obfree(obj, Null(obj)); } else { dropy(obj); } } return(1); } else if(obj->otyp == BOOMERANG) { mon = boomhit(u.dx, u.dy); if(mon == &youmonst) { /* the thing was caught */ (void) addinv(obj); return(1); } } else { if(obj->otyp == PICK_AXE && shkcatch(obj)) return(1); mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 : (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1, obj->olet, NULL, NULL, obj); } if(mon) { /* awake monster if sleeping */ wakeup(mon); if(obj->olet == WEAPON_SYM) { tmp = -1+u.ulevel+mon->data->ac+abon(); if(obj->otyp < ROCK) { if(!uwep || uwep->otyp != obj->otyp+(BOW-ARROW)) tmp -= 4; else { tmp += uwep->spe; } } else if(obj->otyp == BOOMERANG) tmp += 4; tmp += obj->spe; if(u.uswallow || tmp >= rnd(20)) { if(hmon(mon,obj,1) == TRUE){ /* mon still alive */ #ifndef NOWORM cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp); #endif /* NOWORM */ } else mon = 0; /* weapons thrown disappear sometimes */ if(obj->otyp < BOOMERANG && rn2(3)) { /* check bill; free */ obfree(obj, (struct obj *) 0); return(1); } } else miss(objects[obj->otyp].oc_name, mon); } else if(obj->otyp == HEAVY_IRON_BALL) { tmp = -1+u.ulevel+mon->data->ac+abon(); if(!Punished || obj != uball) tmp += 2; if(u.utrap) tmp -= 2; if(u.uswallow || tmp >= rnd(20)) { if(hmon(mon,obj,1) == FALSE) mon = 0; /* he died */ } else miss("iron ball", mon); } else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) { potionhit(mon, obj); return(1); } else { if(cansee(bhitpos.x,bhitpos.y)) pline("You miss %s.",monnam(mon)); else pline("You miss it."); if(obj->olet == FOOD_SYM && mon->data->mlet == 'd') if(tamedog(mon,obj)) return(1); if(obj->olet == GEM_SYM && mon->data->mlet == 'u' && !mon->mtame){ if(obj->dknown && objects[obj->otyp].oc_name_known){ if(objects[obj->otyp].g_val > 0){ u.uluck += 5; goto valuable; } else { pline("%s is not interested in your junk.", Monnam(mon)); } } else { /* value unknown to @ */ u.uluck++; valuable: if(u.uluck > LUCKMAX) /* dan@ut-ngp */ u.uluck = LUCKMAX; pline("%s graciously accepts your gift.", Monnam(mon)); mpickobj(mon, obj); rloc(mon); return(1); } } } } /* the code following might become part of dropy() */ if(obj->otyp == CRYSKNIFE) obj->otyp = WORM_TOOTH; obj->ox = bhitpos.x; obj->oy = bhitpos.y; obj->nobj = fobj; fobj = obj; /* prevent him from throwing articles to the exit and escaping */ /* subfrombill(obj); */ stackobj(obj); if(Punished && obj == uball && (bhitpos.x != u.ux || bhitpos.y != u.uy)){ freeobj(uchain); unpobj(uchain); if(u.utrap){ if(u.utraptype == TT_PIT) pline("The ball pulls you out of the pit!"); else { long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE; pline("The ball pulls you out of the bear trap."); pline("Your %s leg is severely damaged.", (side == LEFT_SIDE) ? "left" : "right"); set_wounded_legs(side, 500+rn2(1000)); losehp(2, "thrown ball"); } u.utrap = 0; } unsee(); uchain->nobj = fobj; fobj = uchain; u.ux = uchain->ox = bhitpos.x - u.dx; u.uy = uchain->oy = bhitpos.y - u.dy; setsee(); (void) inshop(); } if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y); return(1); }
static int dig() { struct rm *lev; int dpx = dig_pos.x, dpy = dig_pos.y; /* perhaps a nymph stole his pick-axe while he was busy digging */ /* or perhaps he teleported away */ if(u.uswallow || !uwep || uwep->otyp != PICK_AXE || dig_level != dlevel || ((dig_down && (dpx != u.ux || dpy != u.uy)) || (!dig_down && dist(dpx,dpy) > 2))) return(0); dig_effort += 10 + abon() + uwep->spe + rn2(5); if(dig_down) { if(!xdnstair) { pline("The floor here seems too hard to dig in."); return(0); } if(dig_effort > 250) { dighole(); return(0); /* done with digging */ } if(dig_effort > 50) { struct trap *ttmp = t_at(dpx,dpy); if(!ttmp) { ttmp = maketrap(dpx,dpy,PIT); ttmp->tseen = 1; pline("You have dug a pit."); u.utrap = rn1(4,2); u.utraptype = TT_PIT; return(0); } } } else if (dig_effort > 100) { char *digtxt; struct obj *obj; lev = &levl[dpx][dpy]; if ((obj = sobj_at(ENORMOUS_ROCK, dpx, dpy))) { fracture_rock(obj); digtxt = "The rock falls apart."; } else if(!lev->typ || lev->typ == SCORR) { lev->typ = CORR; digtxt = "You succeeded in cutting away some rock."; } else if(lev->typ == HWALL || lev->typ == VWALL || lev->typ == SDOOR) { lev->typ = xdnstair ? DOOR : ROOM; digtxt = "You just made an opening in the wall."; } else digtxt = "Now what exactly was it that you were digging in?"; mnewsym(dpx, dpy); prl(dpx, dpy); pline(digtxt); /* after mnewsym & prl */ return(0); } else { if(IS_WALL(levl[dpx][dpy].typ)) { int rno = inroom(dpx,dpy); if(rno >= 0 && rooms[rno].rtype >= 8) { pline("This wall seems too hard to dig into."); return(0); } } pline("You hit the rock with all your might."); } return(1); }