]> granicus.if.org Git - nethack/commitdiff
more thrown object cleanup
authorPatR <rankin@nethack.org>
Fri, 25 Feb 2022 15:10:30 +0000 (07:10 -0800)
committerPatR <rankin@nethack.org>
Fri, 25 Feb 2022 15:10:30 +0000 (07:10 -0800)
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.

include/extern.h
src/end.c
src/save.c

index bfae9f194c4514e2b254ddd67e18489fd49aa996..c20a41f0ca5521fa35daf67c9a72010a30d23651 100644 (file)
@@ -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)
index d1a327a88034f81dc539bc7eb766b57c35c61746..cfebba812b30b65093b62606cbe3d06753425d30 100644 (file)
--- 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;
index fc5f81e21279c9f74eba3f5041c9cae2acc9eb68..cf3ee9116be921e91c41f6f8f6b462445e68ed30 100644 (file)
@@ -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(NHFILEnhfp, 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] */