Fix bhit/mbhit hitting destroyed objects

A monster zapped a wand of striking, hitting a burning potion
of oil, which destroyed items in the same square, and the ray was
checking destroyed item.  Similar thing with a ray done by hero.

The code currently stops checking the objects in the location
if a next object in the chain was destroyed - an improvement
would be to gather all the objects into an array and iterate
over that instead of relying on the nexthere pointer.
This commit is contained in:
Pasi Kallinen
2024-05-07 16:04:56 +03:00
parent f5cde4cfd6
commit a6c5d967d2
2 changed files with 29 additions and 14 deletions

View File

@@ -29,6 +29,8 @@ staticfn void m_use_undead_turning(struct monst *, struct obj *);
staticfn boolean hero_behind_chokepoint(struct monst *);
staticfn boolean mon_has_friends(struct monst *);
staticfn int mbhitm(struct monst *, struct obj *);
staticfn boolean fhito_loc(struct obj *obj, coordxy x, coordxy y,
int (*fhito)(OBJ_P, OBJ_P));
staticfn void mbhit(struct monst *, int, int (*)(MONST_P, OBJ_P),
int (*)(OBJ_P, OBJ_P), struct obj *);
staticfn struct permonst *muse_newcham_mon(struct monst *);
@@ -1622,6 +1624,29 @@ mbhitm(struct monst *mtmp, struct obj *otmp)
return 0;
}
/* hit all objects at x,y with fhito function */
staticfn boolean
fhito_loc(struct obj *obj,
coordxy tx, coordxy ty,
int (*fhito)(OBJ_P, OBJ_P))
{
struct obj *otmp, *next_obj;
int hitanything = 0;
if (!fhito || !OBJ_AT(tx, ty))
return FALSE;
for (otmp = gl.level.objects[tx][ty]; otmp; otmp = next_obj) {
next_obj = otmp->nexthere;
if (otmp->where != OBJ_FLOOR || otmp->ox != tx || otmp->oy != ty)
continue;
hitanything += (*fhito)(otmp, obj);
}
return hitanything ? TRUE : FALSE;
}
/* A modified bhit() for monsters. Based on bhit() in zap.c. Unlike
* buzz(), bhit() doesn't take into account the possibility of a monster
* zapping you, so we need a special function for it. (Unless someone wants
@@ -1667,20 +1692,8 @@ mbhit(
(*fhitm)(mtmp, obj);
range -= 3;
}
/* modified by GAN to hit all objects */
if (fhito) {
int hitanything = 0;
struct obj *next_obj;
for (otmp = gl.level.objects[gb.bhitpos.x][gb.bhitpos.y]; otmp;
otmp = next_obj) {
/* Fix for polymorph bug, Tim Wright */
next_obj = otmp->nexthere;
hitanything += (*fhito)(otmp, obj);
}
if (hitanything)
range--;
}
if (fhito_loc(obj, gb.bhitpos.x, gb.bhitpos.y, fhito))
range--;
ltyp = levl[gb.bhitpos.x][gb.bhitpos.y].typ;
dbx = x, dby = y;
if (otyp == WAN_STRIKING

View File

@@ -2426,6 +2426,8 @@ bhitpile(
continue;
}
}
if (otmp->where != OBJ_FLOOR || otmp->ox != tx || otmp->oy != ty)
continue;
hitanything += (*fhito)(otmp, obj);
}