-/* 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. */
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");
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");