Source:NetHack 2.3e/polyself.c

Below is the full text to polyself.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/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.3	88/01/21 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 fire."); 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 %s out of your armor!",  144.  		   (uarm2 || uarm->otyp != ELVEN_CLOAK) ? "break" : "tear"); 145. #ifdef SHIRT 146. 	    if (uarmu) useup(uarmu); 147. #endif 148. 	    if (uarm2) useup(uarm2); 149. 	    useup(uarm); 150. 	} else	if (index("abcfghikpqrstvxyABEFJQS", turninto)) { 151. 		pline("Your armor falls around you!"); 152. 		if (otmp = uarm2) { 153. 		    setworn((struct obj *)0,otmp->owornmask & W_ARM2); 154. 		    dropx(otmp); 155. 		}  156.  		otmp = uarm; 157. 		setworn((struct obj *)0, otmp->owornmask & W_ARM); 158. 		dropx(otmp); 159. 	}  160.       }  161.  #ifdef SHIRT 162.      else if (uarmu) { 163. 		pline("The transformation causes you to tear out of your shirt!"); 164. 		if (uarmu) useup(uarmu); 165. 	}  166.  #endif 167.      if (!index("enozCGHIKLNOTUVWXYZ&',", turninto)) { 168. 	  if (otmp = uarmg) { 169. 	       pline("You drop your gloves!"); 170. 	       setworn((struct obj *)0, otmp->owornmask & W_ARMG); 171. 	       dropx(otmp); 172. 	       drop_weapon('a'); /* the 'a' is dummy to ensure dropping */ 173. 	  }  174.  	  if (otmp = uarms) { 175. 	       pline("You can no longer hold your shield!"); 176. 	       setworn((struct obj *)0, otmp->owornmask & W_ARMS); 177. 	       dropx(otmp); 178. 	  }  179.  	  if (otmp = uarmh) { 180. 	       pline("Your helmet falls to the floor!"); 181. 	       setworn((struct obj *)0, otmp->owornmask & W_ARMH); 182. 	       dropx(otmp); 183. 	  }  184.       }  185.  }  186.   187.  drop_weapon(turninto) 188. char turninto; 189. {  190.       struct obj *otmp; 191.      if (otmp = uwep) { 192. 	  if (cantwield(turninto)) { 193. 	       pline("You find you must drop your weapon!"); 194. 	       setuwep((struct obj *)0); 195. 	       dropx(otmp); 196. 	  }  197.       }  198.  }  199.   200.  cantwield(c)  /* creature type c cannot wield a weapon */ 201. char c;  202. { 203.       return(!!index("abcdfgjklpqrsuvxyABEFJPRS',",c)); 204. }  205.   206.  cantweararm(c)   /* creature type c cannot wear armor */ 207. char c;  208. { 209.       return(!index("@nGHIKLNOTVWZ&',",c)); 210. }  211.   212.  humanoid(c)   /* creature type c has hands */ 213. char c;  214. { 215.  	return(!!index("@ehintCGHIKLMNOQTVWZ&",c)); 216. }  217.   218.  rehumanize 219. {  220.  	u.mh = u.mhmax = u.mtimedone = 0; 221. 	u.ustr = u.mstr; 222. 	u.ustrmax = u.mstrmax; 223. 	u.usym = '@'; 224. 	prme; 225. 	pline("You return to %sn form!",(pl_character[0]=='E')?"elve":"huma"); 226.  227.  	if (u.uhp < 1)	done("died"); 228. 	if (!Fire_resistance && Inhell) { 229. 	    pline("You burn to a crisp."); 230. 	    killer = "dissipating polymorph spell"; 231. 	   done("died"); 232. 	}  233.  	flags.botl = 1; 234. 	find_ac; 235. }  236.   237.  dobreathe 238. {  239.       if (u.usym == 'D') { 240. 	  if(!getdir(1)) return(0); 241. 	  if (rn2(4)) 242. 	       pline("You exhale a bit of smoke."); 243. 	  else buzz(20, u.ux, u.uy, u.dx, u.dy); 244.      /* Changes must be made in zap.c to accommodate this. */ 245.       } else pline("You do not have the ability to breathe fire!"); 246.      return(1); 247. }  248.   249.  doremove 250. {  251.       if (!Punished) { 252. 	  pline("You do not have a ball attached to your leg!"); 253. 	  return(0); 254.      }  255.       if(u.usym != 'N') 256. 	  pline("You are not capable of removing a locked chain!"); 257.      else { 258. 	  Punished = 0; 259. 	  uchain->spe = 0; 260. 	  uball->spe = 0; 261. 	  uchain->owornmask &= ~W_CHAIN; 262. 	  uball->owornmask &= ~W_BALL; 263. 	  uchain = uball = (struct obj *)0; 264.      }  265.       return(1); 266. }  267.  #endif