Source:NetHack 2.2a/polyself.c

Below is the full text to polyself.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/polyself.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)polyself.c	2.2	87/11/29 2.   /* Polymorph self routine. Called in zap.c. Copyright 1987 by Ken Arromdee */ 3.    4.    #include "hack.h"  5. 6.   #ifdef KAA 7.    8.    extern char genocided[]; 9.   extern char pl_character[PL_CSIZ]; 10.  extern char plname[PL_NSIZ]; 11.   12.   extern long newuexp; 13.   14.   polyself 15.  {  16.   	char buf[BUFSZ]; 17.  	int tmp, tmp2, mntmp; 18.   19.   #ifdef BVH 20.  	if(!Polymorph_control) { 21.  #endif 22.  	    if (rn2(5)-3 > u.uluck) { 23.  		pline("You shudder for a moment."); 24.  		losehp(rn2(30),"system shock"); 25.  		return; 26.  	    }  27.   #ifdef BVH 28.  	} else { 29.  	    char buf[BUFSZ]; 30.  	    int i;  31. 32.  	    pline("Type the letter of the monster to become: "); 33.  	    getlin(buf); 34.  	    for(i=0; i<CMNUM; ++i) 35.  		if(mons[i].mlet == *buf) { 36.  		    mntmp = i;  37. goto gotone; 38.  		}  39.   	}  40.   #endif 41.  	mntmp = rn2(CMNUM); 42.  gotone: 43.  /* We want to disallow certain monsters, but also allow humans. */ 44.   	if (index("w:",mons[mntmp].mlet) || !rn2(5)) { 45.  	    if (!rn2(10)) flags.female = !flags.female; 46.  	    tmp = u.uhpmax; 47.  	    tmp2 = u.ulevel; 48.  	    u.usym = '@'; 49.  	    prme; 50.  	    u.mtimedone = u.mh = u.mhmax = 0; 51.  	    u.ulevel = u.ulevel-2+rn2(5); 52.  	    if (u.ulevel > 127 || u.ulevel == 0) u.ulevel = 1; 53.  	    if (u.ulevel > 14) u.ulevel = 14; 54.  	    if (u.ulevel == 1) u.uexp = rnd(10); 55.  	    else {  /* For the new experience level, random EXP. */ 56.  		u.ulevel--; 57.  		u.uexp = newuexp; 58.  		u.uexp += rn2(u.uexp); 59.  		u.ulevel++; 60.  	    }  61.   	    u.uhpmax = (u.uhpmax-10)*u.ulevel/tmp2 + 19 - rn2(19); 62.  /* If it was u.uhpmax*u.ulevel/tmp+9-rn2(19), then a 1st level character 63.     with 16 hp who polymorphed into a 3rd level one would have an average 64.     of 48 hp. */ 65.   	    u.uhp = u.uhp*u.uhpmax/tmp; 66.  	    tmp = u.ustrmax; 67.  	    u.ustrmax += (rn2(5)-2); 68.  	    if (u.ustrmax > 118) u.ustrmax = 118; 69.  	    if (u.ustrmax < 3) u.ustrmax = 3; 70.  	    u.ustr = u.ustr * u.ustrmax / tmp; 71.  	    if (u.ustr < 3) u.ustr = 3;  /* > 118 is impossible */ 72.  	    u.uhunger = 500 + rn2(500); 73.  	    Sick = 0; 74.  	    Stoned = 0; 75.  	    if (u.uhp <= 0 || u.uhpmax <= 0) { 76.  #ifdef BVH 77.  		if(Polymorph_control) { 78.  		    u.uhp = (u.uhp <= 0) ? 1 : u.uhp; 79.  		    u.uhpmax = (u.uhpmax <= 0) ? 1 : u.uhpmax; 80.  		} else { 81.  #endif 82.  		    killer="unsuccessful polymorph"; 83.  		    done("died"); 84.  #ifdef BVH 85.  		}  86.   #endif 87.  	    }  88.   	    pline("You feel like a new %sman!", flags.female ? "wo" : ""); 89.  newname:    more; 90.  	    do { 91.  		pline("What is your new name? "); 92.  		getlin(buf); 93.  	    } while (buf[0]=='\033' || buf[0]==0); 94.  	    if (!strcmp(plname,buf)) { 95.  		pline("That is the same as your old name!"); 96.  		goto newname; 97.  	    }  98.   	    (void)strncpy(plname, buf, sizeof(plname)-1); 99.  	    flags.botl = 1; 100. 	    find_ac; 101. 	} else { 102. 	    if (index(genocided,mons[mntmp].mlet)) { 103. 		pline("You feel rather %sish.",mons[mntmp].mname); 104. 		return; 105. 	    }  106.  	    if(u.usym == '@') { 107. 		u.mstr = u.ustr; 108. 		u.mstrmax = u.ustrmax; 109. 	    }  110.  	    u.umonnum = mntmp; 111. 	    u.usym = mons[mntmp].mlet; 112. 	    if(index("CDelmoPTUVXYz9", u.usym)) u.ustr = u.ustrmax = 118; 113. 	    if (u.usym == 'D') u.mhmax = 80; 114. 	    else if (!(mons[mntmp].mlevel)) u.mhmax = rnd(4); 115. 	    else u.mhmax = d(mons[mntmp].mlevel,8); 116. 	    u.mh = u.mhmax; 117. 	    pline("You turn into a%s %s!", index("aeioOU",u.usym) ? "n" : "",  118.  		  mons[mntmp].mname); 119. 	    break_armor(u.usym); 120. 	    drop_weapon(u.usym); 121. 	    prme; 122. 	    u.mtimedone = 500 + rn2(500); 123. 	    flags.botl = 1; 124. 	    if (u.usym == 'D') 125. 		pline("Use the command #breathe to breathe."); 126. 	    if (u.usym == 'N') 127. 		pline("Use the command #remove if you have to remove an iron ball."); 128. 	    find_ac; 129. 	}  130.  	if (Inhell && !Fire_resistance) { 131. 	    pline("You burn to a crisp."); 132. 	    killer = "unwise polymorph"; 133. 	    done("died"); 134. 	}  135.  }  136.   137.  break_armor(turninto) 138. char turninto; 139. {  140.       struct obj *otmp; 141.      if (uarm) { 142. 	  if (index("CDMPRUXYdejlouz,'9", turninto)) { 143. 	       pline("The transformation causes you to break out of your armor!"); 144. 	       if (uarm2) useup(uarm2); 145. 	       useup(uarm); 146. 	  } else if (index("abcfghikpqrstvxyABEFJQS", turninto)) { 147. 	       pline("Your armor falls around you!"); 148. 	       if (otmp = uarm2) { 149. 		    setworn((struct obj *)0,otmp->owornmask & W_ARM2); 150. 		    dropx(otmp); 151. 	       }  152.  	       otmp = uarm; 153. 	       setworn((struct obj *)0, otmp->owornmask & W_ARM); 154. 	       dropx(otmp); 155. 	  }  156.       }  157.       if (!index("enozCGHIKLNOTUVWXYZ&',", turninto)) { 158. 	  if (otmp = uarmg) { 159. 	       pline("You drop your gloves!"); 160. 	       setworn((struct obj *)0, otmp->owornmask & W_ARMG); 161. 	       dropx(otmp); 162. 	       drop_weapon('a'); /* the 'a' is dummy to ensure dropping */ 163. 	  }  164.  	  if (otmp = uarms) { 165. 	       pline("You can no longer hold your shield!"); 166. 	       setworn((struct obj *)0, otmp->owornmask & W_ARMS); 167. 	       dropx(otmp); 168. 	  }  169.  	  if (otmp = uarmh) { 170. 	       pline("Your helmet falls to the floor!"); 171. 	       setworn((struct obj *)0, otmp->owornmask & W_ARMH); 172. 	       dropx(otmp); 173. 	  }  174.       }  175.  }  176.   177.  drop_weapon(turninto) 178. char turninto; 179. {  180.       struct obj *otmp; 181.      if (otmp = uwep) { 182. 	  if (cantwield(turninto)) { 183. 	       pline("You find you must drop your weapon!"); 184. 	       setuwep((struct obj *)0); 185. 	       dropx(otmp); 186. 	  }  187.       }  188.  }  189.   190.  cantwield(c)  /* creature type c cannot wield a weapon */ 191. char c;  192. { 193.       return(!!index("abcdfgjklpqrsuvxyABEFJPRS',",c)); 194. }  195.   196.  cantweararm(c)   /* creature type c cannot wear armor */ 197. char c;  198. { 199.       return(!index("@nGHIKLNOTVWZ&',",c)); 200. }  201.   202.  rehumanize 203. {  204.  	u.mh = u.mhmax = u.mtimedone = 0; 205. 	u.ustr = u.mstr; 206. 	u.ustrmax = u.mstrmax; 207. 	u.usym = '@'; 208. 	prme; 209. 	pline("You return to %sn form!",(pl_character[0]=='E')?"elve":"huma"); 210.  211.  	if (u.uhp < 1)	done("died"); 212. 	if (!Fire_resistance && Inhell) { 213. 	    pline("You burn to a crisp."); 214. 	    killer = "dissipating polymorph spell"; 215. 	   done("died"); 216. 	}  217.  	flags.botl = 1; 218. 	find_ac; 219. }  220.   221.  dobreathe 222. {  223.       if (u.usym == 'D') { 224. 	  if(!getdir(1)) return(0); 225. 	  if (rn2(4)) 226. 	       pline("You exhale a bit of smoke."); 227. 	  else buzz(10, u.ux, u.uy, u.dx, u.dy); 228.      /* Changes must be made in zap.c to accommodate this. */ 229.       } else pline("You do not have the ability to breathe fire!"); 230.      return(1); 231. }  232.   233.  doremove 234. {  235.       if (!Punished) { 236. 	  pline("You do not have a ball attached to your leg!"); 237. 	  return(0); 238.      }  239.       if(u.usym != 'N') 240. 	  pline("You are not capable of removing a locked chain!"); 241.      else { 242. 	  Punished = 0; 243. 	  uchain->spe = 0; 244. 	  uball->spe = 0; 245. 	  uchain->owornmask &= ~W_CHAIN; 246. 	  uball->owornmask &= ~W_BALL; 247. 	  uchain = uball = (struct obj *)0; 248.      }  249.       return(1); 250. }  251.  #endif