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.
This commit is contained in:
Pasi Kallinen
2016-01-06 15:33:36 +02:00
parent 72f55fedb5
commit 237c4a2787
6 changed files with 64 additions and 17 deletions

View File

@@ -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

View File

@@ -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 ### */

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;