From ff8512b36bf60b328fa05a3cdd55e0b48f368e00 Mon Sep 17 00:00:00 2001 From: cohrs Date: Thu, 24 Oct 2002 04:13:56 +0000 Subject: [PATCH] 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. --- doc/fixes34.1 | 2 ++ include/extern.h | 2 +- include/mondata.h | 7 +++++-- src/makemon.c | 2 +- src/mhitu.c | 2 +- src/minion.c | 44 ++++++++++++++++++++++++++++++++++++++------ src/monmove.c | 7 ++++--- src/wizard.c | 5 +++-- 8 files changed, 55 insertions(+), 16 deletions(-) diff --git a/doc/fixes34.1 b/doc/fixes34.1 index 1c2d0562b..793333291 100644 --- a/doc/fixes34.1 +++ b/doc/fixes34.1 @@ -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 diff --git a/include/extern.h b/include/extern.h index 26480c436..f97d06de1 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 *)); diff --git a/include/mondata.h b/include/mondata.h index 61bfbba98..20d5da88c 100644 --- a/include/mondata.h +++ b/include/mondata.h @@ -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 || \ diff --git a/src/makemon.c b/src/makemon.c index 3dd99daca..4ca1affd2 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -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; diff --git a/src/mhitu.c b/src/mhitu.c index 1b3de8cb0..88f8200c2 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -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) { diff --git a/src/minion.c b/src/minion.c index 2dfd0d1dc..5d45a1391 100644 --- a/src/minion.c +++ b/src/minion.c @@ -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 diff --git a/src/monmove.c b/src/monmove.c index cdbf5732f..5dc384f65 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -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) diff --git a/src/wizard.c b/src/wizard.c index 698eaa76e..a1fc1b022 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -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 { -- 2.40.0