]> granicus.if.org Git - nethack/commitdiff
fix #H5245 - levitation boots message sequencing
authorPatR <rankin@nethack.org>
Sat, 6 May 2017 21:47:28 +0000 (14:47 -0700)
committerPatR <rankin@nethack.org>
Sat, 6 May 2017 21:47:28 +0000 (14:47 -0700)
Report was for
  You finish taking off your boots.
  You float gently to the altar.  [destination was a red herring]
  [take some action to run through moveloop() for next turn]
  Your movements are slowed slightly because of your load.

Having float_down() do the next encumbrance check instead of
waiting for moveloop() to do so was straightforward.  However,
while testing I noticed the reverse situation (not due to the fix
for the above) when putting on levitation boots
  Your movements are now unencumbered.
  You finish your dressing maneuver.
  You start to float in the air!

Having float_up() do the encumbrance check isn't adequate to fix
this, because it takes multiple turns to put on boots but the
properties they confer are enabled immediately, so moveloop() runs
while hero is already levitating even though the game hasn't told
the player about it yet.  Fix is a hack to defer the effect of
levitation on encumbrance until the boots are fully worn, which
might lead to strangeness somewhere.  It's also boot-specific so
will need to be updated if some other multi-turn armor that confers
levitation ever gets added.

doc/fixes36.1
include/extern.h
src/do_wear.c
src/hack.c
src/trap.c

index e25a866ae2887026195a99397e1aaf20be300448..ddad2f3712b5b201df7d26738940ed983c0ebdfe 100644 (file)
@@ -374,6 +374,10 @@ automatic #overview annotation for quest summons wasn't shown if the quest
        entry portal was on same level as bigroom or rogue level
 gaining or losing strength while wearing gauntlets of power could give
        misleading message about already being as strong or weak as possible
+levitation vs encumbrance message sequencing issues:  putting on boots of
+       levitation reported reduction of encumbrance before finish-wearing
+       and float-up messages, taking off such boots didn't report increase
+       of encumbrance until player took another action
 
 
 Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
index 5de433ee835053b98327ed6dab0290f1e8c01d7b..e8e15e701168000239bc61c4d806351433641f07 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1492733169 2017/04/21 00:06:09 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.586 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1494107197 2017/05/06 21:46:37 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.587 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -439,6 +439,7 @@ E int NDECL(Armor_off);
 E int NDECL(Armor_gone);
 E int NDECL(Helmet_off);
 E int NDECL(Gloves_off);
+E int NDECL(Boots_on);
 E int NDECL(Boots_off);
 E int NDECL(Cloak_off);
 E int NDECL(Shield_off);
index 15f00bbee2fca5a59120176960908e1fd2bf795a..f0c1038dc38b2abbdcbed31a0841bab0ed6acc64 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 do_wear.c       $NHDT-Date: 1455667557 2016/02/17 00:05:57 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.90 $ */
+/* NetHack 3.6 do_wear.c       $NHDT-Date: 1494107204 2017/05/06 21:46:44 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.94 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -23,7 +23,7 @@ STATIC_DCL void FDECL(on_msg, (struct obj *));
 STATIC_DCL void FDECL(toggle_stealth, (struct obj *, long, BOOLEAN_P));
 STATIC_DCL void FDECL(toggle_displacement, (struct obj *, long, BOOLEAN_P));
 STATIC_PTR int NDECL(Armor_on);
-STATIC_PTR int NDECL(Boots_on);
+/* int NDECL(Boots_on); -- moved to extern.h */
 STATIC_PTR int NDECL(Cloak_on);
 STATIC_PTR int NDECL(Helmet_on);
 STATIC_PTR int NDECL(Gloves_on);
@@ -148,7 +148,6 @@ boolean on;
  * [Blindf_on() is an exception and calls setworn() itself.]
  */
 
