]> granicus.if.org Git - nethack/commitdiff
resurrect 'makedefs -m'
authorPatR <rankin@nethack.org>
Tue, 21 Apr 2020 21:04:03 +0000 (14:04 -0700)
committerPatR <rankin@nethack.org>
Tue, 21 Apr 2020 21:04:03 +0000 (14:04 -0700)
Have 'makedefs -m' output default mons[].difficulty values in the
stub 'monstr.c' that still gets generated for that option.  It
would be better to allow specifying which monsters are of interest
but I didn't want to get bogged down by interface issues.

I needed it for mons[PM_ELF].difficulty after changing that monster's
level, so it still has a purpose.  Code is from 3.4.3, reformatted
manually.

doc/fixes37.0
util/makedefs.c

index 72cbdaab93722f4f62e2d03c4089c3534077a986..cb409af8d0dc989507dd8399d549e0cefd238e6e 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.188 $ $NHDT-Date: 1587248920 2020/04/18 22:28:40 $
+$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.195 $ $NHDT-Date: 1587503040 2020/04/21 21:04:00 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -363,3 +363,6 @@ options overhaul: moved the option definitions into include/optlist.h;
        for retrieving the option value, and for processing the option
        following its selection in the 'O' menu, added doc/options.doc file.
 function reglyph_darkroom() relocated from options.c to display.c
+resurrect 'makedefs -m' to be able to derive default mons[].diffculty values
+       suitable for assigning to new or changed monsters
+
index ea75c62a000391f26bb2d2a868dd7ae06aec1135..0af3d901f927df5d1aaf970af48b9a0428c4c46c 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6  makedefs.c  $NHDT-Date: 1582403492 2020/02/22 20:31:32 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.177 $ */
+/* NetHack 3.6  makedefs.c  $NHDT-Date: 1587503038 2020/04/21 21:03:58 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.180 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */
 /* Copyright (c) M. Stephenson, 1990, 1991.                       */
@@ -1771,9 +1771,107 @@ do_dungeon()
     return;
 }
 
+/*
+ * In 3.4.3 and earlier, this code was used to construct monstr[] array
+ * in generated file src/monstr.c.  It wasn't used in 3.6.  For 3.7 it
+ * has been reincarnated as a way to generate default monster strength
+ * values:
+ *      add new monster(s) to src/monst.c with placeholder value for
+ *          the monstr field;
+ *      run 'makedefs -m' to create src/monstr.c; ignore the complaints
+ *          about it being deprecated;
+ *      transfer relevant generated monstr values to src/monst.c;
+ *      delete src/monstr.c.
+ */
+static int FDECL(mstrength, (struct permonst *));
+static boolean FDECL(ranged_attk, (struct permonst *));
+
+ /*
+ * This routine is designed to return an integer value which represents
+ * an approximation of monster strength.  It uses a similar method of
+ * determination as "experience()" to arrive at the strength.
+ */
+static int
+mstrength(ptr)
+struct permonst *ptr;
+{
+    int        i, tmp2, n, tmp = ptr->mlevel;
+
+    if (tmp > 49)              /* special fixed hp monster */
+        tmp = 2 * (tmp - 6) / 4;
+
+    /* For creation in groups */
+    n = (!!(ptr->geno & G_SGROUP));
+    n += (!!(ptr->geno & G_LGROUP)) << 1;
+
+    /* For ranged attacks */
+    if (ranged_attk(ptr))
+        n++;
+
+    /* For higher ac values */
+    n += (ptr->ac < 4);
+    n += (ptr->ac < 0);
+
+    /* For very fast monsters */
+    n += (ptr->mmove >= 18);
+
+    /* For each attack and "special" attack */
+    for (i = 0; i < NATTK; i++) {
+        tmp2 = ptr->mattk[i].aatyp;
+        n += (tmp2 > 0);
+        n += (tmp2 == AT_MAGC);
+        n += (tmp2 == AT_WEAP && (ptr->mflags2 & M2_STRONG));
+    }
+
+    /* For each "special" damage type */
+    for (i = 0; i < NATTK; i++) {
+        tmp2 = ptr->mattk[i].adtyp;
+        if ((tmp2 == AD_DRLI) || (tmp2 == AD_STON) || (tmp2 == AD_DRST)
+            || (tmp2 == AD_DRDX) || (tmp2 == AD_DRCO) || (tmp2 == AD_WERE))
+            n += 2;
+        else if (strcmp(ptr->mname, "grid bug"))
+            n += (tmp2 != AD_PHYS);
+        n += ((int) (ptr->mattk[i].damd * ptr->mattk[i].damn) > 23);
+    }
+
+    /* Leprechauns are special cases.  They have many hit dice so they
+       can hit and are hard to kill, but they don't really do much damage. */
+    if (!strcmp(ptr->mname, "leprechaun"))
+        n -= 2;
+
+    /* Finally, adjust the monster level  0 <= n <= 24 (approx.) */
+    if (n == 0)
+        tmp--;
+    else if (n >= 6)
+        tmp += (n / 2);
+    else
+        tmp += (n / 3 + 1);
+
+    return (tmp >= 0) ? tmp : 0;
+}
+
+/* returns True if monster can attack at range */
+static boolean
+ranged_attk(ptr)
+register struct permonst *ptr;
+{
+    register int i, j;
+    register int atk_mask = (1 << AT_BREA) | (1 << AT_SPIT) | (1 << AT_GAZE);
+
+    for (i = 0; i < NATTK; i++) {
+        if ((j = ptr->mattk[i].aatyp) >= AT_WEAP
+            || (j < 32 && (atk_mask & (1 << j)) != 0))
+            return TRUE;
+    }
+    return FALSE;
+}
+
 void
 do_monstr()
 {
+    struct permonst *ptr;
+    int i, j;
+
     /* Don't break anything for ports that haven't been updated. */
     printf("DEPRECATION WARNINGS:\n");
     printf("'makedefs -m' is deprecated.  Remove all references\n");
@@ -1808,9 +1906,18 @@ do_monstr()
     Fprintf(ofp, "  it from the build process.\n");
     Fprintf(ofp, "monstr[] is deprecated.  Replace monstr[x] with\n");
     Fprintf(ofp, "  mons[x].difficulty\n");
-    Fprintf(ofp, "monstr_init() is deprecated.  Remove all references to it.\n");
+    Fprintf(ofp,
+            "monstr_init() is deprecated.  Remove all references to it.\n");
     Fprintf(ofp, "*/\n");
 
+    /* output derived monstr values as a comment */
+    Fprintf(ofp, "\n\n/*\n * default mons[].difficulty values\n *\n");
+    for (ptr = &mons[0], j = 0; ptr->mlet; ptr++) {
+        i = mstrength(ptr);
+        Fprintf(ofp, "%-24s %2u\n", ptr->mname, (unsigned int) (uchar) i);
+    }
+    Fprintf(ofp, " *\n */\n\n");
+
     Fprintf(ofp, "\nvoid NDECL(monstr_init);\n");
     Fprintf(ofp, "\nvoid\n");
     Fprintf(ofp, "monstr_init()\n");