[comp.sources.bugs] Nethack 2.2 level save bug

bch@ecsvax.UUCP (Byron C. Howes) (12/23/87)

While debugging a version of Nethack2.2 compiled with Turbo C I noted with
some dismay that my ghosts were reincarnated as demon lords when later
versions of myself encountered them.  As this terminated the game fairly
quickly I decided to figure out whether this was, indeed, a feature or
a bug.  I ran across this rather interesting section of code in
savemonchn() (file lev.c)
-------------------------------------------------------------------------
		if (permonstp == &li_dog)
			monsindex = mi = -1;	/* fake index */
		else if (permonstp == &dog)
			monsindex = --mi;	/* fake index */
		else if (permonstp == &la_dog)
			monsindex = --mi;	/* fake index */
#ifdef KAA
		else if (permonstp == &hell_hound)
			monsindex = --mi;	/* fake index */
# ifdef HARD
		else if (permonstp == &d_lord)
			monsindex = --mi;	/* fake index */

		else if (permonstp == &d_prince)
			monsindex = --mi;	/* fake index */
# endif
# ifdef KJSMODS
		else if (permonstp == &pm_guard)
			monsindex = -mi;	/* fake index */

		else if (permonstp == &pm_ghost)
			monsindex = -mi;	/* fake index */

		else if (permonstp == &pm_eel)
			monsindex = -mi;	/* fake index */
# endif
#endif
		else			
			monsindex = permonstp - &mons[0];
		*((int *)&mtmp->data) = monsindex;
		bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
		mtmp->data = permonstp;		/* restore the pointer */
------------------------------------------------------------------------------

Unless I'm entirely dim, I don't see how this code fragment works at all.
Other than the obvious omission of the autodecrement in the last three
references to mi,  mi is only autodecremented if a monster of the given
sort is found.  This leads to significant problems in restoring monsters
in restmonchn (in file save.c).  

My rather inelegant solution is to simply substitute the negative numbers
as literals in both functions.  (*sigh*)
-- 

  	  Byron Howes
usenet/bitnet address:  bch@ecsvax