fix pull request #365 - monster max HP

The recently added sanity check for monster maximum HP was giving
false complaints when Nd8 monster had N mhpmax.  Most noticeable
for level 1 monsters (level 0 monsters use 1d4 instead of 0d8 and
weren't affected) but possible for higher level ones if they were
unlucky--from their own perspective--with all their d8 rolls.

Give level N monsters a minimum of N+1 HP, so minimum of 2 for
level 1 monsters, making 1/8 of those stronger.  Same minimum for
level 0 monsters, 25% of which will become stronger now.  (The pull
request's patch gave every Nd8 monster 1 extra HP; this only does
so for Nd8 and 1d4 ones which have rolled lowest possible amount.)

Also relax the sanity check so that existing to-be-3.7 save files
don't continue to trigger sanity complaints for existing monsters
that have the old minimum.

Fixes 365
This commit is contained in:
PatR
2020-07-14 17:03:51 -07:00
parent ee7fbc4a61
commit abe4db6e60
3 changed files with 26 additions and 12 deletions
+3 -1
View File
@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.248 $ $NHDT-Date: 1594730609 2020/07/14 12:43:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.249 $ $NHDT-Date: 1594771373 2020/07/15 00:02:53 $
General Fixes and Modified Features General Fixes and Modified Features
----------------------------------- -----------------------------------
@@ -287,6 +287,8 @@ only generate shop items on solid floor squares
avoid gcc 10 warning by removing duplicate definition of 'head_engr' avoid gcc 10 warning by removing duplicate definition of 'head_engr'
if a monster removed a corpse from an ice box, the corpse would never rot away if a monster removed a corpse from an ice box, the corpse would never rot away
monster creation on quest levels could make genocided creatures monster creation on quest levels could make genocided creatures
enabling wizard mode 'sanity_check' option would complain about invalid mhpmax
value for level N monsters created with a d8 value of 1 for all N d8's
tty: redraw unexplored locations as S_unexplored rather than <space> after tty: redraw unexplored locations as S_unexplored rather than <space> after
map has been partially overwritten by popup menu or text display map has been partially overwritten by popup menu or text display
+21 -9
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 makemon.c $NHDT-Date: 1591178397 2020/06/03 09:59:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.173 $ */ /* NetHack 3.6 makemon.c $NHDT-Date: 1594771378 2020/07/15 00:02:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.174 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -997,13 +997,16 @@ struct monst *mon;
int mndx; int mndx;
{ {
struct permonst *ptr = &mons[mndx]; struct permonst *ptr = &mons[mndx];
int basehp = 0;
mon->m_lev = adj_lev(ptr); mon->m_lev = adj_lev(ptr);
if (is_golem(ptr)) { if (is_golem(ptr)) {
/* golems have a fixed amount of HP, varying by golem type */
mon->mhpmax = mon->mhp = golemhp(mndx); mon->mhpmax = mon->mhp = golemhp(mndx);
} else if (is_rider(ptr)) { } else if (is_rider(ptr)) {
/* we want low HP, but a high mlevel so they can attack well */ /* we want low HP, but a high mlevel so they can attack well */
mon->mhpmax = mon->mhp = d(10, 8); basehp = 10; /* minimum is 1 per false (weaker) level */
mon->mhpmax = mon->mhp = d(basehp, 8);
} else if (ptr->mlevel > 49) { } else if (ptr->mlevel > 49) {
/* "special" fixed hp monster /* "special" fixed hp monster
* the hit points are encoded in the mlevel in a somewhat strange * the hit points are encoded in the mlevel in a somewhat strange
@@ -1012,17 +1015,26 @@ int mndx;
mon->mhpmax = mon->mhp = 2 * (ptr->mlevel - 6); mon->mhpmax = mon->mhp = 2 * (ptr->mlevel - 6);
mon->m_lev = mon->mhp / 4; /* approximation */ mon->m_lev = mon->mhp / 4; /* approximation */
} else if (ptr->mlet == S_DRAGON && mndx >= PM_GRAY_DRAGON) { } else if (ptr->mlet == S_DRAGON && mndx >= PM_GRAY_DRAGON) {
/* adult dragons */ /* adult dragons; N*(4+rnd(4)) before endgame, N*8 once there */
mon->mhpmax = mon->mhp = basehp = (int) mon->m_lev; /* not really applicable; isolates cast */
(int) (In_endgame(&u.uz) mon->mhpmax = mon->mhp = In_endgame(&u.uz) ? (8 * basehp)
? (8 * mon->m_lev) : (4 * basehp + d(basehp, 4));
: (4 * mon->m_lev + d((int) mon->m_lev, 4)));
} else if (!mon->m_lev) { } else if (!mon->m_lev) {
basehp = 1; /* minimum is 1, increased to 2 below */
mon->mhpmax = mon->mhp = rnd(4); mon->mhpmax = mon->mhp = rnd(4);
} else { } else {
mon->mhpmax = mon->mhp = d((int) mon->m_lev, 8); basehp = (int) mon->m_lev; /* minimum possible is one per level */
mon->mhpmax = mon->mhp = d(basehp, 8);
if (is_home_elemental(ptr)) if (is_home_elemental(ptr))
mon->mhpmax = (mon->mhp *= 3); mon->mhpmax = (mon->mhp *= 3); /* leave 'basehp' as-is */
}
/* if d(X,8) rolled a 1 all X times, give a boost;
most beneficial for level 0 and level 1 monsters, making mhpmax
and starting mhp always be at least 2 */
if (mon->mhpmax == basehp) {
mon->mhpmax += 1;
mon->mhp = mon->mhpmax;
} }
} }
+2 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 mon.c $NHDT-Date: 1594727746 2020/07/14 11:55:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.340 $ */ /* NetHack 3.6 mon.c $NHDT-Date: 1594771374 2020/07/15 00:02:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */ /*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -59,7 +59,7 @@ const char *msg;
/* check before DEADMONSTER() because dead monsters should still /* check before DEADMONSTER() because dead monsters should still
have sane mhpmax */ have sane mhpmax */
if (mtmp->mhpmax < 1 if (mtmp->mhpmax < 1
|| mtmp->mhpmax < (int) mtmp->m_lev + 1 || mtmp->mhpmax < (int) mtmp->m_lev
|| mtmp->mhp > mtmp->mhpmax) || mtmp->mhp > mtmp->mhpmax)
impossible( impossible(
"%s: level %d monster #%u [%s] has %d cur HP, %d max HP", "%s: level %d monster #%u [%s] has %d cur HP, %d max HP",