Source:NetHack 3.0.0/attrib.c

From NetHackWiki
Revision as of 04:19, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/attrib.c moved to Source:NetHack 3.0.0/attrib.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Below is the full text to attrib.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/attrib.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.    /*
2.     *	attrib.c	- attribute modification routines.
3.     *
4.     *	Copyright 1988, M. Stephenson
5.     */
6.    /* NetHack may be freely redistributed.  See license for details. */
7.    
8.    #include	"hack.h"
9.    
10.   const char	*plusattr[] = {	/* part of the output on gain of attribute */
11.   
12.   	"strong", "smart", "wise", "agile", "tough", "charismatic"
13.   };
14.   
15.   const char	*minusattr[] = { /* part of the output on loss of attribute */
16.   
17.   	"weak", "stupid", "foolish", "clumsy", "vulnerable", "ugly"
18.   };
19.   
20.   struct attribs	attrmax = {	/* max values for the attributes */
21.   
22.   	118, 18, 18, 18, 18, 18
23.   },
24.   		attrmin = {	/* min values for the attributes */
25.   
26.   	3, 3, 3, 3, 3, 3
27.   };
28.   
29.   const struct innate {
30.   
31.   	schar	ulevel;
32.   	long	*ability;
33.   	char	*gainstr, *losestr;
34.   }	a_abil[] = { {	 0, &(Stealth), "", "" },
35.   		     {   0, &(Fast), "", "" },
36.   		     {  10, &(Searching), "perceptive", "" },
37.   		     {	 0, 0, 0, 0 } },
38.   
39.   	b_abil[] = { {	 0, &(HPoison_resistance), "", "" },
40.   		     {   7, &(Fast), "quick", "slow" },
41.   		     {  15, &(Stealth), "stealthy", "" },
42.   		     {	 0, 0, 0, 0 } },
43.   
44.   	c_abil[] = { {	 7, &(Fast), "quick", "slow" },
45.   		     {	15, &(Warning), "sensitive", "" },
46.   		     {	 0, 0, 0, 0 } },
47.   
48.   	e_abil[] = { {   0, &(Fast), "", "" },
49.   		     {	 0, &(HSee_invisible), "", "" },
50.   		     {	 0, &(Searching), "", "" },
51.   		     {	 0, &(HSleep_resistance), "", "" },
52.   		     {	 0, 0, 0, 0 } },
53.   
54.   	h_abil[] = { {	 0, &(HPoison_resistance), "", "" },
55.   		     {	15, &(Warning), "sensitive", "" },
56.   		     {	 0, 0, 0, 0 } },
57.   
58.   	k_abil[] = { {	 7, &(Fast), "quick", "slow" },
59.   		     {	 0, 0, 0, 0 } },
60.   
61.   	p_abil[] = { {	15, &(Warning), "sensitive", "" },
62.   		     {  20, &(HFire_resistance), "cool", "warmer" },
63.   		     {	 0, 0, 0, 0 } },
64.   
65.   	r_abil[] = { {	 0, &(Stealth), "", ""  },
66.   		     {  10, &(Searching), "perceptive", "" },
67.   		     {	 0, 0, 0, 0 } },
68.   
69.   	s_abil[] = { {	 0, &(Fast), "", "" },
70.   		     {  15, &(Stealth), "stealthy", "" },
71.   		     {	 0, 0, 0, 0 } },
72.   
73.   	t_abil[] = { {	10, &(Searching), "perceptive", "" },
74.   		     {	20, &(HPoison_resistance), "hardy", "" },
75.   		     {	 0, 0, 0, 0 } },
76.   
77.   	v_abil[] = { {	 0, &(HCold_resistance), "", "" },
78.   		     {	 0, &(Stealth), "", "" },
79.   		     {   7, &(Fast), "quick", "slow" },
80.   		     {	 0, 0, 0, 0 } },
81.   
82.   	w_abil[] = { {	15, &(Warning), "sensitive", "" },
83.   		     {  17, &(HTeleport_control), "controlled","uncontrolled" },
84.   		     {	 0, 0, 0, 0 } };
85.   
86.   const struct clattr {
87.   
88.   	struct	attribs	base, dist;
89.    	schar	align, aligntyp;
90.   	schar	shp, hd, xlev, ndx;
91.   /* According to AD&D, HD for some classes (i.e. Wizard) should be smaller
92.    * (4-sided for wizards).  But this is not AD&D, and using the AD&D
93.    * rule here produces an unplayable character.  This I have used a minimum
94.    * of an 10-sided hit die for everything.  Another AD&D change: wizards get
95.    * a minimum strength of 6 since without one you can't teleport or cast
96.    * spells. --KAA
97.    */
98.   	struct	innate *abil;
99.   }	a_attr = { {	 6,  9,  9,  6,  6,  6 },  /* Archeologist */
100.  		   {	20, 20, 20, 10, 20, 10 },
101.  		    10,  1, 13, 10, 14,  2, a_abil },
102.  
103.  	b_attr = { {	15,  6,  6, 14, 15,  5 },  /* Barbarian */
104.  		   {	30,  6,  7, 20, 30,  7 },
105.  		    10, -1, 16, 12, 10,  3, b_abil },
106.  
107.  	c_attr = { {	 9,  6,  6,  6,  7,  5 },  /* Caveman (fighter) */
108.  		   {	30,  6,  7, 20, 30,  7 },
109.  		     0,  1, 16, 10, 10,  3, c_abil },
110.  
111.  /*
112.  	e_attr = { {	13, 13, 14,  6, 14,  6 },
113.   */
114.  	e_attr = { {	12, 12, 12,  8, 12,  6 },  /* Elf (ranger) */
115.  		   {	30, 10, 10, 20, 20, 10 },
116.  		    10,  1, 15, 10, 11,  2, e_abil },
117.  
118.  	h_attr = { {	 6,  6, 12,  6, 10, 15 },  /* Healer (druid) */
119.  		   {	15, 20, 20, 15, 25, 10 },
120.  		    10,  1, 13, 10, 20,  2, h_abil },
121.  
122.  	k_attr = { {	12,  6, 13,  6,  9, 17 },  /* Knight (paladin) */
123.  		   {	20, 15, 15, 10, 20, 10 },
124.  		    10,  1, 16, 10, 10,  3, k_abil },
125.  
126.  	p_attr = { {	 6,  6,  9,  6,  6,  6 },  /* Priest (cleric) */
127.  		   {	15, 10, 30, 15, 20, 10 },
128.  		     0,  0, 14, 10, 10,  2, p_abil },
129.  
130.  	r_attr = { {	 6,  6,  6,  9,  6,  5 },  /* Rogue (thief) */
131.  		   {	20, 10, 10, 30, 20, 10 },
132.  		    10, -1, 12, 10, 11,  2, r_abil },
133.  
134.  	s_attr = { {	 9,  6,  6,  9, 17,  5 },  /* Samurai (fighter/thief) */
135.  		   {	30, 10, 10, 30, 14, 10 },
136.  		    10,  1, 15, 10, 11,  2, s_abil },
137.  
138.  	t_attr = { {	 6,  9,  5,  6,  6,  9 },  /* Tourist */
139.  		   {	15, 10, 10, 15, 30, 20 },
140.  		     0,  0, 10, 10, 14,  1, t_abil },
141.  
142.  	v_attr = { {	 9,  6,  6,  6,  9,  6 },  /* Valkyrie (fighter) */
143.  		   {	30,  6,  7, 20, 30,  7 },
144.  		     0, -1, 16, 10, 10,  3, v_abil },
145.  
146.  	w_attr = { {	 6,  9,  6,  6,  6,  6 },  /* Wizard (magic-user) */
147.  		   {	10, 30, 10, 20, 20, 10 },
148.  		     0,  0, 12, 10, 12,  1, w_abil },
149.  
150.  	X_attr = { {	 3,  3,  3,  3,  3,  3 },
151.  		   {	20, 15, 15, 15, 20, 15 },
152.  		     0,  0, 12, 10, 14,  1,  0 };
153.  
154.  void
155.  adjattrib(ndx, incr, silent)
156.  
157.  	int	ndx, incr;
158.  	boolean	silent;
159.  {
160.  	if(!incr) return;
161.  
162.  	if(incr > 0) {
163.  	    if((AMAX(ndx) >= attrmax.a[ndx]) && (ACURR(ndx) == AMAX(ndx))) {
164.  
165.  		if(!silent && flags.verbose)
166.  		    pline("You're already as %s as you can get.",
167.  			  plusattr[ndx]);
168.  		ABASE(ndx) = AMAX(ndx) = attrmax.a[ndx]; /* just in case */
169.  		return;
170.  	    }
171.  
172.  	    ABASE(ndx) += incr;
173.  	    if(ABASE(ndx) > AMAX(ndx)) {
174.  		incr = ABASE(ndx) - AMAX(ndx);
175.  		AMAX(ndx) += incr;
176.  		if(AMAX(ndx) > attrmax.a[ndx])
177.  		    AMAX(ndx) = attrmax.a[ndx];
178.  		ABASE(ndx) = AMAX(ndx);
179.  	    }
180.  	} else {
181.  	    if((AMAX(ndx) <= attrmin.a[ndx]) && (ABASE(ndx) == AMAX(ndx))) {
182.  		if(!silent && flags.verbose)
183.  		    pline("You're already as %s as you can get.",
184.  			  minusattr[ndx]);
185.  		ABASE(ndx) = AMAX(ndx) = attrmin.a[ndx]; /* just in case */
186.  		return;
187.  	    }
188.  
189.  	    ABASE(ndx) += incr;
190.  	    if(ABASE(ndx) < attrmin.a[ndx]) {
191.  		incr = ABASE(ndx) - attrmin.a[ndx];
192.  		ABASE(ndx) = attrmin.a[ndx];
193.  		AMAX(ndx) += incr;
194.  		if(AMAX(ndx) < attrmin.a[ndx])
195.  		    AMAX(ndx) = attrmin.a[ndx];
196.  	    }
197.  	}
198.  	if(!silent)
199.  	    You("feel %s%s!",
200.  		  (incr > 1) ? "very ": "",
201.  		  (incr > 0) ? plusattr[ndx] : minusattr[ndx]);
202.  	flags.botl = 1;
203.  	return;
204.  }
205.  
206.  void
207.  gainstr(otmp, incr)
208.  	register struct obj *otmp;
209.  	register int incr;
210.  {
211.  	int num = 1;
212.  
213.  	if(incr) num = incr;
214.  	else {
215.  	    if(ABASE(A_STR) < 18) num = (rn2(4) ? 1 : rnd(6) );
216.  	    else if (ABASE(A_STR) < 103) num = rnd(10);
217.  	}
218.  	adjattrib(A_STR, (otmp && otmp->cursed) ? -num : num, TRUE);
219.  }
220.  
221.  void
222.  losestr(num)	/* may kill you; cause may be poison or monster like 'a' */
223.  	register int num;
224.  {
225.  	int ustr = ABASE(A_STR) - num;
226.  
227.  	while(ustr < 3) {
228.  		ustr++;
229.  		num--;
230.  		u.uhp -= 6;
231.  		u.uhpmax -= 6;
232.  	}
233.  	adjattrib(A_STR, -num, TRUE);
234.  }
235.  
236.  void
237.  change_luck(n)
238.  	register schar n;
239.  {
240.  	u.uluck += n;
241.  	if (u.uluck < 0 && u.uluck < LUCKMIN)	u.uluck = LUCKMIN;
242.  	if (u.uluck > 0 && u.uluck > LUCKMAX)	u.uluck = LUCKMAX;
243.  }
244.  
245.  int
246.  stone_luck(parameter)
247.  boolean parameter; /* So I can't think up of a good name.  So sue me. --KAA */
248.  {
249.  	register struct obj *otmp;
250.  	register int bonchance = 0;
251.  
252.  	for(otmp = invent; otmp; otmp=otmp->nobj)
253.  	    if(otmp->otyp == LUCKSTONE) {
254.  		if (otmp->cursed) bonchance -= otmp->quan;
255.  		else if (otmp->blessed) bonchance += otmp->quan;
256.  		else if (parameter) bonchance += otmp->quan;
257.  	    }
258.  
259.  	return sgn(bonchance);
260.  }
261.  
262.  void
263.  restore_attrib() {
264.  
265.  	int	i;
266.  
267.  	for(i = 0; i < A_MAX; i++) {	/* all temporary losses/gains */
268.  
269.  	   if(ATEMP(i) && ATIME(i)) {
270.  		if(!(--(ATIME(i)))) { /* countdown for change */
271.  		    ATEMP(i) += ATEMP(i) > 0 ? -1 : 1;
272.  
273.  		    if(ATEMP(i)) /* reset timer */
274.  			ATIME(i) = 100 / ACURR(A_CON);
275.  		}
276.  	    }
277.  	}
278.  }
279.  
280.  static struct	clattr *
281.  clx()  {
282.  
283.  	register struct	clattr	*attr;
284.  
285.  	switch	(pl_character[0]) {
286.  
287.  	    case 'A':	attr = &a_attr;
288.  			break;
289.  	    case 'B':	attr = &b_attr;
290.  			break;
291.  	    case 'C':	attr = &c_attr;
292.  			break;
293.  	    case 'E':	attr = &e_attr;
294.  			break;
295.  	    case 'H':	attr = &h_attr;
296.  			break;
297.  	    case 'K':	attr = &k_attr;
298.  			break;
299.  	    case 'P':	attr = &p_attr;
300.  			break;
301.  	    case 'R':	attr = &r_attr;
302.  			break;
303.  	    case 'S':	attr = &s_attr;
304.  			break;
305.  	    case 'T':	attr = &t_attr;
306.  			break;
307.  	    case 'V':	attr = &v_attr;
308.  			break;
309.  	    case 'W':	attr = &w_attr;
310.  			break;
311.  	    default:	/* unknown type */
312.  			attr = &X_attr;
313.  			break;
314.  	}
315.  	return(attr);
316.  }
317.  
318.  static void
319.  init_align() {	/* called from newhp if u.ulevel is 0 */
320.  
321.  	register struct	clattr	*attr = clx();
322.  
323.  	u.ualign = (int)attr->align;
324.  	u.ualigntyp = attr->aligntyp;
325.  }
326.  
327.  void
328.  init_attr(np)
329.  	register int	np;
330.  {
331.  	register int	i, x, tryct;
332.  	register struct	clattr	*attr = clx();
333.  
334.  	for(i = 0; i < A_MAX; i++) {
335.  
336.  	    ABASE(i) = AMAX(i) = attr->base.a[i];
337.  	    ATEMP(i) = ATIME(i) = 0;
338.  	    np -= attr->base.a[i];
339.  	}
340.  
341.  	tryct = 0;
342.  	while(np > 0 && tryct < 100) {
343.  
344.  	    x = rn2(100);
345.  	    for(i = 0; (i < A_MAX) && ((x -= attr->dist.a[i]) > 0); i++);
346.  	    if(i >= A_MAX) continue; /* impossible */
347.  
348.  	    if(ABASE(i) >= attrmax.a[i]) {
349.  
350.  		tryct++;
351.  		continue;
352.  	    }
353.  	    tryct = 0;
354.  	    ABASE(i)++;
355.  	    AMAX(i)++;
356.  	    np--;
357.  	}
358.  
359.  	tryct = 0;
360.  	while(np < 0 && tryct < 100) {		/* for redistribution */
361.  
362.  	    x = rn2(100);
363.  	    for(i = 0; (i < A_MAX) && ((x -= attr->dist.a[i]) > 0); i++);
364.  	    if(i >= A_MAX) continue; /* impossible */
365.  
366.  	    if(ABASE(i) <= attrmin.a[i]) {
367.  
368.  		tryct++;
369.  		continue;
370.  	    }
371.  	    tryct = 0;
372.  	    ABASE(i)--;
373.  	    AMAX(i)--;
374.  	    np++;
375.  	}
376.  }
377.  
378.  #ifdef POLYSELF
379.  void
380.  redist_attr() {
381.  
382.  	register int i, tmp;
383.  
384.  	for(i = 0; i < A_MAX; i++) {
385.  	    if (i==A_INT || i==A_WIS) continue;
386.  		/* Polymorphing doesn't change your mind */
387.  	    tmp = AMAX(i);
388.  	    AMAX(i) += (rn2(5)-2);
389.  	    if (AMAX(i) > attrmax.a[i]) AMAX(i) = attrmax.a[i];
390.  	    if (AMAX(i) < attrmin.a[i]) AMAX(i) = attrmin.a[i];
391.  	    ABASE(i) = ABASE(i) * AMAX(i) / tmp;
392.  	    /* ABASE(i) > attrmax.a[i] is impossible */
393.  	    if (ABASE(i) < attrmin.a[i]) ABASE(i) = attrmin.a[i];
394.  	}
395.  }
396.  #endif
397.  
398.  void
399.  adjabil(flag)
400.  
401.  	int	flag;		/* +ve/-ve  = gain/lose */
402.  {
403.  	register struct	clattr	*attr = clx();
404.  	register struct innate	*abil = attr->abil;
405.  
406.  	if(abil) {
407.  
408.  	    for(; abil->ability; abil++) {
409.  		if ((flag>0 && u.ulevel >= abil->ulevel) ||
410.  					(flag<0 && u.ulevel < abil->ulevel)) {
411.  		    if(flag > 0) {
412.  			if(!(*(abil->ability) & INTRINSIC)) {
413.  			    *(abil->ability) |= INTRINSIC;
414.  			    if(strlen(abil->gainstr))
415.  				You("feel %s!", abil->gainstr);
416.  			}
417.  		    } else {
418.  			if((*(abil->ability) & INTRINSIC)) {
419.  			    *(abil->ability) &= ~INTRINSIC;
420.  			    if(strlen(abil->losestr))
421.  				You("feel %s!", abil->losestr);
422.  			    else if(strlen(abil->gainstr))
423.  				You("feel less %s!", abil->gainstr);
424.  			}
425.  		    }
426.  		} 
427.  	    }
428.  	}
429.  }
430.  
431.  int
432.  newhp() {
433.  	register struct	clattr	*attr = clx();
434.  	int	hp, conplus;
435.  
436.  	if(u.ulevel == 0) {
437.  
438.  		hp = attr->shp;
439.  		init_align();	/* initialize alignment stuff */
440.  		return hp;
441.  	} else {
442.  
443.  	    if(u.ulevel < attr->xlev)
444.  		hp = rnd(attr->hd);
445.  	    else
446.  		hp = attr->ndx;
447.  	}
448.  
449.  	switch(ACURR(A_CON)) {
450.  		case	3:	conplus = -2; break;
451.  		case	4:
452.  		case	5:
453.  		case	6:	conplus = -1; break;
454.  		case	15:
455.  		case	16:	conplus = 1; break;
456.  		case	17:	conplus = 2; break;
457.  		case	18:	conplus = 3; break;
458.  		default:	conplus = 0;
459.  	}
460.  	hp += conplus;
461.  	return((hp <= 0) ? 1 : hp);
462.  }
463.  
464.  schar
465.  acurr(x) { 
466.  	register int tmp = (u.abon.a[x] + u.atemp.a[x] + u.acurr.a[x]);
467.  
468.  	if (x == A_STR) {
469.  		if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER) return(125);
470.  		else return((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp);
471.  	} 
472.  	else return((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp);
473.  }
474.  
475.  /* avoid possible problems with alignment overflow, and provide a centralized
476.   * location for any future alignment limits
477.   */
478.  void
479.  adjalign(n)
480.  register int n;
481.  {
482.  	register int newalign = u.ualign + n;
483.  
484.  	if(n < 0) {
485.  		if(newalign < u.ualign)
486.  			u.ualign = newalign;
487.  	} else
488.  		if(newalign > u.ualign)
489.  			u.ualign = newalign;
490.  }