[comp.sources.games.bugs] NetHack 2.3 Polymorph bug fix

mike@genat.UUCP (Mike Stephenson) (07/26/88)

Here's a bug report I got over the weekend.  It's serious enough to warrent
posting right now, as opposed to just incorperating the fix into the 3.0
development:

   Hi Mike,
   Hope this gets through ok. I finally got around to fixing the problem with
   polymorph of multiple items causing core dumps. It was due to a very nasty
   interaction between two pieces of code.

   In 'bhit', there is a linked-list traversal to hit all objects at a given
   location. This was done with a for-loop. It worked OK for everything
   except polymorph, since every other routine left the object intact. However
   polymorph destroys the old object and makes a new one, and at least on the
   3B2, it also destroys the forward link pointer, which is then erroneously
   followed !

   Here's the modified code from 'bhit' in zap.c:
   
   --------------------------------- Cut Here ----------------------------------

                   /* modified by GAN to hit all objects */
                   if(fhito && o_at(bhitpos.x,bhitpos.y)){
                           int hitanything = 0;
                           otmp = fobj;
                           /* Fix for polymorph bug, Tim Wright */
                           while (otmp) {
                                   struct obj *next_obj;
                                   next_obj = otmp->nobj;
                                   if(otmp->ox == bhitpos.x &&
                                      otmp->oy == bhitpos.y)
                                           hitanything += (*fhito)(otmp, obj);
                                   otmp = next_obj;
                           }
   /* was this - it died due to horrible interaction with mkobj & polymorph !!
    *                      for(otmp = fobj; otmp; otmp = otmp->nobj)
    *                              if(otmp->ox == bhitpos.x &&
    *                                 otmp->oy == bhitpos.y)
    *                                      hitanything += (*fhito)(otmp, obj);
    */
                           if(hitanything) range--;
                   }
                   if(!ZAP_POS(typ)) {
   --------------------------------- Cut Here ----------------------------------
   
	This should be safe, since the creation of a new object inserts it
in the list prior to "fobj".  Thus anything polymorphed will be moved out of
the line of the search, and an "forever" loop circumstance will be avoided.

						Mike Stephenson

Mail:	Genamation Inc.		Phone:	(416) 475-9434
	351 Steelcase Rd. W
	Markham, Ontario.	UUCP:	uunet!mnetor!genat!mike
	Canada   L3R 3W1		    ...utzoo!genat!mike