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
/* ### 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 *));
#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)
#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 || \
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;
&& 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) {
#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);
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;
}
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
#include "hack.h"
#include "mfndpos.h"
#include "artifact.h"
+#include "epri.h"
extern boolean notonhead;
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)
#include "hack.h"
#include "qtext.h"
+#include "epri.h"
extern const int monstr[];
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 */
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 {