partly fix issue #1134 - tutorial leaks obj info

Reported by AndrioCelos, a handful of objects in the tutorial can
be discovered via use, and such discoveries were carrying over to
normal play when the tutorial ended.

This causes the hero to forget such discoveries.  The player will
still be able to remember them.  The proper fix would be to discard
the initialized but not-yet-started game when entering the tutorial
and then start a whole new one when exiting so that saving and
restoring game state would become unnecessary.  This doesn't do that.

This also causes monster birth and death statistics to be reset when
exiting the tutorial.  Affects the #vanquished command and potentially
extinctionist play.

Closes #1134
This commit is contained in:
PatR
2024-03-21 08:32:58 -07:00
parent 058e0cf18c
commit a79d6d8e63
2 changed files with 35 additions and 8 deletions

View File

@@ -1,4 +1,4 @@
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1396 $ $NHDT-Date: 1709928001 2024/03/08 20:00:01 $
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1402 $ $NHDT-Date: 1711034372 2024/03/21 15:19:32 $
General Fixes and Modified Features
-----------------------------------
@@ -1892,6 +1892,8 @@ setting perm_invent in RC file before setting windowtype (whether later in
depending upon whether the default windowtype supported it
if hero was wielding potion(s) of unholy water and a magic trap gave its
remove curse effect, scroll of remove curse would become discovered
objects discovered during the tutorial carried over when normal play resumed;
counts of monsters created and vanquished carried over too
Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 nhlua.c $NHDT-Date: 1705087450 2024/01/12 19:24:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.129 $ */
/* NetHack 3.7 nhlua.c $NHDT-Date: 1711034373 2024/03/21 15:19:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ */
/* Copyright (c) 2018 by Pasi Kallinen */
/* NetHack may be freely redistributed. See license for details. */
@@ -1557,17 +1557,26 @@ nhl_callback(lua_State *L)
}
/* store or restore game state */
/* NOTE: doesn't work when saving/restoring the game */
/* currently handles inventory and turns. */
/*
* Currently handles
* turn counter,
* hero inventory and hunger,
* hero attributes and skills and conducts (all via 'struct u'),
* object discoveries,
* monster generation and vanquished statistics.
* NOTE: wouldn't work after restore if game has been saved, so the
* #save command ('S') is disabled during the tutorial.
*/
/* gamestate(); -- save state */
/* gamestate(true); -- restore state */
staticfn int
nhl_gamestate(lua_State *L)
{
static struct obj *gmst_invent = NULL;
static long gmst_moves = 0;
static struct obj *gmst_invent = NULL;
static genericptr_t
*gmst_ubak = NULL, *gmst_disco = NULL, *gmst_mvitals= NULL;
static boolean gmst_stored = FALSE;
static struct you gmst_ubak;
long wornmask;
struct obj *otmp;
int argc = lua_gettop(L);
@@ -1580,6 +1589,7 @@ nhl_gamestate(lua_State *L)
d_level cur_uz = u.uz, cur_uz0 = u.uz0;
/* restore game state */
pline("Resetting time to move #%ld.", gmst_moves);
gm.moves = gmst_moves;
gl.lastinvnr = 51;
while (gi.invent)
@@ -1592,7 +1602,16 @@ nhl_gamestate(lua_State *L)
if (wornmask)
setworn(otmp, wornmask);
}
u = gmst_ubak;
assert(gmst_ubak != NULL);
(void) memcpy((genericptr_t) &u, gmst_ubak, sizeof u);
free(gmst_ubak), gmst_ubak = NULL;
assert(gmst_disco != NULL);
(void) memcpy((genericptr_t) &gd.disco, gmst_disco, sizeof gd.disco);
free(gmst_disco), gmst_disco = NULL;
assert(gmst_mvitals != NULL);
(void) memcpy((genericptr_t) &gm.mvitals, gmst_mvitals,
sizeof gm.mvitals);
free(gmst_mvitals), gmst_mvitals = NULL;
/* some restored state would confuse the level change in progress */
u.uz = cur_uz, u.uz0 = cur_uz0;
init_uhunger();
@@ -1609,7 +1628,13 @@ nhl_gamestate(lua_State *L)
}
gl.lastinvnr = 51; /* next inv letter to try to use will be 'a' */
gmst_moves = gm.moves;
gmst_ubak = u;
gmst_ubak = (genericptr_t) alloc(sizeof u);
(void) memcpy(gmst_ubak, (genericptr_t) &u, sizeof u);
gmst_disco = (genericptr_t) alloc(sizeof gd.disco);
(void) memcpy(gmst_disco, (genericptr_t) &gd.disco, sizeof gd.disco);
gmst_mvitals = (genericptr_t) alloc(sizeof gm.mvitals);
(void) memcpy(gmst_mvitals, (genericptr_t) &gm.mvitals,
sizeof gm.mvitals);
gmst_stored = TRUE;
} else {
impossible("nhl_gamestate: inconsistent state (%s vs %s)",