From cc46da90e00e54b99f45b8cd1d9d69e7efe0f52c Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 1 Jul 2022 12:29:47 -0400 Subject: [PATCH] Fix #812: recovered stair dlevel Stair dlevels weren't being restored with the correct values when recovered after the game crashed, apparently because they weren't being reset back to their 'absolute' level from a 'relative' level. I'm not totally sure of why this affected only recovered games (maybe that's the only time when the 'relative' stair values are used?) but this fix seems to work. Fixes #812 --- include/hack.h | 5 +++++ src/restore.c | 7 +++++-- src/save.c | 6 ++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/hack.h b/include/hack.h index 6b14d5e86..a57a53059 100644 --- a/include/hack.h +++ b/include/hack.h @@ -254,6 +254,11 @@ enum saveformats { ascii = 3 /* each field, ascii text (just proof of concept) */ }; +enum restore_stages { + REST_GSTATE = 1, /* restoring current level and game state */ + REST_LEVELS = 2, /* restoring remainder of dungeon */ +}; + /* sortloot() return type; needed before extern.h */ struct sortloot_item { struct obj *obj; diff --git a/src/restore.c b/src/restore.c index e328f9084..0ffe4e2f3 100644 --- a/src/restore.c +++ b/src/restore.c @@ -749,7 +749,7 @@ dorecover(NHFILE* nhfp) int rtmp; /* suppress map display if some part of the code tries to update that */ - g.program_state.restoring = 1; + g.program_state.restoring = REST_GSTATE; get_plname_from_file(nhfp, g.plname); getlev(nhfp, 0, (xint8) 0); @@ -776,6 +776,8 @@ dorecover(NHFILE* nhfp) if (rtmp < 2) return rtmp; /* dorecover called recursively */ + g.program_state.restoring = REST_LEVELS; + /* these pointers won't be valid while we're processing the * other levels, but they'll be reset again by restlevelstate() * afterwards, and in the meantime at least u.usteed may mislead @@ -909,7 +911,8 @@ rest_stairs(NHFILE* nhfp) if (nhfp->structlevel) { mread(nhfp->fd, (genericptr_t) &stway, sizeof (stairway)); } - if (stway.tolev.dnum == u.uz.dnum) { + if (g.program_state.restoring != REST_GSTATE + && stway.tolev.dnum == u.uz.dnum) { /* stairway dlevel is relative, make it absolute */ stway.tolev.dlevel += u.uz.dlevel; } diff --git a/src/save.c b/src/save.c index ddf39c207..b8f5939e8 100644 --- a/src/save.c +++ b/src/save.c @@ -717,7 +717,9 @@ save_stairs(NHFILE* nhfp) while (stway) { if (perform_bwrite(nhfp)) { - if (stway->tolev.dnum == u.uz.dnum) { + boolean use_relative = (g.program_state.restoring != REST_GSTATE + && stway->tolev.dnum == u.uz.dnum); + if (use_relative) { /* make dlevel relative to current level */ stway->tolev.dlevel -= u.uz.dlevel; } @@ -725,7 +727,7 @@ save_stairs(NHFILE* nhfp) bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); bwrite(nhfp->fd, (genericptr_t) stway, sizeof *stway); } - if (stway->tolev.dnum == u.uz.dnum) { + if (use_relative) { /* reset staiway dlevel back to absolute */ stway->tolev.dlevel += u.uz.dlevel; }