]> granicus.if.org Git - nethack/commitdiff
avoid "It turns into it"
authornethack.allison <nethack.allison>
Sat, 17 Jan 2004 20:42:14 +0000 (20:42 +0000)
committernethack.allison <nethack.allison>
Sat, 17 Jan 2004 20:42:14 +0000 (20:42 +0000)
<Someone> drew attention to the silly message in the newsgroup

Since I'm not sure if the act of polymorphing has a sound,
I opted to use a new usmellmon() routine to put out a
message based on the smell of the resulting monster
under those circumstances.

Not every monster has a recognizable smell, so no
message at all is given in that case.

olfactory(youmonst.data) will determine whether
you are capable of detecting smells.

There is lots of room for enhancement, and some of the
existing smell-related messages in the source should perhaps
be checking olfactory(youmonst.data) too, but this patch
doesn't go that far.

doc/fixes34.4
include/extern.h
src/cmd.c
src/mon.c
src/mondata.c

index b7ec3aaf561da9b3708df4659c96456af4429ea6..cf49603882e0a793d1f559e51c07397d44ef4d3f 100644 (file)
@@ -13,6 +13,7 @@ trap messages referring to named steed were ackwardly worded when hallucination
        overrode use of the name
 some actions such as eating corpses off the floor didn't check whether hero
        could reach the bottom of a pit
+usmellmon() instead of "It turns into it" during monster polymorph
 
 
 Platform- and/or Interface-Specific Fixes
index 4bc7e4198effea387cdcadb7334c966b870aa0b8..671e85f2ed998807833865ea9742ececf02faf7f 100644 (file)
@@ -973,6 +973,7 @@ E void FDECL(mkmonmoney, (struct monst *, long));
 #endif
 E void FDECL(bagotricks, (struct obj *));
 E boolean FDECL(propagate, (int, BOOLEAN_P,BOOLEAN_P));
+E boolean FDECL(usmellmon, (struct permonst *));
 
 /* ### mapglyph.c ### */
 
@@ -1223,6 +1224,7 @@ E const char *FDECL(locomotion, (const struct permonst *,const char *));
 E const char *FDECL(stagger, (const struct permonst *,const char *));
 E const char *FDECL(on_fire, (struct permonst *,struct attack *));
 E const struct permonst *FDECL(raceptr, (struct monst *));
+E boolean FDECL(olfaction, (struct permonst *));
 
 /* ### monmove.c ### */
 
index 475a6d828e0ccd058b8a234fa5563b1ec7d23d02..84f3e186092a00273c433bac057b96adbb28cdca 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -121,6 +121,7 @@ STATIC_PTR int NDECL(wiz_level_tele);
 STATIC_PTR int NDECL(wiz_level_change);
 STATIC_PTR int NDECL(wiz_show_seenv);
 STATIC_PTR int NDECL(wiz_show_vision);
+STATIC_PTR int NDECL(wiz_smell);
 STATIC_PTR int NDECL(wiz_mon_polycontrol);
 STATIC_PTR int NDECL(wiz_show_wmodes);
 #if defined(__BORLANDC__) && !defined(_WIN32)
@@ -750,6 +751,53 @@ wiz_show_wmodes()
        return 0;
 }
 
+/* #wizsmell command - test usmellmon(). */
+STATIC_PTR int
+wiz_smell()
+{
+       char    out_str[BUFSZ];
+       const char *firstmatch = 0;
+       struct permonst *pm = 0;
+       int     ans = 0;
+       int     mndx;           /* monster index */
+       int     found;          /* count of matching mndxs found */
+       coord   cc;             /* screen pos of unknown glyph */
+       int glyph;              /* glyph at selected position */
+
+       cc.x = u.ux;
+       cc.y = u.uy;
+       mndx = 0;               /* gcc -Wall lint */
+       if (!olfaction(youmonst.data)) {
+               You("are incapable of detecting odors in your present form.");
+               return 0;
+       }
+
+       pline("You can move the cursor to a monster that you want to smell.");
+       do {
+               /* Reset some variables. */
+               pm = (struct permonst *)0;
+               found = 0;
+               out_str[0] = '\0';
+       
+               pline("Pick a monster to smell.");
+               ans = getpos(&cc, TRUE, "a monster");
+               if (ans < 0 || cc.x < 0) {
+                       return 0;       /* done */
+               }
+               /* Convert the glyph at the selected position to a mndxbol. */
+               glyph = glyph_at(cc.x,cc.y);
+               if (glyph_is_monster(glyph))
+                       mndx = glyph_to_mon(glyph);
+               else
+                       mndx = 0;
+               /* Is it a monster? */
+               if (mndx) {
+                       if (!usmellmon(&mons[mndx]))
+                               pline("That monster seems to give off no smell.");
+               } else pline("That is not a monster.");
+       } while (TRUE);
+       return 0;
+}
 #endif /* WIZARD */
 
 
