From cd9f145dbac563b50f335b2e21f8df89f7d232bd Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 23 Jun 2023 15:19:36 -0700 Subject: [PATCH] fix leaving the tutorial levels While running the tutorial, the Save command is disabled. When the tutorial was extended to two levels, stashing and restoring the hero's equipment stopped working as intended if player entered the second level. The attempted fix for that broke re-enabling Save even if the player left the tutorial without entering its second level. This seems to fix things, but I'm flailing around with barely a clue here. A couple of simpler attempts didn't work and I haven't figured out why, so this is a bit more complex than what I wanted. Reorganizing nhl_callback() isn't part of the fix, just avoids use of some redundant code. --- dat/nhcore.lua | 4 ++ dat/nhlib.lua | 12 ++++-- dat/tut-1.lua | 4 +- doc/fixes3-7-0.txt | 2 + include/hack.h | 2 + src/nhlua.c | 103 +++++++++++++++++++-------------------------- 6 files changed, 62 insertions(+), 65 deletions(-) diff --git a/dat/nhcore.lua b/dat/nhcore.lua index 5b188efb9..0fc778f6c 100644 --- a/dat/nhcore.lua +++ b/dat/nhcore.lua @@ -136,5 +136,9 @@ nhcore = { -- getpos_tip is called the first time the code enters getpos() getpos_tip = show_getpos_tip, + + -- enter_tutorial and leave_tutorial + enter_tutorial = tutorial_enter, + leave_tutorial = tutorial_leave, }; diff --git a/dat/nhlib.lua b/dat/nhlib.lua index 9b1fe88f2..f4fab68fb 100644 --- a/dat/nhlib.lua +++ b/dat/nhlib.lua @@ -195,17 +195,23 @@ end function tutorial_enter() -- nh.pline("TUT:enter"); + + -- add the tutorial branch callbacks + nh.callback("cmd_before", "tutorial_cmd_before"); + nh.callback("end_turn", "tutorial_turn"); + + -- save state for later restore nh.gamestate(); end function tutorial_leave() -- nh.pline("TUT:leave"); - -- remove the tutorial level callbacks + -- remove the tutorial branch callbacks nh.callback("cmd_before", "tutorial_cmd_before", true); - nh.callback("level_enter", "tutorial_enter", true); - nh.callback("level_leave", "tutorial_leave", true); nh.callback("end_turn", "tutorial_turn", true); + + -- restore state for regular play nh.gamestate(true); end diff --git a/dat/tut-1.lua b/dat/tut-1.lua index b1937f7b8..345f6906f 100644 --- a/dat/tut-1.lua +++ b/dat/tut-1.lua @@ -254,11 +254,11 @@ des.trap({ type = "magic portal", coord = { 66,2 }, seen = true }); ---------------- -nh.callback("cmd_before", "tutorial_cmd_before"); -- entering and leaving tutorial _branch_ now handled by core +-- // nh.callback("cmd_before", "tutorial_cmd_before"); -- // nh.callback("level_enter", "tutorial_enter"); -- // nh.callback("level_leave", "tutorial_leave"); -nh.callback("end_turn", "tutorial_turn"); +-- // nh.callback("end_turn", "tutorial_turn"); ---------------- diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index ad03dfb6d..d5361ddee 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1618,6 +1618,8 @@ when a magic whistle moved a hidden pet it brought that out of hiding and entering the tutorial stashed hero's equipment for eventual return to normal play but going down stairs to the second tutorial level returned it too soon and allowed any items gathered on the first level to be kept +entering the tutorial disables the Save command; exiting it is supposed to + re-enable that but the change to fix the second level broke that entering the tutorial and then returning to play made the tutorial branch be eligible for a portal destination via wizard's Eye of the Aethiopica 'hard helmet' was based on being metallic so overlooked crystal helmet diff --git a/include/hack.h b/include/hack.h index e6fa6d4b7..b278bd17f 100644 --- a/include/hack.h +++ b/include/hack.h @@ -635,6 +635,8 @@ enum nhcore_calls { NHCORE_MOVELOOP_TURN, NHCORE_GAME_EXIT, NHCORE_GETPOS_TIP, + NHCORE_ENTER_TUTORIAL, + NHCORE_LEAVE_TUTORIAL, NUM_NHCORE_CALLS }; diff --git a/src/nhlua.c b/src/nhlua.c index dd1070b16..23b82087a 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -85,6 +85,8 @@ static const char *const nhcore_call_names[NUM_NHCORE_CALLS] = { "moveloop_turn", "game_exit", "getpos_tip", + "enter_tutorial", + "leave_tutorial", }; static boolean nhcore_call_available[NUM_NHCORE_CALLS]; @@ -1508,62 +1510,43 @@ nhl_callback(lua_State *L) { int argc = lua_gettop(L); int i; + boolean rm; + const char *fn, *cb; - if (argc == 2) { - const char *fn = luaL_checkstring(L, -1); - const char *cb = luaL_checkstring(L, -2); - - if (!gl.luacore) { - nhl_error(L, "nh luacore not inited"); - /*NOTREACHED*/ - return 0; - } - - for (i = 0; i < NUM_NHCB; i++) - if (!strcmp(cb, nhcb_name[i])) - break; - - if (i >= NUM_NHCB) - return 0; - - nhcb_counts[i]++; - - lua_getglobal(gl.luacore, "nh_callback_set"); - lua_pushstring(gl.luacore, cb); - lua_pushstring(gl.luacore, fn); - nhl_pcall(gl.luacore, 2, 0); - } else if (argc == 3) { - boolean rm = lua_toboolean(L, -1); - const char *fn = luaL_checkstring(L, -2); - const char *cb = luaL_checkstring(L, -3); - - if (!gl.luacore) { - nhl_error(L, "nh luacore not inited"); - /*NOTREACHED*/ - return 0; - } - - for (i = 0; i < NUM_NHCB; i++) - if (!strcmp(cb, nhcb_name[i])) - break; - - if (i >= NUM_NHCB) - return 0; - - if (rm) { - nhcb_counts[i]--; - if (nhcb_counts[i] < 0) - impossible("nh.callback counts are wrong"); - } else { - nhcb_counts[i]++; - } - - lua_getglobal(gl.luacore, rm ? "nh_callback_rm" : "nh_callback_set"); - lua_pushstring(gl.luacore, cb); - lua_pushstring(gl.luacore, fn); - nhl_pcall(gl.luacore, 2, 0); + if (!gl.luacore) { + nhl_error(L, "nh luacore not inited"); + /*NOTREACHED*/ + return 0; } + if (argc == 2) { + rm = FALSE; + fn = luaL_checkstring(L, -1); + cb = luaL_checkstring(L, -2); + } else if (argc == 3) { + rm = lua_toboolean(L, -1); + fn = luaL_checkstring(L, -2); + cb = luaL_checkstring(L, -3); + } + + for (i = 0; i < NUM_NHCB; i++) + if (!strcmp(cb, nhcb_name[i])) + break; + if (i >= NUM_NHCB) + return 0; + + if (rm) { + nhcb_counts[i]--; + if (nhcb_counts[i] < 0) + impossible("nh.callback counts are wrong"); + } else { + nhcb_counts[i]++; + } + + lua_getglobal(gl.luacore, rm ? "nh_callback_rm" : "nh_callback_set"); + lua_pushstring(gl.luacore, cb); + lua_pushstring(gl.luacore, fn); + nhl_pcall(gl.luacore, 2, 0); return 0; } @@ -1637,13 +1620,13 @@ RESTORE_WARNING_UNREACHABLE_CODE void tutorial(boolean entering) { - lua_State *L = gl.luacore; + l_nhcore_call(entering ? NHCORE_ENTER_TUTORIAL : NHCORE_LEAVE_TUTORIAL); - /* pass FALSE when entering, to save state; pass TRUE when leaving, - to restore state */ - lua_pushboolean(L, !entering); - (void) nhl_gamestate(L); - lua_pop(L, 1); + if (!entering) { /* after leaving, can't go back */ + nhcore_call_available[NHCORE_ENTER_TUTORIAL] + = nhcore_call_available[NHCORE_LEAVE_TUTORIAL] + = FALSE; + } } static const struct luaL_Reg nhl_functions[] = { @@ -1894,7 +1877,7 @@ nhl_pcall(lua_State *L, int nargs, int nresults) lua_pushcfunction(L, traceback_handler); lua_insert(L, 1); - (void)lua_getallocf(L, (void **)&nud); + (void) lua_getallocf(L, (void **) &nud); #ifdef NHL_SANDBOX if (nud && (nud->steps || nud->perpcall)) { if (nud->perpcall)