]> granicus.if.org Git - nethack/commitdiff
preliminary fix for github issue #726 - restdamage
authorPatR <rankin@nethack.org>
Sat, 9 Apr 2022 19:02:30 +0000 (12:02 -0700)
committerPatR <rankin@nethack.org>
Sat, 9 Apr 2022 19:02:30 +0000 (12:02 -0700)
Reported by entrez, restoring a saved game runs the shop wall/floor
damage repair routine.  It was taking place before attached ball
and chain were fully restored so the repair routine treated them as
ordinary objects if they happened to be in a wall gap that gets
fixed on the same turn as restore takes place.  They could end up
being moved to a spot that's too far from the hero and then trigger
an impossible "b&c distance".

This restores ball and chain before shop damage repair takes place
so the repair routine deals with them sanely and the impossible won't
occur any more.  However, the repair still happens before the current
level's map has been displayed and that looks pretty strange during
the shopkeeper's message.  Also, if the hero and the ball start on
opposite sides of the gap, after the gap is repaired the ball will
still be shown as a remembered object at its old spot even though it
ends up being located at the hero's feet.

Closes #726

but more work is needed...

doc/fixes3-7-0.txt
src/restore.c

index b96989ffc0743ce87b0f69b46d4335d0d3466f03..23f01b8d7fa6642fb527ab76443a9a9b2c0ac49d 100644 (file)
@@ -1,4 +1,4 @@
-NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.864 $ $NHDT-Date: 1649269126 2022/04/06 18:18:46 $
+NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.870 $ $NHDT-Date: 1649530942 2022/04/09 19:02:22 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -872,6 +872,9 @@ object detection always showed a mimic imitating a statue as a tengu even if
        it had information available about some other type of monster
 avoid "the Lord Surtur's corpse glows iridescently" when shk_your() or the()
        is applied to the corpse of unique monster with a personal name
+restoring while attached ball or chain is on floor in a breach of a shop wall
+       could have it be moved out of wall gap as that gets repaired, then
+       might trigger an impossible about being positioned too far from hero
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index c2eb6737e8a36f0e5d316cd991bae889678c907a..21b21e899dabfd2c1b7f60a7f1e3b946a17889ca 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 restore.c       $NHDT-Date: 1629818407 2021/08/24 15:20:07 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.183 $ */
+/* NetHack 3.7 restore.c       $NHDT-Date: 1649530943 2022/04/09 19:02:23 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.194 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2009. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -90,6 +90,14 @@ find_lev_obj(void)
     while ((otmp = fobjtmp) != 0) {
         fobjtmp = otmp->nobj;
         place_object(otmp, otmp->ox, otmp->oy);
+
+        /* fixup(s) performed when restoring the level that the hero
+           is on, rather than just an arbitrary one */
+        if (u.uz.dlevel) { /* 0 during full restore until current level */
+            /* handle uchain and uball when they're on the floor */
+            if (otmp->owornmask & (W_BALL | W_CHAIN))
+                setworn(otmp, otmp->owornmask);
+        }
     }
 }
 
@@ -160,6 +168,14 @@ restdamage(NHFILE* nhfp)
 
         if (ghostly)
             tmp_dam->when += (g.moves - g.omoves);
+
+        /*
+         * This should be removed and handled separately when returning
+         * to a level.  It's a holdover from when restore would catch up
+         * for lost time on any level as it went through all the levels
+         * instead of just splitting the save file into individual level
+         * files.
+         */
         Strcpy(damaged_shops,
                in_rooms(tmp_dam->place.x, tmp_dam->place.y, SHOPBASE));
         if (u.uz.dlevel) {
@@ -760,7 +776,6 @@ dorecover(NHFILE* nhfp)
     unsigned int stuckid = 0, steedid = 0; /* not a register */
     xchar ltmp = 0;
     int rtmp;
-    struct obj *otmp;
 
     /* suppress map display if some part of the code tries to update that */
     g.program_state.restoring = 1;
@@ -861,10 +876,6 @@ dorecover(NHFILE* nhfp)
     reset_glyphmap(gm_levelchange);
     max_rank_sz(); /* to recompute g.mrank_sz (botl.c) */
     init_oclass_probs(); /* recompute g.oclass_prob_totals[] */
-    /* take care of iron ball & chain */
-    for (otmp = fobj; otmp; otmp = otmp->nobj)
-        if (otmp->owornmask)
-            setworn(otmp, otmp->owornmask);
 
     if ((uball && !uchain) || (uchain && !uball)) {
         impossible("restgamestate: lost ball & chain");