fix #K669 - 'nasty' monster summoning
Report complained about multiple Archons causing his character to be swarmed by monsters on the Plane of Fire. I don't think that the behavior has changed significantly from how it worked in 3.4.3. Nobody can summon an Archon directly because they're excluded from the nasties[] list. But whenever summoning picks a genocided 'nasty', the result gets replaced by random monster of appropriate difficulty for the level (which could be an Archon for a high level character in the endgame). [Note that that won't pick an Archon in Gehennom or at arch-lich outside of there because the random monster creation honors the only-in-hell and never-in-hell flags; picking from the nasties[] list doesn't.] This prevents that for any creature (except arch-lich or the Wizard) casting the summon nasties spell. If a replacement creature is a spellcaster it now has to have lower difficulty than the summoner. If not, it will be discarded even though its difficulty is classified as appropriate. So to summon an Archon, the summoner has to have higher difficulty than an Archon; arch-lich and the Wizard are the only ones meeting that criterium. When summoner is an arch-lich, it can't summon another arch-lich (since that wouldn't have lower difficulty than the summoner) and can summon (via replacement for genocided type, and only if outside of Gehennom) at most one Archon. When summoner is the Wizard, he could summon an arch-lich (when in Gehennom; demoted to master lich elsewhere--see below) or an Archon (outside Gehennom only), but at most one per summoning. For post-Wizard harassment, which effectively has infinite difficulty level, it could still happen. However, each instance of harassment is only allowed to create at most one Archon or arch-lich now, so chain summoning should be lessoned. Also if it tries to pick an arch-lich when outside of Gehennom it will switch to master lich instead (which won't be allowed to summon an Archon or an arch- lich or even another master lich). (The monmove.c bit is unrelated, just some comment formatting that I had laying around that got mixed in.)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.142 $ $NHDT-Date: 1584872363 2020/03/22 10:19:23 $
|
||||
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.144 $ $NHDT-Date: 1585361048 2020/03/28 02:04:08 $
|
||||
|
||||
General Fixes and Modified Features
|
||||
-----------------------------------
|
||||
@@ -92,6 +92,8 @@ praying on an unaligned altar outside of Gehennom behaved like an ordinary
|
||||
Discworld typo: Moving Pictures passage 12 "or" -> "of"
|
||||
unicorn corpses and wraith corpses could be sacrificed even if "too old"
|
||||
hero polymorphed into a hider and hiding was not unhidden when teleporting
|
||||
impose tighter restraints on 'summon nasties', both for spellcasting monsters
|
||||
and post-Wizard harassment
|
||||
|
||||
|
||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1584405113 2020/03/17 00:31:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.814 $ */
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1585361043 2020/03/28 02:04:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.815 $ */
|
||||
/* Copyright (c) Steve Creps, 1988. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1218,6 +1218,7 @@ E struct mextra *NDECL(newmextra);
|
||||
E void FDECL(copy_mextra, (struct monst *, struct monst *));
|
||||
E void FDECL(dealloc_mextra, (struct monst *));
|
||||
E struct monst *FDECL(makemon, (struct permonst *, int, int, int));
|
||||
E struct monst *FDECL(unmakemon, (struct monst *, int));
|
||||
E boolean FDECL(create_critters, (int, struct permonst *, BOOLEAN_P));
|
||||
E struct permonst *NDECL(rndmonst);
|
||||
E struct permonst *FDECL(mkclass, (CHAR_P, int));
|
||||
@@ -1406,7 +1407,7 @@ E boolean FDECL(is_flammable, (struct obj *));
|
||||
E boolean FDECL(is_rottable, (struct obj *));
|
||||
E void FDECL(place_object, (struct obj *, int, int));
|
||||
E void FDECL(remove_object, (struct obj *));
|
||||
E void FDECL(discard_minvent, (struct monst *));
|
||||
E void FDECL(discard_minvent, (struct monst *, BOOLEAN_P));
|
||||
E void FDECL(obj_extract_self, (struct obj *));
|
||||
E void FDECL(extract_nobj, (struct obj *, struct obj **));
|
||||
E void FDECL(extract_nexthere, (struct obj *, struct obj **));
|
||||
@@ -3037,7 +3038,7 @@ E int FDECL(tactics, (struct monst *));
|
||||
E boolean FDECL(has_aggravatables, (struct monst *));
|
||||
E void NDECL(aggravate);
|
||||
E void NDECL(clonewiz);
|
||||
E int NDECL(pick_nasty);
|
||||
E int FDECL(pick_nasty, (int));
|
||||
E int FDECL(nasty, (struct monst *));
|
||||
E void NDECL(resurrect);
|
||||
E void NDECL(intervene);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1574722863 2019/11/25 23:01:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.142 $ */
|
||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1585361050 2020/03/28 02:04:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.162 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -923,20 +923,20 @@ int mndx;
|
||||
boolean tally;
|
||||
boolean ghostly;
|
||||
{
|
||||
boolean result;
|
||||
uchar lim = mbirth_limit(mndx);
|
||||
boolean gone = (g.mvitals[mndx].mvflags & G_GONE) != 0; /* geno'd|extinct */
|
||||
boolean gone, result;
|
||||
int lim = mbirth_limit(mndx);
|
||||
|
||||
result = (((int) g.mvitals[mndx].born < lim) && !gone) ? TRUE : FALSE;
|
||||
gone = (g.mvitals[mndx].mvflags & G_GONE) != 0; /* geno'd|extinct */
|
||||
result = ((int) g.mvitals[mndx].born < lim && !gone) ? TRUE : FALSE;
|
||||
|
||||
/* if it's unique, don't ever make it again */
|
||||
if ((mons[mndx].geno & G_UNIQ) && mndx != PM_HIGH_PRIEST)
|
||||
if ((mons[mndx].geno & G_UNIQ) != 0 && mndx != PM_HIGH_PRIEST)
|
||||
g.mvitals[mndx].mvflags |= G_EXTINCT;
|
||||
|
||||
if (g.mvitals[mndx].born < 255 && tally
|
||||
&& (!ghostly || (ghostly && result)))
|
||||
if (g.mvitals[mndx].born < 255 && tally && (!ghostly || result))
|
||||
g.mvitals[mndx].born++;
|
||||
if ((int) g.mvitals[mndx].born >= lim && !(mons[mndx].geno & G_NOGEN)
|
||||
if ((int) g.mvitals[mndx].born >= lim
|
||||
&& !(mons[mndx].geno & G_NOGEN)
|
||||
&& !(g.mvitals[mndx].mvflags & G_EXTINCT)) {
|
||||
if (wizard) {
|
||||
debugpline1("Automatically extinguished %s.",
|
||||
@@ -1391,7 +1391,7 @@ int mmflags;
|
||||
} else {
|
||||
/* no initial inventory is allowed */
|
||||
if (mtmp->minvent)
|
||||
discard_minvent(mtmp);
|
||||
discard_minvent(mtmp, TRUE);
|
||||
mtmp->minvent = (struct obj *) 0; /* caller expects this */
|
||||
}
|
||||
if (ptr->mflags3 && !(mmflags & MM_NOWAIT)) {
|
||||
@@ -1412,6 +1412,34 @@ int mmflags;
|
||||
return mtmp;
|
||||
}
|
||||
|
||||
/* caller rejects makemon()'s result; always returns Null */
|
||||
struct monst *
|
||||
unmakemon(mon, mmflags)
|
||||
struct monst *mon;
|
||||
int mmflags;
|
||||
{
|
||||
boolean countbirth = ((mmflags & MM_NOCOUNTBIRTH) == 0);
|
||||
int mndx = monsndx(mon->data);
|
||||
|
||||
/* if count has reached the limit of 255, we don't know whether
|
||||
that just happened when creating this monster or the threshold
|
||||
had already been reached and further incrments were suppressed;
|
||||
assume the latter */
|
||||
if (countbirth && g.mvitals[mndx].born > 0 && g.mvitals[mndx].born < 255)
|
||||
g.mvitals[mndx].born -= 1;
|
||||
if ((mon->data->geno & G_UNIQ) != 0)
|
||||
g.mvitals[mndx].mvflags &= ~G_EXTINCT;
|
||||
|
||||
mon->mhp = 0; /* let discard_minvent() know that mon isn't being kept */
|
||||
/* uncreate any artifact that the monster was provided with; unlike
|
||||
mongone(), this doesn't protect special items like the Amulet
|
||||
by dropping them so caller should handle them when applicable */
|
||||
discard_minvent(mon, TRUE);
|
||||
|
||||
mongone(mon);
|
||||
return (struct monst *) 0;
|
||||
}
|
||||
|
||||
int
|
||||
mbirth_limit(mndx)
|
||||
int mndx;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 mkobj.c $NHDT-Date: 1578895344 2020/01/13 06:02:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.174 $ */
|
||||
/* NetHack 3.6 mkobj.c $NHDT-Date: 1585361051 2020/03/28 02:04:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.176 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1935,11 +1935,12 @@ register struct obj *otmp;
|
||||
|
||||
/* throw away all of a monster's inventory */
|
||||
void
|
||||
discard_minvent(mtmp)
|
||||
discard_minvent(mtmp, uncreate_artifacts)
|
||||
struct monst *mtmp;
|
||||
boolean uncreate_artifacts;
|
||||
{
|
||||
struct obj *otmp, *mwep = MON_WEP(mtmp);
|
||||
boolean keeping_mon = (!DEADMONSTER(mtmp));
|
||||
boolean keeping_mon = !DEADMONSTER(mtmp);
|
||||
|
||||
while ((otmp = mtmp->minvent) != 0) {
|
||||
/* this has now become very similar to m_useupall()... */
|
||||
@@ -1953,6 +1954,8 @@ struct monst *mtmp;
|
||||
}
|
||||
otmp->owornmask = 0L; /* obfree() expects this */
|
||||
}
|
||||
if (uncreate_artifacts && otmp->oartifact)
|
||||
artifact_exists(otmp, safe_oname(otmp), FALSE);
|
||||
obfree(otmp, (struct obj *) 0); /* dealloc_obj() isn't sufficient */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 mon.c $NHDT-Date: 1581886863 2020/02/16 21:01:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.324 $ */
|
||||
/* NetHack 3.6 mon.c $NHDT-Date: 1585361052 2020/03/28 02:04:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.327 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -2197,7 +2197,7 @@ struct monst *mdef;
|
||||
can't remove them from the game */
|
||||
mdrop_special_objs(mdef);
|
||||
/* release rest of monster's inventory--it is removed from game */
|
||||
discard_minvent(mdef);
|
||||
discard_minvent(mdef, FALSE);
|
||||
m_detach(mdef, mdef->data);
|
||||
}
|
||||
|
||||
@@ -3534,11 +3534,11 @@ struct monst *mon;
|
||||
switch (mon->cham) {
|
||||
case PM_SANDESTIN:
|
||||
if (rn2(7))
|
||||
mndx = pick_nasty();
|
||||
mndx = pick_nasty(mons[PM_ARCHON].difficulty - 1);
|
||||
break;
|
||||
case PM_DOPPELGANGER:
|
||||
if (!rn2(7)) {
|
||||
mndx = pick_nasty();
|
||||
mndx = pick_nasty(mons[PM_JABBERWOCK].difficulty - 1);
|
||||
} else if (rn2(3)) { /* role monsters */
|
||||
mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1, PM_ARCHEOLOGIST);
|
||||
} else if (!rn2(3)) { /* quest guardians */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 monmove.c $NHDT-Date: 1580633722 2020/02/02 08:55:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.129 $ */
|
||||
/* NetHack 3.6 monmove.c $NHDT-Date: 1585361053 2020/03/28 02:04:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.133 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2006. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -874,16 +874,15 @@ register int after;
|
||||
if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) && rn2(10))
|
||||
return 0; /* do not leave hiding place */
|
||||
|
||||
set_apparxy(mtmp);
|
||||
/* where does mtmp think you are? */
|
||||
/* Not necessary if m_move called from this file, but necessary in
|
||||
* other calls of m_move (ex. leprechauns dodging)
|
||||
*/
|
||||
/* Where does 'mtmp' think you are? Not necessary if m_move() called
|
||||
from this file, but needed for other calls of m_move(). */
|
||||
set_apparxy(mtmp); /* set mtmp->mux, mtmp->muy */
|
||||
|
||||
if (!Is_rogue_level(&u.uz))
|
||||
can_tunnel = tunnels(ptr);
|
||||
can_open = !(nohands(ptr) || verysmall(ptr));
|
||||
can_unlock =
|
||||
((can_open && monhaskey(mtmp, TRUE)) || mtmp->iswiz || is_rider(ptr));
|
||||
can_unlock = ((can_open && monhaskey(mtmp, TRUE))
|
||||
|| mtmp->iswiz || is_rider(ptr));
|
||||
doorbuster = is_giant(ptr);
|
||||
if (mtmp->wormno)
|
||||
goto not_special;
|
||||
@@ -1469,7 +1468,7 @@ register int after;
|
||||
add_damage(mtmp->mx, mtmp->my, 0L);
|
||||
}
|
||||
} else if (levl[mtmp->mx][mtmp->my].typ == IRONBARS) {
|
||||
/* As of 3.6.2: was using may_dig() but it doesn't handle bars */
|
||||
/* 3.6.2: was using may_dig() but it doesn't handle bars */
|
||||
if (!(levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE)
|
||||
&& (dmgtype(ptr, AD_RUST) || dmgtype(ptr, AD_CORR))) {
|
||||
if (canseemon(mtmp))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1584655714 2020/03/19 22:08:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.181 $ */
|
||||
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1585361055 2020/03/28 02:04:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.183 $ */
|
||||
/* Copyright (c) 1989 by Jean-Christophe Collet */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1981,7 +1981,7 @@ struct mkroom *croom;
|
||||
}
|
||||
|
||||
if (m->has_invent) {
|
||||
discard_minvent(mtmp);
|
||||
discard_minvent(mtmp, TRUE);
|
||||
invent_carrying_monster = mtmp;
|
||||
}
|
||||
}
|
||||
|
||||
98
src/wizard.c
98
src/wizard.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 wizard.c $NHDT-Date: 1561336025 2019/06/24 00:27:05 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.56 $ */
|
||||
/* NetHack 3.6 wizard.c $NHDT-Date: 1585361057 2020/03/28 02:04:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2016. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -41,7 +41,7 @@ static NEARDATA const int nasties[] = {
|
||||
PM_SILVER_DRAGON, PM_ORANGE_DRAGON, PM_GREEN_DRAGON,
|
||||
PM_YELLOW_DRAGON, PM_GUARDIAN_NAGA, PM_FIRE_GIANT,
|
||||
PM_ALEAX, PM_COUATL, PM_HORNED_DEVIL, PM_BARBED_DEVIL,
|
||||
/* (titans, ki-rin, and golden nagas are suitably nasty, but
|
||||
/* (Archons, titans, ki-rin, and golden nagas are suitably nasty, but
|
||||
they're summoners so would aggravate excessive summoning) */
|
||||
};
|
||||
|
||||
@@ -512,9 +512,10 @@ clonewiz()
|
||||
|
||||
/* also used by newcham() */
|
||||
int
|
||||
pick_nasty()
|
||||
pick_nasty(difcap)
|
||||
int difcap; /* if non-zero, try to make difficulty be lower than this */
|
||||
{
|
||||
int res = nasties[rn2(SIZE(nasties))];
|
||||
int alt, res = nasties[rn2(SIZE(nasties))];
|
||||
|
||||
/* To do? Possibly should filter for appropriate forms when
|
||||
* in the elemental planes or surrounded by water or lava.
|
||||
@@ -526,6 +527,33 @@ pick_nasty()
|
||||
&& !('A' <= mons[res].mlet && mons[res].mlet <= 'Z'))
|
||||
res = nasties[rn2(SIZE(nasties))];
|
||||
|
||||
/* if genocided or too difficult or out of place, try a substitute
|
||||
when a suitable one exists
|
||||
arch-lich -> master lich,
|
||||
master mind flayer -> mind flayer,
|
||||
but the substitutes are likely to be genocided too */
|
||||
alt = res;
|
||||
if ((g.mvitals[res].mvflags & G_GENOD) != 0
|
||||
|| (difcap > 0 && mons[res].difficulty >= difcap)
|
||||
/* note: nasty() -> makemon() ignores G_HELL|G_NOHELL;
|
||||
arch-lich and master lich are both flagged as hell-only;
|
||||
this filtering demotes arch-lich to master lich when
|
||||
outside of Gehennom (unless the latter has been genocided) */
|
||||
|| (mons[res].geno & (Inhell ? G_NOHELL : G_HELL)) != 0)
|
||||
alt = big_to_little(res);
|
||||
if (alt != res && (g.mvitals[alt].mvflags & G_GENOD) == 0) {
|
||||
const char *mname = mons[alt].mname,
|
||||
*lastspace = rindex(mname, ' ');
|
||||
|
||||
/* only non-juveniles can become alternate choice */
|
||||
if (strncmp(mname, "baby ", 5)
|
||||
&& (!lastspace
|
||||
|| (strcmp(lastspace, " hatchling")
|
||||
&& strcmp(lastspace, " pup")
|
||||
&& strcmp(lastspace, " cub"))))
|
||||
res = alt;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -540,11 +568,10 @@ int
|
||||
nasty(summoner)
|
||||
struct monst *summoner;
|
||||
{
|
||||
register struct monst *mtmp;
|
||||
register int i, j;
|
||||
int castalign = (summoner ? sgn(summoner->data->maligntyp) : 0);
|
||||
struct monst *mtmp;
|
||||
coord bypos;
|
||||
int count, census, tmp, makeindex, s_cls, m_cls;
|
||||
int i, j, count, census, tmp, makeindex,
|
||||
s_cls, m_cls, difcap, trylimit, castalign;
|
||||
|
||||
#define MAXNASTIES 10 /* more than this can be created */
|
||||
|
||||
@@ -558,12 +585,14 @@ struct monst *summoner;
|
||||
} else {
|
||||
count = 0;
|
||||
s_cls = summoner ? summoner->data->mlet : 0;
|
||||
difcap = summoner ? summoner->data->difficulty : 0; /* spellcasters */
|
||||
castalign = summoner ? sgn(summoner->data->maligntyp) : 0;
|
||||
tmp = (u.ulevel > 3) ? u.ulevel / 3 : 1;
|
||||
/* if we don't have a casting monster, nasties appear around hero,
|
||||
otherwise they'll appear around spot summoner thinks she's at */
|
||||
bypos.x = u.ux;
|
||||
bypos.y = u.uy;
|
||||
for (i = rnd(tmp); i > 0 && count < MAXNASTIES; --i)
|
||||
for (i = rnd(tmp); i > 0 && count < MAXNASTIES; --i) {
|
||||
/* Of the 42 nasties[], 10 are lawful, 14 are chaotic,
|
||||
* and 18 are neutral.
|
||||
*
|
||||
@@ -585,15 +614,16 @@ struct monst *summoner;
|
||||
/* Don't create more spellcasters of the monsters' level or
|
||||
* higher--avoids chain summoners filling up the level.
|
||||
*/
|
||||
trylimit = 10 + 1; /* 10 tries */
|
||||
do {
|
||||
makeindex = pick_nasty();
|
||||
if (!--trylimit)
|
||||
goto nextj; /* break this loop, continue outer one */
|
||||
makeindex = pick_nasty(difcap);
|
||||
m_cls = mons[makeindex].mlet;
|
||||
} while (summoner
|
||||
&& ((attacktype(&mons[makeindex], AT_MAGC)
|
||||
&& mons[makeindex].difficulty
|
||||
>= mons[summoner->mnum].difficulty)
|
||||
|| (s_cls == S_DEMON && m_cls == S_ANGEL)
|
||||
|| (s_cls == S_ANGEL && m_cls == S_DEMON)));
|
||||
} while ((difcap > 0 && mons[makeindex].difficulty >= difcap
|
||||
&& attacktype(&mons[makeindex], AT_MAGC))
|
||||
|| (s_cls == S_DEMON && m_cls == S_ANGEL)
|
||||
|| (s_cls == S_ANGEL && m_cls == S_DEMON));
|
||||
/* do this after picking the monster to place */
|
||||
if (summoner && !enexto(&bypos, summoner->mux, summoner->muy,
|
||||
&mons[makeindex]))
|
||||
@@ -604,18 +634,46 @@ struct monst *summoner;
|
||||
NO_MM_FLAGS)) != 0) {
|
||||
mtmp->msleeping = mtmp->mpeaceful = mtmp->mtame = 0;
|
||||
set_malign(mtmp);
|
||||
} else /* random monster to substitute for geno'd selection */
|
||||
mtmp = makemon((struct permonst *) 0, bypos.x, bypos.y,
|
||||
NO_MM_FLAGS);
|
||||
} else {
|
||||
/* random monster to substitute for geno'd selection;
|
||||
unlike direct choice, not forced to be hostile [why?];
|
||||
limit spellcasters to inhibit chain summoning */
|
||||
if ((mtmp = makemon((struct permonst *) 0,
|
||||
bypos.x, bypos.y,
|
||||
NO_MM_FLAGS)) != 0) {
|
||||
m_cls = mtmp->data->mlet;
|
||||
if ((difcap > 0 && mtmp->data->difficulty >= difcap
|
||||
&& attacktype(mtmp->data, AT_MAGC))
|
||||
|| (s_cls == S_DEMON && m_cls == S_ANGEL)
|
||||
|| (s_cls == S_ANGEL && m_cls == S_DEMON))
|
||||
mtmp = unmakemon(mtmp, NO_MM_FLAGS); /* Null */
|
||||
}
|
||||
}
|
||||
|
||||
if (mtmp) {
|
||||
/* create at most one arch-lich or Archon regardless
|
||||
of who is doing the summoning (note: Archon is
|
||||
not in nasties[] but could be chosen as random
|
||||
replacement for a genocided selection) */
|
||||
if (mtmp->data == &mons[PM_ARCH_LICH]
|
||||
|| mtmp->data == &mons[PM_ARCHON]) {
|
||||
tmp = min(mons[PM_ARCHON].difficulty, /* A:26 */
|
||||
mons[PM_ARCH_LICH].difficulty); /* L:31 */
|
||||
if (!difcap || difcap > tmp)
|
||||
difcap = tmp; /* rest must be lower difficulty */
|
||||
}
|
||||
/* delay first use of spell or breath attack */
|
||||
mtmp->mspec_used = rnd(4);
|
||||
|
||||
if (++count >= MAXNASTIES
|
||||
|| mtmp->data->maligntyp == 0
|
||||
|| sgn(mtmp->data->maligntyp) == castalign)
|
||||
break;
|
||||
}
|
||||
}
|
||||
nextj:
|
||||
; /* empty; label must be followed by a statement */
|
||||
} /* for j */
|
||||
} /* for i */
|
||||
}
|
||||
|
||||
if (count)
|
||||
|
||||
Reference in New Issue
Block a user