]> granicus.if.org Git - nethack/commitdiff
object deletion bookkeeping
authornethack.rankin <nethack.rankin>
Thu, 22 Mar 2007 04:23:55 +0000 (04:23 +0000)
committernethack.rankin <nethack.rankin>
Thu, 22 Mar 2007 04:23:55 +0000 (04:23 +0000)
     After the apply-wielded-pie-to-blind-self (quite a while back) and
quivered-candle-burns-out (a week or two ago) bugs where object deletion
left dangling worn-object pointers, add a general check to try to catch
such things at the time of deletion.  Also, clear thrownobj and kickobj
pointers at the time corresponding object is deleted.  (This doesn't add
any checks for them becoming null during process of throwing or kicking,
where I'm not sure that the possibility of missile going away is being
adequately tracked).

src/dokick.c
src/shk.c

index 0c88a872fc84f734b7c82e8c8db1ac2678604444..fb54f478acb5c635830c3b4c7b2e9595842751e2 100644 (file)
@@ -11,6 +11,8 @@
 static NEARDATA struct rm *maploc, nowhere;
 static NEARDATA const char *gate_str;
 
+struct obj *kickobj;           /* also used by obfree(shk.c) */
+
 extern boolean notonhead;      /* for long worms */
 
 STATIC_DCL void FDECL(kickdmg, (struct monst *, BOOLEAN_P));
@@ -20,8 +22,6 @@ STATIC_DCL char *FDECL(kickstr, (char *));
 STATIC_DCL void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long));
 STATIC_DCL void FDECL(drop_to, (coord *,SCHAR_P));
 
-static NEARDATA struct obj *kickobj;
-
 static const char kick_passes_thru[] = "kick passes harmlessly through";
 
 STATIC_OVL void
index 07a9c2e75d052ee39c0dfcfbd746e41ea07a29c8..238e108b0e16d7abdf2325457c2bdc2a87d695eb 100644 (file)
--- a/src/shk.c
+++ b/src/shk.c
@@ -27,6 +27,7 @@ STATIC_DCL void FDECL(kops_gone, (BOOLEAN_P));
 
 extern const struct shclass shtypes[]; /* defined in shknam.c */
 extern struct obj *thrownobj;          /* defined in dothrow.c */
+extern struct obj *kickobj;            /* dokick.c */
 
 STATIC_VAR NEARDATA long int followmsg;        /* last time of follow message */
 STATIC_VAR const char and_its_contents[] = " and its contents";
@@ -279,6 +280,7 @@ register struct monst *shkp;
        clear_unpaid(fobj);
        clear_unpaid(level.buriedobjlist);
        if (thrownobj) thrownobj->unpaid = 0;
+       if (kickobj) kickobj->unpaid = 0;
        for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
                clear_unpaid(mtmp->minvent);
        for(mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
@@ -847,6 +849,16 @@ register struct obj *obj, *merge;
 #endif
                }
        }
+       if (obj->owornmask) {
+           impossible("obfree: deleting worn obj (%d: %ld)",
+                      obj->otyp, obj->owornmask);
+           /* unfortunately at this point we don't know whether worn mask
+              applied to hero or a monster or perhaps something bogus, so
+              can't call remove_worn_item() to get <X>_off() side-effects */
+           setnotworn(obj);
+       }
+       if (obj == thrownobj) thrownobj = 0;
+       if (obj == kickobj) kickobj = 0;
        dealloc_obj(obj);
 }