fix github issue #349 - out of depth liches

Change mkclass() to always honor the hell-only monster generation
flag for L class, preventing master and arch-liches outside Gehennom.
For other classes, honor hell-only and outside-hell-only most (89%)
of the time.  When not honored (11%), it allows demons and devils to
appear outside of Gehennom as they have in the past.  [That part
might need to be re-done since it is done for all monsters in the
class on any mkclass() call instead of being done on a class-member
by class-member basis within each such call.]

This prevents out of depth liches in the Castle and ought to do same
for themed rooms of type 'Mausoleum' although I haven't figured out
how to test that.

Fixes #349
This commit is contained in:
PatR
2020-05-27 14:05:42 -07:00
parent c63165e5dc
commit c29ffe1d82
2 changed files with 25 additions and 7 deletions

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.223 $ $NHDT-Date: 1589827569 2020/05/18 18:46:09 $
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.225 $ $NHDT-Date: 1590613502 2020/05/27 21:05:02 $
General Fixes and Modified Features
-----------------------------------
@@ -187,6 +187,9 @@ hold_another_object used hardcoded Stressed to limit carrying instead of
using the 'pickup_burden' option for that
when hold_another_object fails while hero is swallowed, drop the item into
swallower's inventory instead of onto the floor
change mkclass() to usually honor (always honor for L class) the hell-only and
never-in-hell monster creation flags; no more achi-lich in the Castle
(nor master lich there unless demilich gets a potion of gain level)
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 makemon.c $NHDT-Date: 1587024537 2020/04/16 08:08:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.168 $ */
/* NetHack 3.6 makemon.c $NHDT-Date: 1590613502 2020/05/27 21:05:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.170 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1663,8 +1663,7 @@ aligntyp atyp;
{
register int first, last, num = 0;
int k, nums[SPECIAL_PM + 1]; /* +1: insurance for final return value */
int ignore = (spc & G_IGNORE);
int maxmlev, mask = (G_NOGEN | G_UNIQ) & ~spc;
int maxmlev, gmask;
(void) memset((genericptr_t) nums, 0, sizeof nums);
maxmlev = level_difficulty() >> 1;
@@ -1686,13 +1685,24 @@ aligntyp atyp;
return (struct permonst *) 0;
}
gmask = (G_NOGEN | G_UNIQ);
/* traditionally mkclass() ignored hell-only and never-in-hell;
now we usually honor those but not all the time, mostly so that
the majority of major demons aren't constrained to Gehennom;
arch- and master liches are always so constrained (for creation;
lesser liches might grow up into them elsewhere) */
if (rn2(9) || class == S_LICH)
gmask |= (Inhell ? G_NOHELL : G_HELL);
gmask &= ~spc;
gmask |= (spc & G_IGNORE);
/* Assumption #2: monsters of a given class are presented in ascending
* order of strength.
*/
for (last = first; last < SPECIAL_PM && mons[last].mlet == class; last++) {
if (atyp != A_NONE && sgn(mons[last].maligntyp) != sgn(atyp))
continue;
if (mk_gen_ok(last, G_GONE, mask|ignore)) {
if (mk_gen_ok(last, G_GONE, gmask)) {
/* consider it; don't reject a toostrong() monster if we
don't have anything yet (num==0) or if it is the same
(or lower) difficulty as preceding candidate (non-zero
@@ -1738,6 +1748,7 @@ mkclass_poly(class)
int class;
{
register int first, last, num = 0;
int gmask;
for (first = LOW_PM; first < SPECIAL_PM; first++)
if (mons[first].mlet == class)
@@ -1745,14 +1756,18 @@ int class;
if (first == SPECIAL_PM)
return NON_PM;
gmask = (G_NOGEN | G_UNIQ);
if (rn2(9) || class == S_LICH)
gmask |= (Inhell ? G_NOHELL : G_HELL);
for (last = first; last < SPECIAL_PM && mons[last].mlet == class; last++)
if (mk_gen_ok(last, G_GENOD, (G_NOGEN | G_UNIQ)))
if (mk_gen_ok(last, G_GENOD, gmask))
num += mons[last].geno & G_FREQ;
if (!num)
return NON_PM;
for (num = rnd(num); num > 0; first++)
if (mk_gen_ok(first, G_GENOD, (G_NOGEN | G_UNIQ)))
if (mk_gen_ok(first, G_GENOD, gmask))
num -= mons[first].geno & G_FREQ;
first--; /* correct an off-by-one error */