Fix: a number of unblock_points shouldn't unblock unconditionally
Initially diagnosed in an xnethack fuzzer crash - unblock_point shouldn't be called when a closed door becomes non-closed, because it's possible that there's a gas cloud on the space which means it still blocks vision. These always need to be recalc_block_point. A number of them were fixed, but when I went through all the xnethack ones, I found some that were unchanged from upstream NetHack. I reproduced the sanity check impossibles usually by breathing gas at a door as an iron golem and then opening or destroying the door to trigger the unblock_point call. The use of recalc_block_point in wizterrainwish was not triggering this bug, but the previous code there basically duplicated recalc_block_point.
This commit is contained in:
@@ -1435,7 +1435,7 @@ mdig_tunnel(struct monst *mtmp)
|
|||||||
sawit = canseemon(mtmp); /* before door state change and unblock_pt */
|
sawit = canseemon(mtmp); /* before door state change and unblock_pt */
|
||||||
trapped = (here->doormask & D_TRAPPED) ? TRUE : FALSE;
|
trapped = (here->doormask & D_TRAPPED) ? TRUE : FALSE;
|
||||||
here->doormask = trapped ? D_NODOOR : D_BROKEN;
|
here->doormask = trapped ? D_NODOOR : D_BROKEN;
|
||||||
unblock_point(mtmp->mx, mtmp->my); /* vision */
|
recalc_block_point(mtmp->mx, mtmp->my); /* vision */
|
||||||
newsym(mtmp->mx, mtmp->my);
|
newsym(mtmp->mx, mtmp->my);
|
||||||
if (trapped) {
|
if (trapped) {
|
||||||
seeit = canseemon(mtmp);
|
seeit = canseemon(mtmp);
|
||||||
|
|||||||
+1
-1
@@ -949,7 +949,7 @@ kick_door(coordxy x, coordxy y, int avrg_attrib)
|
|||||||
gm.maploc->doormask = D_BROKEN;
|
gm.maploc->doormask = D_BROKEN;
|
||||||
}
|
}
|
||||||
feel_newsym(x, y); /* we know we broke it */
|
feel_newsym(x, y); /* we know we broke it */
|
||||||
unblock_point(x, y); /* vision */
|
recalc_block_point(x, y); /* vision */
|
||||||
if (shopdoor) {
|
if (shopdoor) {
|
||||||
add_damage(x, y, SHOP_DOOR_COST);
|
add_damage(x, y, SHOP_DOOR_COST);
|
||||||
pay_for_damage("break", FALSE);
|
pay_for_damage("break", FALSE);
|
||||||
|
|||||||
+1
-1
@@ -787,7 +787,7 @@ still_chewing(coordxy x, coordxy y)
|
|||||||
lev->typ = CORR;
|
lev->typ = CORR;
|
||||||
}
|
}
|
||||||
|
|
||||||
unblock_point(x, y); /* vision */
|
recalc_block_point(x, y); /* vision */
|
||||||
newsym(x, y);
|
newsym(x, y);
|
||||||
if (digtxt)
|
if (digtxt)
|
||||||
You1(digtxt); /* after newsym */
|
You1(digtxt); /* after newsym */
|
||||||
|
|||||||
+1
-1
@@ -463,7 +463,7 @@ do_earthquake(int force)
|
|||||||
}
|
}
|
||||||
/* wasn't doorless, now it will be */
|
/* wasn't doorless, now it will be */
|
||||||
levl[x][y].doormask = D_NODOOR;
|
levl[x][y].doormask = D_NODOOR;
|
||||||
unblock_point(x, y);
|
recalc_block_point(x, y);
|
||||||
newsym(x, y); /* before pline */
|
newsym(x, y); /* before pline */
|
||||||
if (cansee(x, y))
|
if (cansee(x, y))
|
||||||
pline_The("door collapses.");
|
pline_The("door collapses.");
|
||||||
|
|||||||
+1
-8
@@ -3862,14 +3862,7 @@ wizterrainwish(struct _readobjnam_data *d)
|
|||||||
} else {
|
} else {
|
||||||
if (u.utrap && u.utraptype == TT_LAVA && !is_lava(u.ux, u.uy))
|
if (u.utrap && u.utraptype == TT_LAVA && !is_lava(u.ux, u.uy))
|
||||||
reset_utrap(FALSE);
|
reset_utrap(FALSE);
|
||||||
|
recalc_block_point(x, y);
|
||||||
if (does_block(x, y, lev)) {
|
|
||||||
if (!didblock)
|
|
||||||
block_point(x, y);
|
|
||||||
} else {
|
|
||||||
if (didblock)
|
|
||||||
unblock_point(x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fixups for replaced terrain that aren't handled above */
|
/* fixups for replaced terrain that aren't handled above */
|
||||||
|
|||||||
+1
-1
@@ -3443,7 +3443,7 @@ launch_obj(
|
|||||||
}
|
}
|
||||||
levl[x][y].doormask = D_BROKEN;
|
levl[x][y].doormask = D_BROKEN;
|
||||||
if (dist)
|
if (dist)
|
||||||
unblock_point(x, y);
|
recalc_block_point(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if about to hit something, do so now */
|
/* if about to hit something, do so now */
|
||||||
|
|||||||
Reference in New Issue
Block a user