owornmask sanity_check fix and enhancement
Thinko fix: sanity checking for owornmask was mis-treating OBJ_MIGRATING as OBJ_MINVENT of migrating monsters rather than as unattended objects and would have had problems similar to obfree's inappropriate impossible check. Sanity checking for objects worn in invalid slots (amulet worn in a ring slot and so forth) is extended to items worn by monsters. Also add a check for wielded coins since the loophole that let them become wielded has been closed.
This commit is contained in:
31
src/mkobj.c
31
src/mkobj.c
@@ -1,4 +1,4 @@
|
||||
/* 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 $NHDT-Date: 1430697424 2015/05/03 23:57:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.97 $ */
|
||||
/* 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. */
|
||||
@@ -2032,9 +2032,12 @@ const char *mesg;
|
||||
switch (obj->where) {
|
||||
case OBJ_INVENT:
|
||||
case OBJ_MINVENT:
|
||||
case OBJ_MIGRATING:
|
||||
sanity_check_worn(obj);
|
||||
break;
|
||||
case OBJ_MIGRATING:
|
||||
/* migrating objects overload the owornmask field
|
||||
with a destination code; skip attempt to check it */
|
||||
break;
|
||||
case OBJ_FLOOR:
|
||||
/* note: ball and chain can also be OBJ_FREE, but not across
|
||||
turns so this sanity check shouldn't encounter that */
|
||||
@@ -2180,6 +2183,7 @@ struct obj *obj;
|
||||
/* [W_ART,W_ARTI are property bits for items which aren't worn] */
|
||||
};
|
||||
char maskbuf[60];
|
||||
const char *what;
|
||||
unsigned long owornmask, allmask = 0L;
|
||||
int i, n = 0;
|
||||
|
||||
@@ -2212,8 +2216,7 @@ struct obj *obj;
|
||||
insane_object(obj, ofmt0, maskbuf, (struct monst *)0);
|
||||
}
|
||||
if (n == 1 && (carried(obj) || (owornmask & (W_BALL|W_CHAIN)) != 0L)) {
|
||||
const char *what = 0;
|
||||
|
||||
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 (owornmask) {
|
||||
@@ -2257,11 +2260,24 @@ struct obj *obj;
|
||||
Sprintf(maskbuf, "worn mask 0x%08lx != %s", obj->owornmask, what);
|
||||
insane_object(obj, ofmt0, maskbuf, (struct monst *)0);
|
||||
}
|
||||
}
|
||||
if (n == 1 && (carried(obj) || (owornmask & (W_BALL|W_CHAIN)) != 0L
|
||||
|| mcarried(obj))) {
|
||||
/* check for items worn in invalid slots; practically anything can
|
||||
be wielded/alt-wielded/quivered, so skip obj if it's one of those */
|
||||
be wielded/alt-wielded/quivered, so tests on those are limited */
|
||||
what = 0;
|
||||
if (owornmask & W_ARMOR) {
|
||||
if (obj->oclass != ARMOR_CLASS) what = "armor";
|
||||
} else if (owornmask & (W_WEP|W_SWAPWEP|W_QUIVER)) {
|
||||
/* monsters don't maintain alternate weapon or quiver */
|
||||
if (mcarried(obj) && (owornmask & (W_SWAPWEP|W_QUIVER)) != 0L)
|
||||
what = (owornmask & W_SWAPWEP) != 0L ? "monst alt weapon?"
|
||||
: "monst quiver?";
|
||||
/* hero can quiver gold but not wield it (hence not alt-wield
|
||||
it either); also catches monster wielding gold */
|
||||
else if (obj->oclass == COIN_CLASS
|
||||
&& (owornmask & (W_WEP|W_SWAPWEP)) != 0L)
|
||||
what = (owornmask & W_WEP) != 0L ? "weapon" : "alt weapon";
|
||||
} else if (owornmask & W_AMUL) {
|
||||
if (obj->oclass != AMULET_CLASS) what = "amulet";
|
||||
} else if (owornmask & W_RING) {
|
||||
@@ -2274,16 +2290,19 @@ struct obj *obj;
|
||||
if (obj->oclass != BALL_CLASS) what = "chained ball";
|
||||
} else if (owornmask & W_CHAIN) {
|
||||
if (obj->oclass != CHAIN_CLASS) what = "chain";
|
||||
} else if (owornmask & W_SADDLE) {
|
||||
if (obj->otyp != SADDLE) what = "saddle";
|
||||
}
|
||||
if (what) {
|
||||
char oclassname[30];
|
||||
struct monst *mon = mcarried(obj) ? obj->ocarry : 0;
|
||||
|
||||
/* 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);
|
||||
insane_object(obj, ofmt0, maskbuf, mon);
|
||||
}
|
||||
}
|
||||
#else /* not (BETA || DEBUG) */
|
||||
|
||||
Reference in New Issue
Block a user