extern void decide_to_shapeshift(struct monst *, int);
extern boolean vamp_stone(struct monst *);
extern void check_gear_next_turn(struct monst *);
+#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) || defined(DEBUG)
+extern int mstrength(struct permonst *ptr);
+#endif
/* ### mondata.c ### */
#endif
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) || defined(DEBUG)
static int wiz_display_macros(void);
+static int wiz_check_mdifficulty(void);
#endif
#ifdef DUMB /* stuff commented out in extern.h, but needed here */
{ C('e'), "wizdetect", "reveal hidden things within a small radius",
wiz_detect, IFBURIED | WIZMODECMD, NULL },
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) || defined(DEBUG)
+ { '\0', "wizcheckmdifficulty", "validate the difficulty levels of monsters",
+ wiz_check_mdifficulty, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL },
{ '\0', "wizdispmacros", "validate the display macro ranges",
wiz_display_macros, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL },
#endif
}
#endif /* (NH_DEVEL_STATUS != NH_STATUS_RELEASED) || defined(DEBUG) */
+#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) || defined(DEBUG)
+/* the #wizcheckmdifficulty command */
+static int
+wiz_check_mdifficulty(void)
+{
+ char buf[BUFSZ];
+ winid win;
+ int mhardcoded = 0, mcalculated = 0, trouble = 0, cnt = 0, mdiff = 0;
+ struct permonst *ptr;
+ static const char *const display_issues = "Review of monster difficulties:";
+
+ win = create_nhwindow(NHW_TEXT);
+ for (ptr = &mons[0]; ptr->mlet; ptr++, cnt++) {
+ mcalculated = mstrength(ptr);
+ mhardcoded = (int) ptr->difficulty;
+ mdiff = mhardcoded - mcalculated;
+ if (mdiff) {
+ trouble++;
+ Snprintf(buf, sizeof buf,
+ "%-18s [%4d]: calculated: %2d, hardcoded: %2d (%+d)",
+ ptr->pmnames[NEUTRAL], cnt, mcalculated, mhardcoded,
+ mdiff);
+ putstr(win, 0, buf);
+ }
+ }
+ if (!trouble)
+ putstr(win, 0, "No monster difficulty discrepencies were detected");
+ display_nhwindow(win, FALSE);
+ destroy_nhwindow(win);
+ return ECMD_OK;
+}
+#endif /* (NH_DEVEL_STATUS != NH_STATUS_RELEASED) || defined(DEBUG) */
+
RESTORE_WARNING_FORMAT_NONLITERAL
static void
static void kill_eggs(struct obj *);
static void pacify_guard(struct monst *);
+#ifdef DEBUG
+int mstrength(struct permonst *ptr);
+#endif
+
#define LEVEL_SPECIFIC_NOCORPSE(mdat) \
(Is_rogue_level(&u.uz) \
|| (g.level.flags.graveyard && is_undead(mdat) && rn2(3)))
mon->misc_worn_check |= I_SPECIAL;
}
+#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) || defined(DEBUG)
+/* 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.
+ */
+int
+mstrength(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->pmnames[NEUTRAL], "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->pmnames[NEUTRAL], "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);
+}
+#endif /* (NH_DEVEL_STATUS != NH_STATUS_RELEASED) || DEBUG */
/*mon.c*/