Source:NetHack 2.3e/polyself.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to polyself.c from the source code of NetHack 2.3e.

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

Screenshots and source code from Hack are used under the CWI license.

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