diff --git a/dat/quest.lua b/dat/quest.lua index 891556987..7e484df1d 100644 --- a/dat/quest.lua +++ b/dat/quest.lua @@ -4,7 +4,7 @@ -- - export the quest string replacements to lua, instead of %H etc -- - allow checking if hero is carrying item (see comments for %Cp Arc 00042) -- - fold quest_portal, quest_portal_again, quest_portal_demand into one --- - some roles have no goal_alt, fold into goal_next? +-- - write tests to check questtext validity? -- - qt_pager hack(?): if (qt_msg->delivery == 'p' && strcmp(windowprocs.name, "X11")) @@ -25,6 +25,10 @@ questtext = { + -- If a role doesn't have a specific message, try a fallback + msg_fallbacks = { + goal_alt = "goal_next" + }, common = { TEST_PATTERN = { output = "text", diff --git a/src/pray.c b/src/pray.c index 173996c09..3d4045141 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pray.c $NHDT-Date: 1578895347 2020/01/13 06:02:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */ +/* NetHack 3.6 pray.c $NHDT-Date: 1579401997 2020/01/19 02:46:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.139 $ */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -484,7 +484,7 @@ int trouble; what = rightglow; else if (otmp == uleft) what = leftglow; - decurse: + decurse: if (!otmp) { impossible("fix_worst_trouble: nothing to uncurse."); return; @@ -1496,7 +1496,7 @@ dosacrifice() if (otmp->otyp == AMULET_OF_YENDOR) { if (!highaltar) { - too_soon: + too_soon: if (altaralign == A_NONE && Inhell) /* hero has left Moloch's Sanctum so is in the process of getting away with the Amulet (outside of Gehennom, @@ -1526,7 +1526,8 @@ dosacrifice() /* Moloch's high altar */ if (u.ualign.record > -99) u.ualign.record = -99; - pline("An invisible choir chants in Latin, and you are bathed in darkness..."); + pline( + "An invisible choir chants, and you are bathed in darkness..."); /*[apparently shrug/snarl can be sensed without being seen]*/ pline("%s shrugs and retains dominion over %s,", Moloch, u_gname()); @@ -1593,7 +1594,7 @@ dosacrifice() } if (altaralign != u.ualign.type && highaltar) { - desecrate_high_altar: + desecrate_high_altar: /* * REAL BAD NEWS!!! High altars cannot be converted. Even an attempt * gets the god who owns it truly pissed off. @@ -1830,7 +1831,8 @@ boolean praying; /* false means no messages should be given */ } if (is_undead(g.youmonst.data) && !Inhell - && (g.p_aligntyp == A_LAWFUL || (g.p_aligntyp == A_NEUTRAL && !rn2(10)))) + && (g.p_aligntyp == A_LAWFUL + || (g.p_aligntyp == A_NEUTRAL && !rn2(10)))) g.p_type = -1; /* Note: when !praying, the random factor for neutrals makes the return value a non-deterministic approximation for enlightenment. diff --git a/src/questpgr.c b/src/questpgr.c index 85c272557..5df059fd1 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -432,9 +432,10 @@ boolean common UNUSED; } boolean -com_pager_core(section, msgid) +com_pager_core(section, msgid, showerror) const char *section; const char *msgid; +boolean showerror; { const char *const howtoput[] = { "pline", "window", "text", "menu", "default", NULL }; const int howtoput2i[] = { 1, 2, 2, 3, 0, 0 }; @@ -442,6 +443,7 @@ const char *msgid; lua_State *L; char *synopsis; char *text; + char *fallback_msgid = NULL; if (skip_pager(TRUE)) return FALSE; @@ -449,7 +451,8 @@ const char *msgid; L = nhl_init(); if (!nhl_loadlua(L, QTEXT_FILE)) { - impossible("com_pager: %s not found.", QTEXT_FILE); + if (showerror) + impossible("com_pager: %s not found.", QTEXT_FILE); lua_close(L); return FALSE; } @@ -457,21 +460,40 @@ const char *msgid; lua_settop(L, 0); lua_getglobal(L, "questtext"); if (!lua_istable(L, -1)) { - impossible("com_pager: questtext in %s is not a lua table", QTEXT_FILE); + if (showerror) + impossible("com_pager: questtext in %s is not a lua table", + QTEXT_FILE); lua_close(L); return FALSE; } lua_getfield(L, -1, section); if (!lua_istable(L, -1)) { - impossible("com_pager: questtext[%s] in %s is not a lua table", section, QTEXT_FILE); + if (showerror) + impossible("com_pager: questtext[%s] in %s is not a lua table", + section, QTEXT_FILE); lua_close(L); return FALSE; } - lua_getfield(L, -1, msgid); +tryagain: + lua_getfield(L, -1, fallback_msgid ? fallback_msgid : msgid); if (!lua_istable(L, -1)) { - impossible("com_pager: questtext[%s][%s] in %s is not a lua table", section, msgid, QTEXT_FILE); + if (!fallback_msgid) { + /* Do we have questtxt[msg_fallbacks][]? */ + lua_getfield(L, -3, "msg_fallbacks"); + if (lua_istable(L, -1)) { + fallback_msgid = get_table_str_opt(L, msgid, NULL); + lua_pop(L, 2); + if (fallback_msgid) + goto tryagain; + } + } + + if (showerror) + impossible("com_pager: questtext[%s][%s] in %s is not a lua table", + section, msgid, QTEXT_FILE); + free(fallback_msgid); lua_close(L); return FALSE; } @@ -487,9 +509,11 @@ const char *msgid; nelems = (int) lua_tointeger(L, -1); lua_pop(L, 1); if (nelems < 2) { - impossible( - "com_pager: questtext[%s][%s] in %s in not an array of strings", + if (showerror) + impossible( + "com_pager: questtext[%s][%s] in %s in not an array of strings", section, msgid, QTEXT_FILE); + free(fallback_msgid); lua_close(L); return FALSE; } @@ -518,6 +542,7 @@ const char *msgid; free(synopsis); } + free(fallback_msgid); free(text); lua_close(L); return TRUE; @@ -527,15 +552,15 @@ void com_pager(msgid) const char *msgid; { - com_pager_core("common", msgid); + com_pager_core("common", msgid, TRUE); } void qt_pager(msgid) const char *msgid; { - if (!com_pager_core(g.urole.filecode, msgid)) - com_pager_core("common", msgid); + if (!com_pager_core(g.urole.filecode, msgid, FALSE)) + com_pager_core("common", msgid, TRUE); } struct permonst *