OSDN Git Service

update travis setting
[jnethack/source.git] / src / mondata.c
index f250089..2decb1e 100644 (file)
@@ -1,31 +1,45 @@
-/* NetHack 3.6 mondata.c       $NHDT-Date: 1446604115 2015/11/04 02:28:35 $  $NHDT-Branch: master $:$NHDT-Revision: 1.58 $ */
+/* NetHack 3.6 mondata.c       $NHDT-Date: 1550525093 2019/02/18 21:24:53 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.72 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/*-Copyright (c) Robert Patrick Rankin, 2011. */
 /* NetHack may be freely redistributed.  See license for details. */
 
 /* JNetHack Copyright */
 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019            */
 /* JNetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
-
-/*      These routines provide basic data for any type of monster. */
+/*
+ *      These routines provide basic data for any type of monster.
+ */
 
 /* set up an individual monster's base type (initial creation, shapechange) */
 void
-set_mon_data(mon, ptr, flag)
+set_mon_data(mon, ptr)
 struct monst *mon;
 struct permonst *ptr;
-int flag;
 {
-    mon->data = ptr;
-    if (flag == -1)
-        return; /* "don't care" */
+    int new_speed, old_speed = mon->data ? mon->data->mmove : 0;
 
-    if (flag == 1)
-        mon->mintrinsics |= (ptr->mresists & 0x00FF);
-    else
-        mon->mintrinsics = (ptr->mresists & 0x00FF);
+    mon->data = ptr;
+    mon->mnum = (short) monsndx(ptr);
+
+    if (mon->movement) { /* used to adjust poly'd hero as well as monsters */
+        new_speed = ptr->mmove;
+        /* prorate unused movement if new form is slower so that
+           it doesn't get extra moves leftover from previous form;
+           if new form is faster, leave unused movement as is */
+        if (new_speed < old_speed) {
+            /*
+             * Some static analysis warns that this might divide by 0
+               mon->movement = new_speed * mon->movement / old_speed;
+             * so add a redundant test to suppress that.
+             */
+            mon->movement *= new_speed;
+            if (old_speed > 0) /* old > new and new >= 0, so always True */
+                mon->movement /= old_speed;
+        }
+    }
     return;
 }
 
@@ -252,7 +266,7 @@ struct obj *obj; /* aatyp == AT_WEAP, AT_SPIT */
     if (check_visor) {
         o = (mdef == &youmonst) ? invent : mdef->minvent;
         for (; o; o = o->nobj)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             if ((o->owornmask & W_ARMH)
                 && (s = OBJ_DESCR(objects[o->otyp])) != (char *) 0
                 && !strcmp(s, "visored helmet"))
@@ -309,6 +323,14 @@ register struct permonst *ptr;
                       || (ptr->mlet == S_IMP && ptr != &mons[PM_TENGU]));
 }
 
+/* True if specific monster is especially affected by light-emitting weapons */
+boolean
+mon_hates_light(mon)
+struct monst *mon;
+{
+    return (boolean) (hates_light(mon->data));
+}
+
 /* True iff the type of monster pass through iron bars */
 boolean
 passes_bars(mptr)
@@ -323,7 +345,7 @@ struct permonst *mptr;
 /* returns True if monster can blow (whistle, etc) */
 boolean
 can_blow(mtmp)
