--- nethack-3.4.3/src/hack.c 2003-12-08 00:39:13.000000000 +0100 +++ nethack-3.4.3/src/hack.c 2008-01-06 11:39:06.000000000 +0100 @@ -499,6 +499,71 @@ dosinkfall() } #endif +static NEARDATA int dpx,dpy; /* boulder being attacked */ +static NEARDATA int breakturns; /* concentration turn */ + +STATIC_OVL int +ma_break() +{ + struct obj *bobj, *obj; + int success = 0; + int prob; + /* maybe you teleported away or boulder got eaten by a rock mole */ + if (distu(dpx,dpy) > 2 || + (obj = sobj_at(BOULDER, dpx, dpy)) == 0){ + Your("chakra vanishes uncontrolled."); + make_confused(6+breakturns*P_SKILL(P_BARE_HANDED_COMBAT), FALSE); + return(0); + } + if (breakturns < 48 / P_SKILL(P_BARE_HANDED_COMBAT)){ + breakturns++; + return(1); /* still concentrating */ + } + + You("hit the rock."); + if (In_sokoban(&u.uz)){ + pline("Somehow the rock doesn't fall apart."); + return(0); /* done */ + } + + /* even while blind you can first feel and then image the boulder */ + if (Confusion || Hallucination || Stunned){ + You("miss your mark."); + losehp(d(1,6), "Didn't hit while splitting a boulder.", NO_KILLER_PREFIX); + return(0); + } + + prob = 40; + prob -= u.ulevel; + prob /= P_SKILL(P_BARE_HANDED_COMBAT); + if (uarmg) + switch (uarmg->otyp){ + case GAUNTLETS_OF_POWER: prob -= 10; break; + case GAUNTLETS_OF_FUMBLING: prob *= 4; break; + case LEATHER_GLOVES: + case GAUNTLETS_OF_DEXTERITY: + break; + default: + impossible("Unknown type of gloves (%d)", uarmg->otyp); + } + if (3 > prob) + prob = 3; /* don't be always successful without skill */ + if (P_SKILL(P_BARE_HANDED_COMBAT) > P_EXPERT || !rn2(prob)){ + obj = sobj_at(BOULDER, dpx, dpy); + fracture_rock(obj); + if ((bobj = sobj_at(BOULDER, dpx, dpy)) != 0) { + /* another boulder here, restack it to the top */ + obj_extract_self(bobj); + place_object(bobj, dpx, dpy); + } + pline_The("boulder falls apart."); + } else { + pline("But you are not strong enough to damage the boulder."); + losehp(d(1,6), "trying to split a boulder.", KILLED_BY); + } + return(0); /* done */ +} + boolean may_dig(x,y) register xchar x,y; @@ -1099,19 +1164,33 @@ domove() if (flags.forcefight || /* remembered an 'I' && didn't use a move command */ (glyph_is_invisible(levl[x][y].glyph) && !flags.nopick)) { - boolean expl = (Upolyd && attacktype(youmonst.data, AT_EXPL)); - char buf[BUFSZ]; - Sprintf(buf,"a vacant spot on the %s", surface(x,y)); - You("%s %s.", - expl ? "explode at" : "attack", - !Underwater ? "thin air" : - is_pool(x,y) ? "empty water" : buf); - unmap_object(x, y); /* known empty -- remove 'I' if present */ - newsym(x, y); - nomul(0); - if (expl) { - u.mh = -1; /* dead in the current form */ - rehumanize(); + struct obj *obj; + if ((obj = sobj_at(BOULDER, x, y)) != 0 && + weapon_type(uwep) == P_BARE_HANDED_COMBAT) { + if (P_SKILL(P_BARE_HANDED_COMBAT) < P_BASIC){ + You("don't know enough about martial arts to try splitting a boulder."); + } else { + You("start molding Chakra."); + dpx = x; + dpy = y; + breakturns = 0; + set_occupation(ma_break, "molding chakra", 0); + } + } else { + boolean expl = (Upolyd && attacktype(youmonst.data, AT_EXPL)); + char buf[BUFSZ]; + Sprintf(buf,"a vacant spot on the %s", surface(x,y)); + You("%s %s.", + expl ? "explode at" : "attack", + !Underwater ? "thin air" : + is_pool(x,y) ? "empty water" : buf); + unmap_object(x, y); /* known empty -- remove 'I' if present */ + newsym(x, y); + nomul(0); + if (expl) { + u.mh = -1; /* dead in the current form */ + rehumanize(); + } } return; }