Source:NetHack 3.0.0/polyself.c

Below is the full text to polyself.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/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	3.0	88/10/22 2.   /* Polymorph self routine. Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ 3.   /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   #ifdef POLYSELF 8.    9.    static void break_armor, drop_weapon; 10.  static void skinback; 11.  static void uunstick; 12.   13.   void 14.  polyself 15.  {  16.   	char buf[BUFSZ]; 17.  	int tmp, tmp2, mntmp = -1; 18.  	int tries=0; 19.  	boolean draconian = (uarm && uarm->otyp==DRAGON_SCALE_MAIL &&  20.   		uarm->corpsenm >= PM_GREY_DRAGON &&  21.   		uarm->corpsenm <= PM_YELLOW_DRAGON); 22.  	/* We have to calculate sticky in multiple places since we might go  23. * through any one of them without going through the others. 24.  	 */  25.   	boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow; 26.   27.   	if(!Polymorph_control && !draconian) { 28.  	    if (rn2(20) > ACURR(A_CON)) { 29.  		You("shudder for a moment."); 30.  		losehp(rn2(30),"system shock"); 31.  		return; 32.  	    }  33.   	}  34.    35.   	if (Polymorph_control) { 36.  		do { 37.  			pline("Become what kind of monster? [type the name] "); 38.  			getlin(buf); 39.  			mntmp = name_to_mon(buf); 40.  			if (mntmp < 0) 41.  				pline("I've never heard of such monsters."); 42.  			else if (!polyok(&mons[mntmp])) 43.  				You("cannot polymorph into that."); 44.  			else break; 45.  		} while(++tries < 5); 46.  		if (tries==5) pline(thats_enough_tries); 47.  	} else if (draconian) 48.  		mntmp = uarm->corpsenm; 49.   50.   	if (mntmp < 0) { 51.  		tries = 0; 52.  		do { 53.  			mntmp = rn2(PM_CHAMELEON); 54.  			/* All valid monsters are from 0 to PM_CHAMELEON-1 */ 55.  		} while(!polyok(&mons[mntmp]) && tries++ < 200); 56.  	}  57.    58.   	if (draconian && mntmp==uarm->corpsenm) { 59.  		if (!(mons[uarm->corpsenm].geno & G_GENOD)) { 60.  			You("merge with your scaly armor."); 61.  			uskin = uarm; 62.  			uarm = (struct obj *)0; 63.  		}  64.   	}  65.   	/* The below polyok should never fail unless just about everything 66.  	 * was genocided...  67. */ 68.   	if (!polyok(&mons[mntmp]) || !rn2(5)) { 69.  		if (!rn2(10)) { 70.  			flags.female = !flags.female; 71.  			max_rank_sz; 72.  			if (pl_character[0]=='P') 73.  				Strcpy(pl_character+6, flags.female?"ess":""); 74.  			if (pl_character[0]=='C') 75.  				Strcpy(pl_character+5,  76.   				flags.female ? "woman" : "man"); 77.  		}  78.   		if (u.umonnum != -1) { 79.  			u.acurr = u.macurr;	/* restore old attribs */ 80.  			u.amax = u.mamax; 81.  		}  82.   	    tmp = u.uhpmax; 83.  	    tmp2 = u.ulevel; 84.  	    u.usym = S_HUMAN; 85.  	    u.umonnum = -1; 86.  	    if (u.uundetected) u.uundetected = 0; 87.  	    prme; 88.  	    u.mtimedone = u.mh = u.mhmax = 0; 89.  	    u.ulevel = u.ulevel-2+rn2(5); 90.  	    if (u.ulevel > 127 || u.ulevel == 0) u.ulevel = 1; 91.  	    if (u.ulevel > MAXULEV) u.ulevel = MAXULEV; 92.   93.   	    for(tmp = u.ulevel; tmp != tmp2; tmp += (tmp2 < u.ulevel) ? -1 : 1) 94.  		adjabil((tmp2 > u.ulevel) ? -1 : 1); 95.  	    tmp = u.uhpmax; 96.   97.   	    /* random experience points for the new experience level */ 98.  	    u.uexp = rndexp; 99.  #ifndef LINT 100. 	    u.uhpmax = (u.uhpmax-10)*(long)u.ulevel/tmp2 + 19 - rn2(19); 101. #endif 102. /* If it was u.uhpmax*u.ulevel/tmp+9-rn2(19), then a 1st level character 103.    with 16 hp who polymorphed into a 3rd level one would have an average 104.    of 48 hp. */ 105.  #ifndef LINT 106. 	    u.uhp = u.uhp * (long)u.uhpmax/tmp; 107. #endif 108. #ifdef SPELLS 109. 	    tmp = u.uenmax; 110. #ifndef LINT 111. 	    u.uenmax = u.uenmax * (long)u.ulevel/tmp2 + 9 - rn2(19); 112. #endif 113. 	    if (u.uenmax < 0) u.uenmax = 0; 114. #ifndef LINT 115. 	    u.uen = (tmp ? u.uen * (long)u.uenmax / tmp : u.uenmax); 116. #endif 117. #endif 118. 	    (void)redist_attr; 119. 	    u.uhunger = rn1(500,500); 120. 	    Sick = 0; 121. 	    Stoned = 0; 122. 	    if (u.uhp <= 0 || u.uhpmax <= 0) { 123.  124.  		if(Polymorph_control) { 125. 		    if (u.uhp <= 0) u.uhp = 1; 126. 		    if (u.uhpmax <= 0) u.uhpmax = 1; 127. 		} else { 128. 		    Your("new form doesn't seem healthy enough to survive."); 129. 		    killer="unsuccessful polymorph"; 130. 		    done("died"); 131. 		}  132.  	    }  133.  	    set_uasmon; 134. 	    You("feel like a new %sman!", flags.female ? "wo" : ""); 135. #ifdef WIZARD 136. 	    if(!wizard) { 137. #endif 138. newname:	more; 139. 		do { 140. 		    pline("What is your new name? "); 141. 		    getlin(buf); 142. 		} while (buf[0]=='\033' || buf[0]==0); 143. 		if (!strcmp(plname,buf)) { 144. 		    pline("That is the same as your old name!"); 145. 		    goto newname; 146. 		}  147.  		(void)strncpy(plname, buf, sizeof(plname)-1); 148. 		Sprintf(SAVEF, "save/%d%s", getuid, plname); 149. 		regularize(SAVEF+5);		/* avoid. or / in name */ 150. #ifdef WIZARD 151. 	    }  152.  #endif 153. 	    flags.botl = 1; 154. 	    skinback; 155. 	    find_ac; 156. 	    if (sticky) uunstick; 157. 	} else if(!polymon(mntmp)) return; 158.  159.  	if (!uarmg) selftouch("No longer petrify-resistant, you"); 160. 	if (Inhell && !Fire_resistance) { 161. 	    You("burn to a crisp."); 162. 	    killer = "unwise polymorph"; 163. 	    done("burned"); 164. 	}  165.  }  166.   167.  int 168. polymon(mntmp)	/* returns 1 if polymorph successful */ 169. 	int	mntmp; 170. {  171.  	int	tmp; 172. 	boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow; 173.  174.  	if (mons[mntmp].geno & G_GENOD) { 175. 		You("feel rather %s-ish.",mons[mntmp].mname); 176. 		return(0); 177. 	}  178.   179.  	if (u.umonnum == -1) { 180. 		/* Human to monster; save human stats */ 181. 		u.macurr = u.acurr; 182. 		u.mamax = u.amax; 183. 	} else { 184. 		/* Monster to monster; restore human stats, to be  185. * immediately changed to provide stats for the new monster 186. 		 */  187.  		u.acurr = u.macurr; 188. 		u.amax = u.mamax; 189. 	}  190.  	u.umonnum = mntmp; 191. 	set_uasmon; 192. 	u.usym = mons[mntmp].mlet; 193. 	/* New stats for monster, to last only as long as polymorphed. 194. 	 * Currently only strength gets changed. 195. 	 */  196.  	if(strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = 118; 197.  198.  	if (resists_ston(uasmon) && Stoned) { /* parnes@eniac.seas.upenn.edu */ 199. 		Stoned = 0; 200. 		You("no longer seem to be petrifying."); 201. 	}  202.  	if (u.usym == S_FUNGUS && Sick) { 203. 		Sick = 0; 204. 		You("no longer feel sick."); 205. 	}  206.  	if (u.usym == S_DRAGON && mntmp >= PM_GREY_DRAGON) u.mhmax = 80; 207. #ifdef GOLEMS 208. 	else if (is_golem(uasmon)) u.mhmax = golemhp(mntmp); 209. #endif /* GOLEMS */ 210. 	else { 211.  212.  		/*  213.  		tmp = adj_lev(&mons[mntmp]); 214. 		 * We can't do this, since there's no such thing as an  215. * "experience level of you as a monster" for a polymorphed 216. 		 * character. 217. 		 */  218.  		tmp = mons[mntmp].mlevel; 219. 		if (!tmp) u.mhmax = rnd(4); 220. 		else u.mhmax = d(tmp, 8); 221. 	}  222.  	u.mh = u.mhmax; 223. 	You("turn into a%s %s!",  224.  		index(vowels, *(mons[mntmp].mname)) ? "n" : "",  225.  		mons[mntmp].mname); 226. 	if (uskin && mntmp != uskin->corpsenm) 227. 		skinback; 228. 	break_armor; 229. 	drop_weapon(1); 230. 	if (u.uundetected && !hides_under(uasmon)) u.uundetected = 0; 231. 	else if (hides_under(uasmon) && (levl[u.ux][u.uy].omask || 232. 			levl[u.ux][u.uy].gmask)) 233. 		u.uundetected = 1; 234. 	prme; 235. 	if (!sticky && !u.uswallow && u.ustuck && sticks(uasmon)) u.ustuck = 0; 236. 	else if (sticky && !sticks(uasmon)) uunstick; 237. 	u.mtimedone = 500 + rn2(500); 238. 	if (u.ulevel < mons[mntmp].mlevel) 239. 	/* Low level characters can't become high level monsters for long */ 240. 		u.mtimedone = u.mtimedone * u.ulevel / mons[mntmp].mlevel; 241. 	flags.botl = 1; 242. 	if (can_breathe(uasmon)) 243. 		pline("Use the command #monster for breath weapon."); 244. 	if (attacktype(uasmon, AT_SPIT)) 245. 		pline("Use the command #monster to spit venom."); 246. 	if (u.usym == S_NYMPH) 247. 		pline("Use the command #monster if you have to remove an iron ball."); 248. 	if (u.usym == S_UMBER) 249. 		pline("Use the command #monster to confuse monsters."); 250. 	if (is_hider(uasmon)) 251. 		pline("Use the command #monster to hide."); 252. 	if (is_were(uasmon)) 253. 		pline("Use the command #monster to summon help."); 254. 	if (webmaker(uasmon)) 255. 		pline("Use the command #monster to spin a web."); 256. 	if (lays_eggs(uasmon) || u.umonnum == PM_QUEEN_BEE) 257. 		pline("Use the command #sit to lay an egg."); 258. 	find_ac; 259. 	return(1); 260. }  261.   262.  static void 263. break_armor { 264.      struct obj *otmp; 265.  266.       if (breakarm(uasmon)) { 267. 	if (otmp = uarm) { 268. 		You("break out of your armor!"); 269. 		(void) Armor_gone; 270. 		useup(otmp); 271. 	}  272.  	if (otmp = uarmc) { 273. 		Your("cloak tears apart!"); 274. 		(void) Cloak_off; 275. 		useup(otmp); 276. 	}  277.  #ifdef SHIRT 278. 	if (uarmu) { 279. 		Your("shirt rips to shreds!"); 280. 		useup(uarmu); 281. 	}  282.  #endif 283.      } else if (sliparm(uasmon)) { 284. 	if (otmp = uarm) { 285. 		Your("armor falls around you!"); 286. 		(void) Armor_gone; 287. 		dropx(otmp); 288. 	}  289.  	if (otmp = uarmc) { 290. 		You("shrink out of your cloak!"); 291. 		(void) Cloak_off; 292. 		dropx(otmp); 293. 	}  294.  #ifdef SHIRT 295. 	if (otmp = uarmu) { 296. 		You("become much too small for your shirt!"); 297. 		setworn((struct obj *)0, otmp->owornmask & W_ARMU); 298. 		dropx(otmp); 299. 	}  300.  #endif 301.      }  302.       if (nohands(uasmon) || verysmall(uasmon)) { 303. 	  if (otmp = uarmg) { 304. 	       /* Drop weapon along with gloves */ 305. 	       You("drop your gloves%s!", uwep ? " and weapon" : ""); 306. 	       (void) Gloves_off; 307. 	       dropx(otmp); 308. 	       drop_weapon(0); 309. 	  }  310.  	  if (otmp = uarms) { 311. 	       You("can no longer hold your shield!"); 312. 	       (void) Shield_off; 313. 	       dropx(otmp); 314. 	  }  315.  	  if (otmp = uarmh) { 316. 	       Your("helmet falls to the floor!"); 317. 	       (void) Helmet_off; 318. 	       dropx(otmp); 319. 	  }  320.  	  if (otmp = uarmf) { 321. 	       Your("boots %s off your feet!",  322.  			verysmall(uasmon) ? "slide" : "get pushed"); 323. 	       (void) Boots_off; 324. 	       dropx(otmp); 325. 	  }  326.       }  327.  }  328.   329.  static void 330. drop_weapon(alone) 331. int alone; 332. {  333.       struct obj *otmp; 334.      if (otmp = uwep) { 335. 	  /* !alone check below is currently superfluous but in the 336. 	   * future it might not be so if there are monsters which cannot 337. 	   * wear gloves but can wield weapons 338. 	   */  339.  	  if (!alone || cantwield(uasmon)) { 340. 	       if (alone) You("find you must drop your weapon!"); 341. 	       uwepgone; 342. 	       dropx(otmp); 343. 	  }  344.       }  345.  }  346.   347.  void 348. rehumanize 349. {  350.  	boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow; 351.  352.  	u.mh = u.mhmax = u.mtimedone = 0; 353.  	u.acurr = u.macurr;		/* restore old strength */ 354.  	u.amax = u.mamax; 355. 	u.usym = S_HUMAN; 356. 	u.umonnum = -1; 357. 	skinback; 358. 	set_uasmon; 359. 	You("return to %sn form!",(pl_character[0]=='E')?"elve":"huma"); 360.  361.  	if (u.uhp < 1)	done("died"); 362. 	if (!Fire_resistance && Inhell) { 363. 	    You("burn to a crisp."); 364. 	    killer = "dissipating polymorph spell"; 365. 	   done("burned"); 366. 	}  367.  	if (!uarmg) selftouch("No longer petrify-resistant, you"); 368. 	if (sticky) uunstick; 369. 	nomul(0); 370. 	if (u.uundetected) u.uundetected = 0; 371. 	prme; 372. 	flags.botl = 1; 373. 	find_ac; 374. }  375.   376.  int 377. dobreathe { 378. 	if(!getdir(1)) return(0); 379. 	if (rn2(4)) 380. 	    You("produce a loud and noxious belch."); 381. 	else { 382. 	    register struct attack *mattk; 383. 	    register int i;  384. 385. 	    for(i = 0; i < NATTK; i++) { 386. 		mattk = &(uasmon->mattk[i]); 387. 		if(mattk->aatyp == AT_BREA) break; 388. 	    }  389.  	    buzz((int) (20 + mattk->adtyp-1), (int)mattk->damn,  390.  		u.ux, u.uy, u.dx, u.dy); 391. 	}  392.  	return(1); 393. }  394.   395.  int 396. dospit { 397. 	struct obj *otmp; 398.  399.  	if (!getdir(1)) return(0); 400. 	otmp = mksobj(u.umonnum==PM_COBRA ? BLINDING_VENOM : ACID_VENOM, FALSE); 401. 	(void) throwit(otmp); 402. 	return(1); 403. }  404.   405.  int 406. doremove { 407.      if (!Punished) { 408. 	  You("are not chained to anything!"); 409. 	  return(0); 410.      }  411.       unpunish; 412.      return(1); 413. }  414.   415.  int 416. dospinweb { 417. 	register struct trap *ttmp = t_at(u.ux,u.uy); 418.  419.  	if (Levitation) { 420. 		You("must be on the ground to spin a web."); 421. 		return(0); 422. 	}  423.  	if (u.uswallow) { 424. 		You("release web fluid inside %s.", mon_nam(u.ustuck)); 425. 		pline("%s regurgitates you!", Monnam(u.ustuck)); 426. 		u.ux = u.ustuck->mx; 427. 		u.uy = u.ustuck->my; 428. 		mnexto(u.ustuck); 429. 		u.uswallow = 0; 430. 		u.ustuck = 0; 431. 		setsee; 432. 		docrt; 433. 		return(1); 434. 	}  435.  	if (u.utrap) { 436. 		You("cannot spin webs while stuck in a trap."); 437. 		return(0); 438. 	}  439.  	if (ttmp) switch (ttmp->ttyp) { 440. 		case SPIKED_PIT: 441. 		case PIT: You("spin a web, covering up the pit."); 442. 			deltrap(ttmp); 443. 			if (Invisible) newsym(u.ux, u.uy); 444. 			return(1); 445. 		case WEB: You("make the web thicker."); 446. 			return(1); 447. 		case SQBRD: pline("The squeaky board is muffled."); 448. 			deltrap(ttmp); 449. 			if (Invisible) newsym(u.ux, u.uy); 450. 			return(1); 451. 		case TELEP_TRAP: 452. 		case LEVEL_TELEP: 453. 			Your("webbing vanishes!"); 454. 			return(0); 455. 		case TRAPDOOR: if (!is_maze_lev) { 456. 				You("web over the trapdoor."); 457. 				deltrap(ttmp); 458. 				if (Invisible) newsym(u.ux, u.uy); 459. 				return 1; 460. 			}  461.  			/* Fall through */ 462. 		case MGTRP: 463. 		case POLY_TRAP: 464. 		case DART_TRAP: 465. 		case ARROW_TRAP: 466. #ifdef SPELLS 467. 		case ANTI_MAGIC: 468. #endif 469. 		case LANDMINE: 470. 		case SLP_GAS_TRAP: 471. 		case BEAR_TRAP: 472. 		case RUST_TRAP: 473. 			You("have triggered a trap!"); 474. 			dotrap(ttmp); 475. 			return(1); 476. 		default: 477. 			impossible("Webbing over trap type %d?",ttmp->ttyp); 478. 			return(0); 479. 	}  480.  	ttmp = maketrap(u.ux, u.uy, WEB); 481. 	ttmp->tseen = 1; 482. 	if (Invisible) newsym(u.ux, u.uy); 483. 	return(1); 484. }  485.   486.  int 487. dosummon 488. {  489.  	You("call upon your brethren for help!"); 490. 	if (!were_summon(uasmon,TRUE)) 491. 		pline("But none arrive."); 492. 	return(1); 493. }  494.   495.  int 496. doconfuse 497. {  498.  	register struct monst *mtmp; 499. 	int looked = 0; 500.  501.  	if (Blind) { 502. 		You("can't see anything to gaze at."); 503. 		return 0; 504. 	}  505.  	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 506. 	    if (canseemon(mtmp)) { 507. 		looked = 1; 508. 		if (Invis && !perceives(mtmp->data)) 509. 		    pline("%s seems not to notice your gaze.", Monnam(mtmp)); 510. 		else if (mtmp->minvis && !See_invisible) 511. 		    You("can't see where to gaze at %s.", Monnam(mtmp)); 512. 		else if (mtmp->mimic) 513. 		    continue; 514. 		else if (flags.safe_dog && !Confusion && !Hallucination  515.  		  && (mtmp->data->mlet == S_DOG || mtmp->data->mlet == S_FELINE)  516.  		  && mtmp->mtame) { 517. 		    if (mtmp->mnamelth) 518. 			You("avoid gazing at %s.", NAME(mtmp)); 519. 		    else 520. 			You("avoid gazing at your %s.",  521.  						mtmp->data->mname); 522. 		} else { 523. 		    if (flags.confirm && mtmp->mpeaceful && !Confusion  524.  							&& !Hallucination) { 525. 			pline("Really confuse %s? ", mon_nam(mtmp)); 526. 			(void) fflush(stdout); 527. 			if (yn != 'y') continue; 528. 			setmangry(mtmp); 529. 		    }  530.  		    if (mtmp->mfroz || mtmp->mstun || mtmp->msleep ||  531.  							mtmp->mblinded) 532. 			continue; 533. 		    if (!mtmp->mconf) 534. 			Your("gaze confuses %s!", mon_nam(mtmp)); 535. 		    else 536. 			pline("%s is getting more and more confused.",  537.  							Monnam(mtmp)); 538. 		    mtmp->mconf = 1; 539. 		    if ((mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) { 540. 			You("are frozen by %s's gaze!", mon_nam(mtmp)); 541. 			nomul((u.ulevel > 6 || rn2(4)) ?  542.  				-d((int)mtmp->m_lev+1, 543. 					(int)mtmp->data->mattk[0].damd)  544.  				: -200); 545. 			return 1; 546. 		    }  547.  #ifdef MEDUSA 548. 		    if ((mtmp->data==&mons[PM_MEDUSA]) && !mtmp->mcan) { 549. 			pline("Gazing at an awake medusa is not a very good idea..."); 550. 			You("turn to stone..."); 551. 			done("stoned"); 552. 		    }  553.  #endif 554. 		}  555.  	    }  556.  	}  557.  	if (!looked) You("gaze at no place in particular."); 558. 	return 1; 559. }  560.   561.  int 562. dohide 563. {  564.  	if (u.uundetected || u.usym == S_MIMIC_DEF) { 565. 		pline("You are already hiding."); 566. 		return(0); 567. 	}  568.  	if (u.usym == S_MIMIC) { 569. 		u.usym = S_MIMIC_DEF; 570. 		prme; 571. 	} else { 572. 		newsym(u.ux,u.uy); 573. 		u.uundetected = 1; 574. 	}  575.  	return(1); 576. }  577.   578.  static void 579. uunstick 580. {  581.  	kludge("%s is no longer in your clutches...", Monnam(u.ustuck)); 582. 	u.ustuck = 0; 583. }  584.   585.  static void 586. skinback 587. {  588.  	if (uskin) { 589. 		Your("skin returns to its original form."); 590. 		uarm = uskin; 591. 		uskin = (struct obj *)0; 592. 	}	  593.  }  594.  #endif 595.  596.  char * 597. body_part(part) 598. {  599.  	/* Note: it is assumed these will never be >22 characters long, 600. 	 * plus the trailing null, after pluralizing (since sometimes a  601.  	 * buffer is made a fixed size and must be able to hold it) 602. 	 */  603.  	static const char *humanoid_parts[] = { "arm", "eye", "face", "finger", 604. 		"fingertip", "foot", "hand", "handed", "head", "leg", 605. 		"light headed", "neck", "toe" }; 606. #ifdef POLYSELF 607. 	static const char *jelly_parts[] = { "pseudopod", "dark spot", "front", 608. 		"pseudopod extension", "pseudopod extremity", 609. 		"pseudopod root", "grasp", "grasped", "cerebral area", 610. 		"lower pseudopod", "viscous", "middle", 611. 		"pseudopod extremity" }, 612. 	*animal_parts[] = { "forelimb", "eye", "face", "foreclaw", "claw tip", 613. 		"rear claw", "foreclaw", "clawed", "head", "rear limb", 614. 		"light headed", "neck", "rear claw tip" }, 615. 	*horse_parts[] = { "forelimb", "eye", "face", "forehoof", "hoof tip", 616. 		"rear hoof", "foreclaw", "hooved", "head", "rear limb", 617. 		"light headed", "neck", "rear hoof tip" }, 618. 	*sphere_parts[] = { "appendage", "optic nerve", "body", "tentacle", 619. 		"tentacle tip", "lower appendage", "tentacle", "tentacled", 620. 		"body", "lower tentacle", "rotational", "equator", 621. 		"lower tentacle tip" }, 622. 	*fungus_parts[] = { "mycelium", "visual area", "front", "hypha", 623. 		"hypha", "root", "strand", "stranded", "cap area", 624. 		"rhizome", "sporulated", "stalk", "rhizome tip" }, 625. 	*vortex_parts[] = { "region", "eye", "front", "minor current", 626. 		"minor current", "lower current", "swirl", "swirled", 627. 		"central core", "lower current", "addled", "center", 628. 		"edge" }, 629. 	*snake_parts[] = { "vestigal limb", "eye", "face", "large scale", 630. 		"large scale tip", "rear region", "scale gap", "scale gapped", 631. 		"head", "rear region", "light headed", "neck", "rear scale" }; 632. 	  633.  	if (humanoid(uasmon) || (u.usym==S_CENTAUR && 634. 		(part==ARM || part==FINGER || part==FINGERTIP  635.  		|| part==HAND || part==HANDED))) return humanoid_parts[part]; 636. 	if (u.usym==S_CENTAUR || u.usym==S_UNICORN) return horse_parts[part]; 637. 	if (u.usym==S_SNAKE || u.usym==S_NAGA || u.usym==S_WORM) 638. 		return snake_parts[part]; 639. 	if (u.usym==S_EYE) return sphere_parts[part]; 640. 	if (u.usym==S_JELLY || u.usym==S_PUDDING) return jelly_parts[part]; 641. 	if (u.usym==S_VORTEX || u.usym==S_ELEMENTAL) return vortex_parts[part]; 642. 	if (u.usym==S_FUNGUS) return fungus_parts[part]; 643. 	return animal_parts[part]; 644. #else 645. 	return humanoid_parts[part]; 646. #endif 647. }  648.   649.  int 650. poly_gender 651. {  652.  /* Returns gender of polymorphed player; 0/1=same meaning as flags.female, 653.  * 2=none. 654.  * Used in: 655.  *	- Seduction by succubus/incubus 656.  *	- Talking to nymphs (sounds.c)  657. * Not used in: 658.  *	- Messages given by nymphs stealing armor (they can't steal from  659.   *	  incubi/succubi/nymphs, and nonhumanoids can't wear armor). 660.  *	- Amulet of change (must refer to real gender no matter what  661.   *	  polymorphed into). 662.  *	- Priest/Priestess, Caveman/Cavewoman (ditto) 663.  *	- Polymorph self (only happens when human) 664.  *	- Shopkeeper messages (since referred to as "creature" and not "sir"  665.   *	  or "lady" when polymorphed) 666.  */  667.  #ifdef POLYSELF 668. 	if (uasmon->mflags1 & M1_FEM) return 1; 669. #ifdef HARD 670. 	if (u.umonnum==PM_INCUBUS) return 0; 671. #endif 672. 	if (!humanoid(uasmon)) return 2; 673. #endif 674. 	return flags.female; 675. }  676.   677.  #ifdef POLYSELF 678. #ifdef GOLEMS 679. void 680. ugolemeffects(damtype, dam) 681. int damtype; 682. {  683.  	int heal = 0; 684. 	/* We won't bother with "slow"/"haste" since players do not 685. 	 * have a monster-specific slow/haste so there is no way to  686. * restore the old velocity once they are back to human. 687. 	 */  688.  	if (u.umonnum != PM_FLESH_GOLEM && u.umonnum != PM_IRON_GOLEM) 689. 		return; 690. 	switch (damtype) { 691. 		case AD_ELEC: if (u.umonnum == PM_IRON_GOLEM) 692. 				heal = dam / 6; /* Approx 1 per die */ 693. 			break; 694. 		case AD_FIRE: if (u.umonnum == PM_IRON_GOLEM) 695. 				heal = dam; 696. 			break; 697. 	}  698.  	if (heal && (u.mh < u.mhmax)) { 699. 		u.mh += heal; 700. 		if (u.mh > u.mhmax) u.mh = u.mhmax; 701. 		flags.botl = 1; 702. 		pline("Strangely, you feel better than before."); 703. 	}  704.  }  705.  #endif /* GOLEMS */ 706. #endif