-/* 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. */
/* JNetHack Copyright */
/* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018 */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020 */
/* JNetHack may be freely redistributed. See license for details. */
#include "hack.h"
{ 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. */
Sprintf(buf, "%s\82ð\82Í\82¸\82µ\82Ä", distant_name(old, doname));
else
buf[0] = '\0';
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s%s puts on %s.", Monnam(mon), buf,
distant_name(best, doname));
#else
distant_name(best,doname));
#endif
if (autocurse)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s %s %s %s for a moment.", s_suffix(Monnam(mon)),
simpleonames(best), otense(best, "glow"),
hcolor(NH_BLACK));
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;
if ((otmp = which_armor(mon, W_ARMC)) != 0) {
if (otmp->oartifact) {
if (vis)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s %s falls off!", s_suffix(Monnam(mon)),
cloak_simple_name(otmp));
#else
m_lose_armor(mon, otmp);
} else {
if (vis)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s %s tears apart!", s_suffix(Monnam(mon)),
cloak_simple_name(otmp));
#else
} else if (sliparm(mdat)) {
if ((otmp = which_armor(mon, W_ARM)) != 0) {
if (vis)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s armor falls around %s!", s_suffix(Monnam(mon)),
pronoun);
#else
if ((otmp = which_armor(mon, W_ARMC)) != 0) {
if (vis) {
if (is_whirly(mon->data))
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s %s falls, unsupported!", s_suffix(Monnam(mon)),
cloak_simple_name(otmp));
#else
cloak_simple_name(otmp));
#endif
else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s shrinks out of %s %s!", Monnam(mon), ppronoun,
cloak_simple_name(otmp));
#else
if ((otmp = which_armor(mon, W_ARMU)) != 0) {
if (vis) {
if (sliparm(mon->data))
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s seeps right through %s shirt!", Monnam(mon),
ppronoun);
#else
pline("%s\82Í\8e©\95ª\82Ì\83V\83\83\83c\82É\82µ\82Ý\8d\9e\82ñ\82¾\81I", Monnam(mon));
#endif
else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s becomes much too small for %s shirt!",
Monnam(mon), ppronoun);
#else
/* [caller needs to handle weapon checks] */
if ((otmp = which_armor(mon, W_ARMG)) != 0) {
if (vis)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s drops %s gloves%s!", Monnam(mon), ppronoun,
MON_WEP(mon) ? " and weapon" : "");
#else
}
if ((otmp = which_armor(mon, W_ARMS)) != 0) {
if (vis)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s can no longer hold %s shield!", Monnam(mon),
ppronoun);
#else
/* flimsy test for horns matches polyself handling */
&& (handless_or_tiny || !is_flimsy(otmp))) {
if (vis)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s helmet falls to the %s!", s_suffix(Monnam(mon)),
surface(mon->mx, mon->my));
#else
*/
pline("%s\82Ì\8cC\82Í\82Ê\82°\97\8e\82¿\82½\81I", Monnam(mon));
else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s boots %s off %s feet!", s_suffix(Monnam(mon)),
verysmall(mdat) ? "slide" : "are pushed", ppronoun);
#else