Source:NetHack 3.1.0/polyself.c

From NetHackWiki
Jump to navigation Jump to search

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

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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