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.
This commit is contained in:
PatR
2022-02-25 07:10:30 -08:00
parent 2012254c39
commit ca97f4f3dd
3 changed files with 11 additions and 5 deletions

View 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)

View File

@@ -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;

View 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(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] */