fix #H164 - boulder pushing bug (trunk only)
From a bug report...): pushing a boulder onto a level teleporter trap
could repeat the
You push the boulder and suddenly it disappears!
message. That would happen whenever the teleport destination was the same
as the current level (20% chance). The boulder wasn't being moved onto the
trap location so was still present when the pushing code tried to handle
the next one in the pile. I've changed so that pushing stops whenever a
pushed boulder is affected by a trap, and also so that the boulder gets
moved as usual when a level teleporter fails to send it somewhere.
I've always thought it's pretty strange that pushing ever operates
on more than one boulder in the same turn in any situation, but I haven't
changed that for the non-trap cases. (Usually the first boulder pushed
ends up blocking the second one, so you get a "you try to move it, but
in vain" message which seems odd since you just moved one. But if there's
a pool of water or lava in the path, you can actually push multiple
boulders successfully.)
This commit is contained in:
@@ -152,6 +152,7 @@ wielded light source susceptible to water gets extinguished when weapon rusts
|
||||
don't discover unknown bag of tricks when monster it releases is undetected
|
||||
make region ttl field a long instead of short to get rid of lint warnings
|
||||
about a possible loss of data
|
||||
pushing a boulder onto a level teleporter trap could issue repeat messages
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific Fixes
|
||||
|
||||
45
src/hack.c
45
src/hack.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)hack.c 3.5 2006/07/08 */
|
||||
/* SCCS Id: @(#)hack.c 3.5 2006/08/09 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -163,7 +163,11 @@ moverock()
|
||||
goto cannot_push;
|
||||
}
|
||||
|
||||
if (ttmp)
|
||||
if (ttmp) {
|
||||
/* if a trap operates on the boulder, don't attempt
|
||||
to move any others at this location; return -1
|
||||
if another boulder is in hero's way, or 0 if he
|
||||
should advance to the vacated boulder position */
|
||||
switch(ttmp->ttyp) {
|
||||
case LANDMINE:
|
||||
if (rn2(10)) {
|
||||
@@ -178,7 +182,7 @@ moverock()
|
||||
/* if the boulder remains, it should fill the pit */
|
||||
fill_pit(u.ux, u.uy);
|
||||
if (cansee(rx,ry)) newsym(rx,ry);
|
||||
continue;
|
||||
return sobj_at(BOULDER, sx, sy) ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case SPIKED_PIT:
|
||||
@@ -192,7 +196,7 @@ moverock()
|
||||
place_object(otmp, rx, ry);
|
||||
}
|
||||
if (mtmp && !Blind) newsym(rx, ry);
|
||||
continue;
|
||||
return sobj_at(BOULDER, sx, sy) ? -1 : 0;
|
||||
case HOLE:
|
||||
case TRAPDOOR:
|
||||
if (Blind)
|
||||
@@ -212,9 +216,19 @@ moverock()
|
||||
levl[rx][ry].wall_info &= ~W_NONDIGGABLE;
|
||||
levl[rx][ry].candig = 1;
|
||||
if (cansee(rx,ry)) newsym(rx,ry);
|
||||
continue;
|
||||
return sobj_at(BOULDER, sx, sy) ? -1 : 0;
|
||||
case LEVEL_TELEP:
|
||||
case TELEP_TRAP:
|
||||
{
|
||||
int newlev = 0; /* lint suppresion */
|
||||
d_level dest;
|
||||
|
||||
if (ttmp->ttyp == LEVEL_TELEP) {
|
||||
newlev = random_teleport_level();
|
||||
if (newlev == depth(&u.uz) || In_endgame(&u.uz))
|
||||
/* trap didn't work; skip "disappears" message */
|
||||
goto dopush;
|
||||
}
|
||||
#ifdef STEED
|
||||
if (u.usteed)
|
||||
pline("%s pushes %s and suddenly it disappears!",
|
||||
@@ -223,14 +237,9 @@ moverock()
|
||||
#endif
|
||||
You("push %s and suddenly it disappears!",
|
||||
the(xname(otmp)));
|
||||
if (ttmp->ttyp == TELEP_TRAP)
|
||||
if (ttmp->ttyp == TELEP_TRAP) {
|
||||
(void)rloco(otmp);
|
||||
else {
|
||||
int newlev = random_teleport_level();
|
||||
d_level dest;
|
||||
|
||||
if (newlev == depth(&u.uz) || In_endgame(&u.uz))
|
||||
continue;
|
||||
} else {
|
||||
obj_extract_self(otmp);
|
||||
add_to_migration(otmp);
|
||||
get_level(&dest, newlev);
|
||||
@@ -239,8 +248,13 @@ moverock()
|
||||
otmp->owornmask = (long)MIGR_RANDOM;
|
||||
}
|
||||
seetrap(ttmp);
|
||||
continue;
|
||||
return sobj_at(BOULDER, sx, sy) ? -1 : 0;
|
||||
}
|
||||
default:
|
||||
break; /* boulder not affected by this trap */
|
||||
}
|
||||
}
|
||||
|
||||
if (closed_door(rx, ry))
|
||||
goto nopushmsg;
|
||||
if (boulder_hits_pool(otmp, rx, ry, TRUE))
|
||||
@@ -262,6 +276,7 @@ moverock()
|
||||
/* note: reset to zero after save/restore cycle */
|
||||
static NEARDATA long lastmovetime;
|
||||
#endif
|
||||
dopush:
|
||||
#ifdef STEED
|
||||
if (!u.usteed) {
|
||||
#endif
|
||||
@@ -289,7 +304,7 @@ moverock()
|
||||
newsym(sx, sy);
|
||||
}
|
||||
} else {
|
||||
nopushmsg:
|
||||
nopushmsg:
|
||||
#ifdef STEED
|
||||
if (u.usteed)
|
||||
pline("%s tries to move %s, but cannot.",
|
||||
@@ -298,7 +313,7 @@ moverock()
|
||||
#endif
|
||||
You("try to move %s, but in vain.", the(xname(otmp)));
|
||||
if (Blind) feel_location(sx, sy);
|
||||
cannot_push:
|
||||
cannot_push:
|
||||
if (throws_rocks(youmonst.data)) {
|
||||
#ifdef STEED
|
||||
if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) {
|
||||
|
||||
Reference in New Issue
Block a user