From a311f4b46748a8aea8f719dc850660732dfee00e Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 3 Feb 2025 11:42:36 -0800 Subject: [PATCH] fix issue #1362 - carrying Mitre of Holiness Issue reported by elunna: the definition of the Mitre of Holiness specifies that carrying it should confer fire resistance but that didn't work. The Mitre's definition (added in 3.1.0) has always included that, but such a capability had never been implemented. Wearing it didn't confer fire resistance either--its definition doesn't bother to specify a 'defend' attribute since the 'carry' one should cover that. This adds carrying capability for damage types fire, cold, sleep, disintegration, electrity, poison, acid, and petrification. Fire is still specified by the Mitre; none of the others are currently used. Fixes #1362 --- doc/fixes3-7-0.txt | 6 ++++- include/extern.h | 3 ++- include/monst.h | 27 ++++++++------------ src/mondata.c | 61 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 77 insertions(+), 20 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 3c6a8e235..d4b8d1671 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1484 $ $NHDT-Date: 1726862062 2024/09/20 19:54:22 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1533 $ $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ General Fixes and Modified Features ----------------------------------- @@ -1500,6 +1500,10 @@ when you hear a monster incant a scroll, ensure that the 'I' invisible proceed with showpaths option even if the sysconf file is missing angry shopkeeper was not charging for thrown items avoid "You fall down a deep shaft!" if deliberately flying down +since introduction in 3.1.0, the definition for Mitre of Holiness has specified + that carrying it provides fire resistance, but that had never been + implemented; wearing it didn't confer fire resistance either--there is + no 'defends' capability for it since carrying should encompass that Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 265b69259..e9988c798 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1723580890 2024/08/13 20:28:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1435 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1476 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1803,6 +1803,7 @@ extern boolean attacktype(struct permonst *, int) NONNULLARG1; extern boolean noattacks(struct permonst *) NONNULLARG1; extern boolean poly_when_stoned(struct permonst *) NONNULLARG1; extern boolean defended(struct monst *, int) NONNULLARG1; +extern boolean Resists_Elem(struct monst *, int) NONNULLARG1; extern boolean resists_drli(struct monst *) NONNULLARG1; extern boolean resists_magm(struct monst *) NONNULLARG1; extern boolean resists_blnd(struct monst *) NONNULLARG1; diff --git a/include/monst.h b/include/monst.h index a7f39c18e..b3f8956fd 100644 --- a/include/monst.h +++ b/include/monst.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 monst.h $NHDT-Date: 1678560511 2023/03/11 18:48:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.54 $ */ +/* NetHack 3.7 monst.h $NHDT-Date: 1738640524 2025/02/03 19:42:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -268,22 +268,15 @@ struct monst { #endif #define mon_resistancebits(mon) \ ((mon)->data->mresists | (mon)->mextrinsics | (mon)->mintrinsics) -#define resists_fire(mon) \ - ((mon_resistancebits(mon) & MR_FIRE) != 0) -#define resists_cold(mon) \ - ((mon_resistancebits(mon) & MR_COLD) != 0) -#define resists_sleep(mon) \ - ((mon_resistancebits(mon) & MR_SLEEP) != 0) -#define resists_disint(mon) \ - ((mon_resistancebits(mon) & MR_DISINT) != 0) -#define resists_elec(mon) \ - ((mon_resistancebits(mon) & MR_ELEC) != 0) -#define resists_poison(mon) \ - ((mon_resistancebits(mon) & MR_POISON) != 0) -#define resists_acid(mon) \ - ((mon_resistancebits(mon) & MR_ACID) != 0) -#define resists_ston(mon) \ - ((mon_resistancebits(mon) & MR_STONE) != 0) +#define resists_fire(mon) Resists_Elem(mon, MR_FIRE) +#define resists_cold(mon) Resists_Elem(mon, MR_COLD) +#define resists_sleep(mon) Resists_Elem(mon, MR_SLEEP) +#define resists_disint(mon) Resists_Elem(mon, MR_DISINT) +#define resists_elec(mon) Resists_Elem(mon, MR_ELEC) +#define resists_poison(mon) Resists_Elem(mon, MR_POISON) +#define resists_acid(mon) Resists_Elem(mon, MR_ACID) +#define resists_ston(mon) Resists_Elem(mon, MR_STONE) + #define is_lminion(mon) \ (is_minion((mon)->data) && mon_aligntyp(mon) == A_LAWFUL) diff --git a/src/mondata.c b/src/mondata.c index 49a887a80..bb032bdfd 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mondata.c $NHDT-Date: 1711620615 2024/03/28 10:10:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.132 $ */ +/* NetHack 3.7 mondata.c $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.140 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -123,6 +123,65 @@ defended(struct monst *mon, int adtyp) return FALSE; } +/* returns True if monster resists particular elemental damage; mostly used + in order to check effects of carried artifacts */ +boolean +Resists_Elem(struct monst *mon, int restyp) +{ + struct obj *o; + long slotmask; + boolean is_you = (mon == &gy.youmonst); + int u_resist, dmgtyp = 0, proptyp = 0; + + switch (restyp) { + case MR_FIRE: + case MR_COLD: + case MR_SLEEP: + case MR_DISINT: + case MR_ELEC: + case MR_POISON: + case MR_ACID: + case MR_STONE: + dmgtyp = restyp; + proptyp = dmgtyp - 1; /* valid for dmgtyp|restyp 2..9 */ + break; + + /* accept these, but we expect callers to use their routines directly */ + case ANTIMAGIC: + return resists_magm(mon); + case DRAIN_RES: + return resists_drli(mon); + case BLND_RES: + return resists_blnd(mon); + + default: + impossible("Resists_Elem(%d), unexpected resistance type", restyp); + return FALSE; + } + u_resist = u.uprops[restyp].intrinsic || u.uprops[restyp].extrinsic; + + if (is_you ? u_resist : ((mon_resistancebits(mon) & restyp) != 0)) + return TRUE; + /* check for resistance granted by wielded weapon */ + o = is_you ? uwep : MON_WEP(mon); + if (o && o->oartifact && defends(dmgtyp, o)) + return TRUE; + /* check for resistance granted by worn or carried items */ + o = is_you ? gi.invent : mon->minvent; + slotmask = W_ARMOR | W_ACCESSORY; + if (!is_you /* assumes monsters don't wield non-weapons */ + || (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep)))) + slotmask |= W_WEP; + if (is_you && u.twoweap) + slotmask |= W_SWAPWEP; + for (; o; o = o->nobj) + if (((o->owornmask & slotmask) != 0L + && objects[o->otyp].oc_oprop == restyp) + || (o->oartifact && defends_when_carried(dmgtyp, o))) + return TRUE; + return FALSE; +} + /* returns True if monster is drain-life resistant */ boolean resists_drli(struct monst *mon)