]> granicus.if.org Git - nethack/commitdiff
noxious quest nemeses
authorPatR <rankin@nethack.org>
Sun, 12 Jun 2022 20:19:13 +0000 (13:19 -0700)
committerPatR <rankin@nethack.org>
Sun, 12 Jun 2022 20:19:13 +0000 (13:19 -0700)
Refine the code added by pull request #763 to check the quest nemesis
death message for reference to noxious fumes rather than having the
three relevant roles be hardcoded.

doc/fixes3-7-0.txt
include/extern.h
src/mon.c
src/questpgr.c

index c223bdf66090c54364cfaa3ab977233a4b35db83..4af91791fed730663c92f456d5b973c3c604a47c 100644 (file)
@@ -1,4 +1,4 @@
-HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.946 $ $NHDT-Date: 1654931291 2022/06/11 07:08:11 $
+HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.949 $ $NHDT-Date: 1655065133 2022/06/12 20:18:53 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -1676,6 +1676,7 @@ if built with DEBUG enabled and running in wizard mode, starting play with
        DEBUGFILES=seethru in environment makes clouds on the Plane of Air,
        water on Plane of Water, and fumaroles on Plane of Fire be transparent
 add wizard mode #wizkill command to remove monster(s) from play
+some quest nemeses release a cloud of poisonous gas when they die
 
 
 Platform- and/or Interface-Specific New Features
index 160f0829af2fb2f40f9d37665d4a1c4f96a6af48..f9525d6fdf471d0e7f50a17abe218cfb3685a255 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 extern.h        $NHDT-Date: 1654896957 2022/06/10 21:35:57 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1119 $ */
+/* NetHack 3.7 extern.h        $NHDT-Date: 1655065134 2022/06/12 20:18:54 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1121 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -2231,6 +2231,7 @@ extern short quest_info(int);
 extern const char *ldrname(void);
 extern boolean is_quest_artifact(struct obj *);
 extern struct obj *find_quest_artifact(unsigned);
+extern int stinky_nemesis(struct monst *);
 extern void com_pager(const char *);
 extern void qt_pager(const char *);
 extern struct permonst *qt_montype(void);
index 170a8ed9e8aa02fc2c04de1a4f97cd932398e9da..cfae1214e450ce6903c8cbc0421e79041ea34931 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -1,4 +1,4 @@
-/* NetHack 3.7 mon.c   $NHDT-Date: 1654465182 2022/06/05 21:39:42 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.433 $ */
+/* NetHack 3.7 mon.c   $NHDT-Date: 1655065140 2022/06/12 20:19:00 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.436 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2380,16 +2380,11 @@ m_detach(
     if (mtmp->iswiz)
         wizdead();
     if (mtmp->data->msound == MS_NEMESIS) {
-        struct permonst *mdat = mtmp->data;
         nemdead();
         /* The Archeologist, Caveman, and Priest quest texts describe
-           the nemesis's body creating noxious fumes/gas when
-           killed. */
-        if (mdat == &mons[PM_MINION_OF_HUHETOTL]
-            || mdat == &mons[PM_CHROMATIC_DRAGON]
-            || mdat == &mons[PM_NALZOK]) {
+           the nemesis's body creating noxious fumes/gas when killed. */
+        if (stinky_nemesis(mtmp))
             create_gas_cloud(mx, my, 5, 8);
-        }
     }
     if (mtmp->data->msound == MS_LEADER)
         leaddead();
index 4cfed0439bbb969a85a565120f411ad564c3ad06..bbf08351db1e2cf15ced4247480c4cb2e62045ae 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 questpgr.c      $NHDT-Date: 1652827965 2022/05/17 22:52:45 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */
+/* NetHack 3.7 questpgr.c      $NHDT-Date: 1655065145 2022/06/12 20:19:05 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.79 $ */
 /*      Copyright 1991, M. Stephenson                             */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -24,7 +24,7 @@ static void convert_line(char *,char *);
 static void deliver_by_pline(const char *);
 static void deliver_by_window(const char *, int);
 static boolean skip_pager(boolean);
