Source:NetHack 3.2.0/attrib.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to attrib.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.    /*	SCCS Id: @(#)attrib.c	3.2	96/03/28	*/
2.    /*	Copyright 1988, 1989, 1990, 1992, M. Stephenson		  */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    /*  attribute modification routines. */
6.    
7.    #include "hack.h"
8.    #include "artifact.h"
9.    
10.   /* #define DEBUG	/* uncomment for debugging info */
11.   
12.   #ifdef OVLB
13.   
14.   	/* part of the output on gain or loss of attribute */
15.   static
16.   const char	*plusattr[] = {
17.   	"strong", "smart", "wise", "agile", "tough", "charismatic"
18.   },
19.   		*minusattr[] = {
20.   	"weak", "stupid", "foolish", "clumsy", "vulnerable", "ugly"
21.   };
22.   
23.   	/* maximum and minimum values for the attributes */
24.   struct attribs	attrmax = {
25.   	{ 118, 18, 18, 18, 18, 18 }
26.   },
27.   		attrmin = {
28.   	{ 3, 3, 3, 3, 3, 3 }
29.   };
30.   
31.   static
32.   const struct innate {
33.   	schar	ulevel;
34.   	long	*ability;
35.   	const char *gainstr, *losestr;
36.   }	a_abil[] = { {	 1, &(Stealth), "", "" },
37.   		     {   1, &(Fast), "", "" },
38.   		     {  10, &(Searching), "perceptive", "" },
39.   		     {	 0, 0, 0, 0 } },
40.   
41.   	b_abil[] = { {	 1, &(HPoison_resistance), "", "" },
42.   		     {   7, &(Fast), "quick", "slow" },
43.   		     {  15, &(Stealth), "stealthy", "" },
44.   		     {	 0, 0, 0, 0 } },
45.   
46.   	c_abil[] = { {	 7, &(Fast), "quick", "slow" },
47.   		     {	15, &(Warning), "sensitive", "" },
48.   		     {	 0, 0, 0, 0 } },
49.   
50.   	e_abil[] = { {   1, &(Fast), "", "" },
51.   		     {	 1, &(HSee_invisible), "", "" },
52.   		     {	 1, &(Searching), "", "" },
53.   		     {	 1, &(HSleep_resistance), "", "" },
54.   		     {	 0, 0, 0, 0 } },
55.   
56.   	h_abil[] = { {	 1, &(HPoison_resistance), "", "" },
57.   		     {	15, &(Warning), "sensitive", "" },
58.   		     {	 0, 0, 0, 0 } },
59.   
60.   	k_abil[] = { {	 7, &(Fast), "quick", "slow" },
61.   		     {	 0, 0, 0, 0 } },
62.   
63.   	p_abil[] = { {	15, &(Warning), "sensitive", "" },
64.   		     {  20, &(HFire_resistance), "cool", "warmer" },
65.   		     {	 0, 0, 0, 0 } },
66.   
67.   	r_abil[] = { {	 1, &(Stealth), "", ""  },
68.   		     {  10, &(Searching), "perceptive", "" },
69.   		     {	 0, 0, 0, 0 } },
70.   
71.   	s_abil[] = { {	 1, &(Fast), "", "" },
72.   		     {  15, &(Stealth), "stealthy", "" },
73.   		     {	 0, 0, 0, 0 } },
74.   
75.   	t_abil[] = { {	10, &(Searching), "perceptive", "" },
76.   		     {	20, &(HPoison_resistance), "hardy", "" },
77.   		     {	 0, 0, 0, 0 } },
78.   
79.   	v_abil[] = { {	 1, &(HCold_resistance), "", "" },
80.   		     {	 1, &(Stealth), "", "" },
81.   		     {   7, &(Fast), "quick", "slow" },
82.   		     {	 0, 0, 0, 0 } },
83.   
84.   	w_abil[] = { {	15, &(Warning), "sensitive", "" },
85.   		     {  17, &(HTeleport_control), "controlled","uncontrolled" },
86.   		     {	 0, 0, 0, 0 } };
87.   
88.   static
89.   const struct clattr {
90.   	struct	attribs	base, cldist;
91.   	align	align;
92.   	schar	shp, hd, xlev, ndx;
93.   /* According to AD&D, HD for some classes (ex. Wizard) should be smaller
94.    * (4-sided for wizards).  But this is not AD&D, and using the AD&D
95.    * rule here produces an unplayable character.  Thus I have used a minimum
96.    * of an 10-sided hit die for everything.  Another AD&D change: wizards get
97.    * a minimum strength of 6 since without one you can't teleport or cast
98.    * spells. --KAA
99.    */
100.  	const struct	innate *abil;
101.  }	a_attr = { {{  7, 10, 10,  7,  7,  7 }},  /* Archeologist */
102.  		   {{ 20, 20, 20, 10, 20, 10 }},
103.  		   { A_LAWFUL,  10 },  13, 10, 14,  2, a_abil },
104.  
105.  	b_attr = { {{ 16,  7,  7, 15, 16,  6 }},  /* Barbarian */
106.  		   {{ 30,  6,  7, 20, 30,  7 }},
107.  		   { A_NEUTRAL, 10 },  16, 12, 10,  3, b_abil },
108.  
109.  	c_attr = { {{ 10,  7,  7,  7,  8,  6 }},  /* Caveman (fighter) */
110.  		   {{ 30,  6,  7, 20, 30,  7 }},
111.  		   { A_LAWFUL,   0 },  16, 10, 10,  3, c_abil },
112.  
113.  	e_attr = { {{ 13, 13, 13,  9, 13,  7 }},  /* Elf (ranger) */
114.  		   {{ 30, 10, 10, 20, 20, 10 }},
115.  		   { A_CHAOTIC, 10 },  15, 10, 11,  2, e_abil },
116.  
117.  	h_attr = { {{  7,  7, 13,  7, 11, 16 }},  /* Healer (druid) */
118.  		   {{ 15, 20, 20, 15, 25, 10 }},
119.  		   { A_NEUTRAL, 10 },  13, 10, 20,  2, h_abil },
120.  
121.  	k_attr = { {{ 13,  7, 14,  8, 10, 17 }},  /* Knight (paladin) */
122.  		   {{ 20, 15, 15, 10, 20, 10 }},
123.  		   { A_LAWFUL,  10 },  16, 10, 10,  3, k_abil },
124.  
125.  	p_attr = { {{  7,  7, 10,  7,  7,  7 }},  /* Priest (cleric) */
126.  		   {{ 15, 10, 30, 15, 20, 10 }},
127.  		   { A_NEUTRAL,  0 },  14, 10, 10,  2, p_abil },
128.  
129.  	r_attr = { {{  7,  7,  7, 10,  7,  6 }},  /* Rogue (thief) */
130.  		   {{ 20, 10, 10, 30, 20, 10 }},
131.  		   { A_CHAOTIC, 10 },  12, 10, 11,  2, r_abil },
132.  
133.  	s_attr = { {{ 10,  8,  7, 10, 17,  6 }},  /* Samurai (fighter/thief) */
134.  		   {{ 30, 10, 10, 30, 14, 10 }},
135.  		   { A_LAWFUL,  10 },  15, 10, 11,  2, s_abil },
136.  
137.  #ifdef TOURIST
138.  	t_attr = { {{  7, 10,  6,  7,  7, 10 }},  /* Tourist */
139.  		   {{ 15, 10, 10, 15, 30, 20 }},
140.  		   { A_NEUTRAL,  0 },  10, 10, 14,  1, t_abil },
141.  #endif
142.  
143.  	v_attr = { {{ 10,  7,  7,  7, 10,  7 }},  /* Valkyrie (fighter) */
144.  		   {{ 30,  6,  7, 20, 30,  7 }},
145.  		   { A_NEUTRAL,  0 },  16, 10, 10,  3, v_abil },
146.  
147.  	w_attr = { {{  7, 10,  7,  7,  7,  7 }},  /* Wizard (magic-user) */
148.  		   {{ 10, 30, 10, 20, 20, 10 }},
149.  		   { A_NEUTRAL,  0 },  12, 10, 12,  1, w_abil },
150.  
151.  	X_attr = { {{  3,  3,  3,  3,  3,  3 }},
152.  		   {{ 20, 15, 15, 15, 20, 15 }},
153.  		   { A_NEUTRAL,  0 },  12, 10, 14,  1,  0 };
154.  
155.  static long next_check = 600L;	/* arbitrary first setting */
156.  static NEARDATA const struct clattr *NDECL(clx);
157.  static void NDECL(init_align);
158.  static void NDECL(exerper);
159.  
160.  /* adjust an attribute; return TRUE if change is made, FALSE otherwise */
161.  boolean
162.  adjattrib(ndx, incr, msgflg)
163.  	int	ndx, incr;
164.  	int	msgflg;	    /* positive => no message, zero => message, and */
165.  {			    /* negative => conditional (msg if change made) */
166.  	if (!incr) return FALSE;
167.  
168.  	if ((ndx == A_INT || ndx == A_WIS)
169.  				&& uarmh && uarmh->otyp == DUNCE_CAP) {
170.  		if (msgflg == 0)
171.  		    Your("cap constricts briefly, then relaxes again.");
172.  		return FALSE;
173.  	}
174.  
175.  	if (incr > 0) {
176.  	    if ((AMAX(ndx) >= ATTRMAX(ndx)) && (ACURR(ndx) >= AMAX(ndx))) {
177.  		if (msgflg == 0 && flags.verbose)
178.  		    pline("You're already as %s as you can get.",
179.  			  plusattr[ndx]);
180.  		ABASE(ndx) = AMAX(ndx) = ATTRMAX(ndx); /* just in case */
181.  		return FALSE;
182.  	    }
183.  
184.  	    ABASE(ndx) += incr;
185.  	    if(ABASE(ndx) > AMAX(ndx)) {
186.  		incr = ABASE(ndx) - AMAX(ndx);
187.  		AMAX(ndx) += incr;
188.  		if(AMAX(ndx) > ATTRMAX(ndx))
189.  		    AMAX(ndx) = ATTRMAX(ndx);
190.  		ABASE(ndx) = AMAX(ndx);
191.  	    }
192.  	} else {
193.  	    if (ABASE(ndx) <= ATTRMIN(ndx)) {
194.  		if (msgflg == 0 && flags.verbose)
195.  		    pline("You're already as %s as you can get.",
196.  			  minusattr[ndx]);
197.  		ABASE(ndx) = ATTRMIN(ndx); /* just in case */
198.  		return FALSE;
199.  	    }
200.  
201.  	    ABASE(ndx) += incr;
202.  	    if(ABASE(ndx) < ATTRMIN(ndx)) {
203.  		incr = ABASE(ndx) - ATTRMIN(ndx);
204.  		ABASE(ndx) = ATTRMIN(ndx);
205.  		AMAX(ndx) += incr;
206.  		if(AMAX(ndx) < ATTRMIN(ndx))
207.  		    AMAX(ndx) = ATTRMIN(ndx);
208.  	    }
209.  	}
210.  	if (msgflg <= 0)
211.  	    You_feel("%s%s!",
212.  		  (incr > 1 || incr < -1) ? "very ": "",
213.  		  (incr > 0) ? plusattr[ndx] : minusattr[ndx]);
214.  	flags.botl = 1;
215.  	if (moves > 0 && (ndx == A_STR || ndx == A_CON))
216.  		(void)encumber_msg();
217.  	return TRUE;
218.  }
219.  
220.  void
221.  gainstr(otmp, incr)
222.  	register struct obj *otmp;
223.  	register int incr;
224.  {
225.  	int num = 1;
226.  
227.  	if(incr) num = incr;
228.  	else {
229.  	    if(ABASE(A_STR) < 18) num = (rn2(4) ? 1 : rnd(6) );
230.  	    else if (ABASE(A_STR) < 103) num = rnd(10);
231.  	}
232.  	(void) adjattrib(A_STR, (otmp && otmp->cursed) ? -num : num, TRUE);
233.  }
234.  
235.  void
236.  losestr(num)	/* may kill you; cause may be poison or monster like 'a' */
237.  	register int num;
238.  {
239.  	int ustr = ABASE(A_STR) - num;
240.  
241.  	while(ustr < 3) {
242.  		ustr++;
243.  		num--;
244.  		u.uhp -= 6;
245.  		u.uhpmax -= 6;
246.  	}
247.  	(void) adjattrib(A_STR, -num, TRUE);
248.  }
249.  
250.  void
251.  change_luck(n)
252.  	register schar n;
253.  {
254.  	u.uluck += n;
255.  	if (u.uluck < 0 && u.uluck < LUCKMIN)	u.uluck = LUCKMIN;
256.  	if (u.uluck > 0 && u.uluck > LUCKMAX)	u.uluck = LUCKMAX;
257.  }
258.  
259.  int
260.  stone_luck(parameter)
261.  boolean parameter; /* So I can't think up of a good name.  So sue me. --KAA */
262.  {
263.  	register struct obj *otmp;
264.  	register long bonchance = 0;
265.  
266.  	for(otmp = invent; otmp; otmp=otmp->nobj)
267.  	    if (otmp->otyp == LUCKSTONE
268.  		|| (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) {
269.  		if (otmp->cursed) bonchance -= otmp->quan;
270.  		else if (otmp->blessed) bonchance += otmp->quan;
271.  		else if (parameter) bonchance += otmp->quan;
272.  	    }
273.  
274.  	return sgn((int)bonchance);
275.  }
276.  
277.  /* there has just been an inventory change affecting a luck-granting item */
278.  void
279.  set_moreluck()
280.  {
281.  	int luckbon = stone_luck(TRUE);
282.  
283.  	if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0;
284.  	else if (luckbon >= 0) u.moreluck = LUCKADD;
285.  	else u.moreluck = -LUCKADD;
286.  }
287.  
288.  #endif /* OVLB */
289.  #ifdef OVL1
290.  
291.  void
292.  restore_attrib()
293.  {
294.  	int	i;
295.  
296.  	for(i = 0; i < A_MAX; i++) {	/* all temporary losses/gains */
297.  
298.  	   if(ATEMP(i) && ATIME(i)) {
299.  		if(!(--(ATIME(i)))) { /* countdown for change */
300.  		    ATEMP(i) += ATEMP(i) > 0 ? -1 : 1;
301.  
302.  		    if(ATEMP(i)) /* reset timer */
303.  			ATIME(i) = 100 / ACURR(A_CON);
304.  		}
305.  	    }
306.  	}
307.  	(void)encumber_msg();
308.  }
309.  
310.  #endif /* OVL1 */
311.  #ifdef OVLB
312.  
313.  #define AVAL	50		/* tune value for exercise gains */
314.  
315.  void
316.  exercise(i, inc_or_dec)
317.  int	i;
318.  boolean	inc_or_dec;
319.  {
320.  #ifdef DEBUG
321.  	pline("Exercise:");
322.  #endif
323.  	if (i == A_INT || i == A_CHA) return;	/* can't exercise these */
324.  
325.  	/* no physical exercise while polymorphed; the body's temporary */
326.  	if (u.umonnum >= LOW_PM && i != A_WIS) return;
327.  
328.  	if(abs(AEXE(i)) < AVAL) {
329.  		/*
330.  		 *	Law of diminishing returns (Part I):
331.  		 *
332.  		 *	Gain is harder at higher attribute values.
333.  		 *	79% at "3" --> 0% at "18"
334.  		 *	Loss is even at all levels (50%).
335.  		 *
336.  		 *	Note: *YES* ACURR is the right one to use.
337.  		 */
338.  		AEXE(i) += (inc_or_dec) ? (rn2(19) > ACURR(i)) : -rn2(2);
339.  #ifdef DEBUG
340.  		pline("%s, %s AEXE = %d",
341.  			(i == A_STR) ? "Str" : (i == A_WIS) ? "Wis" :
342.  			(i == A_DEX) ? "Dex" : "Con",
343.  			(inc_or_dec) ? "inc" : "dec", AEXE(i));
344.  #endif
345.  	}
346.  	if (moves > 0 && (i == A_STR || i == A_CON)) (void)encumber_msg();
347.  }
348.  
349.  /* hunger values - from eat.c */
350.  #define SATIATED	0
351.  #define NOT_HUNGRY	1
352.  #define HUNGRY		2
353.  #define WEAK		3
354.  #define FAINTING	4
355.  #define FAINTED		5
356.  #define STARVED		6
357.  
358.  static void
359.  exerper()
360.  {
361.  	if(!(moves % 10)) {
362.  		/* Hunger Checks */
363.  
364.  		int hs = (u.uhunger > 1000) ? SATIATED :
365.  			 (u.uhunger > 150) ? NOT_HUNGRY :
366.  			 (u.uhunger > 50) ? HUNGRY :
367.  			 (u.uhunger > 0) ? WEAK : FAINTING;
368.  
369.  #ifdef DEBUG
370.  		pline("exerper: Hunger checks");
371.  #endif
372.  		switch (hs) {
373.  		    case SATIATED:	exercise(A_DEX, FALSE); break;
374.  		    case NOT_HUNGRY:	exercise(A_CON, TRUE); break;
375.  		    case WEAK:		exercise(A_STR, FALSE); break;
376.  		    case FAINTING:
377.  		    case FAINTED:	exercise(A_CON, FALSE); break;
378.  		}
379.  
380.  		/* Encumberance Checks */
381.  #ifdef DEBUG
382.  		pline("exerper: Encumber checks");
383.  #endif
384.  		switch (near_capacity()) {
385.  		    case MOD_ENCUMBER:	exercise(A_STR, TRUE); break;
386.  		    case HVY_ENCUMBER:	exercise(A_STR, TRUE);
387.  					exercise(A_DEX, FALSE); break;
388.  		    case EXT_ENCUMBER:	exercise(A_DEX, FALSE);
389.  					exercise(A_CON, FALSE); break;
390.  		}
391.  
392.  	}
393.  
394.  	/* status checks */
395.  	if(!(moves % 5)) {
396.  #ifdef DEBUG
397.  		pline("exerper: Status checks");
398.  #endif
399.  		if ((HClairvoyant & (INTRINSIC|TIMEOUT)) &&
400.  			!(HClairvoyant & I_BLOCKED))	exercise(A_WIS, TRUE);
401.  		if (HRegeneration)			exercise(A_STR, TRUE);
402.  
403.  		if(Sick || Vomiting)			exercise(A_CON, FALSE);
404.  		if(Confusion || Hallucination)		exercise(A_WIS, FALSE);
405.  		if(Wounded_legs || Fumbling || HStun)	exercise(A_DEX, FALSE);
406.  	}
407.  }
408.  
409.  void
410.  exerchk()
411.  {
412.  	int	i, mod_val;
413.  
414.  	/*	Check out the periodic accumulations */
415.  	exerper();
416.  
417.  #ifdef DEBUG
418.  	if(moves >= next_check)
419.  		pline("exerchk: ready to test. multi = %d.", multi);
420.  #endif
421.  	/*	Are we ready for a test?	*/
422.  	if(moves >= next_check && !multi) {
423.  #ifdef DEBUG
424.  	    pline("exerchk: testing.");
425.  #endif
426.  	    /*
427.  	     *	Law of diminishing returns (Part II):
428.  	     *
429.  	     *	The effects of "exercise" and "abuse" wear
430.  	     *	off over time.  Even if you *don't* get an
431.  	     *	increase/decrease, you lose some of the
432.  	     *	accumulated effects.
433.  	     */
434.  	    for(i = 0; i < A_MAX; AEXE(i++) /= 2) {
435.  
436.  		if(ABASE(i) >= 18 || !AEXE(i)) continue;
437.  		if(i == A_INT || i == A_CHA) continue;/* can't exercise these */
438.  
439.  #ifdef DEBUG
440.  		pline("exerchk: testing %s (%d).",
441.  			(i == A_STR) ? "Str" : (i == A_WIS) ? "Wis" :
442.  			(i == A_DEX) ? "Dex" : "Con", AEXE(i));
443.  #endif
444.  		/*
445.  		 *	Law of diminishing returns (Part III):
446.  		 *
447.  		 *	You don't *always* gain by exercising.
448.  		 *	[MRS 92/10/28 - Treat Wisdom specially for balance.]
449.  		 */
450.  		if(rn2(AVAL) > ((i != A_WIS) ? abs(AEXE(i)*2/3) : abs(AEXE(i))))
451.  		    continue;
452.  		mod_val = sgn(AEXE(i));
453.  
454.  #ifdef DEBUG
455.  		pline("exerchk: changing %d.", i);
456.  #endif
457.  		if(adjattrib(i, mod_val, -1)) {
458.  #ifdef DEBUG
459.  		    pline("exerchk: changed %d.", i);
460.  #endif
461.  		    /* if you actually changed an attrib - zero accumulation */
462.  		    AEXE(i) = 0;
463.  		    /* then print an explanation */
464.  		    switch(i) {
465.  		    case A_STR: You((mod_val >0) ?
466.  				    "must have been exercising." :
467.  				    "must have been abusing your body.");
468.  				break;
469.  		    case A_WIS: You((mod_val >0) ?
470.  				    "must have been very observant." :
471.  				    "haven't been paying attention.");
472.  				break;
473.  		    case A_DEX: You((mod_val >0) ?
474.  				    "must have been working on your reflexes." :
475.  				    "haven't been working on reflexes lately.");
476.  				break;
477.  		    case A_CON: You((mod_val >0) ?
478.  				    "must be leading a healthy life-style." :
479.  				    "haven't been watching your health.");
480.  				break;
481.  		    }
482.  		}
483.  	    }
484.  	    next_check += rn1(200,800);
485.  #ifdef DEBUG
486.  	    pline("exerchk: next check at %ld.", next_check);
487.  #endif
488.  	}
489.  }
490.  
491.  /* next_check will otherwise have its initial 600L after a game restore */
492.  void
493.  reset_attribute_clock()
494.  {
495.  	if (moves > 600L) next_check = moves + rn1(50,800);
496.  }
497.  
498.  static const struct	clattr *
499.  clx()
500.  {
501.  	register const struct	clattr	*attr;
502.  
503.  	switch (u.role) {
504.  	    case 'A':	attr = &a_attr;
505.  			break;
506.  	    case 'B':	attr = &b_attr;
507.  			break;
508.  	    case 'C':	attr = &c_attr;
509.  			break;
510.  	    case 'E':	attr = &e_attr;
511.  			break;
512.  	    case 'H':	attr = &h_attr;
513.  			break;
514.  	    case 'K':	attr = &k_attr;
515.  			break;
516.  	    case 'P':	attr = &p_attr;
517.  			break;
518.  	    case 'R':	attr = &r_attr;
519.  			break;
520.  	    case 'S':	attr = &s_attr;
521.  			break;
522.  #ifdef TOURIST
523.  	    case 'T':	attr = &t_attr;
524.  			break;
525.  #endif
526.  	    case 'V':	attr = &v_attr;
527.  			break;
528.  	    case 'W':	attr = &w_attr;
529.  			break;
530.  	    default:	/* unknown type */
531.  			attr = &X_attr;
532.  			break;
533.  	}
534.  	return(attr);
535.  }
536.  
537.  static void
538.  init_align()	/* called from newhp if u.ulevel is 0 */
539.  {
540.  	register const struct	clattr	*attr = clx();
541.  
542.  	u.ualign = attr->align;
543.  	/* there should be priests of every stripe */
544.  	if (Role_is('P'))
545.  	     u.ualign.type = (rn2(2)) ? attr->align.type : (rn2(2)) ? 1 : -1;
546.  	else u.ualign.type = attr->align.type;
547.  }
548.  
549.  void
550.  init_attr(np)
551.  	register int	np;
552.  {
553.  	register int	i, x, tryct;
554.  	register const struct	clattr	*attr = clx();
555.  
556.  	for(i = 0; i < A_MAX; i++) {
557.  
558.  	    ABASE(i) = AMAX(i) = attr->base.a[i];
559.  	    ATEMP(i) = ATIME(i) = 0;
560.  	    np -= attr->base.a[i];
561.  	}
562.  
563.  	tryct = 0;
564.  	while(np > 0 && tryct < 100) {
565.  
566.  	    x = rn2(100);
567.  	    for (i = 0; (i < A_MAX) && ((x -= attr->cldist.a[i]) > 0); i++) ;
568.  	    if(i >= A_MAX) continue; /* impossible */
569.  
570.  	    if(ABASE(i) >= ATTRMAX(i)) {
571.  
572.  		tryct++;
573.  		continue;
574.  	    }
575.  	    tryct = 0;
576.  	    ABASE(i)++;
577.  	    AMAX(i)++;
578.  	    np--;
579.  	}
580.  
581.  	tryct = 0;
582.  	while(np < 0 && tryct < 100) {		/* for redistribution */
583.  
584.  	    x = rn2(100);
585.  	    for (i = 0; (i < A_MAX) && ((x -= attr->cldist.a[i]) > 0); i++) ;
586.  	    if(i >= A_MAX) continue; /* impossible */
587.  
588.  	    if(ABASE(i) <= ATTRMIN(i)) {
589.  
590.  		tryct++;
591.  		continue;
592.  	    }
593.  	    tryct = 0;
594.  	    ABASE(i)--;
595.  	    AMAX(i)--;
596.  	    np++;
597.  	}
598.  }
599.  
600.  void
601.  redist_attr()
602.  {
603.  	register int i, tmp;
604.  
605.  	for(i = 0; i < A_MAX; i++) {
606.  	    if (i==A_INT || i==A_WIS) continue;
607.  		/* Polymorphing doesn't change your mind */
608.  	    tmp = AMAX(i);
609.  	    AMAX(i) += (rn2(5)-2);
610.  	    if (AMAX(i) > ATTRMAX(i)) AMAX(i) = ATTRMAX(i);
611.  	    if (AMAX(i) < ATTRMIN(i)) AMAX(i) = ATTRMIN(i);
612.  	    ABASE(i) = ABASE(i) * AMAX(i) / tmp;
613.  	    /* ABASE(i) > ATTRMAX(i) is impossible */
614.  	    if (ABASE(i) < ATTRMIN(i)) ABASE(i) = ATTRMIN(i);
615.  	}
616.  	(void)encumber_msg();
617.  }
618.  
619.  void
620.  adjabil(oldlevel,newlevel)
621.  int oldlevel, newlevel;
622.  {
623.  	register const struct clattr	*attr = clx();
624.  #ifdef GCC_WARN
625.  	/* this is the "right" definition */
626.  	register const struct innate	*abil = attr->abil;
627.  #else
628.  	/* this one satisfies more compilers */
629.  	register struct innate	*abil = (struct innate *)attr->abil;
630.  #endif
631.  
632.  	if(abil) {
633.  	    for(; abil->ability; abil++) {
634.  		if(oldlevel < abil->ulevel && newlevel >= abil->ulevel) {
635.  			/* Abilities gained at level 1 can never be lost
636.  			 * via level loss, only via means that remove _any_
637.  			 * sort of ability.  A "gain" of such an ability from
638.  			 * an outside source is devoid of meaning, so we set
639.  			 * FROMOUTSIDE to avoid such gains.
640.  			 */
641.  			if (abil->ulevel == 1)
642.  				*(abil->ability) |= (FROMEXPER|FROMOUTSIDE);
643.  			else
644.  				*(abil->ability) |= FROMEXPER;
645.  			if(!(*(abil->ability) & FROMOUTSIDE)) {
646.  			    if(*(abil->gainstr))
647.  				You_feel("%s!", abil->gainstr);
648.  			}
649.  		} else if (oldlevel >= abil->ulevel && newlevel < abil->ulevel) {
650.  			*(abil->ability) &= ~FROMEXPER;
651.  			if((*(abil->ability) & INTRINSIC)) {
652.  			    if(*(abil->losestr))
653.  				You_feel("%s!", abil->losestr);
654.  			    else if(*(abil->gainstr))
655.  				You_feel("less %s!", abil->gainstr);
656.  			}
657.  		}
658.  	    }
659.  	}
660.  }
661.  
662.  int
663.  newhp()
664.  {
665.  	register const struct clattr	*attr = clx();
666.  	int	hp, conplus;
667.  
668.  	if(u.ulevel == 0) {
669.  
670.  		hp = attr->shp;
671.  		init_align();	/* initialize alignment stuff */
672.  		return hp;
673.  	} else {
674.  
675.  	    if(u.ulevel < attr->xlev)
676.  		hp = rnd(attr->hd);
677.  	    else
678.  		hp = attr->ndx;
679.  	}
680.  
681.  	switch(ACURR(A_CON)) {
682.  		case	3:	conplus = -2; break;
683.  		case	4:
684.  		case	5:
685.  		case	6:	conplus = -1; break;
686.  		case	15:
687.  		case	16:	conplus = 1; break;
688.  		case	17:	conplus = 2; break;
689.  		case	18:	conplus = 3; break;
690.  		default:	conplus = 0;
691.  	}
692.  	hp += conplus;
693.  	return((hp <= 0) ? 1 : hp);
694.  }
695.  
696.  #endif /* OVLB */
697.  #ifdef OVL0
698.  
699.  schar
700.  acurr(x)
701.  int x;
702.  {
703.  	register int tmp = (u.abon.a[x] + u.atemp.a[x] + u.acurr.a[x]);
704.  
705.  	if (x == A_STR) {
706.  		if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER) return(125);
707.  #ifdef WIN32_BUG
708.  		else return(x=((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp));
709.  #else
710.  		else return((schar)((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp));
711.  #endif
712.  	} else if (x == A_CHA) {
713.  		if (tmp < 18 && (u.usym == S_NYMPH ||
714.  		    u.umonnum==PM_SUCCUBUS || u.umonnum == PM_INCUBUS))
715.  		    return 18;
716.  	} else if (x == A_INT || x == A_WIS) {
717.  		/* yes, this may raise int/wis if player is sufficiently
718.  		 * stupid.  there are lower levels of cognition than "dunce".
719.  		 */
720.  		if (uarmh && uarmh->otyp == DUNCE_CAP) return(6);
721.  	}
722.  #ifdef WIN32_BUG
723.  	return(x=((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp));
724.  #else
725.  	return((schar)((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp));
726.  #endif
727.  }
728.  
729.  /* condense clumsy ACURR(A_STR) value into value that fits into game formulas
730.   */
731.  schar
732.  acurrstr()
733.  {
734.  	register int str = ACURR(A_STR);
735.  
736.  	if (str <= 18) return((schar)str);
737.  	if (str <= 121) return((schar)(19 + str / 50)); /* map to 19-21 */
738.  	else return((schar)(str - 100));
739.  }
740.  
741.  #endif /* OVL0 */
742.  #ifdef OVL2
743.  
744.  /* avoid possible problems with alignment overflow, and provide a centralized
745.   * location for any future alignment limits
746.   */
747.  void
748.  adjalign(n)
749.  register int n;
750.  {
751.  	register int newalign = u.ualign.record + n;
752.  
753.  	if(n < 0) {
754.  		if(newalign < u.ualign.record)
755.  			u.ualign.record = newalign;
756.  	} else
757.  		if(newalign > u.ualign.record) {
758.  			u.ualign.record = newalign;
759.  			if(u.ualign.record > ALIGNLIM)
760.  				u.ualign.record = ALIGNLIM;
761.  		}
762.  }
763.  
764.  #endif /* OVL2 */
765.  
766.  /*attrib.c*/