From: PatR Date: Wed, 28 Jul 2021 20:45:56 +0000 (-0700) Subject: fix #K2154 - monster wearing alchemy smock X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0891ef4e22ccb56bacd41ce302d4178c1c6525aa;p=nethack fix #K2154 - monster wearing alchemy smock For the hero, a worn alchemy smock confers both poison resistance and acid resistance. For monsters, it was only conferring poison resistance. Change ut to add acid resistance too. --- diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b535ea9c1..b40f69fb0 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.609 $ $NHDT-Date: 1627414178 2021/07/27 19:29:38 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.610 $ $NHDT-Date: 1627505147 2021/07/28 20:45:47 $ General Fixes and Modified Features ----------------------------------- @@ -576,6 +576,8 @@ some monsters should not have been scared of bugle playing monsters that drowned would never leave a corpse (holdover from decades ago when it wasn't possible to recover anything from a water location) give alternate message if hero is blind when throne gives "your vision clears" +monster wearing an alchemy smock was only getting poison resistance from it, + not acid resistance; give both properties, just like for hero Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/worn.c b/src/worn.c index 050d20c91..1a04fb066 100644 --- a/src/worn.c +++ b/src/worn.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 worn.c $NHDT-Date: 1606919259 2020/12/02 14:27:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 3.7 worn.c $NHDT-Date: 1627505148 2021/07/28 20:45:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -333,6 +333,16 @@ mon_adjust_speed(struct monst *mon, } } +/* alchemy smock confers two properites, poison and acid resistance + but objects[ALCHEMY_SMOCK].oc_oprop can only describe one of them; + if it is poison resistance, alternate property is acid resistance; + if someone changes it to acid resistance, alt becomes posion resist; + if someone changes it to hallucination resistance, all bets are off */ +#define altprop(o) \ + (((o)->otyp == ALCHEMY_SMOCK) \ + ? (POISON_RES + ACID_RES - objects[(o)->otyp].oc_oprop) \ + : 0) + /* armor put on or taken off; might be magical variety [TODO: rename to 'update_mon_extrinsics()' and change all callers...] */ void @@ -342,12 +352,14 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on, int unseen; uchar mask; struct obj *otmp; - int which = (int) objects[obj->otyp].oc_oprop; + int which = (int) objects[obj->otyp].oc_oprop, + altwhich = altprop(obj); unseen = !canseemon(mon); if (!which) goto maybe_blocks; + again: if (on) { switch (which) { case INVIS: @@ -409,14 +421,30 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on, case POISON_RES: case ACID_RES: case STONE_RES: + /* + * Update monster's extrinsics (for worn objects only; + * 'obj' itself might still be worn or already unworn). + * + * If an alchemy smock is being taken off, this code will + * be run twice (via 'goto again') and other worn gear + * gets tested for conferring poison resistance on the + * first pass and acid resistance on the second. + * + * If some other item is being taken off, there will be + * only one pass but a worn alchemy smock will be an + * alternate source for either of those two resistances. + */ mask = (uchar) (1 << (which - 1)); - /* update monster's extrinsics (for worn objects only; - 'obj' itself might still be worn or already unworn) */ - for (otmp = mon->minvent; otmp; otmp = otmp->nobj) - if (otmp != obj - && otmp->owornmask - && (int) objects[otmp->otyp].oc_oprop == which) + for (otmp = mon->minvent; otmp; otmp = otmp->nobj) { + if (otmp == obj || !otmp->owornmask) + continue; + if ((int) objects[otmp->otyp].oc_oprop == which) break; + /* check whether 'otmp' confers target property as an extra + one rather than as the one specified for it in objects[] */ + if (altprop(otmp) == which) + break; + } if (!otmp) mon->mextrinsics &= ~((unsigned short) mask); break; @@ -425,6 +453,13 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on, } } + /* worn alchemy smock/apron confers both poison resistance and acid + resistance to the hero so do likewise for monster who wears one */ + if (altwhich && which != altwhich) { + which = altwhich; + goto again; + } + maybe_blocks: /* obj->owornmask has been cleared by this point, so we can't use it. However, since monsters don't wield armor, we don't have to guard @@ -446,6 +481,8 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on, newsym(mon->mx, mon->my); } +#undef altprop + int find_mac(struct monst *mon) {