Merge branch 'NetHack-3.6.2-beta01' into NetHack-3.6.2
This commit is contained in:
@@ -271,6 +271,8 @@ clairvoyance revealing underwater or under-lava objects left object displayed
|
||||
make it easier to clear 'pickup_types' (menustyles Traditional and Combination
|
||||
could do so by setting it to 'a'; now ' ' works too; Full and Partial
|
||||
allowed unselecting every object class; now 'all classes' is a choice)
|
||||
distribution of monsters selected by mkclass() didn't match expected distrib
|
||||
(cited example was ndemon() creating twice as many incubi as succubi)
|
||||
|
||||
|
||||
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1544669659 2018/12/13 02:54:19 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.667 $ */
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1544998887 2018/12/16 22:21:27 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.671 $ */
|
||||
/* Copyright (c) Steve Creps, 1988. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1152,6 +1152,7 @@ E boolean FDECL(create_critters, (int, struct permonst *, BOOLEAN_P));
|
||||
E struct permonst *NDECL(rndmonst);
|
||||
E void FDECL(reset_rndmonst, (int));
|
||||
E struct permonst *FDECL(mkclass, (CHAR_P, int));
|
||||
E struct permonst *FDECL(mkclass_aligned, (CHAR_P, int, ALIGNTYP_P));
|
||||
E int FDECL(mkclass_poly, (int));
|
||||
E int FDECL(adj_lev, (struct permonst *));
|
||||
E struct permonst *FDECL(grow_up, (struct monst *, struct monst *));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1542798623 2018/11/21 11:10:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.128 $ */
|
||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1544998885 2018/12/16 22:21:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.131 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1635,59 +1635,89 @@ int mndx, mvflagsmask, genomask;
|
||||
}
|
||||
|
||||
/* Make one of the multiple types of a given monster class.
|
||||
* The second parameter specifies a special casing bit mask
|
||||
* to allow the normal genesis masks to be deactivated.
|
||||
* Returns Null if no monsters in that class can be made.
|
||||
*/
|
||||
The second parameter specifies a special casing bit mask
|
||||
to allow the normal genesis masks to be deactivated.
|
||||
Returns Null if no monsters in that class can be made. */
|
||||
struct permonst *
|
||||
mkclass(class, spc)
|
||||
char class;
|
||||
int spc;
|
||||
{
|
||||
return mkclass_aligned(class, spc, A_NONE);
|
||||
}
|
||||
|
||||
/* mkclass() with alignment restrictions; used by ndemon() */
|
||||
struct permonst *
|
||||
mkclass_aligned(class, spc, atyp)
|
||||
char class;
|
||||
int spc;
|
||||
aligntyp atyp;
|
||||
{
|
||||
register int first, last, num = 0;
|
||||
int k, nums[SPECIAL_PM + 1]; /* +1: insurance for final return value */
|
||||
int maxmlev, mask = (G_NOGEN | G_UNIQ) & ~spc;
|
||||
|
||||
(void) memset((genericptr_t) nums, 0, sizeof nums);
|
||||
maxmlev = level_difficulty() >> 1;
|
||||
if (class < 1 || class >= MAXMCLASSES) {
|
||||
impossible("mkclass called with bad class!");
|
||||
return (struct permonst *) 0;
|
||||
}
|
||||
/* Assumption #1: monsters of a given class are contiguous in the
|
||||
* mons[] array.
|
||||
* mons[] array. Player monsters and quest denizens
|
||||
* are an exception; mkclass() won't pick them.
|
||||
* SPECIAL_PM is long worm tail and separates the
|
||||
* regular monsters from the exceptions.
|
||||
*/
|
||||
for (first = LOW_PM; first < SPECIAL_PM; first++)
|
||||
if (mons[first].mlet == class)
|
||||
break;
|
||||
if (first == SPECIAL_PM)
|
||||
return (struct permonst *) 0;
|
||||
|
||||
for (last = first; last < SPECIAL_PM && mons[last].mlet == class; last++)
|
||||
if (mk_gen_ok(last, G_GONE, mask)) {
|
||||
/* consider it */
|
||||
if (num && toostrong(last, maxmlev)
|
||||
&& mons[last].difficulty != mons[last - 1].difficulty && rn2(2))
|
||||
break;
|
||||
num += mons[last].geno & G_FREQ;
|
||||
}
|
||||
if (!num)
|
||||
if (first == SPECIAL_PM) {
|
||||
impossible("mkclass found no class %d monsters", class);
|
||||
return (struct permonst *) 0;
|
||||
}
|
||||
|
||||
/* Assumption #2: monsters of a given class are presented in ascending
|
||||
* order of strength.
|
||||
*/
|
||||
for (num = rnd(num); num > 0; first++)
|
||||
if (mk_gen_ok(first, G_GONE, mask)) {
|
||||
/* skew towards lower value monsters at lower exp. levels */
|
||||
num -= mons[first].geno & G_FREQ;
|
||||
if (num && adj_lev(&mons[first]) > (u.ulevel * 2)) {
|
||||
/* but not when multiple monsters are same level */
|
||||
if (mons[first].mlevel != mons[first + 1].mlevel)
|
||||
num--;
|
||||
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)) {
|
||||
/* 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
|
||||
'num' implies last > first so mons[last-1] is safe);
|
||||
sometimes accept it even if high difficulty */
|
||||
if (num && toostrong(last, maxmlev)
|
||||
&& mons[last].difficulty > mons[last - 1].difficulty
|
||||
&& rn2(2))
|
||||
break;
|
||||
if ((k = (mons[last].geno & G_FREQ)) > 0) {
|
||||
/* skew towards lower value monsters at lower exp. levels
|
||||
(this used to be done in the next loop, but that didn't
|
||||
work well when multiple species had the same level and
|
||||
were followed by one that was past the bias threshold;
|
||||
cited example was sucubus and incubus, where the bias
|
||||
against picking the next demon resulted in incubus
|
||||
being picked nearly twice as often as sucubus);
|
||||
we need the '+1' in case the entire set is too high
|
||||
level (really low level hero) */
|
||||
nums[last] = k + 1 - (adj_lev(&mons[last]) > (u.ulevel * 2));
|
||||
num += nums[last];
|
||||
}
|
||||
}
|
||||
first--; /* correct an off-by-one error */
|
||||
}
|
||||
if (!num)
|
||||
return (struct permonst *) 0;
|
||||
|
||||
return &mons[first];
|
||||
/* the hard work has already been done; 'num' should hit 0 before
|
||||
first reaches last (which is actually one past our last candidate) */
|
||||
for (num = rnd(num); first < last; first++)
|
||||
if ((num -= nums[first]) <= 0)
|
||||
break;
|
||||
|
||||
return nums[first] ? &mons[first] : (struct permonst *) 0;
|
||||
}
|
||||
|
||||
/* like mkclass(), but excludes difficulty considerations; used when
|
||||
|
||||
49
src/minion.c
49
src/minion.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 minion.c $NHDT-Date: 1432512773 2015/05/25 00:12:53 $ $NHDT-Branch: master $:$NHDT-Revision: 1.33 $ */
|
||||
/* NetHack 3.6 minion.c $NHDT-Date: 1544998886 2018/12/16 22:21:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.40 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2008. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -256,7 +256,7 @@ register struct monst *mtmp;
|
||||
flags.female ? "Sister" : "Brother");
|
||||
if (!tele_restrict(mtmp))
|
||||
(void) rloc(mtmp, TRUE);
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
cash = money_cnt(invent);
|
||||
demand =
|
||||
@@ -292,7 +292,7 @@ register struct monst *mtmp;
|
||||
}
|
||||
}
|
||||
mongone(mtmp);
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
long
|
||||
@@ -323,7 +323,7 @@ struct monst *mtmp;
|
||||
}
|
||||
(void) money2mon(mtmp, offer);
|
||||
context.botl = 1;
|
||||
return (offer);
|
||||
return offer;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -336,9 +336,9 @@ aligntyp atyp;
|
||||
pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS);
|
||||
if (!(mvitals[pm].mvflags & G_GONE)
|
||||
&& (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
|
||||
return (pm);
|
||||
return pm;
|
||||
}
|
||||
return (dlord(atyp)); /* approximate */
|
||||
return dlord(atyp); /* approximate */
|
||||
}
|
||||
|
||||
int
|
||||
@@ -351,9 +351,9 @@ aligntyp atyp;
|
||||
pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX);
|
||||
if (!(mvitals[pm].mvflags & G_GONE)
|
||||
&& (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
|
||||
return (pm);
|
||||
return pm;
|
||||
}
|
||||
return (ndemon(atyp)); /* approximate */
|
||||
return ndemon(atyp); /* approximate */
|
||||
}
|
||||
|
||||
/* create lawful (good) lord */
|
||||
@@ -361,9 +361,9 @@ int
|
||||
llord()
|
||||
{
|
||||
if (!(mvitals[PM_ARCHON].mvflags & G_GONE))
|
||||
return (PM_ARCHON);
|
||||
return PM_ARCHON;
|
||||
|
||||
return (lminion()); /* approximate */
|
||||
return lminion(); /* approximate */
|
||||
}
|
||||
|
||||
int
|
||||
@@ -375,7 +375,7 @@ lminion()
|
||||
for (tryct = 0; tryct < 20; tryct++) {
|
||||
ptr = mkclass(S_ANGEL, 0);
|
||||
if (ptr && !is_lord(ptr))
|
||||
return (monsndx(ptr));
|
||||
return monsndx(ptr);
|
||||
}
|
||||
|
||||
return NON_PM;
|
||||
@@ -383,19 +383,26 @@ lminion()
|
||||
|
||||
int
|
||||
ndemon(atyp)
|
||||
aligntyp atyp;
|
||||
aligntyp atyp; /* A_NONE is used for 'any alignment' */
|
||||
{
|
||||
int tryct;
|
||||
struct permonst *ptr;
|
||||
|
||||
for (tryct = 0; tryct < 20; tryct++) {
|
||||
ptr = mkclass(S_DEMON, 0);
|
||||
if (ptr && is_ndemon(ptr)
|
||||
&& (atyp == A_NONE || sgn(ptr->maligntyp) == sgn(atyp)))
|
||||
return (monsndx(ptr));
|
||||
}
|
||||
|
||||
return NON_PM;
|
||||
/*
|
||||
* 3.6.2: [fix #H2204, 22-Dec-2010, eight years later...]
|
||||
* pick a correctly aligned demon in one try. This used to
|
||||
* use mkclass() to choose a random demon type and keep trying
|
||||
* (up to 20 times) until it got one with the desired alignment.
|
||||
* mkclass_aligned() skips wrongly aligned potential candidates.
|
||||
* [The only neutral demons are djinni and mail daemon and
|
||||
* mkclass() won't pick them, but call it anyway in case either
|
||||
* aspect of that changes someday.]
|
||||
*/
|
||||
#if 0
|
||||
if (atyp == A_NEUTRAL)
|
||||
return NON_PM;
|
||||
#endif
|
||||
ptr = mkclass_aligned(S_DEMON, 0, atyp);
|
||||
return (ptr && is_ndemon(ptr)) ? monsndx(ptr) : NON_PM;
|
||||
}
|
||||
|
||||
/* guardian angel has been affected by conflict so is abandoning hero */
|
||||
|
||||
Reference in New Issue
Block a user