sanity check owornmask
Extend the processing done by the wizard mode 'sanity_check' option to look for anomalies with obj->owornmask since there seem to have been a few lately. I haven't actually triggered any so this code isn't very well exercized yet. sanity_check uses pline() rather than impossible() or debugpline() to deliver messages so might not be very useful with keymasking. A sizeable chunk of this diff is just cleaning up indentation so that I could see what I was working with....
This commit is contained in:
+112
-1
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.5 mkobj.c $NHDT-Date: 1428715841 2015/04/11 01:30:41 $ $NHDT-Branch: master $:$NHDT-Revision: 1.91 $ */
|
/* 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 $Date: 2012/03/10 02:49:08 $ $Revision: 1.70 $ */
|
/* NetHack 3.5 mkobj.c $Date: 2012/03/10 02:49:08 $ $Revision: 1.70 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -16,6 +16,7 @@ STATIC_DCL const char *FDECL(where_name, (struct obj *));
|
|||||||
STATIC_DCL void FDECL(insane_object,
|
STATIC_DCL void FDECL(insane_object,
|
||||||
(struct obj *,const char *,const char *,struct monst *));
|
(struct obj *,const char *,const char *,struct monst *));
|
||||||
STATIC_DCL void FDECL(check_contained, (struct obj *,const char *));
|
STATIC_DCL void FDECL(check_contained, (struct obj *,const char *));
|
||||||
|
STATIC_DCL void FDECL(sanity_check_worn, (struct obj *));
|
||||||
|
|
||||||
struct icp {
|
struct icp {
|
||||||
int iprob; /* probability of an item type */
|
int iprob; /* probability of an item type */
|
||||||
@@ -2024,6 +2025,31 @@ const char *mesg;
|
|||||||
mesg, (struct monst *)0);
|
mesg, (struct monst *)0);
|
||||||
check_contained(obj, mesg);
|
check_contained(obj, mesg);
|
||||||
}
|
}
|
||||||
|
if (obj->owornmask) {
|
||||||
|
char maskbuf[40];
|
||||||
|
boolean bc_ok = FALSE;
|
||||||
|
|
||||||
|
switch (obj->where) {
|
||||||
|
case OBJ_INVENT:
|
||||||
|
case OBJ_MINVENT:
|
||||||
|
case OBJ_MIGRATING:
|
||||||
|
sanity_check_worn(obj);
|
||||||
|
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 */
|
||||||
|
bc_ok = TRUE;
|
||||||
|
/*FALLTHRU*/
|
||||||
|
default:
|
||||||
|
if ((obj != uchain && obj != uball) || !bc_ok) {
|
||||||
|
/* discovered an object not in inventory which
|
||||||
|
erroneously has worn mask set */
|
||||||
|
Sprintf(maskbuf, "worn mask 0x%08lx", obj->owornmask);
|
||||||
|
insane_object(obj, ofmt0, maskbuf, (struct monst *)0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2140,6 +2166,91 @@ check_contained(container, mesg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check an object in hero's or monster's inventory which has worn mask set */
|
||||||
|
STATIC_OVL void
|
||||||
|
sanity_check_worn(obj)
|
||||||
|
struct obj *obj;
|
||||||
|
{
|
||||||
|
#if defined(BETA) || defined(DEBUG)
|
||||||
|
static unsigned long wearbits[] = {
|
||||||
|
W_ARM, W_ARMC, W_ARMH, W_ARMS, W_ARMG, W_ARMF, W_ARMU,
|
||||||
|
W_WEP, W_QUIVER, W_SWAPWEP, W_AMUL, W_RINGL, W_RINGR,
|
||||||
|
W_TOOL, W_SADDLE, W_BALL, W_CHAIN,
|
||||||
|
0
|
||||||
|
/* [W_ART,W_ARTI are property bits for items which aren't worn] */
|
||||||
|
};
|
||||||
|
char maskbuf[60];
|
||||||
|
unsigned long allmask = 0L;
|
||||||
|
int i, n = 0;
|
||||||
|
|
||||||
|
for (i = 0; wearbits[i]; ++i) {
|
||||||
|
allmask |= wearbits[i];
|
||||||
|
if ((obj->owornmask & wearbits[i]) != 0L) ++n;
|
||||||
|
}
|
||||||
|
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)) {
|
||||||
|
/* 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)) {
|
||||||
|
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 */
|
||||||
|
break;
|
||||||
|
case W_ARMC: if (obj != uarmc) what = "cloak";
|
||||||
|
break;
|
||||||
|
case W_ARMH: if (obj != uarmh) what = "helm";
|
||||||
|
break;
|
||||||
|
case W_ARMS: if (obj != uarms) what = "shield";
|
||||||
|
break;
|
||||||
|
case W_ARMG: if (obj != uarmg) what = "gloves";
|
||||||
|
break;
|
||||||
|
case W_ARMF: if (obj != uarmf) what = "boots";
|
||||||
|
break;
|
||||||
|
case W_ARMU: if (obj != uarmu) what = "shirt";
|
||||||
|
break;
|
||||||
|
case W_WEP: if (obj != uwep) what = "primary weapon";
|
||||||
|
break;
|
||||||
|
case W_QUIVER: if (obj != uquiver) what = "quiver";
|
||||||
|
break;
|
||||||
|
case W_SWAPWEP: if (obj != uswapwep)
|
||||||
|
what = u.twoweap ? "secondary weapon" : "alternate weapon";
|
||||||
|
break;
|
||||||
|
case W_AMUL: if (obj != uamul) what = "amulet";
|
||||||
|
break;
|
||||||
|
case W_RINGL: if (obj != uleft) what = "left ring";
|
||||||
|
break;
|
||||||
|
case W_RINGR: if (obj != uright) what = "right ring";
|
||||||
|
break;
|
||||||
|
case W_TOOL: if (obj != ublindf) what = "blindfold";
|
||||||
|
break;
|
||||||
|
/* case W_SADDLE: */
|
||||||
|
case W_BALL: if (obj != uball) what = "ball";
|
||||||
|
break;
|
||||||
|
case W_CHAIN: if (obj != uchain) what = "chain";
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (what) {
|
||||||
|
Sprintf(maskbuf, "worn mask 0x%08lx != %s", obj->owornmask, what);
|
||||||
|
insane_object(obj, ofmt0, maskbuf, (struct monst *)0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* not (BETA || DEBUG) */
|
||||||
|
/* dummy use of obj to avoid "arg not used" complaint */
|
||||||
|
if (!obj) insane_object(obj, ofmt0, "<null>", (struct monst *)0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wrapper to make "near this object" convenient
|
* wrapper to make "near this object" convenient
|
||||||
|
|||||||
Reference in New Issue
Block a user