From d046be66bc587e8e2dd905a3f36241a540d9a785 Mon Sep 17 00:00:00 2001 From: "nethack.allison" Date: Sat, 3 Jun 2006 17:48:22 +0000 Subject: [PATCH] lost ball and chain (trunk only) 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 | 2 ++ include/hack.h | 1 + include/patchlevel.h | 2 +- src/restore.c | 15 ++++++++++++++- src/save.c | 7 +++++++ 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 93494c9ae..415f28efa 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -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 diff --git a/include/hack.h b/include/hack.h index 1e3b31e34..5078b0ae3 100644 --- a/include/hack.h +++ b/include/hack.h @@ -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 ") diff --git a/include/patchlevel.h b/include/patchlevel.h index 92fc31d2a..f774eb2a5 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -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" diff --git a/src/restore.c b/src/restore.c index 8175ee9af..55f66a7c0 100644 --- a/src/restore.c +++ b/src/restore.c @@ -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)); diff --git a/src/save.c b/src/save.c index 8c5437fe1..6820b4699 100644 --- a/src/save.c +++ b/src/save.c @@ -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)) { -- 2.40.0