From e26d9ffee0cc4ae4a0f32731d780334c4c2ef3cd Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Fri, 22 Dec 2006 04:05:13 +0000 Subject: [PATCH] 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. --- doc/fixes34.4 | 1 + src/apply.c | 8 ++++++-- src/trap.c | 11 ++++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/doc/fixes34.4 b/doc/fixes34.4 index 01e68472e..c469edf68 100644 --- a/doc/fixes34.4 +++ b/doc/fixes34.4 @@ -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 diff --git a/src/apply.c b/src/apply.c index 7483aa46c..16ac4ae82 100644 --- a/src/apply.c +++ b/src/apply.c @@ -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(); diff --git a/src/trap.c b/src/trap.c index 1924f976e..f53384490 100644 --- a/src/trap.c +++ b/src/trap.c @@ -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 */ + } } }