is_lminion should only match lawful minions

When Angels were introduced, they were always lawful.  Somewhere along the
line, non-lawful angels were added, but is_lminion and uses of it was never
updated to address this change.  Among other things, this resulted in
non-lawful angels delivering messages via #chat that are only appropriate
for lawful angels.  That is addressed simply by changing the definition of
is_lminion, which must take a struct monst, not a permonst, to return valid
results.  Also, non-lawful angels should summon appropriate monsters, not
lawful minions.
This commit is contained in:
cohrs
2002-10-24 04:13:56 +00:00
parent 71480033c6
commit ff8512b36b
8 changed files with 55 additions and 16 deletions

View File

@@ -288,6 +288,8 @@ breaking wand of digging on a drawbridge shouldn't dig/hole a pit in the bridge
avoid mimicking gold when the character has the Unchanging attribute
handle polearm wielded prior to mounting the same as one wielded while mounted,
and one still used after dismounting like one wielded while not mounted
non-lawful angels don't chat using lawful messages and shouldn't summon
lawful help
Platform- and/or Interface-Specific Fixes

View File

@@ -960,7 +960,7 @@ E int FDECL(doseduce, (struct monst *));
/* ### minion.c ### */
E void FDECL(msummon, (struct permonst *));
E void FDECL(msummon, (struct monst *));
E void FDECL(summon_minion, (ALIGNTYP_P,BOOLEAN_P));
E int FDECL(demon_talk, (struct monst *));
E long FDECL(bribe, (struct monst *));

View File

@@ -19,6 +19,11 @@
#define resists_acid(mon) (((mon)->mintrinsics & MR_ACID) != 0)
#define resists_ston(mon) (((mon)->mintrinsics & MR_STONE) != 0)
#define is_lminion(mon) (is_minion((mon)->data) && \
(mon)->data->maligntyp >= A_COALIGNED && \
((mon)->data != &mons[PM_ANGEL] || \
EPRI(mon)->shralign > 0))
#define is_flyer(ptr) (((ptr)->mflags1 & M1_FLY) != 0L)
#define is_floater(ptr) ((ptr)->mlet == S_EYE)
#define is_clinger(ptr) (((ptr)->mflags1 & M1_CLING) != 0L)
@@ -106,8 +111,6 @@
#define is_dlord(ptr) (is_demon(ptr) && is_lord(ptr))
#define is_dprince(ptr) (is_demon(ptr) && is_prince(ptr))
#define is_minion(ptr) ((ptr)->mflags2 & M2_MINION)
#define is_lminion(ptr) (is_minion(ptr) && \
(ptr)->maligntyp >= A_COALIGNED)
#define likes_gold(ptr) (((ptr)->mflags2 & M2_GREEDY) != 0L)
#define likes_gems(ptr) (((ptr)->mflags2 & M2_JEWELS) != 0L)
#define likes_objs(ptr) (((ptr)->mflags2 & M2_COLLECT) != 0L || \

View File

