endgame trap fix

Someone in the newsgroup claims to have reported this in mid-October,
but he uses a fake address in news and maybe he did so with his mail too,
resulting it not being delivered.  Anyway, arming a land mine on the Plane
of Air, then setting it off, produced a pit in the air.  This fixes that
directly, in case someone manages to do it again, and it also prevents
land mines and bear traps from being armed in midair in the first place.
Ditto for Plane of Water; water/pool locations were already covered (can't
arm there), and the bubbles ought to be treated similarly to Plane of Air.

     When testing this, I managed to get a crash while restoring a saved
game.  I had worn a blindfold and armed a land mine on the water level
(with just the no-pit part of the patch in place), then saved.  When
restoring, I got a crash in restore_waterlevel() at one or the other of
these lines (traceback pointed at the first, but it has to have actually
been the second; an access violation from an address derived by applying
a small offset to a null pointer):
	ebubbles = b;
	b->next = (struct bubble *)0;
After that, I couldn't reproduce it with a wished-for trap and couldn't
stay in one place long enough again to successfully arm a trap object.
So there may be a nasty bug still present, perhaps now hidden by no longer
being able to create a new trap on that level.
This commit is contained in:
nethack.rankin
2006-12-22 04:05:13 +00:00
parent fb07e9d06f
commit e26d9ffee0
3 changed files with 15 additions and 5 deletions

View File

@@ -290,6 +290,7 @@ can't engrave on floor while inside solid rock, wall, or closed door
remove engravings at drawbridge location when it is opened, closed, or wrecked
monster killed in midst of multi-shot volley throwing/shooting might cause
freed memory to be accessed, potentially triggering a crash
can't arm bear traps or land mines on Planes of Air or Water
Platform- and/or Interface-Specific Fixes

View File

@@ -2112,6 +2112,7 @@ struct obj *otmp;
int ttyp, tmp;
const char *what = (char *)0;
char buf[BUFSZ];
int levtyp = levl[u.ux][u.uy].typ;
const char *occutext = "setting the trap";
if (nohands(youmonst.data))
@@ -2132,10 +2133,13 @@ struct obj *otmp;
else if (On_stairs(u.ux, u.uy))
what = (u.ux == xdnladder || u.ux == xupladder) ?
"on the ladder" : "on the stairs";
else if (IS_FURNITURE(levl[u.ux][u.uy].typ) ||
IS_ROCK(levl[u.ux][u.uy].typ) ||
else if (IS_FURNITURE(levtyp) || IS_ROCK(levtyp) ||
closed_door(u.ux, u.uy) || t_at(u.ux, u.uy))
what = "here";
else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz))
what = (levtyp == AIR) ? "in midair" :
(levtyp == CLOUD) ? "in a cloud" :
"in this place"; /* Air/Water Plane catch-all */
if (what) {
You_cant("set a trap %s!",what);
reset_trapset();

View File

@@ -1446,9 +1446,14 @@ struct trap *trap;
}
/* convert landmine into pit */
if (trap) {
trap->ttyp = PIT; /* explosion creates a pit */
trap->madeby_u = FALSE; /* resulting pit isn't yours */
seetrap(trap); /* and it isn't concealed */
if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
/* no pits here */
deltrap(trap);
} else {
trap->ttyp = PIT; /* explosion creates a pit */
trap->madeby_u = FALSE; /* resulting pit isn't yours */
seetrap(trap); /* and it isn't concealed */
}
}
}