-/* NetHack 3.6 worn.c $NHDT-Date: 1496959481 2017/06/08 22:04:41 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.49 $ */
+/* NetHack 3.6 worn.c $NHDT-Date: 1550524569 2019/02/18 21:16:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.56 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
{ W_TOOL, &ublindf },
{ W_BALL, &uball },
{ W_CHAIN, &uchain },
- { 0, 0 } };
+ { 0, 0 }
+};
/* This only allows for one blocking item per property */
#define w_blocks(o, m) \
update_inventory();
}
+/* return item worn in slot indiciated by wornmask; needed by poly_obj() */
+struct obj *
+wearmask_to_obj(wornmask)
+long wornmask;
+{
+ const struct worn *wp;
+
+ for (wp = worn; wp->w_mask; wp++)
+ if (wp->w_mask & wornmask)
+ return *wp->w_obj;
+ return (struct obj *) 0;
+}
+
/* return a bitmask of the equipment slot(s) a given item might be worn in */
long
wearslot(obj)
}
}
-/* armor put on or taken off; might be magical variety */
+/* armor put on or taken off; might be magical variety
+ [TODO: rename to 'update_mon_extrinsics()' and change all callers...] */
void
update_mon_intrinsics(mon, obj, on, silently)
struct monst *mon;
if (which <= 8) { /* 1 thru 8 correspond to MR_xxx mask values */
/* FIRE,COLD,SLEEP,DISINT,SHOCK,POISON,ACID,STONE */
mask = (uchar) (1 << (which - 1));
- mon->mintrinsics |= (unsigned short) mask;
+ mon->mextrinsics |= (unsigned short) mask;
}
break;
}
case ACID_RES:
case STONE_RES:
mask = (uchar) (1 << (which - 1));
- /* If the monster doesn't have this resistance intrinsically,
- check whether any other worn item confers it. Note that
- we don't currently check for anything conferred via simply
- carrying an object. */
- if (!(mon->data->mresists & mask)) {
- for (otmp = mon->minvent; otmp; otmp = otmp->nobj)
- if (otmp->owornmask
- && (int) objects[otmp->otyp].oc_oprop == which)
- break;
- if (!otmp)
- mon->mintrinsics &= ~((unsigned short) mask);
- }
+ /* 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)
+ break;
+ if (!otmp)
+ mon->mextrinsics &= ~((unsigned short) mask);
break;
default:
break;
}
}
-maybe_blocks:
+ 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
against that and can get away with a blanket worn-mask value. */
struct obj *otmp, *nobj;
struct monst *mtmp;
+ /*
+ * 'Object' bypass is also used for one monster function:
+ * polymorph control of long worms. Activated via setting
+ * context.bypasses even if no specific object has been
+ * bypassed.
+ */
+
for (otmp = fobj; otmp; otmp = nobj) {
nobj = otmp->nobj;
if (otmp->bypass) {
continue;
for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
otmp->bypass = 0;
+ /* long worm created by polymorph has mon->mextra->mcorpsenm set
+ to PM_LONG_WORM to flag it as not being subject to further
+ polymorph (so polymorph zap won't hit monster to transform it
+ into a long worm, then hit that worm's tail and transform it
+ again on same zap); clearing mcorpsenm reverts worm to normal */
+ if (mtmp->data == &mons[PM_LONG_WORM] && has_mcorpsenm(mtmp))
+ MCORPSENM(mtmp) = NON_PM;
}
for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
otmp->bypass = 0;
+ /* no MCORPSENM(mtmp)==PM_LONG_WORM check here; long worms can't
+ be just created by polymorph and migrating at the same time */
}
/* billobjs and mydogs chains don't matter here */
context.bypasses = FALSE;
return objchain;
}
+/* like nxt_unbypassed_obj() but operates on sortloot_item array rather
+ than an object linked list; the array contains obj==Null terminator;
+ there's an added complication that the array may have stale pointers
+ for deleted objects (see Multiple-Drop case in askchain(invent.c)) */
+struct obj *
+nxt_unbypassed_loot(lootarray, listhead)
+Loot *lootarray;
+struct obj *listhead;
+{
+ struct obj *o, *obj;
+
+ while ((obj = lootarray->obj) != 0) {
+ for (o = listhead; o; o = o->nobj)
+ if (o == obj)
+ break;
+ if (o && !obj->bypass) {
+ bypass_obj(obj);
+ break;
+ }
+ ++lootarray;
+ }
+ return obj;
+}
+
void
mon_break_armor(mon, polyspot)
struct monst *mon;