From: Pasi Kallinen Date: Wed, 6 Jan 2016 13:33:36 +0000 (+0200) Subject: Allow dissolving iron bars with potion of acid X-Git-Tag: NetHack-3.6.1_RC01~1064^2~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=237c4a2787119a5fc72741f650943923f7e4b12c;p=nethack Allow dissolving iron bars with potion of acid Force-fight iron bars with wielded potion of acid to dissolve them This change comes via UnNetHack by Patric Mueller. --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 88bbeecb7..292a9ff31 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -96,6 +96,7 @@ make commands that accept a count prefix for item selection show "Count:" like command repeating does allow picking a used inventory letter from menu when #adjusting zapping wand of opening at yourself, unlock carried boxes +dissolve iron bars by force-fighting with wielded potion of acid Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 52ffc37aa..ea89ad2ba 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1503,7 +1503,8 @@ E void FDECL(m_useupall, (struct monst *, struct obj *)); E void FDECL(m_useup, (struct monst *, struct obj *)); E void FDECL(m_throw, (struct monst *, int, int, int, int, int, struct obj *)); -E boolean FDECL(hits_bars, (struct obj **, int, int, int, int)); +E void FDECL(hit_bars, (struct obj **, int, int, int, int, boolean, boolean)); +E boolean FDECL(hits_bars, (struct obj **, int, int, int, int, int, int)); /* ### muse.c ### */ diff --git a/src/hack.c b/src/hack.c index 6305ad1e7..098546579 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1437,6 +1437,19 @@ domove() } } + if (context.forcefight && levl[x][y].typ == IRONBARS && uwep) { + struct obj *obj = uwep; + if (breaktest(obj)) { + if (obj->quan > 1L) + obj = splitobj(obj, 1L); + else + setuwep((struct obj *)0); + freeinv(obj); + } + hit_bars(&obj, u.ux, u.uy, x, y, TRUE, TRUE); + return; + } + /* specifying 'F' with no monster wastes a turn */ if (context.forcefight /* remembered an 'I' && didn't use a move command */ diff --git a/src/mthrowu.c b/src/mthrowu.c index b63a47900..54ef961fd 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -318,7 +318,9 @@ struct obj *obj; /* missile (or stack providing it) */ || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ) || closed_door(bhitpos.x + dx, bhitpos.y + dy) || (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS - && hits_bars(&singleobj, bhitpos.x, bhitpos.y, 0, 0))) { + && hits_bars(&singleobj, + bhitpos.x, bhitpos.y, + bhitpos.x + dx, bhitpos.y + dy, 0, 0))) { (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y); return; } @@ -455,7 +457,10 @@ struct obj *obj; /* missile (or stack providing it) */ || closed_door(bhitpos.x + dx, bhitpos.y + dy) /* missile might hit iron bars */ || (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS - && hits_bars(&singleobj, bhitpos.x, bhitpos.y, !rn2(5), 0)) + && hits_bars(&singleobj, + bhitpos.x, bhitpos.y, + bhitpos.x + dx, bhitpos.y + dy, + !rn2(5), 0)) /* Thrown objects "sink" */ || IS_SINK(levl[bhitpos.x][bhitpos.y].typ)) { if (singleobj) /* hits_bars might have destroyed it */ @@ -831,11 +836,45 @@ int type; return (struct obj *) 0; } +void +hit_bars(objp, objx, objy, barsx, barsy, your_fault, from_invent) +struct obj **objp; /* *objp will be set to NULL if object breaks */ +int objx, objy, barsx, barsy; +boolean your_fault, from_invent; +{ + struct obj *otmp = *objp; + int obj_type = otmp->otyp; + boolean unbreakable = (levl[barsx][barsy].wall_info & W_NONDIGGABLE) != 0; + + if (your_fault + ? hero_breaks(otmp, objx, objy, from_invent) + : breaks(otmp, objx, objy)) { + *objp = 0; /* object is now gone */ + /* breakage makes its own noises */ + if (obj_type == POT_ACID) { + if (cansee(barsx, barsy) && !unbreakable) + pline_The("iron bars are dissolved!"); + else + You_hear(Hallucination ? "angry snakes!" : "a hissing noise."); + if (!unbreakable) + dissolve_bars(barsx, barsy); + } + } + else if (obj_type == BOULDER || obj_type == HEAVY_IRON_BALL) + pline("Whang!"); + else if (otmp->oclass == COIN_CLASS + || objects[obj_type].oc_material == GOLD + || objects[obj_type].oc_material == SILVER) + pline("Clink!"); + else + pline("Clonk!"); +} + /* TRUE iff thrown/kicked/rolled object doesn't pass through iron bars */ boolean -hits_bars(obj_p, x, y, always_hit, whodidit) +hits_bars(obj_p, x, y, barsx, barsy, always_hit, whodidit) struct obj **obj_p; /* *obj_p will be set to NULL if object breaks */ -int x, y; +int x, y, barsx, barsy; int always_hit; /* caller can force a hit for items which would fit through */ int whodidit; /* 1==hero, 0=other, -1==just check whether it'll pass thru */ { @@ -885,17 +924,7 @@ int whodidit; /* 1==hero, 0=other, -1==just check whether it'll pass thru */ } if (hits && whodidit != -1) { - if (whodidit ? hero_breaks(otmp, x, y, FALSE) : breaks(otmp, x, y)) - *obj_p = otmp = 0; /* object is now gone */ - /* breakage makes its own noises */ - else if (obj_type == BOULDER || obj_type == HEAVY_IRON_BALL) - pline("Whang!"); - else if (otmp->oclass == COIN_CLASS - || objects[obj_type].oc_material == GOLD - || objects[obj_type].oc_material == SILVER) - pline("Clink!"); - else - pline("Clonk!"); + hit_bars(obj_p, x,y, barsx,barsy, whodidit, FALSE); } return hits; diff --git a/src/trap.c b/src/trap.c index 7f9a1ea7d..71700c6c8 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1889,7 +1889,9 @@ int style; if (dist > 0 && isok(bhitpos.x + dx, bhitpos.y + dy) && levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) { x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */ - if (hits_bars(&singleobj, x2, y2, !rn2(20), 0)) { + if (hits_bars(&singleobj, + x2, y2, x2+dx, y2+dy, + !rn2(20), 0)) { if (!singleobj) { used_up = TRUE; launch_drop_spot((struct obj *) 0, 0, 0); diff --git a/src/zap.c b/src/zap.c index 3295e690a..1aaa3d14e 100644 --- a/src/zap.c +++ b/src/zap.c @@ -3103,6 +3103,7 @@ struct obj **pobj; /* object tossed/used, set to NULL /* iron bars will block anything big enough */ if ((weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) && typ == IRONBARS && hits_bars(pobj, x - ddx, y - ddy, + bhitpos.x, bhitpos.y, point_blank ? 0 : !rn2(5), 1)) { /* caveat: obj might now be null... */ obj = *pobj;