diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 8bade1d23..5af951add 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1576,6 +1576,7 @@ water elementals move slightly more slowly the "totally digested" instadeath timer is much faster slow monster effects are more effective against faster enemies light-spell is clerical, if playing a priest +boomerang can hit multiple monsters Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 3d8261029..899f72b4a 100644 --- a/include/extern.h +++ b/include/extern.h @@ -829,6 +829,7 @@ extern void hurtle(int, int, int, boolean); extern void mhurtle(struct monst *, int, int, int) NONNULLARG1; extern boolean harmless_missile(struct obj *) NONNULLARG1; extern boolean throwing_weapon(struct obj *) NONNULLARG1; +extern boolean throwit_mon_hit(struct obj *, struct monst *) NONNULLARG1; extern void throwit(struct obj *, long, boolean, struct obj *) NONNULLARG1; extern int omon_adj(struct monst *, struct obj *, boolean) NONNULLPTRS; extern boolean should_mulch_missile(struct obj *); diff --git a/src/dothrow.c b/src/dothrow.c index 35b52aa6c..952913a43 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1474,6 +1474,37 @@ swallowit(struct obj *obj) throwit_return(TRUE); } +/* thrown object hits a monster. + mon may be NULL. + returns TRUE if shopkeeper caught the object. + may delete object, clearing gt.thrownobj */ +boolean +throwit_mon_hit(struct obj *obj, struct monst *mon) +{ + if (mon) { + boolean obj_gone; + + if (mon->isshk && obj->where == OBJ_MINVENT && obj->ocarry == mon) { + return TRUE; + } + (void) snuff_candle(obj); + gn.notonhead = (gb.bhitpos.x != mon->mx || gb.bhitpos.y != mon->my); + obj_gone = thitmonst(mon, obj); + /* Monster may have been tamed; this frees old mon [obsolete] */ + mon = m_at(gb.bhitpos.x, gb.bhitpos.y); + + /* [perhaps this should be moved into thitmonst or hmon] */ + if (mon && mon->isshk + && (!inside_shop(u.ux, u.uy) + || !strchr(in_rooms(mon->mx, mon->my, SHOPBASE), *u.ushops))) + hot_pursuit(mon); + + if (obj_gone) + gt.thrownobj = (struct obj *) 0; + } + return FALSE; +} + /* throw an object, NB: obj may be consumed in the process */ void throwit( @@ -1661,27 +1692,9 @@ throwit( } } - if (mon) { - boolean obj_gone; - - if (mon->isshk && obj->where == OBJ_MINVENT && obj->ocarry == mon) { - throwit_return(TRUE); /* alert shk caught it */ - return; - } - (void) snuff_candle(obj); - gn.notonhead = (gb.bhitpos.x != mon->mx || gb.bhitpos.y != mon->my); - obj_gone = thitmonst(mon, obj); - /* Monster may have been tamed; this frees old mon [obsolete] */ - mon = m_at(gb.bhitpos.x, gb.bhitpos.y); - - /* [perhaps this should be moved into thitmonst or hmon] */ - if (mon && mon->isshk - && (!inside_shop(u.ux, u.uy) - || !strchr(in_rooms(mon->mx, mon->my, SHOPBASE), *u.ushops))) - hot_pursuit(mon); - - if (obj_gone) - gt.thrownobj = (struct obj *) 0; + if (throwit_mon_hit(obj, mon)) { + throwit_return(TRUE); /* alert shk caught it */ + return; } if (!gt.thrownobj) { diff --git a/src/zap.c b/src/zap.c index d3fdf72eb..52697a4ae 100644 --- a/src/zap.c +++ b/src/zap.c @@ -4139,6 +4139,7 @@ boomhit(struct obj *obj, coordxy dx, coordxy dy) int boom; /* showsym[] index */ struct monst *mtmp; boolean counterclockwise = URIGHTY; /* ULEFTY => clockwise */ + int nhits = (obj->spe + 1); /* counterclockwise traversal patterns, from @ to 1 then on through to 9 * ..........................54................................. @@ -4173,8 +4174,12 @@ boomhit(struct obj *obj, coordxy dx, coordxy dy) } if ((mtmp = m_at(gb.bhitpos.x, gb.bhitpos.y)) != 0) { m_respond(mtmp); - tmp_at(DISP_END, 0); - return mtmp; + if (nhits-- < 0) { + tmp_at(DISP_END, 0); + return mtmp; + } else if (throwit_mon_hit(obj, mtmp) || !gt.thrownobj) { + break; + } } if (!ZAP_POS(levl[gb.bhitpos.x][gb.bhitpos.y].typ) || closed_door(gb.bhitpos.x, gb.bhitpos.y)) {