From: PatR Date: Sat, 9 Apr 2022 19:02:30 +0000 (-0700) Subject: preliminary fix for github issue #726 - restdamage X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dadbea1d8cf9382c034a437bc73cc0b543fc1b02;p=nethack preliminary fix for github issue #726 - restdamage 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... --- diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index b96989ffc..23f01b8d7 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -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 diff --git a/src/restore.c b/src/restore.c index c2eb6737e..21b21e899 100644 --- a/src/restore.c +++ b/src/restore.c @@ -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");