diff --git a/src/mkobj.c b/src/mkobj.c index 50f2b5b7e..899581128 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 mkobj.c $NHDT-Date: 1430472720 2015/05/01 09:32:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.95 $ */ +/* NetHack 3.5 mkobj.c $NHDT-Date: 1430559882 2015/05/02 09:44:42 $ $NHDT-Branch: master $:$NHDT-Revision: 1.96 $ */ /* NetHack 3.5 mkobj.c $Date: 2012/03/10 02:49:08 $ $Revision: 1.70 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2180,32 +2180,44 @@ struct obj *obj; /* [W_ART,W_ARTI are property bits for items which aren't worn] */ }; char maskbuf[60]; - unsigned long allmask = 0L; + unsigned long owornmask, allmask = 0L; int i, n = 0; + /* use owornmask for testing and bit twiddling, but use original + obj->owornmask for printing */ + owornmask = obj->owornmask; + /* figure out how many bits are set, and also which are viable */ for (i = 0; wearbits[i]; ++i) { + if ((owornmask & wearbits[i]) != 0L) ++n; allmask |= wearbits[i]; - if ((obj->owornmask & wearbits[i]) != 0L) ++n; + } + if (n == 2 && carried(obj) && obj == uball && (owornmask & W_BALL) != 0L + && (owornmask & (W_WEP|W_SWAPWEP|W_QUIVER)) != 0L) { + /* chained ball can be wielded/alt-wielded/quivered; if so, + pretend it's not chained in order to check the weapon pointer + (we've already verified the ball pointer by successfully passing + the if-condition to get here...) */ + owornmask &= ~W_BALL; + n = 1; } if (n > 1) { /* multiple bits set */ Sprintf(maskbuf, "worn mask (multiple) 0x%08lx", obj->owornmask); insane_object(obj, ofmt0, maskbuf, (struct monst *)0); } - if ((obj->owornmask & ~allmask) != 0L - || (carried(obj) && (obj->owornmask & W_SADDLE) != 0L)) { + if ((owornmask & ~allmask) != 0L + || (carried(obj) && (owornmask & W_SADDLE) != 0L)) { /* non-wearable bit(s) set */ Sprintf(maskbuf, "worn mask (bogus)) 0x%08lx", obj->owornmask); insane_object(obj, ofmt0, maskbuf, (struct monst *)0); } - if (n == 1 && (carried(obj) - || (obj->owornmask & (W_BALL|W_CHAIN)) != 0L)) { + if (n == 1 && (carried(obj) || (owornmask & (W_BALL|W_CHAIN)) != 0L)) { const char *what = 0; /* verify that obj in hero's invent (or ball/chain elsewhere) with owornmask of W_foo is the object pointed to by ufoo */ - switch (obj->owornmask) { - case W_ARM: if (obj != uarm) what = "armor"; /* suit */ + switch (owornmask) { + case W_ARM: if (obj != uarm) what = "suit"; break; case W_ARMC: if (obj != uarmc) what = "cloak"; break; @@ -2245,6 +2257,34 @@ struct obj *obj; Sprintf(maskbuf, "worn mask 0x%08lx != %s", obj->owornmask, what); insane_object(obj, ofmt0, maskbuf, (struct monst *)0); } + /* check for items worn in invalid slots; practically anything can + be wielded/alt-wielded/quivered, so skip obj if it's one of those */ + what = 0; + if (owornmask & W_ARMOR) { + if (obj->oclass != ARMOR_CLASS) what = "armor"; + } else if (owornmask & W_AMUL) { + if (obj->oclass != AMULET_CLASS) what = "amulet"; + } else if (owornmask & W_RING) { + if (obj->oclass != RING_CLASS && obj->otyp != MEAT_RING) + what = "ring"; + } else if (owornmask & W_TOOL) { + if (obj->otyp != BLINDFOLD && obj->otyp != TOWEL + && obj->otyp != LENSES) what = "blindfold"; + } else if (owornmask & W_BALL) { + if (obj->oclass != BALL_CLASS) what = "chained ball"; + } else if (owornmask & W_CHAIN) { + if (obj->oclass != CHAIN_CLASS) what = "chain"; + } + if (what) { + char oclassname[30]; + + /* if we've found a potion worn in the amulet slot, + this yields "worn (potion amulet)" */ + Strcpy(oclassname, def_oc_syms[(uchar)obj->oclass].name); + Sprintf(maskbuf, "worn (%s %s)", + makesingular(oclassname), what); + insane_object(obj, ofmt0, maskbuf, (struct monst *)0); + } } #else /* not (BETA || DEBUG) */ /* dummy use of obj to avoid "arg not used" complaint */