fix #H4142 - resistance from Excalibur

Enlightenment and end of game disclosure didn't report level-drain
resistance if that was obtained via wielding Excalibur (or Stormbringer
or Staff of Aesculapius).  Drain_resistance wasn't one of the attributes
set for intrinsics/extrinsics when wielding or unwielding weapon or
wearing/unwearing other equipment.  loseexp() checks resists_drli()
which does check for items in use, so level drain would be aborted,
possibly after messages claimed that it was taming place.  I didn't try
to untangle any of that, just changed set_artifact_intrinsic to include
a test for DRAIN_RES.
This commit is contained in:
PatR
2015-12-25 14:13:05 -08:00
parent efe2ca1f92
commit 6f595dabcc
2 changed files with 22 additions and 17 deletions

View File

@@ -57,6 +57,8 @@ do not autopickup unpaid items in shops
death due an unseen gas spore's explosion resulted in "killed by a died"
allow optional parameter "true", "yes", "false", or "no" for boolean options
actually make the castle chest not trapped
level-drain resistance wasn't shown during enlightenment if it was conferred
by worn/wielded equipment
Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 artifact.c $NHDT-Date: 1446369462 2015/11/01 09:17:42 $ $NHDT-Branch: master $:$NHDT-Revision: 1.96 $ */
/* NetHack 3.6 artifact.c $NHDT-Date: 1451081581 2015/12/25 22:13:01 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.99 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -18,13 +18,12 @@ extern boolean notonhead; /* for long worms */
#define get_artifact(o) \
(((o) && (o)->oartifact) ? &artilist[(int) (o)->oartifact] : 0)
STATIC_DCL boolean
FDECL(bane_applies, (const struct artifact *, struct monst *));
STATIC_DCL boolean FDECL(bane_applies, (const struct artifact *,
struct monst *));
STATIC_DCL int FDECL(spec_applies, (const struct artifact *, struct monst *));
STATIC_DCL int FDECL(arti_invoke, (struct obj *));
STATIC_DCL boolean
FDECL(Mb_hit, (struct monst * magr, struct monst *mdef, struct obj *, int *,
int, BOOLEAN_P, char *));
STATIC_DCL boolean FDECL(Mb_hit, (struct monst * magr, struct monst *mdef,
struct obj *, int *, int, BOOLEAN_P, char *));
STATIC_DCL unsigned long FDECL(abil_to_spfx, (long *));
STATIC_DCL uchar FDECL(abil_to_adtyp, (long *));
STATIC_DCL boolean FDECL(untouchable, (struct obj *, BOOLEAN_P));
@@ -462,12 +461,13 @@ boolean being_worn;
*/
void
set_artifact_intrinsic(otmp, on, wp_mask)
register struct obj *otmp;
struct obj *otmp;
boolean on;
long wp_mask;
{
long *mask = 0;
register const struct artifact *oart = get_artifact(otmp);
register const struct artifact *art, *oart = get_artifact(otmp);
register struct obj *obj;
register uchar dtyp;
register long spfx;
@@ -489,19 +489,21 @@ long wp_mask;
mask = &EDisint_resistance;
else if (dtyp == AD_DRST)
mask = &EPoison_resistance;
else if (dtyp == AD_DRLI)
mask = &EDrain_resistance;
if (mask && wp_mask == W_ART && !on) {
/* find out if some other artifact also confers this intrinsic */
/* if so, leave the mask alone */
register struct obj *obj;
for (obj = invent; obj; obj = obj->nobj)
/* find out if some other artifact also confers this intrinsic;
if so, leave the mask alone */
for (obj = invent; obj; obj = obj->nobj) {
if (obj != otmp && obj->oartifact) {
register const struct artifact *art = get_artifact(obj);
art = get_artifact(obj);
if (art->cary.adtyp == dtyp) {
mask = (long *) 0;
break;
}
}
}
}
if (mask) {
if (on)
@@ -514,10 +516,9 @@ long wp_mask;
spfx = (wp_mask != W_ART) ? oart->spfx : oart->cspfx;
if (spfx && wp_mask == W_ART && !on) {
/* don't change any spfx also conferred by other artifacts */
register struct obj *obj;
for (obj = invent; obj; obj = obj->nobj)
if (obj != otmp && obj->oartifact) {
register const struct artifact *art = get_artifact(obj);
art = get_artifact(obj);
spfx &= ~art->cspfx;
}
}
@@ -1738,6 +1739,7 @@ long *abil;
{ &EAntimagic, AD_MAGM },
{ &EDisint_resistance, AD_DISN },
{ &EPoison_resistance, AD_DRST },
{ &EDrain_resistance, AD_DRLI },
};
int k;
@@ -1792,7 +1794,6 @@ long *abil;
long wornmask = (W_ARM | W_ARMC | W_ARMH | W_ARMS
| W_ARMG | W_ARMF | W_ARMU
| W_AMUL | W_RINGL | W_RINGR | W_TOOL
/* [do W_ART and W_ARTI actually belong here?] */
| W_ART | W_ARTI);
if (u.twoweap)
@@ -1808,7 +1809,9 @@ long *abil;
if (art) {
if (dtyp) {
if (art->cary.adtyp == dtyp || art->defn.adtyp == dtyp)
if (art->cary.adtyp == dtyp /* carried */
|| (art->defn.adtyp == dtyp /* defends while worn */
&& (obj->owornmask & ~(W_ART | W_ARTI))))
return obj;
}
if (spfx) {