From: PatR Date: Fri, 25 Feb 2022 15:10:30 +0000 (-0800) Subject: more thrown object cleanup X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ca97f4f3dd082ecea4c5d5ff55fed654c73e2ec8;p=nethack more thrown object cleanup Handle thrown or kicked object that's in transit for hangup save and panic save in addition to normal end of game. Affects ball and chain placement too, if they've been temporarily taken off the map. --- diff --git a/include/extern.h b/include/extern.h index bfae9f194..c20a41f0c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -744,6 +744,7 @@ extern boolean Popeye(int); extern void done1(int); extern int done2(void); extern void done_in_by(struct monst *, int); +extern void done_object_cleanup(void); #endif /* !MAKEDEFS_C && MDLIB_C */ extern void panic(const char *, ...) PRINTF_F(1, 2) NORETURN; #if !defined(MAKEDEFS_C) && !defined(MDLIB_C) diff --git a/src/end.c b/src/end.c index d1a327a88..cfebba812 100644 --- a/src/end.c +++ b/src/end.c @@ -28,7 +28,6 @@ static void done_hangup(int); static void disclose(int, boolean); static void get_valuables(struct obj *); static void sort_valuables(struct valuable_data *, int); -static void done_object_cleanup(void); static void artifact_score(struct obj *, boolean, winid); static void really_done(int) NORETURN; static void savelife(int); @@ -1039,7 +1038,7 @@ odds_and_ends(struct obj *list, int what) #endif /* deal with some objects which may be in an abnormal state at end of game */ -static void +void done_object_cleanup(void) { int ox, oy; diff --git a/src/save.c b/src/save.c index fc5f81e21..cf3ee9116 100644 --- a/src/save.c +++ b/src/save.c @@ -92,6 +92,11 @@ dosave0(void) u.uinwater = 1, iflags.save_uinwater = 0; /* bypass set_uinwater() */ if (iflags.save_uburied) u.uburied = 1, iflags.save_uburied = 0; + /* extra handling for hangup save or panic save; without this, + a thrown light source might trigger an "obj_is_local" panic; + if a thrown or kicked object is in transit, put it on the map; + when punished, make sure ball and chain are placed too */ + done_object_cleanup(); /* maybe force some items onto map */ if (!g.program_state.something_worth_saving || !g.SAVEF[0]) goto done; @@ -451,7 +456,7 @@ savestateinlock(void) #endif void -savelev(NHFILE* nhfp, xchar lev) +savelev(NHFILE *nhfp, xchar lev) { #ifdef TOS short tlev; @@ -512,8 +517,7 @@ savelev(NHFILE* nhfp, xchar lev) if (nhfp->mode == FREEING) /* see above */ goto skip_lots; - savelevl(nhfp, - (boolean) ((sfsaveinfo.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP)); + savelevl(nhfp, ((sfsaveinfo.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP)); if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) g.lastseentyp, sizeof g.lastseentyp); bwrite(nhfp->fd, (genericptr_t) &g.moves, sizeof g.moves); @@ -1064,6 +1068,7 @@ free_dungeons(void) return; } +/* free a lot of allocated memory which is ordinarily freed during save */ void freedynamicdata(void) { @@ -1097,6 +1102,7 @@ freedynamicdata(void) dmonsfree(); /* release dead monsters */ /* level-specific data */ + done_object_cleanup(); /* maybe force some OBJ_FREE items onto map */ free_current_level(); /* game-state data [ought to reorganize savegamestate() to handle this] */