Source:NetHack 3.2.0/polyself.c

Below is the full text to polyself.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.2	95/11/12	*/ 2.   /*	Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ 3.   /* NetHack may be freely redistributed. See license for details. */ 4.     5.    /*  6.     * Polymorph self routine. 7.    *  8.     * Note:  the light source handling code assumes that both youmonst.m_id 9.    * and youmonst.mx will always remain 0 when it handles the case of the 10.   * player polymorphed into a light-emitting monster. 11.   */  12.    13.   #include "hack.h"  14. 15.  #ifdef OVLB 16.  static void FDECL(polyman, (const char *,const char *)); 17.  static void NDECL(break_armor); 18.  static void FDECL(drop_weapon,(int)); 19.  static void NDECL(skinback); 20.  static void NDECL(uunstick); 21.  static int FDECL(armor_to_dragon,(int)); 22.   23.   /* update the "uasmon" structure */ 24.  void 25.  set_uasmon 26.  {  27.   	if (u.umonnum >= LOW_PM) { 28.  	    uasmon = &mons[u.umonnum]; 29.  	} else { 30.  	    uasmon = &playermon; 31.  #if 0 32.  	    /* We do not currently use uasmon or playermon to check the below 33.  	     * attributes of the player, and it is generally pointless to do  34. * so. Furthermore, we do not call set_uasmon often enough to 35. * use uasmon or playermon for this purpose; for instance, we do 36. * not call it every time we wear armor. 37.  	     */  38.   	    playermon.mlevel = u.ulevel; 39.  	    playermon.ac = u.uac; 40.  	    playermon.mr = (u.ulevel > 8) ? 5 * (u.ulevel - 7) : u.ulevel; 41.  #endif 42.  	}  43.   	set_mon_data(&youmonst, uasmon, 0); 44.  	return; 45.  }  46.    47.   /* make a (new) human out of the player */ 48.  static void 49.  polyman(fmt, arg) 50.  const char *fmt, *arg; 51.  {  52.   	boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow; 53.   54.   	if (u.umonnum != PM_PLAYERMON) { 55.  		u.acurr = u.macurr;	/* restore old attribs */ 56.  		u.amax = u.mamax; 57.  		u.umonnum = PM_PLAYERMON; 58.  		flags.female = u.mfemale; 59.  	}  60.   	u.usym = S_HUMAN; 61.  	set_uasmon; 62.   63.   	u.mh = u.mhmax = 0; 64.  	u.mtimedone = 0; 65.  	skinback; 66.  	u.uundetected = 0; 67.  	newsym(u.ux,u.uy); 68.   69.   	if (sticky) uunstick; 70.  	find_ac; 71.   72.   	You(fmt, arg); 73.  	/* check whether player foolishly genocided self while poly'd */ 74.  	if (mvitals[u.umonster].mvflags & G_GENOD) done(GENOCIDED); 75.   76.   	if(!Levitation && !u.ustuck &&  77.   	   (is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy))) 78.  		spoteffects; 79.  }  80.    81.   void 82.  change_sex 83.  {  84.   	flags.female = !flags.female; 85.  	max_rank_sz; 86.  	if (Role_is('P')) { 87.  		Strcpy(pl_character+6, flags.female ? "ess" : ""); 88.  		u.umonster = flags.female ? PM_PRIESTESS : PM_PRIEST; 89.  	} else if (Role_is('C')) { 90.  		Strcpy(pl_character+4, flags.female ? "woman" : "man"); 91.  		u.umonster = flags.female ? PM_CAVEWOMAN : PM_CAVEMAN; 92.  	}  93.   }  94.    95.   void 96.  newman 97.  {  98.   	int tmp, tmp2; 99.   100.  	if (!rn2(10)) change_sex; 101.  102.  	tmp = u.uhpmax; 103. 	tmp2 = u.ulevel; 104. 	u.ulevel = u.ulevel + rn1(5, -2); 105. 	if (u.ulevel > 127 || u.ulevel < 1) u.ulevel = 1; 106. 	if (u.ulevel > MAXULEV) u.ulevel = MAXULEV; 107.  108.  	adjabil(tmp2, (int)u.ulevel); 109. 	reset_rndmonst(NON_PM);	/* new monster generation criteria */ 110.  111.  	/* random experience points for the new experience level */ 112. 	u.uexp = rndexp; 113.  114.  	/* u.uhpmax * u.ulevel / tmp2: proportionate hit points to new level 115. 	 * -10 and +10: don't apply proportionate HP to 10 of a starting 116. 	 *   character's hit points (since a starting character's hit points  117.  	 *   are not on the same scale with hit points obtained through level  118.  	 *   gain) 119. 	 * 9 - rn2(19): random change of -9 to +9 hit points 120. 	 */  121.  #ifndef LINT 122. 	u.uhpmax = ((u.uhpmax - 10) * (long)u.ulevel / tmp2 + 10) + 123. 		(9 - rn2(19)); 124. #endif 125.  126.  #ifdef LINT 127. 	u.uhp = u.uhp + tmp; 128. #else 129. 	u.uhp = u.uhp * (long)u.uhpmax/tmp; 130. #endif 131.  132.  	tmp = u.uenmax; 133. #ifndef LINT 134. 	u.uenmax = u.uenmax * (long)u.ulevel / tmp2 + 9 - rn2(19); 135. #endif 136. 	if (u.uenmax < 0) u.uenmax = 0; 137. #ifndef LINT 138. 	u.uen = (tmp ? u.uen * (long)u.uenmax / tmp : u.uenmax); 139. #endif 140.  141.  	redist_attr; 142. 	u.uhunger = rn1(500,500); 143. 	newuhs(FALSE); 144. 	if (Sick) make_sick(0L, (char *) 0, FALSE, SICK_ALL); 145. 	Stoned = 0; 146. 	if (u.uhp <= 0 || u.uhpmax <= 0) { 147. 		if (Polymorph_control) { 148. 		    if (u.uhp <= 0) u.uhp = 1; 149. 		    if (u.uhpmax <= 0) u.uhpmax = 1; 150. 		} else { 151. 		    Your("new form doesn't seem healthy enough to survive."); 152. 		    killer_format = KILLED_BY_AN; 153. 		    killer="unsuccessful polymorph"; 154. 		    done(DIED); 155. 		}  156.  	}  157.  	polyman("feel like a new %s!",  158.  		Role_is('E') ? "elf" : flags.female ? "woman" : "man"); 159. 	flags.botl = 1; 160. 	(void) encumber_msg; 161. }  162.   163.  void 164. polyself 165. {  166.  	char buf[BUFSZ]; 167. 	int old_light, new_light; 168. 	int mntmp = NON_PM; 169. 	int tries=0; 170. 	boolean draconian = (uarm &&  171.  				uarm->otyp >= GRAY_DRAGON_SCALE_MAIL &&  172.  				uarm->otyp <= YELLOW_DRAGON_SCALES); 173.  174.  	boolean iswere = (u.ulycn >= LOW_PM || is_were(uasmon)); 175. 	boolean isvamp = (u.usym == S_VAMPIRE || u.umonnum == PM_VAMPIRE_BAT); 176.  177.  	if(!Polymorph_control && !draconian && !iswere && !isvamp) { 178. 	    if (rn2(20) > ACURR(A_CON)) { 179. 		You(shudder_for_moment); 180. 		losehp(rnd(30), "system shock", KILLED_BY_AN); 181. 		exercise(A_CON, FALSE); 182. 		return; 183. 	    }  184.  	}  185.  	old_light = (u.umonnum >= LOW_PM) ? emits_light(uasmon) : 0; 186.  187.  	if (Polymorph_control) { 188. 		do { 189. 			getlin("Become what kind of monster? [type the name]",  190.  				buf); 191. 			mntmp = name_to_mon(buf); 192. 			if (mntmp < LOW_PM) 193. 				pline("I've never heard of such monsters."); 194. 			/* Note:  humans are illegal as monsters, but an  195. * illegal monster forces newman, which is what we 196. * want if they specified a human.... */ 197.  			else if (!polyok(&mons[mntmp]) &&  198.  			    (Role_is('E') ? !is_elf(&mons[mntmp]) 199. 					  : !is_human(&mons[mntmp]))) 200. 				You("cannot polymorph into that."); 201. 			else break; 202. 		} while(++tries < 5); 203. 		if (tries==5) pline(thats_enough_tries); 204. 		/* allow skin merging, even when polymorph is controlled */ 205. 		if (draconian &&  206.  		    (mntmp == armor_to_dragon(uarm->otyp) || tries == 5)) 207. 		    goto do_merge; 208. 	} else if (draconian || iswere || isvamp) { 209. 		/* special changes that don't require polyok */ 210. 		if (draconian) { 211. 		    do_merge: 212. 			mntmp = armor_to_dragon(uarm->otyp); 213. 			if (!(mvitals[mntmp].mvflags & G_GENOD)) { 214. 				/* allow G_EXTINCT */ 215. 				You("merge with your scaly armor."); 216. 				uskin = uarm; 217. 				uarm = (struct obj *)0; 218. 				/* save/restore hack */ 219. 				uskin->owornmask |= I_SPECIAL; 220. 			}  221.  		} else if (iswere) { 222. 			if (is_were(uasmon)) 223. 				mntmp = PM_HUMAN; /* Illegal; force newman */ 224. 			else 225. 				mntmp = u.ulycn; 226. 		} else { 227. 			if (u.usym == S_VAMPIRE) 228. 				mntmp = PM_VAMPIRE_BAT; 229. 			else 230. 				mntmp = PM_VAMPIRE; 231. 		}  232.  		if (polymon(mntmp)) 233. 			goto made_change; 234. 	}  235.   236.  	if (mntmp < LOW_PM) { 237. 		tries = 0; 238. 		do { 239. 			/* randomly pick an "ordinary" monster */ 240. 			mntmp = rn1(SPECIAL_PM - LOW_PM, LOW_PM); 241. 		} while((!polyok(&mons[mntmp]) || is_placeholder(&mons[mntmp]))  242.  				&& tries++ < 200); 243. 	}  244.   245.  	/* The below polyok fails either if everything is genocided, or if  246. * we deliberately chose something illegal to force newman. 247. 	 */  248.  	if (!polyok(&mons[mntmp]) || !rn2(5)) 249. 		newman; 250. 	else if(!polymon(mntmp)) return; 251.  252.  	if (!uarmg) selftouch("No longer petrify-resistant, you"); 253.  254.   made_change: 255. 	new_light = (u.umonnum >= LOW_PM) ? emits_light(uasmon) : 0; 256. 	if (old_light != new_light) { 257. 	    if (old_light) 258. 		del_light_source(LS_MONSTER, (genericptr_t)&youmonst); 259. 	    if (new_light == 1) ++new_light;  /* otherwise it's undetectable */ 260. 	    if (new_light) 261. 		new_light_source(u.ux, u.uy, new_light,  262.  				 LS_MONSTER, (genericptr_t)&youmonst); 263. 	}  264.  }  265.   266.  /* (try to) make a mntmp monster out of the player */ 267. int 268. polymon(mntmp)	/* returns 1 if polymorph successful */ 269. int	mntmp; 270. {  271.  	boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow; 272. 	boolean dochange = FALSE; 273. 	int	tmp; 274.  275.  	if (mvitals[mntmp].mvflags & G_GENOD) {	/* allow G_EXTINCT */ 276. 		You_feel("rather %s-ish.",mons[mntmp].mname); 277. 		exercise(A_WIS, TRUE); 278. 		return(0); 279. 	}  280.   281.  	if (u.umonnum == PM_PLAYERMON) { 282. 		/* Human to monster; save human stats */ 283. 		u.macurr = u.acurr; 284. 		u.mamax = u.amax; 285. 		u.mfemale = flags.female; 286. 	} else { 287. 		/* Monster to monster; restore human stats, to be  288. * immediately changed to provide stats for the new monster 289. 		 */  290.  		u.acurr = u.macurr; 291. 		u.amax = u.mamax; 292. 		flags.female = u.mfemale; 293. 	}  294.   295.  	if (is_male(&mons[mntmp])) { 296. 		if(flags.female) dochange = TRUE; 297. 	} else if (is_female(&mons[mntmp])) { 298. 		if(!flags.female) dochange = TRUE; 299. 	} else if (!is_neuter(&mons[mntmp]) && mntmp != u.ulycn) { 300. 		if(!rn2(10)) dochange = TRUE; 301. 	}  302.  	if (dochange) { 303. 		flags.female = !flags.female; 304. 		You("%s %s %s!",  305.  		    (u.umonnum != mntmp) ? "turn into a" : "feel like a new",  306.  		    flags.female ? "female" : "male",  307.  		    mons[mntmp].mname); 308. 	} else { 309. 		if (u.umonnum != mntmp) 310. 			You("turn into %s!", an(mons[mntmp].mname)); 311. 		else 312. 			You_feel("like a new %s!", mons[mntmp].mname); 313. 	}  314.  	if (Stoned && poly_when_stoned(&mons[mntmp])) { 315. 		/* poly_when_stoned already checked stone golem genocide */ 316. 		You("turn to stone!"); 317. 		mntmp = PM_STONE_GOLEM; 318. 		Stoned = 0; 319. 	}  320.   321.  	u.umonnum = mntmp; 322. 	u.usym = mons[mntmp].mlet; 323. 	set_uasmon; 324.  325.  	/* New stats for monster, to last only as long as polymorphed. 326. 	 * Currently only strength gets changed. 327. 	 */  328.  	if(strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = 118; 329.  330.  	if (resists_ston(&youmonst) && Stoned) { /* parnes@eniac.seas.upenn.edu */ 331. 		Stoned = 0; 332. 		You("no longer seem to be petrifying."); 333. 	}  334.  	if (u.usym == S_FUNGUS && Sick) { 335. 		make_sick(0L, (char *) 0, FALSE, SICK_ALL); 336. 		You("no longer feel sick."); 337. 	}  338.  	if (nohands(uasmon)) Glib = 0; 339.  340.  	if (u.usym == S_DRAGON && mntmp >= PM_GRAY_DRAGON) 341. 		u.mhmax = 8 * mons[mntmp].mlevel; 342. 	else if (is_golem(uasmon)) u.mhmax = golemhp(mntmp); 343. 	else { 344. 		/*  345.  		tmp = adj_lev(&mons[mntmp]); 346. 		 * We can't do this, since there's no such thing as an  347. * "experience level of you as a monster" for a polymorphed 348. 		 * character. 349. 		 */  350.  		tmp = mons[mntmp].mlevel; 351. 		if (!tmp) u.mhmax = rnd(4); 352. 		else u.mhmax = d(tmp, 8); 353. 	}  354.  	u.mh = u.mhmax; 355.  356.  	u.mtimedone = rn1(500, 500); 357. 	if (u.ulevel < mons[mntmp].mlevel) 358. 	/* Low level characters can't become high level monsters for long */ 359. #ifdef DUMB 360. 		{  361.  		/* DRS/NS 2.2.6 messes up -- Peter Kendell */ 362. 			int	mtd = u.mtimedone, 363. 				ulv = u.ulevel, 364. 				mlv = mons[mntmp].mlevel; 365.  366.  			u.mtimedone = mtd * ulv / mlv; 367. 		}  368.  #else 369. 		u.mtimedone = u.mtimedone * u.ulevel / mons[mntmp].mlevel; 370. #endif 371.  372.  	if (uskin && mntmp != armor_to_dragon(uskin->otyp)) 373. 		skinback; 374. 	break_armor; 375. 	drop_weapon(1); 376. 	if (hides_under(uasmon)) 377. 		u.uundetected = OBJ_AT(u.ux, u.uy); 378. 	else if (uasmon->mlet == S_EEL) 379. 		u.uundetected = is_pool(u.ux, u.uy); 380. 	else 381. 		u.uundetected = 0; 382. 	newsym(u.ux,u.uy);		/* Change symbol */ 383.  384.  	if (!sticky && !u.uswallow && u.ustuck && sticks(uasmon)) u.ustuck = 0; 385. 	else if (sticky && !sticks(uasmon)) uunstick; 386.  387.  	if (flags.verbose) { 388. 	    static const char use_thec[] = "Use the command #%s to %s."; 389. 	    static const char monsterc[] = "monster"; 390. 	    if (can_breathe(uasmon)) 391. 		pline(use_thec,monsterc,"use your breath weapon"); 392. 	    if (attacktype(uasmon, AT_SPIT)) 393. 		pline(use_thec,monsterc,"spit venom"); 394. 	    if (u.usym == S_NYMPH) 395. 		pline(use_thec,monsterc,"remove an iron ball"); 396. 	    if (u.usym == S_UMBER) 397. 		pline(use_thec,monsterc,"confuse monsters"); 398. 	    if (is_hider(uasmon)) 399. 		pline(use_thec,monsterc,"hide"); 400. 	    if (is_were(uasmon)) 401. 		pline(use_thec,monsterc,"summon help"); 402. 	    if (webmaker(uasmon)) 403. 		pline(use_thec,monsterc,"spin a web"); 404. 	    if (u.umonnum == PM_GREMLIN) 405. 		pline(use_thec,monsterc,"multiply in a fountain"); 406. 	    if (u.usym == S_UNICORN) 407. 		pline(use_thec,monsterc,"use your horn"); 408. 	    if (u.umonnum == PM_MIND_FLAYER) 409. 		pline(use_thec,monsterc,"emit a mental blast"); 410. 	    if (uasmon->msound == MS_SHRIEK) /* worthless, actually */ 411. 		pline(use_thec,monsterc,"shriek"); 412. 	    if (lays_eggs(uasmon) && flags.female) 413. 		pline(use_thec,"sit","lay an egg"); 414. 	}  415.  	/* you now know what an egg of your type looks like */ 416. 	if (lays_eggs(uasmon)) { 417. 	    learn_egg_type(u.umonnum); 418. 	    /* make queen bees recognize killer bee eggs */ 419. 	    learn_egg_type(egg_type_from_parent(u.umonnum, TRUE)); 420. 	}  421.  	find_ac; 422. 	if((!Levitation && !u.ustuck && !is_flyer(uasmon) && 423. 	    (is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy))) ||  424.  	   (Underwater && !is_swimmer(uasmon))) 425. 	    spoteffects; 426. 	if (passes_walls(uasmon) && u.utrap && u.utraptype == TT_INFLOOR) { 427. 	    u.utrap = 0; 428. 	    pline_The("rock seems to no longer trap you."); 429. 	} else if (likes_lava(uasmon) && u.utrap && u.utraptype == TT_LAVA) { 430. 	    u.utrap = 0; 431. 	    pline_The("lava now feels soothing."); 432. 	}  433.  	if (amorphous(uasmon) || is_whirly(uasmon) || unsolid(uasmon)) { 434. 	    if (Punished) { 435. 		You("slip out of the iron chain."); 436. 		unpunish; 437. 	    }  438.  	}  439.  	if (u.utrap && (u.utraptype == TT_WEB || u.utraptype == TT_BEARTRAP) &&  440.  		(amorphous(uasmon) || is_whirly(uasmon) || unsolid(uasmon) || 441. 		  (uasmon->msize <= MZ_SMALL && u.utraptype == TT_BEARTRAP))) { 442. 	    You("are no longer stuck in the %s.",  443.  		    u.utraptype == TT_WEB ? "web" : "bear trap"); 444. 	    /* probably should burn webs too if PM_FIRE_ELEMENTAL */ 445. 	    u.utrap = 0; 446. 	}  447.  	if (uasmon->mlet == S_SPIDER && u.utrap && u.utraptype == TT_WEB) { 448. 	    You("orient yourself on the web."); 449. 	    u.utrap = 0; 450. 	}  451.  	flags.botl = 1; 452. 	vision_full_recalc = 1; 453. 	exercise(A_CON, FALSE); 454. 	exercise(A_WIS, TRUE); 455. 	(void) encumber_msg; 456. 	return(1); 457. }  458.   459.  static void 460. break_armor 461. {  462.      register struct obj *otmp; 463.  464.      if (breakarm(uasmon)) { 465. 	if ((otmp = uarm) != 0) { 466. 		if (donning(otmp)) cancel_don; 467. 		You("break out of your armor!"); 468. 		exercise(A_STR, FALSE); 469. 		(void) Armor_gone; 470. 		useup(otmp); 471. 	}  472.  	if ((otmp = uarmc) != 0) { 473. 	    if(otmp->oartifact) { 474. 		Your("cloak falls off!"); 475. 		(void) Cloak_off; 476. 		dropx(otmp); 477. 	    } else { 478. 		Your("cloak tears apart!"); 479. 		(void) Cloak_off; 480. 		useup(otmp); 481. 	    }  482.  	}  483.  #ifdef TOURIST 484. 	if (uarmu) { 485. 		Your("shirt rips to shreds!"); 486. 		useup(uarmu); 487. 	}  488.  #endif 489.     } else if (sliparm(uasmon)) { 490. 	if ((otmp = uarm) != 0) { 491. 		if (donning(otmp)) cancel_don; 492. 		Your("armor falls around you!"); 493. 		(void) Armor_gone; 494. 		dropx(otmp); 495. 	}  496.  	if ((otmp = uarmc) != 0) { 497. 		if (is_whirly(uasmon)) 498. 			Your("cloak falls, unsupported!"); 499. 		else You("shrink out of your cloak!"); 500. 		(void) Cloak_off; 501. 		dropx(otmp); 502. 	}  503.  #ifdef TOURIST 504. 	if ((otmp = uarmu) != 0) { 505. 		if (is_whirly(uasmon)) 506. 			You("seep right through your shirt!"); 507. 		else You("become much too small for your shirt!"); 508. 		setworn((struct obj *)0, otmp->owornmask & W_ARMU); 509. 		dropx(otmp); 510. 	}  511.  #endif 512.     }  513.      if (nohands(uasmon) || verysmall(uasmon)) { 514. 	if ((otmp = uarmg) != 0) { 515. 	    if (donning(otmp)) cancel_don; 516. 	    /* Drop weapon along with gloves */ 517. 	    You("drop your gloves%s!", uwep ? " and weapon" : ""); 518. 	    drop_weapon(0); 519. 	    (void) Gloves_off; 520. 	    dropx(otmp); 521. 	}  522.  	if ((otmp = uarms) != 0) { 523. 	    You("can no longer hold your shield!"); 524. 	    (void) Shield_off; 525. 	    dropx(otmp); 526. 	}  527.  	if ((otmp = uarmh) != 0) { 528. 	    if (donning(otmp)) cancel_don; 529. 	    Your("helmet falls to the %s!", surface(u.ux, u.uy)); 530. 	    (void) Helmet_off; 531. 	    dropx(otmp); 532. 	}  533.      }  534.      if (nohands(uasmon) || verysmall(uasmon) || slithy(uasmon) ||  535.  		u.usym == S_CENTAUR) { 536. 	if ((otmp = uarmf) != 0) { 537. 	    if (donning(otmp)) cancel_don; 538. 	    if (is_whirly(uasmon)) 539. 		Your("boots fall away!"); 540. 	    else Your("boots %s off your feet!",  541.  			verysmall(uasmon) ? "slide" : "are pushed"); 542. 	    (void) Boots_off; 543. 	    dropx(otmp); 544. 	}  545.      }  546.  }  547.   548.  static void 549. drop_weapon(alone) 550. int alone; 551. {  552.      struct obj *otmp; 553.     if ((otmp = uwep) != 0) { 554. 	/* !alone check below is currently superfluous but in the 555. 	 * future it might not be so if there are monsters which cannot 556. 	 * wear gloves but can wield weapons 557. 	 */  558.  	if (!alone || cantwield(uasmon)) { 559. 	    struct obj *wep = uwep; 560.  561.  	    if (alone) You("find you must drop your weapon!"); 562. 	    uwepgone; 563. 	    if (!wep->cursed || wep->otyp != LOADSTONE) 564. 		dropx(otmp); 565. 	}  566.      }  567.  }  568.   569.  void 570. rehumanize 571. {  572.  	if (emits_light(uasmon)) 573. 	    del_light_source(LS_MONSTER, (genericptr_t)&youmonst); 574. 	polyman("return to %s form!", Role_is('E') ? "elven" : "human"); 575.  576.  	if (u.uhp < 1)	done(DIED); 577. 	if (!uarmg) selftouch("No longer petrify-resistant, you"); 578. 	nomul(0); 579.  580.  	flags.botl = 1; 581. 	vision_full_recalc = 1; 582. 	(void) encumber_msg; 583. }  584.   585.  int 586. dobreathe { 587. 	if (Strangled) { 588. 	    You_cant("breathe.  Sorry."); 589. 	    return(0); 590. 	}  591.  	if (!getdir((char *)0)) return(0); 592. 	if (rn2(4)) 593. 	    You("produce a loud and noxious belch."); 594. 	else { 595. 	    register struct attack *mattk; 596. 	    register int i;  597. 598. 	    for(i = 0; i < NATTK; i++) { 599. 		mattk = &(uasmon->mattk[i]); 600. 		if(mattk->aatyp == AT_BREA) break; 601. 	    }  602.  	    buzz((int) (20 + mattk->adtyp-1), (int)mattk->damn,  603.  		u.ux, u.uy, u.dx, u.dy); 604. 	}  605.  	return(1); 606. }  607.   608.  int 609. dospit { 610. 	struct obj *otmp; 611.  612.  	if (!getdir((char *)0)) return(0); 613. 	otmp = mksobj(u.umonnum==PM_COBRA ? BLINDING_VENOM : ACID_VENOM,  614.  			TRUE, FALSE); 615. 	otmp->spe = 1; /* to indicate it's yours */ 616. 	throwit(otmp); 617. 	return(1); 618. }  619.   620.  int 621. doremove { 622. 	if (!Punished) { 623. 		You("are not chained to anything!"); 624. 		return(0); 625. 	}  626.  	unpunish; 627. 	return(1); 628. }  629.   630.  int 631. dospinweb 632. {  633.  	register struct trap *ttmp = t_at(u.ux,u.uy); 634.  635.  	if (Levitation || Is_airlevel(&u.uz)  636.  	    || Underwater || Is_waterlevel(&u.uz)) { 637. 		You("must be on the ground to spin a web."); 638. 		return(0); 639. 	}  640.  	if (u.uswallow) { 641. 		You("release web fluid inside %s.", mon_nam(u.ustuck)); 642. 		if (is_animal(u.ustuck->data)) { 643. 			expels(u.ustuck, u.ustuck->data, TRUE); 644. 			return(0); 645. 		}  646.  		if (is_whirly(u.ustuck->data)) { 647. 			int i;  648. 649. 			for (i = 0; i < NATTK; i++) 650. 				if (u.ustuck->data->mattk[i].aatyp == AT_ENGL) 651. 					break; 652. 			if (i == NATTK) 653. 			       impossible("Swallower has no engulfing attack?"); 654. 			else { 655. 				char sweep[30]; 656.  657.  				sweep[0] = '\0'; 658. 				switch(u.ustuck->data->mattk[i].adtyp) { 659. 					case AD_FIRE: 660. 						Strcpy(sweep, "ignites and "); 661. 						break; 662. 					case AD_ELEC: 663. 						Strcpy(sweep, "fries and "); 664. 						break; 665. 					case AD_COLD: 666. 						Strcpy(sweep,  667.  						      "freezes, shatters and "); 668. 						break; 669. 				}  670.  				pline_The("web %sis swept away!", sweep); 671. 			}  672.  			return(0); 673. 		}		     /* default: a nasty jelly-like creature */ 674. 		pline_The("web dissolves into %s.", mon_nam(u.ustuck)); 675. 		return(0); 676. 	}  677.  	if (u.utrap) { 678. 		You("cannot spin webs while stuck in a trap."); 679. 		return(0); 680. 	}  681.  	exercise(A_DEX, TRUE); 682. 	if (ttmp) switch (ttmp->ttyp) { 683. 		case PIT: 684. 		case SPIKED_PIT: You("spin a web, covering up the pit."); 685. 			deltrap(ttmp); 686. 			bury_objs(u.ux, u.uy); 687. 			if (Invisible) newsym(u.ux, u.uy); 688. 			return(1); 689. 		case SQKY_BOARD: pline_The("squeaky board is muffled."); 690. 			deltrap(ttmp); 691. 			if (Invisible) newsym(u.ux, u.uy); 692. 			return(1); 693. 		case TELEP_TRAP: 694. 		case LEVEL_TELEP: 695. 		case MAGIC_PORTAL: 696. 			Your("webbing vanishes!"); 697. 			return(0); 698. 		case WEB: You("make the web thicker."); 699. 			return(1); 700. 		case HOLE: 701. 		case TRAPDOOR: 702. 			You("web over the %s.",  703.  			    (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole"); 704. 			deltrap(ttmp); 705. 			if (Invisible) newsym(u.ux, u.uy); 706. 			return 1; 707. 		case ARROW_TRAP: 708. 		case DART_TRAP: 709. 		case BEAR_TRAP: 710. 		case LANDMINE: 711. 		case SLP_GAS_TRAP: 712. 		case RUST_TRAP: 713. 		case MAGIC_TRAP: 714. 		case ANTI_MAGIC: 715. 		case POLY_TRAP: 716. 			You("have triggered a trap!"); 717. 			dotrap(ttmp); 718. 			return(1); 719. 		default: 720. 			impossible("Webbing over trap type %d?", ttmp->ttyp); 721. 			return(0); 722. 	}  723.  	ttmp = maketrap(u.ux, u.uy, WEB); 724. 	if (ttmp) { 725. 		ttmp->tseen = 1; 726. 		ttmp->madeby_u = 1; 727. 	}  728.  	if (Invisible) newsym(u.ux, u.uy); 729. 	return(1); 730. }  731.   732.  int 733. dosummon 734. {  735.  	You("call upon your brethren for help!"); 736. 	exercise(A_WIS, TRUE); 737. 	if (!were_summon(uasmon,TRUE)) 738. 		pline("But none arrive."); 739. 	return(1); 740. }  741.   742.  int 743. doconfuse 744. {  745.  	register struct monst *mtmp; 746. 	int looked = 0; 747. 	char qbuf[QBUFSZ]; 748.  749.  	if (Blind) { 750. 		You_cant("see anything to gaze at."); 751. 		return 0; 752. 	}  753.  	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 754. 	    if (canseemon(mtmp)) { 755. 		looked++; 756. 		if (Invis && !perceives(mtmp->data)) 757. 		    pline("%s seems not to notice your gaze.", Monnam(mtmp)); 758. 		else if (mtmp->minvis && !See_invisible) 759. 		    You_cant("see where to gaze at %s.", Monnam(mtmp)); 760. 		else if (mtmp->m_ap_type == M_AP_FURNITURE  761.  			|| mtmp->m_ap_type == M_AP_OBJECT) { 762. 		    looked--; 763. 		    continue; 764. 		} else if (flags.safe_dog && !Confusion && !Hallucination  765.  		  && mtmp->mtame) { 766. 		    if (mtmp->mnamelth) 767. 			You("avoid gazing at %s.", NAME(mtmp)); 768. 		    else 769. 			You("avoid gazing at your %s.",  770.  						mtmp->data->mname); 771. 		} else { 772. 		    if (flags.confirm && mtmp->mpeaceful && !Confusion  773.  							&& !Hallucination) { 774. 			Sprintf(qbuf, "Really confuse %s?", mon_nam(mtmp)); 775. 			if (yn(qbuf) != 'y') continue; 776. 			setmangry(mtmp); 777. 		    }  778.  		    if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleep ||  779.  				    !mtmp->mcansee || !haseyes(mtmp->data)) { 780. 			looked--; 781. 			continue; 782. 		    }  783.  		    if (!mon_reflects(mtmp,"Your gaze is reflected by %s %s.")){ 784. 			if (!mtmp->mconf) 785. 			    Your("gaze confuses %s!", mon_nam(mtmp)); 786. 			else 787. 			    pline("%s is getting more and more confused.",  788.  							    Monnam(mtmp)); 789. 			mtmp->mconf = 1; 790. 		    }  791.  		    if ((mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) { 792. 			You("are frozen by %s gaze!",  793.  			                 s_suffix(mon_nam(mtmp))); 794. 			nomul((u.ulevel > 6 || rn2(4)) ?  795.  				-d((int)mtmp->m_lev+1, 796. 					(int)mtmp->data->mattk[0].damd)  797.  				: -200); 798. 			return 1; 799. 		    }  800.  		    if ((mtmp->data==&mons[PM_MEDUSA]) && !mtmp->mcan) { 801. 			pline("Gazing at the awake Medusa is not a very good idea."); 802. 			/* as if gazing at a sleeping anything is fruitful... */ 803.  			You("turn to stone..."); 804. 			done(STONING); 805. 		    }  806.  		}  807.  	    }  808.  	}  809.  	if (!looked) You("gaze at no place in particular."); 810. 	return 1; 811. }  812.   813.  int 814. dohide 815. {  816.  	if (u.uundetected || u.usym == S_MIMIC_DEF) { 817. 		You("are already hiding."); 818. 		return(0); 819. 	}  820.  	if (u.usym == S_MIMIC) { 821. 		u.usym = S_MIMIC_DEF; 822. 	} else { 823. 		u.uundetected = 1; 824. 	}  825.  	newsym(u.ux,u.uy); 826. 	return(1); 827. }  828.   829.  int 830. domindblast 831. {  832.  	struct monst *mtmp, *nmon; 833.  834.  	You("concentrate."); 835. 	if (rn2(3)) return 0; 836. 	pline("A wave of psychic energy pours out."); 837. 	for(mtmp=fmon; mtmp; mtmp = nmon) { 838. 		int u_sen; 839.  840.  		nmon = mtmp->nmon; 841. 		if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM) 842. 			continue; 843. 		if(mtmp->mpeaceful) 844. 			continue; 845. 		u_sen = telepathic(mtmp->data) && !mtmp->mcansee; 846. 		if (u_sen || (telepathic(mtmp->data) && rn2(2)) || !rn2(10)) { 847. 			You("lock in on %s %s.", s_suffix(mon_nam(mtmp)),  848.  				u_sen ? "telepathy" :  849.  				telepathic(mtmp->data) ? "latent telepathy" :  850.  				"mind"); 851. 			mtmp->mhp -= rnd(15); 852. 			if (mtmp->mhp <= 0) 853. 				killed(mtmp); 854. 		}  855.  	}  856.  	return 1; 857. }  858.   859.  static void 860. uunstick 861. {  862.  	pline("%s is no longer in your clutches.", Monnam(u.ustuck)); 863. 	u.ustuck = 0; 864. }  865.   866.  static void 867. skinback 868. {  869.  	if (uskin) { 870. 		Your("skin returns to its original form."); 871. 		uarm = uskin; 872. 		uskin = (struct obj *)0; 873. 		/* undo save/restore hack */ 874. 		uarm->owornmask &= ~I_SPECIAL; 875. 	}  876.  }  877.   878.  #endif /* OVLB */ 879. #ifdef OVL1 880. const char * 881. body_part(part) 882. int part; 883. {  884.  	static NEARDATA const char 885. 	*humanoid_parts[] = { "arm", "eye", "face", "finger", 886. 		"fingertip", "foot", "hand", "handed", "head", "leg", 887. 		"light headed", "neck", "spine", "toe", "hair" }, 888. 	*jelly_parts[] = { "pseudopod", "dark spot", "front", 889. 		"pseudopod extension", "pseudopod extremity", 890. 		"pseudopod root", "grasp", "grasped", "cerebral area", 891. 		"lower pseudopod", "viscous", "middle", "surface", 892. 		"pseudopod extremity", "ripples" }, 893. 	*animal_parts[] = { "forelimb", "eye", "face", "foreclaw", "claw tip", 894. 		"rear claw", "foreclaw", "clawed", "head", "rear limb", 895. 		"light headed", "neck", "spine", "rear claw tip", "fur" }, 896. 	*horse_parts[] = { "forelimb", "eye", "face", "forehoof", "hoof tip", 897. 		"rear hoof", "foreclaw", "hooved", "head", "rear limb", 898. 		"light headed", "neck", "backbone", "rear hoof tip", "mane" }, 899. 	*sphere_parts[] = { "appendage", "optic nerve", "body", "tentacle", 900. 		"tentacle tip", "lower appendage", "tentacle", "tentacled", 901. 		"body", "lower tentacle", "rotational", "equator", "body", 902. 		"lower tentacle tip", "cilia" }, 903. 	*fungus_parts[] = { "mycelium", "visual area", "front", "hypha", 904. 		"hypha", "root", "strand", "stranded", "cap area", 905. 		"rhizome", "sporulated", "stalk", "root", "rhizome tip", 906. 		"spores" }, 907. 	*vortex_parts[] = { "region", "eye", "front", "minor current", 908. 		"minor current", "lower current", "swirl", "swirled", 909. 		"central core", "lower current", "addled", "center", 910. 		"currents", "edge", "currents" }, 911. 	*snake_parts[] = { "vestigial limb", "eye", "face", "large scale", 912. 		"large scale tip", "rear region", "scale gap", "scale gapped", 913. 		"head", "rear region", "light headed", "neck", "length", 914. 		"rear scale", "scales" }; 915. 	/* claw attacks are overloaded in mons[]; most humanoids with 916. 	   such attacks should still reference hands rather than claws */ 917. 	static const char not_claws[] = { 918. 		S_HUMAN, S_MUMMY, S_ZOMBIE, S_ANGEL, 919. 		S_NYMPH, S_LEPRECHAUN, S_QUANTMECH, S_VAMPIRE, 920. 		S_ORC, S_GIANT,		/* quest nemeses */ 921. 		'\0'		/* string terminator; assert( S_xxx != 0 ); */ 922. 	};  923.   924.  	if (part == HAND || part == HANDED) {	/* some special cases */ 925. 	    if (u.usym == S_DOG || u.usym == S_FELINE || u.usym == S_YETI) 926. 		return part == HAND ? "paw" : "pawed"; 927. 	    if (humanoid(uasmon) && attacktype(uasmon, AT_CLAW) &&  928.  		  !index(not_claws, u.usym) && u.umonnum != PM_STONE_GOLEM  929.  		  && u.umonnum != PM_INCUBUS && u.umonnum != PM_SUCCUBUS) 930. 		return part == HAND ? "claw" : "clawed"; 931. 	}  932.  	if (humanoid(uasmon) && (part==ARM || part==FINGER || part==FINGERTIP 933. 		|| part==HAND || part==HANDED)) return humanoid_parts[part]; 934. 	if (u.usym==S_CENTAUR || u.usym==S_UNICORN) return horse_parts[part]; 935. 	if (slithy(uasmon)) return snake_parts[part]; 936. 	if (u.usym==S_EYE) return sphere_parts[part]; 937. 	if (u.usym==S_JELLY || u.usym==S_PUDDING || u.usym==S_BLOB) 938. 		return jelly_parts[part]; 939. 	if (u.usym==S_VORTEX || u.usym==S_ELEMENTAL) return vortex_parts[part]; 940. 	if (u.usym==S_FUNGUS) return fungus_parts[part]; 941. 	if (humanoid(uasmon)) return humanoid_parts[part]; 942. 	return animal_parts[part]; 943. }  944.   945.  #endif /* OVL1 */ 946. #ifdef OVL0 947.  948.  int 949. poly_gender 950. {  951.  /* Returns gender of polymorphed player; 0/1=same meaning as flags.female, 952.  * 2=none. 953.  * Used in: 954.  *	- Seduction by succubus/incubus 955.  *	- Talking to nymphs (sounds.c)  956. * Not used in: 957.  *	- Messages given by nymphs stealing armor (they can't steal from  958.   *	  incubi/succubi/nymphs, and nonhumanoids can't wear armor). 959.  *	- Amulet of change (must refer to real gender no matter what  960.   *	  polymorphed into). 961.  *	- Priest/Priestess, Caveman/Cavewoman (ditto) 962.  *	- Polymorph self (only happens when human) 963.  *	- Shopkeeper messages (since referred to as "creature" and not "sir"  964.   *	  or "lady" when polymorphed) 965.  */  966.  	if (!humanoid(uasmon)) return 2; 967. 	return flags.female; 968. }  969.   970.  #endif /* OVL0 */ 971. #ifdef OVLB 972.  973.  void 974. ugolemeffects(damtype, dam) 975. int damtype, dam; 976. {  977.  	int heal = 0; 978. 	/* We won't bother with "slow"/"haste" since players do not 979. 	 * have a monster-specific slow/haste so there is no way to  980. * restore the old velocity once they are back to human. 981. 	 */  982.  	if (u.umonnum != PM_FLESH_GOLEM && u.umonnum != PM_IRON_GOLEM) 983. 		return; 984. 	switch (damtype) { 985. 		case AD_ELEC: if (u.umonnum == PM_IRON_GOLEM) 986. 				heal = dam / 6; /* Approx 1 per die */ 987. 			break; 988. 		case AD_FIRE: if (u.umonnum == PM_IRON_GOLEM) 989. 				heal = dam; 990. 			break; 991. 	}  992.  	if (heal && (u.mh < u.mhmax)) { 993. 		u.mh += heal; 994. 		if (u.mh > u.mhmax) u.mh = u.mhmax; 995. 		flags.botl = 1; 996. 		pline("Strangely, you feel better than before."); 997. 		exercise(A_STR, TRUE); 998. 	}  999.  }  1000.  1001. static int 1002. armor_to_dragon(atyp) 1003. int atyp; 1004. { 1005. 	switch(atyp) { 1006. 	   case GRAY_DRAGON_SCALE_MAIL: 1007. 	   case GRAY_DRAGON_SCALES: 1008. 		return PM_GRAY_DRAGON; 1009. 	   case RED_DRAGON_SCALE_MAIL: 1010. 	   case RED_DRAGON_SCALES: 1011. 		return PM_RED_DRAGON; 1012. 	   case ORANGE_DRAGON_SCALE_MAIL: 1013. 	   case ORANGE_DRAGON_SCALES: 1014. 		return PM_ORANGE_DRAGON; 1015. 	   case WHITE_DRAGON_SCALE_MAIL: 1016. 	   case WHITE_DRAGON_SCALES: 1017. 		return PM_WHITE_DRAGON; 1018. 	   case BLACK_DRAGON_SCALE_MAIL: 1019. 	   case BLACK_DRAGON_SCALES: 1020. 		return PM_BLACK_DRAGON; 1021. 	   case BLUE_DRAGON_SCALE_MAIL: 1022. 	   case BLUE_DRAGON_SCALES: 1023. 		return PM_BLUE_DRAGON; 1024. 	   case GREEN_DRAGON_SCALE_MAIL: 1025. 	   case GREEN_DRAGON_SCALES: 1026. 		return PM_GREEN_DRAGON; 1027. 	   case YELLOW_DRAGON_SCALE_MAIL: 1028. 	   case YELLOW_DRAGON_SCALES: 1029. 		return PM_YELLOW_DRAGON; 1030. 	   default: 1031. 		return -1; 1032. 	} 1033. }  1034.  1035. #endif /* OVLB */ 1036. 1037. /*polyself.c*/