-STATIC_PTR
 int
 Boots_on(VOID_ARGS)
 {
@@ -1274,7 +1273,7 @@ cancel_don()
     context.takeoff.cancelled_don =
         (afternmv == Boots_on || afternmv == Helmet_on
          || afternmv == Gloves_on || afternmv == Armor_on);
-    afternmv = 0;
+    afternmv = (int NDECL((*))) 0;
     nomovemsg = (char *) 0;
     multi = 0;
     context.takeoff.delay = 0;
index 1c7e44804809f298e977a7c0d618f816907c78ae..a250d86ded154173169479d4f288fd40046b0dfe 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 hack.c  $NHDT-Date: 1464485934 2016/05/29 01:38:54 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.168 $ */
+/* NetHack 3.6 hack.c  $NHDT-Date: 1494107206 2017/05/06 21:46:46 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.174 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -552,10 +552,10 @@ dosinkfall()
     /*
      * Interrupt multi-turn putting on/taking off of armor (in which
      * case we reached the sink due to being teleported while busy;
-     * in 3.4.3, Boots_on()/Boots_off() [called via (*aftermv)() when
+     * in 3.4.3, Boots_on()/Boots_off() [called via (*afternmv)() when
      * 'multi' reaches 0] triggered a crash if we were donning/doffing
      * levitation boots [because the Boots_off() below causes 'uarmf'
-     * to be null by the time 'aftermv' gets called]).
+     * to be null by the time 'afternmv' gets called]).
      *
      * Interrupt donning/doffing if we fall onto the sink, or if the
      * code below is going to remove levitation boots even when we
@@ -2766,9 +2766,13 @@ const char *msg_override;
     nomovemsg = 0;
     u.usleep = 0;
     multi_reason = NULL;
-    if (afternmv)
-        (*afternmv)();
-    afternmv = 0;
+    if (afternmv) {
+        int NDECL((*f)) = afternmv;
+        /* clear afternmv before calling it (to override the
+           encumbrance hack for levitation--see weight_cap()) */
+        afternmv = (int NDECL((*))) 0;
+        (void) (*f)();
+    }
 }
 
 STATIC_OVL void
@@ -2843,7 +2847,16 @@ boolean k_format;
 int
 weight_cap()
 {
-    register long carrcap;
+    long carrcap, save_ELev = ELevitation;
+
+    /* boots take multiple turns to wear but any properties they
+       confer are enabled at the start rather than the end; that
+       causes message sequencing issues for boots of levitation
+       so defer their encumbrance benefit until they're fully worn */
+    if (afternmv == Boots_on && (ELevitation & W_ARMF) != 0L) {
+        ELevitation &= ~W_ARMF;
+        float_vs_flight(); /* in case Levitation is blocking Flying */
+    }
 
     carrcap = 25 * (ACURRSTR + ACURR(A_CON)) + 50;
     if (Upolyd) {
@@ -2873,6 +2886,12 @@ weight_cap()
         if (carrcap < 0)
             carrcap = 0;
     }
+
+    if (ELevitation != save_ELev) {
+        ELevitation = save_ELev;
+        float_vs_flight();
+    }
+
     return (int) carrcap;
 }
 
index 2c9b4e51156f9bc172bfa2dcf85dceffbf389861..ddf065a0ccc43d670fb249075e1626521e8da6f8 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 trap.c  $NHDT-Date: 1489745987 2017/03/17 10:19:47 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.277 $ */
+/* NetHack 3.6 trap.c  $NHDT-Date: 1494107206 2017/05/06 21:46:46 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.278 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -2794,6 +2794,9 @@ float_up()
     if (Flying)
         You("are no longer able to control your flight.");
     BFlying |= I_SPECIAL;
+    /* levitation gives maximum carrying capacity, so encumbrance
+       state might be reduced */
+    (void) encumber_msg();
     return;
 }
 
@@ -2837,12 +2840,14 @@ long hmask, emask; /* might cancel timeout */
         BFlying &= ~I_SPECIAL;
         if (Flying) {
             You("have stopped levitating and are now flying.");
+            (void) encumber_msg(); /* carrying capacity might have changed */
             return 1;
         }
     }
     if (u.uswallow) {
         You("float down, but you are still %s.",
             is_animal(u.ustuck->data) ? "swallowed" : "engulfed");
+        (void) encumber_msg();
         return 1;
     }
 
@@ -2924,6 +2929,11 @@ long hmask, emask; /* might cancel timeout */
         }
     }
 
+    /* levitation gives maximum carrying capacity, so having it end
+       potentially triggers greater encumbrance; do this after
+       'come down' messages, before trap activation or autopickup */
+    (void) encumber_msg();
+
     /* can't rely on u.uz0 for detecting trap door-induced level change;
        it gets changed to reflect the new level before we can check it */
     assign_level(&current_dungeon_level, &u.uz);