Boomerangs can hit multiple monsters

The number of monsters it can hit depends on the enchantment.
This commit is contained in:
Pasi Kallinen
2026-02-04 22:35:19 +02:00
parent 27adb7c71d
commit 37168ab188
4 changed files with 43 additions and 23 deletions

View File

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

View File

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

View File

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

View File

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