@@ -1516,6 +1564,7 @@ struct ext_func_tab extcmdlist[] = {
         {(char *)0, (char *)0, donull, TRUE},
        {(char *)0, (char *)0, donull, TRUE},
        {(char *)0, (char *)0, donull, TRUE},
+       {(char *)0, (char *)0, donull, TRUE},
 #ifdef DEBUG
        {(char *)0, (char *)0, donull, TRUE},
 #endif
@@ -1541,6 +1590,7 @@ static const struct ext_func_tab debug_extcmdlist[] = {
        {"stats", "show memory statistics", wiz_show_stats, TRUE},
        {"timeout", "look at timeout queue", wiz_timeout_queue, TRUE},
        {"vision", "show vision array", wiz_show_vision, TRUE},
+       {"wizsmell", "smell monster", wiz_smell, TRUE},
 #ifdef DEBUG
        {"wizdebug", "wizard debug command", wiz_debug_cmd, TRUE},
 #endif
index 1cd3835ec42b925f5bff3f977e0e534509ff6799..09b66811e71c4318f3fdd6ba47d4081c35d90229 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -2347,7 +2347,7 @@ boolean msg;              /* "The oldmon turns into a newmon!" */
        int mhp, hpn, hpd;
        int mndx, tryct;
        struct permonst *olddata = mtmp->data;
-       char oldname[BUFSZ];
+       char oldname[BUFSZ], newname[BUFSZ];
 
        if (msg) {
            /* like Monnam() but never mention saddle */
@@ -2487,9 +2487,13 @@ boolean msg;             /* "The oldmon turns into a newmon!" */
        if (msg) {
            uchar save_mnamelth = mtmp->mnamelth;
            mtmp->mnamelth = 0;
-           pline("%s turns into %s!", oldname,
-                 mdat == &mons[PM_GREEN_SLIME] ? "slime" :
-                 x_monnam(mtmp, ARTICLE_A, (char*)0, SUPPRESS_SADDLE, FALSE));
+           Strcpy(newname,
+                  (mdat == &mons[PM_GREEN_SLIME]) ? "slime" :
+                  x_monnam(mtmp, ARTICLE_A, (char *)0,SUPPRESS_SADDLE, FALSE));
+           if (!strcmpi(oldname,"it") && !strcmpi(newname,"it"))
+                   (void) usmellmon(mdat);
+           else
+                   pline("%s turns into %s!", oldname, newname);
            mtmp->mnamelth = save_mnamelth;
        }
 
@@ -2768,4 +2772,120 @@ short otyp;
        }
 }
 
+boolean
+usmellmon(mdat)
+struct permonst *mdat;
+{
+       int mndx;
+       boolean nonspecific = FALSE;
+       boolean msg_given = FALSE;
+
+       if (mdat) {
+           if (!olfaction(youmonst.data)) return FALSE;
+           mndx = monsndx(mdat);
+           switch (mndx) {
+               case PM_MINOTAUR:
+                       You("notice a bovine smell.");
+                       msg_given = TRUE;
+                       break;
+               case PM_CAVEMAN:
+               case PM_CAVEWOMAN:
+               case PM_BARBARIAN:
+               case PM_NEANDERTHAL:
+                       You("smell body odor.");
+                       msg_given = TRUE;
+                       break;
+/*
+               case PM_PESTILENCE:
+               case PM_FAMINE:
+               case PM_DEATH:
+                       break;
+*/
+               case PM_HORNED_DEVIL:
+               case PM_BALROG:
+               case PM_ASMODEUS:
+               case PM_DISPATER:
+               case PM_YEENOGHU:
+               case PM_ORCUS:
+                       break;
+               case PM_HUMAN_WEREJACKAL:
+               case PM_HUMAN_WERERAT:
+               case PM_HUMAN_WEREWOLF:
+               case PM_WEREJACKAL:
+               case PM_WERERAT:
+               case PM_WEREWOLF:
+               case PM_OWLBEAR:
+                       You("detect an odor reminiscent of an animal's den.");
+                       msg_given = TRUE;
+                       break;
+/*
+               case PM_PURPLE_WORM:
+                       break;
+*/
+               case PM_STEAM_VORTEX:
+                       You("smell steam.");
+                       msg_given = TRUE;
+                       break;
+               case PM_GREEN_SLIME:
+                       pline("%s stinks.", Something);
+                       msg_given = TRUE;
+                       break;
+               case PM_VIOLET_FUNGUS:
+               case PM_SHRIEKER:
+                       You("smell mushrooms.");
+                       msg_given = TRUE;
+                       break;
+               /* These are here to avoid triggering the
+                  nonspecific treatment through the default case below*/
+               case PM_WHITE_UNICORN:
+               case PM_GRAY_UNICORN:
+               case PM_BLACK_UNICORN:
+               case PM_JELLYFISH:
+                       break;
+               default:
+                       nonspecific = TRUE;
+                       break;
+           }
+
+           if (nonspecific) switch(mdat->mlet) {
+               case S_DOG:
+                       You("notice a dog smell.");
+                       msg_given = TRUE;
+                       break;
+               case S_DRAGON:
+                       You("smell a dragon!");
+                       msg_given = TRUE;
+                       break;
+               case S_FUNGUS:
+                       pline("%s smells moldy.", Something);
+                       msg_given = TRUE;
+                       break;
+               case S_UNICORN:
+                       You("detect a%s odor reminiscent of a stable.",
+                               (mndx == PM_PONY) ? "n" : " strong");
+                       msg_given = TRUE;
+                       break;
+               case S_ZOMBIE:
+                       You("smell rotting flesh.");
+                       msg_given = TRUE;
+                       break;
+               case S_EEL:
+                       You("smell fish.");
+                       msg_given = TRUE;
+                       break;
+               case S_ORC:
+                       if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC)))
+                           You("notice an attractive smell.");
+                       else
+                           pline(
+                           "A foul stench makes you feel a little nauseated.");
+                       msg_given = TRUE;
+                       break;
+               default:
+                       break;
+           }
+       }
+       return (msg_given) ? TRUE : FALSE;
+}
+
 /*mon.c*/
