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
+2
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 avoid mimicking gold when the character has the Unchanging attribute
handle polearm wielded prior to mounting the same as one wielded while mounted, 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 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 Platform- and/or Interface-Specific Fixes
+1 -1
View File
@@ -960,7 +960,7 @@ E int FDECL(doseduce, (struct monst *));
/* ### minion.c ### */ /* ### minion.c ### */
E void FDECL(msummon, (struct permonst *)); E void FDECL(msummon, (struct monst *));
E void FDECL(summon_minion, (ALIGNTYP_P,BOOLEAN_P)); E void FDECL(summon_minion, (ALIGNTYP_P,BOOLEAN_P));
E int FDECL(demon_talk, (struct monst *)); E int FDECL(demon_talk, (struct monst *));
E long FDECL(bribe, (struct monst *)); E long FDECL(bribe, (struct monst *));
+5 -2
View File
@@ -19,6 +19,11 @@
#define resists_acid(mon) (((mon)->mintrinsics & MR_ACID) != 0) #define resists_acid(mon) (((mon)->mintrinsics & MR_ACID) != 0)
#define resists_ston(mon) (((mon)->mintrinsics & MR_STONE) != 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_flyer(ptr) (((ptr)->mflags1 & M1_FLY) != 0L)
#define is_floater(ptr) ((ptr)->mlet == S_EYE) #define is_floater(ptr) ((ptr)->mlet == S_EYE)
#define is_clinger(ptr) (((ptr)->mflags1 & M1_CLING) != 0L) #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_dlord(ptr) (is_demon(ptr) && is_lord(ptr))
#define is_dprince(ptr) (is_demon(ptr) && is_prince(ptr)) #define is_dprince(ptr) (is_demon(ptr) && is_prince(ptr))
#define is_minion(ptr) ((ptr)->mflags2 & M2_MINION) #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_gold(ptr) (((ptr)->mflags2 & M2_GREEDY) != 0L)
#define likes_gems(ptr) (((ptr)->mflags2 & M2_JEWELS) != 0L) #define likes_gems(ptr) (((ptr)->mflags2 & M2_JEWELS) != 0L)
#define likes_objs(ptr) (((ptr)->mflags2 & M2_COLLECT) != 0L || \ #define likes_objs(ptr) (((ptr)->mflags2 & M2_COLLECT) != 0L || \
+1 -1
View File
@@ -1439,7 +1439,7 @@ register int otyp;
if (mtmp->data->mlet == S_DEMON) { if (mtmp->data->mlet == S_DEMON) {
/* demons never get blessed objects */ /* demons never get blessed objects */
if (otmp->blessed) curse(otmp); 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 */ /* lawful minions don't get cursed, bad, or rusting objects */
otmp->cursed = FALSE; otmp->cursed = FALSE;
if(otmp->spe < 0) otmp->spe = 0; if(otmp->spe < 0) otmp->spe = 0;
+1 -1
View File
@@ -477,7 +477,7 @@ mattacku(mtmp)
&& mtmp->data != &mons[PM_BALROG] && mtmp->data != &mons[PM_BALROG]
&& mtmp->data != &mons[PM_SUCCUBUS] && mtmp->data != &mons[PM_SUCCUBUS]
&& mtmp->data != &mons[PM_INCUBUS]) && mtmp->data != &mons[PM_INCUBUS])
if(!mtmp->mcan && !rn2(13)) msummon(mdat); if(!mtmp->mcan && !rn2(13)) msummon(mtmp);
/* Special lycanthrope handling code */ /* Special lycanthrope handling code */
if(!mtmp->cham && is_were(mdat) && !range2) { if(!mtmp->cham && is_were(mdat) && !range2) {
+38 -6
View File
@@ -7,11 +7,24 @@
#include "epri.h" #include "epri.h"
void void
msummon(ptr) /* ptr summons a monster */ msummon(mon) /* mon summons a monster */
register struct permonst *ptr; struct monst *mon;
{ {
register struct permonst *ptr;
register int dtype = NON_PM, cnt = 0; 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])) { if (is_dprince(ptr) || (ptr == &mons[PM_WIZARD_OF_YENDOR])) {
dtype = (!rn2(20)) ? dprince(atyp) : dtype = (!rn2(20)) ? dprince(atyp) :
@@ -25,10 +38,26 @@ register struct permonst *ptr;
dtype = (!rn2(20)) ? dlord(atyp) : dtype = (!rn2(20)) ? dlord(atyp) :
(!rn2(6)) ? ndemon(atyp) : monsndx(ptr); (!rn2(6)) ? ndemon(atyp) : monsndx(ptr);
cnt = 1; cnt = 1;
} else if (is_lminion(ptr)) { } else if (is_lminion(mon)) {
dtype = (is_lord(ptr) && !rn2(20)) ? llord() : dtype = (is_lord(ptr) && !rn2(20)) ? llord() :
(is_lord(ptr) || !rn2(6)) ? lminion() : monsndx(ptr); (is_lord(ptr) || !rn2(6)) ? lminion() : monsndx(ptr);
cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1; 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; if (dtype == NON_PM) return;
@@ -45,10 +74,13 @@ register struct permonst *ptr;
} }
while (cnt > 0) { 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--; cnt--;
} }
return;
} }
void void
+4 -3
View File
@@ -5,6 +5,7 @@
#include "hack.h" #include "hack.h"
#include "mfndpos.h" #include "mfndpos.h"
#include "artifact.h" #include "artifact.h"
#include "epri.h"
extern boolean notonhead; extern boolean notonhead;
@@ -130,9 +131,9 @@ int x, y;
struct monst *mtmp; struct monst *mtmp;
{ {
if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee || if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee ||
mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN || mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN ||
is_lminion(mtmp->data) || is_rider(mtmp->data) || is_lminion(mtmp) || mtmp->data == &mons[PM_ANGEL] ||
mtmp->data == &mons[PM_MINOTAUR]) is_rider(mtmp->data) || mtmp->data == &mons[PM_MINOTAUR])
return(FALSE); return(FALSE);
return (boolean)(sobj_at(SCR_SCARE_MONSTER, x, y) return (boolean)(sobj_at(SCR_SCARE_MONSTER, x, y)
+3 -2
View File
@@ -9,6 +9,7 @@
#include "hack.h" #include "hack.h"
#include "qtext.h" #include "qtext.h"
#include "epri.h"
extern const int monstr[]; extern const int monstr[];
@@ -428,7 +429,7 @@ nasty(mcast)
int count=0; int count=0;
if(!rn2(10) && Inhell) { if(!rn2(10) && Inhell) {
msummon(&mons[PM_WIZARD_OF_YENDOR]); msummon((struct monst *) 0); /* summons like WoY */
count++; count++;
} else { } else {
tmp = (u.ulevel > 3) ? u.ulevel/3 : 1; /* just in case -- rph */ tmp = (u.ulevel > 3) ? u.ulevel/3 : 1; /* just in case -- rph */
@@ -621,7 +622,7 @@ register struct monst *mtmp;
verbalize("%s %s!", verbalize("%s %s!",
random_malediction[rn2(SIZE(random_malediction))], random_malediction[rn2(SIZE(random_malediction))],
random_insult[rn2(SIZE(random_insult))]); 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)) + com_pager(rn2(QTN_ANGELIC - 1 + (Hallucination ? 1 : 0)) +
QT_ANGELIC); QT_ANGELIC);
} else { } else {