diff --git a/src/do.c b/src/do.c index 58e239ca8..726aa8c16 100644 --- a/src/do.c +++ b/src/do.c @@ -1138,6 +1138,9 @@ boolean at_stairs, falling, portal; struct monst *mtmp; char whynot[BUFSZ]; char *annotation; +#ifdef CONWAY + char need_late_reload_call = 0; +#endif if (dunlev(newlevel) > dunlevs_in_dungeon(newlevel)) newlevel->dlevel = dunlevs_in_dungeon(newlevel); @@ -1211,6 +1214,10 @@ boolean at_stairs, falling, portal; fd = currentlevel_rewrite(); if (fd < 0) return; +#ifdef DROPLEVEL + /* We're now committed to the level change. */ + if(dropleveltempsfn) (*dropleveltempsfn)(); +#endif if (falling) /* assuming this is only trap door or hole */ impact_drop((struct obj *) 0, u.ux, u.uy, newlevel->dlevel); @@ -1308,9 +1315,8 @@ boolean at_stairs, falling, portal; (void) nhclose(fd); oinit(); /* reassign level dependent obj probabilities */ #ifdef CONWAY - if(level.flags.conway){ - conway_restore(); - } + /* XXX move into DROPLEVEL framework? */ + need_late_reload_call = 1; #endif } reglyph_darkroom(); @@ -1554,6 +1560,15 @@ boolean at_stairs, falling, portal; #ifdef INSURANCE save_currentstate(); #endif +#ifdef CONWAY + if (need_late_reload_call){ + /* This MUST be after save_currenstate() to prevent freeing + * the state table we just allocated. */ + if(level.flags.conway){ + conway_restore(); + } + } +#endif if ((annotation = get_annotation(&u.uz)) != 0) You("remember this level as %s.", annotation); diff --git a/src/mkmaze.c b/src/mkmaze.c index 88536e1e3..b4155b349 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -7,6 +7,9 @@ #include "lev.h" /* save & restore info */ #define CONWAY_DEBUG +#ifdef CONWAY_DEBUG +static int conway_moved = 2; +#endif /* from sp_lev.c, for fixup_special() */ extern lev_region *lregions; @@ -1833,12 +1836,17 @@ static void conway_cleanup() { #ifdef CONWAY_DEBUG paniclog("trace","conway_cleanup()"); + if(!conway_moved){ + panic("conway cleanup with no moves"); + } #endif if (ls) { free(ls); + ls = NULL; } if (lslev) { free(lslev); + lslev = NULL; } DROPLEVEL_UNWIND(helddroplevel); } @@ -1847,6 +1855,7 @@ conway_cleanup() { void conway_restore() { #ifdef CONWAY_DEBUG + conway_moved = 0; paniclog("trace","conway_restore()"); #endif DROPLEVEL_WINDUP(conway_cleanup); @@ -1862,12 +1871,14 @@ conway_setup() { int subtype = rn2(3); char *force = nh_getenv("SPLEVTYPE2"); #ifdef CONWAY_DEBUG + if(conway_moved != 2) + impossible("moved != 2 in conway_setup"); paniclog("trace","conway_setup()"); #endif conway_restore(); - if (force) { - int tmp = atoi(force); - if (tmp>=0 && tmp <=2) + if (force && *force) { + int tmp = atoi(force); + if (tmp>=0 && tmp <=2) subtype = tmp; } switch(subtype) { @@ -1967,8 +1978,18 @@ void conway_update() { int x, y; +#ifdef CONWAY_DEBUG + conway_moved = 1; +#endif if (!lslev) +#ifdef CONWAY_DEBUG + { + impossible("DEBUG: conway update doing emergency recovery"); + conway_setup(); + } +#else panic("conway_update: lslev=null"); +#endif /* Be unpredictable: Life updates about half of the time, but not on alternate moves. */ diff --git a/src/save.c b/src/save.c index 5f6674b40..8426a2cee 100644 --- a/src/save.c +++ b/src/save.c @@ -545,9 +545,6 @@ skip_lots: save_regions(fd, mode); if (mode != FREE_SAVE) bflush(fd); -#ifdef DROPLEVEL - if(dropleveltempsfn) (*dropleveltempsfn)(); -#endif } STATIC_OVL void