@@ -1439,7 +1439,7 @@ register int otyp;
if (mtmp->data->mlet == S_DEMON) {
/* demons never get blessed objects */
if (otmp->blessed) curse(otmp);
} else if(is_lminion(mtmp->data)) {
} else if(is_lminion(mtmp)) {
/* lawful minions don't get cursed, bad, or rusting objects */
otmp->cursed = FALSE;
if(otmp->spe < 0) otmp->spe = 0;

View File

@@ -477,7 +477,7 @@ mattacku(mtmp)
&& mtmp->data != &mons[PM_BALROG]
&& mtmp->data != &mons[PM_SUCCUBUS]
&& mtmp->data != &mons[PM_INCUBUS])
if(!mtmp->mcan && !rn2(13)) msummon(mdat);
if(!mtmp->mcan && !rn2(13)) msummon(mtmp);
/* Special lycanthrope handling code */
if(!mtmp->cham && is_were(mdat) && !range2) {

View File

@@ -7,12 +7,25 @@
#include "epri.h"
void
msummon(ptr) /* ptr summons a monster */
register struct permonst *ptr;
msummon(mon) /* mon summons a monster */
struct monst *mon;
{
register struct permonst *ptr;
register int dtype = NON_PM, cnt = 0;
aligntyp atyp = (ptr->maligntyp==A_NONE) ? A_NONE : sgn(ptr->maligntyp);
aligntyp atyp;
struct monst *mtmp;
if (mon) {
ptr = mon->data;
atyp = (ptr->maligntyp==A_NONE) ? A_NONE : sgn(ptr->maligntyp);
if (mon->ispriest || mon->data == &mons[PM_ALIGNED_PRIEST]
|| mon->data == &mons[PM_ANGEL])
atyp = EPRI(mon)->shralign;
} else {
ptr = &mons[PM_WIZARD_OF_YENDOR];
atyp = (ptr->maligntyp==A_NONE) ? A_NONE : sgn(ptr->maligntyp);
}
if (is_dprince(ptr) || (ptr == &mons[PM_WIZARD_OF_YENDOR])) {
dtype = (!rn2(20)) ? dprince(atyp) :
(!rn2(4)) ? dlord(atyp) : ndemon(atyp);
@@ -25,10 +38,26 @@ register struct permonst *ptr;
dtype = (!rn2(20)) ? dlord(atyp) :
(!rn2(6)) ? ndemon(atyp) : monsndx(ptr);
cnt = 1;
} else if (is_lminion(ptr)) {
} else if (is_lminion(mon)) {
dtype = (is_lord(ptr) && !rn2(20)) ? llord() :
(is_lord(ptr) || !rn2(6)) ? lminion() : monsndx(ptr);
cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1;
} else if (ptr == &mons[PM_ANGEL]) {
/* non-lawful angels can also summon */
if (!rn2(6)) {
switch (atyp) { /* see summon_minion */
case A_NEUTRAL:
dtype = PM_AIR_ELEMENTAL + rn2(4);
break;
case A_CHAOTIC:
case A_NONE:
dtype = ndemon(atyp);
break;
}
} else {
dtype = PM_ANGEL;
}
cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1;
}
if (dtype == NON_PM) return;
@@ -45,10 +74,13 @@ register struct permonst *ptr;
}
while (cnt > 0) {
(void)makemon(&mons[dtype], u.ux, u.uy, NO_MM_FLAGS);
mtmp = makemon(&mons[dtype], u.ux, u.uy, NO_MM_FLAGS);
if (mtmp && (dtype == PM_ANGEL)) {
/* alignment should match the summoner */
EPRI(mtmp)->shralign = atyp;
}
cnt--;
}
return;
}
void

View File

@@ -5,6 +5,7 @@
#include "hack.h"
#include "mfndpos.h"
#include "artifact.h"
#include "epri.h"
extern boolean notonhead;
@@ -130,9 +131,9 @@ int x, y;
struct monst *mtmp;
{
if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee ||
mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN ||
is_lminion(mtmp->data) || is_rider(mtmp->data) ||
mtmp->data == &mons[PM_MINOTAUR])
mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN ||
is_lminion(mtmp) || mtmp->data == &mons[PM_ANGEL] ||
is_rider(mtmp->data) || mtmp->data == &mons[PM_MINOTAUR])
return(FALSE);
return (boolean)(sobj_at(SCR_SCARE_MONSTER, x, y)

View File

@@ -9,6 +9,7 @@
#include "hack.h"
#include "qtext.h"
#include "epri.h"
extern const int monstr[];
@@ -428,7 +429,7 @@ nasty(mcast)
int count=0;
if(!rn2(10) && Inhell) {
msummon(&mons[PM_WIZARD_OF_YENDOR]);
msummon((struct monst *) 0); /* summons like WoY */
count++;
} else {
tmp = (u.ulevel > 3) ? u.ulevel/3 : 1; /* just in case -- rph */
@@ -621,7 +622,7 @@ register struct monst *mtmp;
verbalize("%s %s!",
random_malediction[rn2(SIZE(random_malediction))],
random_insult[rn2(SIZE(random_insult))]);
} else if(is_lminion(mtmp->data)) {
} else if(is_lminion(mtmp)) {
com_pager(rn2(QTN_ANGELIC - 1 + (Hallucination ? 1 : 0)) +
QT_ANGELIC);
} else {