]> granicus.if.org Git - nethack/commitdiff
lost ball and chain (trunk only)
authornethack.allison <nethack.allison>
Sat, 3 Jun 2006 17:48:22 +0000 (17:48 +0000)
committernethack.allison <nethack.allison>
Sat, 3 Jun 2006 17:48:22 +0000 (17:48 +0000)
Saving the game while punished, not carrying the attached ball,
and while swallowed by a purple worm resulted in losing the
ball and chain.

Since the required information was not being written to the
save file at all, I couldn't come up with a clean way to do this
for the branch, and preserve save file format. I could think
of lots of kludgy ways to do it (insert ball and chain into
the hero's inventory prior to saving, and remove it on restore, etc.)

doc/fixes35.0
include/hack.h
include/patchlevel.h
src/restore.c
src/save.c

index 93494c9aef914b5d74411a0d65dbdf7df19e84eb..415f28efa9fa0e5cdfd508aded47eabb3379b7f9 100644 (file)
@@ -145,6 +145,8 @@ meditating monsters stop meditating when affected by something which wakes
 monsters capable of hiding can't do so when trapped or while holding you
 limit recursive calls to spoteffects (poly'd hero fell into water, reverted
        to human because of it, fell into same water, then crawled out twice)
+ensure that the punishment ball and chain make it into the save file after being
+       temporarily orphaned from the normal chains in the swallowing code
 
 
 Platform- and/or Interface-Specific Fixes
index 1e3b31e34d1dfd8bd73d645e7137f6a07ddf51c4..5078b0ae318faa65a98dd4c46f15a585b7f81f15 100644 (file)
@@ -305,6 +305,7 @@ NEARDATA extern coord bhitpos;      /* place where throw or zap hits or stops */
 /* Some misc definitions */
 #define POTION_OCCUPANT_CHANCE(n) (13 + 2*(n))
 #define WAND_BACKFIRE_CHANCE 100
+#define BALL_IN_MON    (u.uswallow && uball && uball->where == OBJ_FREE)
 
 /* Flags to control menus */
 #define MENUTYPELEN sizeof("traditional ")
index 92fc31d2a40050457f2d312197082f1405edd45e..f774eb2a56bd72dc422f53ea92aadca370ac024a 100644 (file)
@@ -13,7 +13,7 @@
  * Incrementing EDITLEVEL can be used to force invalidation of old bones
  * and save files.
  */
-#define EDITLEVEL      31
+#define EDITLEVEL      32
 
 #define COPYRIGHT_BANNER_A \
 "NetHack, Copyright 1985-2006"
index 8175ee9af88e4c35ceae842f8a6de39962a695d1..55f66a7c06bd104c980d8022b982958a7ad5ef78 100644 (file)
@@ -511,7 +511,7 @@ unsigned int *stuckid, *steedid;    /* STEED */
 {
        /* discover is actually flags.explore */
        boolean remember_discover = discover;
-       struct obj *otmp;
+       struct obj *otmp, *tmp_bc;
        int uid;
 
        mread(fd, (genericptr_t) &uid, sizeof uid);
@@ -563,6 +563,19 @@ unsigned int *stuckid, *steedid;   /* STEED */
 #ifndef GOLDOBJ
        put_gold_back(&invent, &u.ugold);
 #endif
+       /* tmp_bc only gets set here if the ball & chain were orphaned
+          because you were swallowed; otherwise they will be on the floor
+          or in your inventory */
+       tmp_bc = restobjchn(fd, FALSE, FALSE);
+       if (tmp_bc) {
+           for(otmp = tmp_bc; otmp; otmp = otmp->nobj) {
+               if(otmp->owornmask)
+                       setworn(otmp, otmp->owornmask);
+           }
+           if (!uball || !uchain)
+               impossible("restgamestate: lost ball & chain");
+       }
+
        migrating_objs = restobjchn(fd, FALSE, FALSE);
        migrating_mons = restmonchn(fd, FALSE);
        mread(fd, (genericptr_t) mvitals, sizeof(mvitals));
index 8c5437fe168a4e5c4fb9822e799e255f2d837eb2..6820b4699290afe81821eedccb3ef02d1f474c1b 100644 (file)
@@ -347,6 +347,13 @@ register int fd, mode;
        if (!release_data(mode))
                put_gold_back(&invent, &u.ugold);
 #endif
+       if (BALL_IN_MON) {
+               /* prevent loss of ball & chain when swallowed */
+               uball->nobj = uchain;
+               uchain->nobj = (struct obj *)0;
+               saveobjchn(fd, uball, mode);
+       }
+
        saveobjchn(fd, migrating_objs, mode);
        savemonchn(fd, migrating_mons, mode);
        if (release_data(mode)) {