-register struct monst *mtmp;
+struct monst *mtmp;
 {
     if ((is_silent(mtmp->data) || mtmp->data->msound == MS_BUZZ)
         && (breathless(mtmp->data) || verysmall(mtmp->data)
@@ -334,6 +356,18 @@ register struct monst *mtmp;
     return TRUE;
 }
 
+/* for casting spells and reading scrolls while blind */
+boolean
+can_chant(mtmp)
+struct monst *mtmp;
+{
+    if ((mtmp == &youmonst && Strangled)
+        || is_silent(mtmp->data) || !has_head(mtmp->data)
+        || mtmp->data->msound == MS_BUZZ || mtmp->data->msound == MS_BURBLE)
+        return FALSE;
+    return TRUE;
+}
+
 /* True if mon is vulnerable to strangulation */
 boolean
 can_be_strangled(mon)
@@ -716,8 +750,14 @@ const char *in_str;
             /* Outdated names */
             { "invisible stalker", PM_STALKER },
             { "high-elf", PM_ELVENKING }, /* PM_HIGH_ELF is obsolete */
+            /* other misspellings or incorrect words */
+            { "wood-elf", PM_WOODLAND_ELF },
+            { "wood elf", PM_WOODLAND_ELF },
+            { "woodland nymph", PM_WOOD_NYMPH },
             { "halfling", PM_HOBBIT },    /* potential guess for polyself */
-            /* Hyphenated names */
+            { "genie", PM_DJINNI }, /* potential guess for ^G/#wizgenesis */
+            /* Hyphenated names -- it would be nice to handle these via
+               fuzzymatch() but it isn't able to ignore trailing stuff */
             { "ki rin", PM_KI_RIN },
             { "uruk hai", PM_URUK_HAI },
             { "orc captain", PM_ORC_CAPTAIN },
@@ -737,6 +777,7 @@ const char *in_str;
             { "lurkers above", PM_LURKER_ABOVE },
             { "cavemen", PM_CAVEMAN },
             { "cavewomen", PM_CAVEWOMAN },
+            { "watchmen", PM_WATCHMAN },
             { "djinn", PM_DJINNI },
             { "mumakil", PM_MUMAK },
             { "erinyes", PM_ERINYS },
@@ -751,11 +792,12 @@ const char *in_str;
     }
 
     for (len = 0, i = LOW_PM; i < NUMMONS; i++) {
-        register int m_i_len = strlen(mons[i].mname);
+        register int m_i_len = (int) strlen(mons[i].mname);
 
         if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
             if (m_i_len == slen) {
-                return i; /* exact match */
+                mntmp = i;
+                break; /* exact match */
             } else if (slen > m_i_len
 #if 0 /*JP*/
                        && (str[m_i_len] == ' '
@@ -815,7 +857,7 @@ int *mndx_p;
         { 0, NON_PM }
     };
     const char *p, *x;
-    int i;
+    int i, len;
 
     if (mndx_p)
         *mndx_p = NON_PM; /* haven't [yet] matched a specific type */
@@ -837,6 +879,8 @@ int *mndx_p;
         return i;
     } else {
         /* multiple characters */
+        if (!strcmpi(in_str, "long")) /* not enough to match "long worm" */
+            return 0; /* avoid false whole-word match with "long worm tail" */
         in_str = makesingular(in_str);
         /* check for special cases */
         for (i = 0; falsematch[i]; i++)
@@ -852,21 +896,20 @@ int *mndx_p;
                 return mons[i].mlet;
             }
         /* check monster class descriptions */
+        len = (int) strlen(in_str);
         for (i = 1; i < MAXMCLASSES; i++) {
             x = def_monsyms[i].explain;
-            if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' '))
+            if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' ')
+                && ((int) strlen(p) >= len
+                    && (p[len] == '\0' || p[len] == ' ')))
                 return i;
         }
-        /* check individual species names; not as thorough as mon_to_name()
-           but our caller can call that directly if desired */
-        for (i = LOW_PM; i < NUMMONS; i++) {
-            x = mons[i].mname;
-            if ((p = strstri(x, in_str)) != 0
-                && (p == x || *(p - 1) == ' ')) {
-                if (mndx_p)
-                    *mndx_p = i;
-                return mons[i].mlet;
-            }
+        /* check individual species names */
+        i = name_to_mon(in_str);
+        if (i != NON_PM) {
+            if (mndx_p)
+                *mndx_p = i;
+            return mons[i].mlet;
         }
     }
     return 0;
@@ -885,10 +928,13 @@ register struct monst *mtmp;
 /* Like gender(), but lower animals and such are still "it".
    This is the one we want to use when printing messages. */
 int
-pronoun_gender(mtmp)
+pronoun_gender(mtmp, override_vis)
 register struct monst *mtmp;
+boolean override_vis; /* if True then 'no it' unless neuter */
 {
-    if (is_neuter(mtmp->data) || !canspotmon(mtmp))
+    if (!override_vis && !canspotmon(mtmp))
+        return 2;
+    if (is_neuter(mtmp->data))
         return 2;
     return (humanoid(mtmp->data) || (mtmp->data->geno & G_UNIQ)
             || type_is_pname(mtmp->data)) ? (int) mtmp->female : 2;
@@ -1015,6 +1061,32 @@ int montype;
     return montype;
 }
 
