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)