-static boolean com_pager_core(const char *, const char *, boolean);
+static boolean com_pager_core(const char *, const char *, boolean, char **);
 
 short
 quest_info(int typ)
@@ -143,6 +143,55 @@ homebase(void) /* return your role leader's location */
     return g.urole.homebase;
 }
 
+/* returns 1 if nemesis death message mentions noxious fumes, otherwise 0;
+   does not display the message */
+int
+stinky_nemesis(struct monst *mon)
+{
+    char *mesg = 0;
+    int res = 0;
+
+#if 0
+    /* get the quest text for dying nemesis; don't assume that mon is
+       hero's own role's nemesis (overkill since m_detach() and nemdead()
+       both make that assumption--valid for normal play but not necessarily
+       valid for wizard mode) */
+    int r, mndx = monsndx(mon->data);
+    for (r = 0; roles[r].name.m || roles[r].name.f; ++r)
+        if (roles[r].neminum == mndx) {
+            (void) com_pager_core(roles[r].filecode, "killed_nemesis",
+                                  FALSE, &mesg);
+            break;
+        }
+#else
+    nhUse(mon);
+    /* since nemdead() just gave the message for hero's nemesis even if 'mon'
+       is some other role's nemesis (feasible in wizard mode), base any gas
+       cloud on the text that was shown even if not appropriate for 'mon' */
+    (void) com_pager_core(g.urole.filecode, "killed_nemesis", FALSE, &mesg);
+#endif
+
+    /* this is somewhat fragile; it assumes that when both (noxious or
+       poisonous or toxic) and (gas or fumes) are present, the latter
+       refers to the former rather than to something unrelated; it does
+       make sure that fumes occurs after noxious rather than before */
+    if (mesg) {
+        char *p;
+
+        /* change newlines into spaces to cope with "...noxious\nfumes..." */
+        (void) strNsubst(mesg, "\n", " ", 0);
+
+        if (((p = strstri(mesg, "noxious")) != 0
+             || (p = strstri(mesg, "poisonous")) != 0
+             || (p = strstri(mesg, "toxic")) != 0)
+            && (strstri(p, " gas") || strstri(p, " fumes")))
+            res = 1;
+
+        free((genericptr_t) mesg);
+    }
+    return res;
+}
+
 /* replace deity, leader, nemesis, or artifact name with pronoun;
    overwrites cvt_buf[] */
 static void
@@ -415,7 +464,8 @@ static boolean
 com_pager_core(
     const char *section,
     const char *msgid,
-    boolean showerror)
+    boolean showerror,
+    char **rawtext)
 {
     static const char *const howtoput[] = {
         "pline", "window", "text", "menu", "default", NULL
@@ -486,8 +536,13 @@ com_pager_core(
         goto compagerdone;
     }
 
-    synopsis = get_table_str_opt(L, "synopsis", NULL);
     text = get_table_str_opt(L, "text", NULL);
+    if (rawtext) {
+        *rawtext = dupstr(text);
+        res = TRUE;
+        goto compagerdone;
+    }
+    synopsis = get_table_str_opt(L, "synopsis", NULL);
     output = howtoput2i[get_table_option(L, "output", "default", howtoput)];
 
     if (!text) {
@@ -564,14 +619,14 @@ com_pager_core(
 void
 com_pager(const char *msgid)
 {
-    com_pager_core("common", msgid, TRUE);
+    (void) com_pager_core("common", msgid, TRUE, (char **) 0);
 }
 
 void
 qt_pager(const char *msgid)
 {
-    if (!com_pager_core(g.urole.filecode, msgid, FALSE))
-        com_pager_core("common", msgid, TRUE);
+    if (!com_pager_core(g.urole.filecode, msgid, FALSE, (char **) 0))
+        (void) com_pager_core("common", msgid, TRUE, (char **) 0);
 }
 
 struct permonst *