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 ### */
|| 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;
}
|| 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 */
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 */
{
}
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;