+/* determine whether two permonst indices are part of the same progression;
+   existence of progressions with more than one step makes it a bit tricky */
+boolean
+big_little_match(montyp1, montyp2)
+int montyp1, montyp2;
+{
+    int l, b;
+
+    /* simplest case: both are same pm */
+    if (montyp1 == montyp2)
+        return TRUE;
+    /* assume it isn't possible to grow from one class letter to another */
+    if (mons[montyp1].mlet != mons[montyp2].mlet)
+        return FALSE;
+    /* check whether montyp1 can grow up into montyp2 */
+    for (l = montyp1; (b = little_to_big(l)) != l; l = b)
+        if (b == montyp2)
+            return TRUE;
+    /* check whether montyp2 can grow up into montyp1 */
+    for (l = montyp2; (b = little_to_big(l)) != l; l = b)
+        if (b == montyp1)
+            return TRUE;
+    /* neither grows up to become the other; no match */
+    return FALSE;
+}
+
 /*
  * Return the permonst ptr for the race of the monster.
  * Returns correct pointer for non-polymorphed and polymorphed
@@ -1037,7 +1109,7 @@ static const char *levitate[4] = { "
 /*JP
 static const char *flys[4] = { "fly", "Fly", "flutter", "Flutter" };
 */
-static const char *flys[4] = { "\94ò\82Ô", "\94ò\82Ô", "\82Í\82½\82ß\82­", "\82Í\82½\82ß\82­" };
+static const char *flys[4] = { "\94ò\82Ô", "\94ò\82Ô", "\82¨\82Ì\82Ì\82­", "\82¨\82Ì\82Ì\82­" };
 /*JP
 static const char *flyl[4] = { "fly", "Fly", "stagger", "Stagger" };
 */
@@ -1049,11 +1121,11 @@ static const char *slither[4] = { "
 /*JP
 static const char *ooze[4] = { "ooze", "Ooze", "tremble", "Tremble" };
 */
-static const char *ooze[4] = { "\82É\82\82Ý\8fo\82é", "\82É\82\82Ý\8fo\82é", "\90k\82¦\82é", "\90k\82¦\82é" };
+static const char *ooze[4] = { "\82É\82\82Ý\8fo\82é", "\82É\82\82Ý\8fo\82é", "\90g\90k\82¢\82·\82é", "\90g\90k\82¢\82·\82é" };
 /*JP
 static const char *immobile[4] = { "wiggle", "Wiggle", "pulsate", "Pulsate" };
 */
-static const char *immobile[4] = { "\90k\82¦\82é", "\90k\82¦\82é", "\90k\82¦\82é", "\90k\82¦\82é" };
+static const char *immobile[4] = { "\93®\82­", "\93®\82­", "\90k\82¦\82é", "\90k\82¦\82é" };
 /*JP
 static const char *crawl[4] = { "crawl", "Crawl", "falter", "Falter" };
 */
@@ -1076,6 +1148,12 @@ const char *def;
                         : def);
 }
 
+/*JP:
+ * \81u\82æ\82ë\82ß\82­\81v\82ð\89ö\95¨\82Ì\8eí\97Þ\82É\82æ\82Á\82Ä\95Ï\82¦\82é\81B
+ * \8e©\95ª\82É\91Î\82µ\82Ä\8eg\82¤\8fê\8d\87\82É\82Í\8aù\82É\81u\82­\82ç\82­\82ç\82·\82é\81v\82ª\8eg\82í\82ê\82Ä\82¢\82é\82Ì\82Å\81A
+ * \95Ï\89»\82µ\82Ä\82¢\82Ä\82à\82»\82Ì\82Ü\82Ü\82É\82·\82é\81B
+ * \91\8a\8eè\82É\91Î\82µ\82Ä\8eg\82¤\8fê\8d\87\82Í\81u\82­\82ç\82­\82ç\82·\82é\81v\82Í\95s\8e©\91R\82È\82Ì\82Å\82±\82ê\82ð\8eg\82¤\81B
+ */
 const char *
 stagger(ptr, def)
 const struct permonst *ptr;