diff --git a/src/mon.c b/src/mon.c index f04e2418c..6ad8a0fb5 100644 --- a/src/mon.c +++ b/src/mon.c @@ -3433,6 +3433,8 @@ set_ustuck(struct monst *mtmp) disp.botl = TRUE; u.ustuck = mtmp; + if (u.ustuck_mid) + u.ustuck_mid = 0; if (!u.ustuck) { u.uswallow = 0; u.uswldtim = 0; diff --git a/src/restore.c b/src/restore.c index 5ab2342c7..8a7ad8743 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1219,8 +1219,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) u.usteed_mid = 0; } else { if (mtmp->m_id == u.ustuck_mid) { - set_ustuck(mtmp); - u.ustuck_mid = 0; + set_ustuck(mtmp); /* set_ustuck clears u.ustuck_mid */ } place_monster(mtmp, mtmp->mx, mtmp->my); if (mtmp->wormno) diff --git a/src/save.c b/src/save.c index d03000408..7eb7f5eb6 100644 --- a/src/save.c +++ b/src/save.c @@ -285,13 +285,32 @@ savegamestate(NHFILE *nhfp) Sfo_long(nhfp, &svw.wreserve, "wreserve"); Sfo_int32(nhfp, &svw.wtreserved, "wtreserved"); /* - * It is critical to ensure that u.ustuck_mid and u.usteed_mid - * hold current and correct data, in case this is needed by - * recover. + * In a normal save operation initiated by the player, + * the u.ustuck_mid and u.usteed_mid were already set + * by savemonchn() called from savelev_core(). Under + * that operation, u.ustuck and u.usteed pointers no longer + * point to valid locations here. Their non-zero values serve + * only to flag that they are were set, but the pointers + * must not be dereferenced. */ - u.ustuck_mid = (u.ustuck) ? u.ustuck->m_id : 0; - u.usteed_mid = (u.usteed) ? u.usteed->m_id : 0; + if (program_state.in_checkpoint) { + /* + * It is critical to ensure that u.ustuck_mid and u.usteed_mid + * hold current and correct data, in case this is needed by + * recover. The pointers, if set, are still pointing at + * valid data during a checkpoint operation, unlike during + * a synchronized save operation. + */ + u.ustuck_mid = (u.ustuck) ? u.ustuck->m_id : 0; + u.usteed_mid = (u.usteed) ? u.usteed->m_id : 0; + } Sfo_you(nhfp, &u, "gamestate-you"); + + /* clear the in-memory value of these, now that they have been + * successfully written out. + */ + u.ustuck_mid = 0; + u.usteed_mid = 0; Sfo_char(nhfp, yyyymmddhhmmss(ubirthday), "gamestate-ubirthday", 14); Sfo_long(nhfp, &urealtime.realtime, "gamestate-realtime"); Sfo_char(nhfp, yyyymmddhhmmss(urealtime.start_timing), "gamestate-start_timing", 14);