diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index e9f7289bb..5a0d06e3c 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1311,6 +1311,7 @@ if a monster fled from hero by intentionally jumping into a vault teleporter, but the spot would remain a secret corridor and not become accessible spellbooks weight 50 units but Book of the Dead only 20, and novels only 1; the Book of the Dead has been changed to 50 and novels to 10 +save and restore hero tracks, increase track length Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index de4802bd8..f44a56487 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2919,6 +2919,9 @@ extern int tt_doppel(struct monst *); extern void initrack(void); extern void settrack(void); extern coord *gettrack(coordxy, coordxy); +extern void save_track(NHFILE *); +extern void rest_track(NHFILE *); +extern void printtrack(void); /* ### trap.c ### */ diff --git a/include/patchlevel.h b/include/patchlevel.h index 2ce8c4101..42ba716f6 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 90 +#define EDITLEVEL 91 /* * Development status possibilities. diff --git a/src/allmain.c b/src/allmain.c index c20175e3c..6f8c47856 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -77,6 +77,7 @@ moveloop_preamble(boolean resuming) /* give hero initial movement points; new game only--for restore, pending movement points were included in the save file */ u.umovement = NORMAL_SPEED; + initrack(); } gc.context.botlx = TRUE; /* for STATUS_HILITES */ if (resuming) { /* restoring old game */ @@ -89,7 +90,6 @@ moveloop_preamble(boolean resuming) gd.defer_see_monsters = FALSE; see_monsters(); } - initrack(); u.uz0.dlevel = u.uz.dlevel; gc.context.move = 0; diff --git a/src/do.c b/src/do.c index 4fad35dc4..dd963232a 100644 --- a/src/do.c +++ b/src/do.c @@ -1787,8 +1787,6 @@ goto_level( if ((mtmp = m_at(u.ux, u.uy)) != 0) u_collide_m(mtmp); - initrack(); - /* initial movement of bubbles just before vision_recalc */ if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) movebubbles(); diff --git a/src/restore.c b/src/restore.c index fe9034be6..109f1770e 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1150,6 +1150,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) rest_regions(nhfp); rest_bubbles(nhfp); /* for water and air; empty marker on other levels */ load_exclusions(nhfp); + rest_track(nhfp); if (ghostly) { stairway *stway = gs.stairs; diff --git a/src/save.c b/src/save.c index 7d04cb1fe..d8edaaae8 100644 --- a/src/save.c +++ b/src/save.c @@ -554,6 +554,7 @@ savelev_core(NHFILE *nhfp, xint8 lev) save_regions(nhfp); save_bubbles(nhfp, lev); /* for water and air */ save_exclusions(nhfp); + save_track(nhfp); if (nhfp->mode != FREEING) { if (nhfp->structlevel) diff --git a/src/teleport.c b/src/teleport.c index 5183db45b..f0d30fe29 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -502,7 +502,6 @@ teleds(coordxy nux, coordxy nuy, int teleds_flags) fill_pit(u.ux0, u.uy0); if (ball_active && uchain && uchain->where == OBJ_FREE) placebc(); /* put back the ball&chain if they were taken off map */ - initrack(); /* teleports mess up tracking monsters without this */ update_player_regions(); /* * Make sure the hero disappears from the old location. This will diff --git a/src/track.c b/src/track.c index b5ccd2d7f..20f0a9d8a 100644 --- a/src/track.c +++ b/src/track.c @@ -6,7 +6,7 @@ #include "hack.h" -#define UTSZ 50 +#define UTSZ 100 static NEARDATA int utcnt, utpnt; static NEARDATA coord utrack[UTSZ]; @@ -15,6 +15,7 @@ void initrack(void) { utcnt = utpnt = 0; + (void) memset((genericptr_t) &utrack, 0, sizeof(utrack)); } /* add to track */ @@ -30,6 +31,8 @@ settrack(void) utpnt++; } +/* get a track coord on or next to x,y and last tracked by hero, + returns null if no such track */ coord * gettrack(coordxy x, coordxy y) { @@ -43,20 +46,48 @@ gettrack(coordxy x, coordxy y) tc--; ndist = distmin(x, y, tc->x, tc->y); - /* if far away, skip track entries til we're closer */ - if (ndist > 2) { - ndist -= 2; /* be careful due to extra decrement at top of loop */ - cnt -= ndist; - if (cnt <= 0) - return (coord *) 0; /* too far away, no matches possible */ - if (tc < &utrack[ndist]) - tc += (UTSZ - ndist); - else - tc -= ndist; - } else if (ndist <= 1) + if (ndist <= 1) return (ndist ? tc : 0); } return (coord *) 0; } +/* save the hero tracking info */ +void +save_track(NHFILE *nhfp) +{ + if (perform_bwrite(nhfp)) { + if (nhfp->structlevel) { + int i; + + bwrite(nhfp->fd, (genericptr_t) &utcnt, sizeof utcnt); + bwrite(nhfp->fd, (genericptr_t) &utpnt, sizeof utpnt); + for (i = 0; i < utcnt; i++) { + bwrite(nhfp->fd, (genericptr_t) &utrack[i].x, sizeof utrack[i].x); + bwrite(nhfp->fd, (genericptr_t) &utrack[i].y, sizeof utrack[i].y); + } + } + } + if (release_data(nhfp)) + initrack(); +} + +/* restore the hero tracking info */ +void +rest_track(NHFILE *nhfp) +{ + if (nhfp->structlevel) { + int i; + + mread(nhfp->fd, (genericptr_t) &utcnt, sizeof utcnt); + mread(nhfp->fd, (genericptr_t) &utpnt, sizeof utpnt); + if (utcnt > UTSZ || utpnt > UTSZ) + panic("rest_track: impossible pt counts"); + for (i = 0; i < utcnt; i++) { + mread(nhfp->fd, (genericptr_t) &utrack[i].x, sizeof utrack[i].x); + mread(nhfp->fd, (genericptr_t) &utrack[i].y, sizeof utrack[i].y); + } + } +} + /*track.c*/