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
|
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
|
make region ttl field a long instead of short to get rid of lint warnings
|
||||||
about a possible loss of data
|
about a possible loss of data
|
||||||
|
pushing a boulder onto a level teleporter trap could issue repeat messages
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
+30
-15
@@ -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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -163,7 +163,11 @@ moverock()
|
|||||||
goto cannot_push;
|
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) {
|
switch(ttmp->ttyp) {
|
||||||
case LANDMINE:
|
case LANDMINE:
|
||||||
if (rn2(10)) {
|
if (rn2(10)) {
|
||||||
@@ -178,7 +182,7 @@ moverock()
|
|||||||
/* if the boulder remains, it should fill the pit */
|
/* if the boulder remains, it should fill the pit */
|
||||||
fill_pit(u.ux, u.uy);
|
fill_pit(u.ux, u.uy);
|
||||||
if (cansee(rx,ry)) newsym(rx,ry);
|
if (cansee(rx,ry)) newsym(rx,ry);
|
||||||
continue;
|
return sobj_at(BOULDER, sx, sy) ? -1 : 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SPIKED_PIT:
|
case SPIKED_PIT:
|
||||||
@@ -192,7 +196,7 @@ moverock()
|
|||||||
place_object(otmp, rx, ry);
|
place_object(otmp, rx, ry);
|
||||||
}
|
}
|
||||||
if (mtmp && !Blind) newsym(rx, ry);
|
if (mtmp && !Blind) newsym(rx, ry);
|
||||||
continue;
|
return sobj_at(BOULDER, sx, sy) ? -1 : 0;
|
||||||
case HOLE:
|
case HOLE:
|
||||||
case TRAPDOOR:
|
case TRAPDOOR:
|
||||||
if (Blind)
|
if (Blind)
|
||||||
@@ -212,9 +216,19 @@ moverock()
|
|||||||
levl[rx][ry].wall_info &= ~W_NONDIGGABLE;
|
levl[rx][ry].wall_info &= ~W_NONDIGGABLE;
|
||||||
levl[rx][ry].candig = 1;
|
levl[rx][ry].candig = 1;
|
||||||
if (cansee(rx,ry)) newsym(rx,ry);
|
if (cansee(rx,ry)) newsym(rx,ry);
|
||||||
continue;
|
return sobj_at(BOULDER, sx, sy) ? -1 : 0;
|
||||||
case LEVEL_TELEP:
|
case LEVEL_TELEP:
|
||||||
case TELEP_TRAP:
|
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
|
#ifdef STEED
|
||||||
if (u.usteed)
|
if (u.usteed)
|
||||||
pline("%s pushes %s and suddenly it disappears!",
|
pline("%s pushes %s and suddenly it disappears!",
|
||||||
@@ -223,14 +237,9 @@ moverock()
|
|||||||
#endif
|
#endif
|
||||||
You("push %s and suddenly it disappears!",
|
You("push %s and suddenly it disappears!",
|
||||||
the(xname(otmp)));
|
the(xname(otmp)));
|
||||||
if (ttmp->ttyp == TELEP_TRAP)
|
if (ttmp->ttyp == TELEP_TRAP) {
|
||||||
(void)rloco(otmp);
|
(void)rloco(otmp);
|
||||||
else {
|
} else {
|
||||||
int newlev = random_teleport_level();
|
|
||||||
d_level dest;
|
|
||||||
|
|
||||||
if (newlev == depth(&u.uz) || In_endgame(&u.uz))
|
|
||||||
continue;
|
|
||||||
obj_extract_self(otmp);
|
obj_extract_self(otmp);
|
||||||
add_to_migration(otmp);
|
add_to_migration(otmp);
|
||||||
get_level(&dest, newlev);
|
get_level(&dest, newlev);
|
||||||
@@ -239,8 +248,13 @@ moverock()
|
|||||||
otmp->owornmask = (long)MIGR_RANDOM;
|
otmp->owornmask = (long)MIGR_RANDOM;
|
||||||
}
|
}
|
||||||
seetrap(ttmp);
|
seetrap(ttmp);
|
||||||
continue;
|
return sobj_at(BOULDER, sx, sy) ? -1 : 0;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break; /* boulder not affected by this trap */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (closed_door(rx, ry))
|
if (closed_door(rx, ry))
|
||||||
goto nopushmsg;
|
goto nopushmsg;
|
||||||
if (boulder_hits_pool(otmp, rx, ry, TRUE))
|
if (boulder_hits_pool(otmp, rx, ry, TRUE))
|
||||||
@@ -262,6 +276,7 @@ moverock()
|
|||||||
/* note: reset to zero after save/restore cycle */
|
/* note: reset to zero after save/restore cycle */
|
||||||
static NEARDATA long lastmovetime;
|
static NEARDATA long lastmovetime;
|
||||||
#endif
|
#endif
|
||||||
|
dopush:
|
||||||
#ifdef STEED
|
#ifdef STEED
|
||||||
if (!u.usteed) {
|
if (!u.usteed) {
|
||||||
#endif
|
#endif
|
||||||
@@ -289,7 +304,7 @@ moverock()
|
|||||||
newsym(sx, sy);
|
newsym(sx, sy);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nopushmsg:
|
nopushmsg:
|
||||||
#ifdef STEED
|
#ifdef STEED
|
||||||
if (u.usteed)
|
if (u.usteed)
|
||||||
pline("%s tries to move %s, but cannot.",
|
pline("%s tries to move %s, but cannot.",
|
||||||
@@ -298,7 +313,7 @@ moverock()
|
|||||||
#endif
|
#endif
|
||||||
You("try to move %s, but in vain.", the(xname(otmp)));
|
You("try to move %s, but in vain.", the(xname(otmp)));
|
||||||
if (Blind) feel_location(sx, sy);
|
if (Blind) feel_location(sx, sy);
|
||||||
cannot_push:
|
cannot_push:
|
||||||
if (throws_rocks(youmonst.data)) {
|
if (throws_rocks(youmonst.data)) {
|
||||||
#ifdef STEED
|
#ifdef STEED
|
||||||
if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) {
|
if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) {
|
||||||
|
|||||||
Reference in New Issue
Block a user