[net.games.hack] Bug in protection from shape changers

kneller@ucsfcgl.UUCP (Don Kneller%Langridge) (11/23/85)

There is a bug in the implementation of the ring of protection
from shape changers.  Currently, when you *put on* the ring,
any *already existing* chameleons will be no longer be able
to change form and will appear as ':'.  The bug is that the
the ring only takes effect at the instant you put it on and
only affects the existing chameleons.  New chameleons are
*unaffected* because there is no check to see if you are
wearing the ring.  Also, no check is made when you remove the
ring, so the previously affected chameleons will still be
unable to change form.

So, even if you are wearing the ring, you can die after being
swallowed by a chameleon looking like a lurker or trapper.

The fix is in three parts:
	1) When you remove the ring, chameleons can change again.
	2) When a chameleon is created, check if you are wearing
	   the ring and if so, the chameleon cannot change shapes.
	3) An optional 'fix' for being swallowed by a chameleon
	   which causes you to be regurgitated if you are inside a
	   monster that cannot swallow you.


1) Fixes for removing the ring of protection from shape changers.
   Also fixes a bug in polymorph concerning hiding monsters
   (polymorphing a 's' or 'S' to something else like a 'U' and
   the 'U' still being capable of hiding under objects).

*** hack.do_wear.orig	Fri Nov 22 16:19:15 1985
--- hack.do_wear.c	Tue Sep 10 23:16:09 1985
***************
*** 266,271
  	case RIN_INCREASE_DAMAGE:
  		u.udaminc -= obj->spe;
  		break;
  	}
  }
  

--- 266,277 -----
  	case RIN_INCREASE_DAMAGE:
  		u.udaminc -= obj->spe;
  		break;
+ 	case RIN_PROTECTION_FROM_SHAPE_CHANGERS:
+ 		/* If you're no longer protected, let the chameleons
+ 		 * change shape again - dgk
+ 		 */
+ 		restartcham();
+ 		break;
  	}
  }


*** hack.mon.orig	Fri Nov 22 16:18:19 1985
--- hack.mon.c		Sat Sep 14 23:24:48 1985
***************
*** 775,780
  		}
  }
  
  newcham(mtmp,mdat)	/* make a chameleon look like a new monster */
  			/* returns 1 if the monster actually changed */
  register struct monst *mtmp;

--- 775,789 -----
  		}
  }
  
+ restartcham()	/* Let the chameleons change again - dgk */
+ {
+ 	register struct monst *mtmp;
+ 
+ 	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ 		if (mtmp->data->mlet == ':') 
+ 			mtmp->cham = 1;
+ }
+ 
  newcham(mtmp,mdat)	/* make a chameleon look like a new monster */
  			/* returns 1 if the monster actually changed */
  register struct monst *mtmp;
***************
*** 796,801
  	hpn = mtmp->mhpmax;
  	mtmp->mhpmax = 2 + (hpn*mhp)/hpd;
  	mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0;
  #ifndef NOWORM
  	if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp);
  			/* perhaps we should clear mtmp->mtame here? */

--- 805,814 -----
  	hpn = mtmp->mhpmax;
  	mtmp->mhpmax = 2 + (hpn*mhp)/hpd;
  	mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0;
+ 	/* only 's' and 'S' can hide under other objects - dgk */
+ 	mtmp->mhide = (mdat->mlet == 's' || mdat->mlet == 'S') ? 1 : 0;
+ 	if (!mtmp->mhide)
+ 		mtmp->mundetected = 0;
  #ifndef NOWORM
  	if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp);
  			/* perhaps we should clear mtmp->mtame here? */


2) Fixes that check if you are wearing the ring of protection from shape
   changers and if so, the created chameleon cannot change shape.

*** hack.makemon.orig	Fri Nov 22 16:21:13 1985
--- hack.makemon.c	Tue Sep 10 23:13:39 1985
***************
*** 76,83
  			(void) mkobj_at(0, mtmp->mx, mtmp->my);
  	}
  	if(ptr->mlet == ':') {
! 		mtmp->cham = 1;
! 		(void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
  	}
  	if(ptr->mlet == 'I' || ptr->mlet == ';')
  		mtmp->minvis = 1;

--- 76,91 -----
  			(void) mkobj_at(0, mtmp->mx, mtmp->my);
  	}
  	if(ptr->mlet == ':') {
! 		/* If you're protected with a ring, don't create
! 		 * any shape-changing chameleons - dgk
! 		 */
! 		if (Protection_from_shape_changers)
! 			mtmp->cham = 0;
! 		else {
! 			mtmp->cham = 1;
! 			(void) newcham(mtmp,
! 					&mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
! 		}
  	}
  	if(ptr->mlet == 'I' || ptr->mlet == ';')
  		mtmp->minvis = 1;

3) Finally, an optional fix for changing the result when you are inside
   a monster that cannot swallow you.  Currently, you die instantly.
   With this change, you get regurgitated and the monster you were
   swallowed by appears beside you.  This change is optional because
   it is not a bug fix.

*** hack.mhitu.orig	Fri Nov 22 16:47:38 1985
--- hack.mhitu.c	Fri Nov 22 16:46:34 1985
***************
*** 43,50
  			break;
  		default:
  			/* This is not impossible! */
! 			pline("The mysterious monster totally digests you.");
! 			u.uhp = 0;
  		}
  		if(u.uhp < 1) done_in_by(mtmp);
  		return(0);

--- 43,58 -----
  			break;
  		default:
  			/* This is not impossible! */
! 			/* The new behavior - dgk */
! 			pline("You get regurgitated!");
! 			u.ux = mtmp->mx;
! 			u.uy = mtmp->my;
! 			u.uswallow = 0;
! 			u.ustuck = 0;
! 			mnexto(mtmp);
! 			setsee();
! 			docrt();
! 			break;
  		}
  		if(u.uhp < 1) done_in_by(mtmp);
  		return(0);
-- 
	Don Kneller
UUCP:	...ucbvax!ucsfcgl!kneller
ARPA:	kneller@ucsf-cgl.ARPA
BITNET:	kneller@ucsfcgl.BITNET