]> granicus.if.org Git - nethack/commitdiff
owornmask sanity_check fix and enhancement
authorPatR <rankin@nethack.org>
Sun, 3 May 2015 23:57:09 +0000 (16:57 -0700)
committerPatR <rankin@nethack.org>
Sun, 3 May 2015 23:57:09 +0000 (16:57 -0700)
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.

src/mkobj.c

index 8995811280f1841f8d0c1f1f1f0de0290e7cbcb3..e8447ee2efc6438e44c6e76b873bb27c5823a0e0 100644 (file)
@@ -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) */