]> granicus.if.org Git - nethack/commitdiff
is_lminion should only match lawful minions
authorcohrs <cohrs>
Thu, 24 Oct 2002 04:13:56 +0000 (04:13 +0000)
committercohrs <cohrs>
Thu, 24 Oct 2002 04:13:56 +0000 (04:13 +0000)
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.

doc/fixes34.1
include/extern.h
include/mondata.h
src/makemon.c
src/mhitu.c
src/minion.c
src/monmove.c
src/wizard.c

index 1c2d0562be5908aca1c0f1408f54241daa8a2c84..79333329198aa7b60a4dc292a62fd381b9cb539c 100644 (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
index 26480c43662762d6ad611c9871f5177ec8112d2a..f97d06de1e671e2b61f1382c69f29fa9a554054e 100644 (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 *));
index 61bfbba98808bac88a2bfbcc11e75718f96cd23a..20d5da88c79956d7d0c683cc5c431ea34593e896 100644 (file)
 #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 || \
index 3dd99daca5beceafec7f5c6e68a27432e0ab91ec..4ca1affd22695572ee4cda4e1f6effcb4d63dd6b 100644 (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;
index 1b3de8cb07f78814352a1562c9b80348fedb64f5..88f8200c2bf84b387bc9a14e0b440f9d4c7334ca 100644 (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) {
index 2dfd0d1dcf381da242a13ed6f31bcde946a8743c..5d45a1391c480f1e7f0dff9231c78b1773a4ffc9 100644 (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
index cdbf5732f752135af921d949b51e25c1c9dba369..5dc384f65d97625bb76caed92cf9b7d7897fc655 100644 (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)
index 698eaa76ef8622f0c9c0412f8e7361b7ef74af13..a1fc1b0222484d6fc4ba48165a29f05086963a6d 100644 (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 {