]> granicus.if.org Git - nethack/commitdiff
fix #H6203 - jumping over water doesn't
authorPatR <rankin@nethack.org>
Mon, 9 Oct 2017 22:27:24 +0000 (15:27 -0700)
committerPatR <rankin@nethack.org>
Mon, 9 Oct 2017 22:27:24 +0000 (15:27 -0700)
Accidentally caused by my grappling hook fix 2 months ago, attempting
to jump over water made hero enter that water and drown (or crawl out).
hurtle_step() was originally intended to be used for recoil while
levitating, but it is used in other situations where not levitating
and behavior for the two circumstances should be different.

This doesn't fix things properly, just gets jumping working again.

doc/fixes36.1
include/extern.h
include/youprop.h
src/apply.c
src/dothrow.c

index 19c92f722fdc0d8a604ea1beca065fb6f42b6276..ab147170d1369980cb0e99e6fb632abbed28b257 100644 (file)
@@ -509,6 +509,8 @@ hero poly'd into vampire could drain monster down to 0 HP without killing it,
 "you observe a fog cloud where a vampire/bat was" if an unseen vampire on the
        far side of a closed door shifted shape to pass under that door
 fix mention_walls reporting secret doors as solid stone
+jumping over water unintentionally moved hero through that water, causing
+       drowning if not able to water walk or fly
 
 
 Platform- and/or Interface-Specific Fixes
index cc2bf44dcc8976dfc80f0040c12d302ce0495fe6..31180fd664893bfecf03ec4547d7d51568650fc3 100644 (file)
@@ -536,11 +536,11 @@ E int FDECL(thitmonst, (struct monst *, struct obj *));
 E int FDECL(hero_breaks, (struct obj *, XCHAR_P, XCHAR_P, BOOLEAN_P));
 E int FDECL(breaks, (struct obj *, XCHAR_P, XCHAR_P));
 E void FDECL(release_camera_demon, (struct obj *, XCHAR_P, XCHAR_P));
-E void FDECL(breakobj,
-             (struct obj *, XCHAR_P, XCHAR_P, BOOLEAN_P, BOOLEAN_P));
+E void FDECL(breakobj, (struct obj *, XCHAR_P, XCHAR_P, BOOLEAN_P, BOOLEAN_P));
 E boolean FDECL(breaktest, (struct obj *));
 E boolean FDECL(walk_path, (coord *, coord *,
                             boolean (*)(genericptr, int, int), genericptr_t));
+E boolean FDECL(hurtle_jump, (genericptr_t, int, int));
 E boolean FDECL(hurtle_step, (genericptr_t, int, int));
 
 /* ### drawing.c ### */
index 79fa70a7846c1ff7e5be32feb49193e04a19e739..d71ec8b5cada97c9df392b830cf5f47855174e8f 100644 (file)
      && !BFlying)
 /* May touch surface; does not override any others */
 
-#define Wwalking (u.uprops[WWALKING].extrinsic && !Is_waterlevel(&u.uz))
+#define EWwalking u.uprops[WWALKING].extrinsic
+#define Wwalking (EWwalking && !Is_waterlevel(&u.uz))
 /* Don't get wet, can't go under water; overrides others except levitation */
 /* Wwalking is meaningless on water level */
 
index c477a4fb81c4a38bbe0fba7d28d0dae9b716ac8a..ca72cc466e8a5d98e6419eba39989475791382df 100644 (file)
@@ -1769,10 +1769,10 @@ int magic; /* 0=Physical, otherwise skill level */
             temp = -temp;
         if (range < temp)
             range = temp;
-        (void) walk_path(&uc, &cc, hurtle_step, (genericptr_t) &range);
-        /* hurtle_step results in (u.ux, u.uy) == (cc.x, cc.y) and usually
-         * moves the ball if punished, but does not handle all the effects
-         * of landing on the final position.
+        (void) walk_path(&uc, &cc, hurtle_jump, (genericptr_t) &range);
+        /* hurtle_jump -> hurtle_step results in <u.ux,u.uy> == <cc.x,cc.y>
+         * and usually moves the ball if punished, but does not handle all
+         * the effects of landing on the final position.
          */
         teleds(cc.x, cc.y, FALSE);
         sokoban_guilt();
index 6c9aeb315c8a10bffb53a8c5e4998b96c4d6b214..9918e5e778b17bb52e3f727c84d0d7216dcd8ccb 100644 (file)
@@ -519,6 +519,25 @@ genericptr_t arg;
     return FALSE;
 }
 
+/* hack for hurtle_step() -- it ought to be changed to take an argument
+   indicating lev/fly-to-dest vs lev/fly-to-dest-minus-one-land-on-dest
+   vs drag-to-dest; original callers use first mode, jumping wants second,
+   grappling hook backfire and thrown chained ball need third */
+boolean
+hurtle_jump(arg, x, y)
+genericptr_t arg;
+int x, y;
+{
+    boolean res;
+    long save_EWwalking = EWwalking;
+
+    /* prevent jumping over water from being placed in that water */
+    EWwalking |= I_SPECIAL;
+    res = hurtle_step(arg, x, y);
+    EWwalking = save_EWwalking;
+    return res;
+}
+
 /*
  * Single step for the hero flying through the air from jumping, flying,
  * etc.  Called from hurtle() and jump() via walk_path().  We expect the