index 13c3a127e3a25eae48fed97b9a35e2ac76dc570c..b9fd5b3ed9d9e4b80e28753ab7dac1e7822c1c01 100644 (file)
@@ -720,4 +720,30 @@ struct attack *mattk;
     return what;
 }
 
+/*
+ * Returns:
+ *     TRUE if monster is presumed to have a sense of smell.
+ *     FALSE if monster definitely does not have a sense of smell.
+ *
+ *     Do not base this on presence of a head or nose, since many
+ *     creatures sense smells other ways (feelers, forked-tongues, etc.)
+ *     We're assuming all insects can smell at a distance too.
+ */
+boolean
+olfaction(mdat)
+struct permonst *mdat;
+{
+       if (mdat && (is_golem(mdat)   ||
+           mdat->mlet == S_EYE       ||        /* spheres  */
+           mdat->mlet == S_JELLY     ||
+           mdat->mlet == S_PUDDING   ||
+           mdat->mlet == S_BLOB      ||
+           mdat->mlet == S_VORTEX    ||
+           mdat->mlet == S_ELEMENTAL ||
+           mdat->mlet == S_FUNGUS    ||        /* mushrooms and fungi */
+           mdat->mlet == S_LIGHT))
+           return FALSE;
+       return TRUE;
+}
+
 /*mondata.c*/