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...
This commit is contained in:
PatR
2022-04-09 12:02:30 -07:00
parent ea15bc05ec
commit dadbea1d8c
2 changed files with 21 additions and 7 deletions

View 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

View 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");