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:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -7,12 +7,25 @@
|
|||||||
#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) :
|
||||||
(!rn2(4)) ? dlord(atyp) : ndemon(atyp);
|
(!rn2(4)) ? dlord(atyp) : ndemon(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
@@ -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
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user