Source:SLASH'EM 0.0.7E7F2/attrib.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to attrib.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/attrib.c#line123]], for example.

The latest source code for vanilla NetHack is at 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.4	2002/10/07	*/
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.    
9.    /* #define DEBUG */	/* uncomment for debugging info */
10.   
11.   #ifdef OVLB
12.   
13.   	/* part of the output on gain or loss of attribute */
14.   static
15.   const char	* const plusattr[] = {
16.   	"strong", "smart", "wise", "agile", "tough", "charismatic"
17.   },
18.   		* const minusattr[] = {
19.   	"weak", "stupid", "foolish", "clumsy", "fragile", "repulsive"
20.   };
21.   
22.   
23.   /* KMH, intrinsics patch -- many of these are updated */
24.   static
25.   const struct innate {
26.   	schar	ulevel;
27.   	long	*ability;
28.   	const char *gainstr, *losestr;
29.   }	arc_abil[] = { {	 1, &(HStealth), "", "" },
30.   		     {   1, &(HFast), "", "" },
31.   		     {  10, &(HSearching), "perceptive", "" },
32.   		     {	 0, 0, 0, 0 } },
33.   
34.   	bar_abil[] = { {	 1, &(HPoison_resistance), "", "" },
35.   		     {   7, &(HFast), "quick", "slow" },
36.   		     {  15, &(HStealth), "stealthy", "" },
37.   		     {	 0, 0, 0, 0 } },
38.   
39.   	cav_abil[] = { {	 7, &(HFast), "quick", "slow" },
40.   		     {	15, &(HWarning), "sensitive", "" },
41.   		     {	 0, 0, 0, 0 } },
42.   
43.   	fla_abil[] = { {   1, &(HFire_resistance), "", "" },
44.   		     {  13, &(HCold_resistance), "warm", "cooler" },
45.   		     {   0, 0, 0, 0 } },
46.   
47.   	hea_abil[] = { {	 1, &(HPoison_resistance), "", "" },
48.   		     {	15, &(HWarning), "sensitive", "" },
49.   		     {	 0, 0, 0, 0 } },
50.   
51.   	ice_abil[] = { {   1, &(HCold_resistance), "", "" },
52.   		     {  13, &(HFire_resistance), "cool", "warmer" },
53.   		     {   0, 0, 0, 0 } },
54.   
55.   	kni_abil[] = { {	 7, &(HFast), "quick", "slow" },
56.   		     {	 0, 0, 0, 0 } },
57.   
58.   	mon_abil[] = { {   1, &(HFast), "", "" },
59.   		     {   1, &(HSleep_resistance), "", "" },
60.   		     {   1, &(HSee_invisible), "", "" },
61.   		     {   3, &(HPoison_resistance), "healthy", "" },
62.   		     {   5, &(HStealth), "stealthy", "" },
63.   		     {   7, &(HWarning), "sensitive", "" },
64.   		     {   9, &(HSearching), "perceptive", "unaware" },
65.   #if 0
66.   		     {  11, &(HFire_resistance), "cool", "warmer" },
67.   		     {  13, &(HCold_resistance), "warm", "cooler" },
68.   		     {  15, &(HShock_resistance), "insulated", "conductive" },
69.   		     /* WAC -- made the above three attribs techs */
70.   #endif
71.   		     {  17, &(HTeleport_control), "controlled","uncontrolled" },
72.   		     {   0, 0, 0, 0 } },
73.   
74.   	nec_abil[] = { {   1, &(HDrain_resistance), "", "" },
75.   		     {   1, &(HSick_resistance), "", "" },
76.   		     {   3, &(HUndead_warning), "sensitive", "" },
77.   		     {   0, 0, 0, 0 } },
78.   
79.   	pri_abil[] = { {	15, &(HWarning), "sensitive", "" },
80.   		     {  20, &(HFire_resistance), "cool", "warmer" },
81.   		     {	 0, 0, 0, 0 } },
82.   
83.   	ran_abil[] = { {   1, &(HSearching), "", "" },
84.   		     {	 7, &(HStealth), "stealthy", "" },
85.   		     {	15, &(HSee_invisible), "", "" },
86.   		     {	 0, 0, 0, 0 } },
87.   
88.   	rog_abil[] = { {	 1, &(HStealth), "", ""  },
89.   		     {  10, &(HSearching), "perceptive", "" },
90.   		     {	 0, 0, 0, 0 } },
91.   
92.   	sam_abil[] = { {	 1, &(HFast), "", "" },
93.   		     {  15, &(HStealth), "stealthy", "" },
94.   		     {	 0, 0, 0, 0 } },
95.   
96.   	tou_abil[] = { {	10, &(HSearching), "perceptive", "" },
97.   		     {	20, &(HPoison_resistance), "hardy", "" },
98.   		     {	 0, 0, 0, 0 } },
99.   
100.  	und_abil[] = { {   1, &(HStealth), "", "" },
101.  		     {   1, &(HDrain_resistance), "", "" },
102.  		     {   1, &(HSick_resistance), "", "" },
103.  		     {   1, &(HUndead_warning), "", "" },
104.  		     {   7, &(HFast), "quick", "slow" },
105.  		     {   9, &(HPoison_resistance), "hardy", "less healthy" },
106.  		     {   0, 0, 0, 0 } },
107.  
108.  	val_abil[] = { {	 1, &(HCold_resistance), "", "" },
109.  		     {	 1, &(HStealth), "", "" },
110.  		     {   7, &(HFast), "quick", "slow" },
111.  		     {	 0, 0, 0, 0 } },
112.  
113.  #ifdef YEOMAN
114.  	yeo_abil[] = {
115.  		     {   7, &(HFast), "quick", "slow" },
116.  		     {  15, &(HSwimming), "ready to swim","afraid of the water" },
117.  		     {   0, 0, 0, 0 } },
118.  #endif
119.  
120.  	wiz_abil[] = { {	15, &(HWarning), "sensitive", "" },
121.  		     {  17, &(HTeleport_control), "controlled","uncontrolled" },
122.  		     {	 0, 0, 0, 0 } },
123.  
124.  	/* Intrinsics conferred by race */
125.  	dop_abil[] = {/* {   1, &(HPolymorph), "", "" },*/
126.  		       {   9, &(HPolymorph_control), "your choices improve", "choiceless" },
127.  		       {   0, 0, 0, 0 } },
128.  
129.  #ifdef DWARF
130.  	dwa_abil[] = { { 1, &(HSearching), "", "" },
131.  /*			{  10, &(HFire_resistance), "cool", "warmer" },*/
132.  			{   0, 0, 0, 0 } },
133.  #endif
134.  
135.  	elf_abil[] = { {	4, &(HSleep_resistance), "awake", "tired" },
136.  		     {	 0, 0, 0, 0 } },
137.  
138.  	gno_abil[] = { {   5, &(HStealth), "stealthy", "" },
139.  /*		     {   9, &(HFast), "quick", "slow" },
140.  		     {   11, &(HSearching), "perceptive", "unaware" },*/
141.  		     {   0, 0, 0, 0 } },
142.  
143.  	hob_abil[] = { {  1, &(HStealth), "", "" },
144.  		     {   7, &(HFast), "quick", "slow" },
145.  		     {   0, 0, 0, 0 } },
146.  
147.  
148.  	lyc_abil[] = { /*{   1, &(HPoison_resistance), "", "" },*/
149.  		     {   1, &(HRegeneration), "", "" },
150.  /*		     {   7, &(HStealth), "stealthy", "" },*/
151.  		     {   0, 0, 0, 0 } },
152.  
153.  	orc_abil[] = { {	1, &(HPoison_resistance), "", "" },
154.  		     {	 0, 0, 0, 0 } };
155.  
156.  static long next_check = 600L;	/* arbitrary first setting */
157.  STATIC_DCL void NDECL(exerper);
158.  STATIC_DCL void FDECL(postadjabil, (long *));
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;	    /* 2 => no message at all, 1 => no message */
165.  			    /* except encumber, zero => message, and */
166.  {			    /* negative => conditional (msg if change made) */
167.  	if (Fixed_abil || !incr) return FALSE;
168.  
169.  	if ((ndx == A_INT || ndx == A_WIS)
170.  				&& uarmh && uarmh->otyp == DUNCE_CAP) {
171.  		if (msgflg == 0)
172.  		    Your("cap constricts briefly, then relaxes again.");
173.  		return FALSE;
174.  	}
175.  
176.  	if (incr > 0) {
177.  	    if ((AMAX(ndx) >= ATTRMAX(ndx)) && (ACURR(ndx) >= AMAX(ndx))) {
178.  		if (msgflg == 0 && flags.verbose)
179.  		    pline("You're already as %s as you can get.",
180.  			  plusattr[ndx]);
181.  		ABASE(ndx) = AMAX(ndx) = ATTRMAX(ndx); /* just in case */
182.  		return FALSE;
183.  	    }
184.  
185.  	    ABASE(ndx) += incr;
186.  	    if(ABASE(ndx) > AMAX(ndx)) {
187.  		incr = ABASE(ndx) - AMAX(ndx);
188.  		AMAX(ndx) += incr;
189.  		if(AMAX(ndx) > ATTRMAX(ndx))
190.  		    AMAX(ndx) = ATTRMAX(ndx);
191.  		ABASE(ndx) = AMAX(ndx);
192.  	    }
193.  	} else {
194.  	    if (ABASE(ndx) <= ATTRMIN(ndx)) {
195.  		if (msgflg == 0 && flags.verbose)
196.  		    pline("You're already as %s as you can get.",
197.  			  minusattr[ndx]);
198.  		ABASE(ndx) = ATTRMIN(ndx); /* just in case */
199.  		return FALSE;
200.  	    }
201.  
202.  	    ABASE(ndx) += incr;
203.  	    if(ABASE(ndx) < ATTRMIN(ndx)) {
204.  		incr = ABASE(ndx) - ATTRMIN(ndx);
205.  		ABASE(ndx) = ATTRMIN(ndx);
206.  		AMAX(ndx) += incr;
207.  		if(AMAX(ndx) < ATTRMIN(ndx))
208.  		    AMAX(ndx) = ATTRMIN(ndx);
209.  	    }
210.  	}
211.  	if (msgflg <= 0)
212.  	    You_feel("%s%s!",
213.  		  (incr > 1 || incr < -1) ? "very ": "",
214.  		  (incr > 0) ? plusattr[ndx] : minusattr[ndx]);
215.  	flags.botl = 1;
216.  	if (msgflg <= 1 && moves > 1 && (ndx == A_STR || ndx == A_CON))
217.  		(void)encumber_msg();
218.  	return TRUE;
219.  }
220.  
221.  void
222.  gainstr(otmp, incr)
223.  	register struct obj *otmp;
224.  	register int incr;
225.  {
226.  	int num = 1;
227.  
228.  	if(incr) num = incr;
229.  	else {
230.  	    if(ABASE(A_STR) < 18) num = (rn2(4) ? 1 : rnd(6) );
231.  	    else if (ABASE(A_STR) < STR18(85)) num = rnd(10);
232.  	}
233.  	(void) adjattrib(A_STR, (otmp && otmp->cursed) ? -num : num, TRUE);
234.  }
235.  
236.  void
237.  losestr(num)	/* may kill you; cause may be poison or monster like 'a' */
238.  	register int num;
239.  {
240.  	int ustr = ABASE(A_STR) - num;
241.  
242.  	while(ustr < 3) {
243.  	    ++ustr;
244.  	    --num;
245.  	    if (Upolyd) {
246.  		u.mh -= 6;
247.  		u.mhmax -= 6;
248.  	    } else {
249.  		u.uhp -= 6;
250.  		u.uhpmax -= 6;
251.  	    }
252.  	}
253.  	(void) adjattrib(A_STR, -num, TRUE);
254.  }
255.  
256.  void
257.  change_luck(n)
258.  	register schar n;
259.  {
260.  	u.uluck += n;
261.  	if (u.uluck < 0 && u.uluck < LUCKMIN)	u.uluck = LUCKMIN;
262.  	if (u.uluck > 0 && u.uluck > LUCKMAX)	u.uluck = LUCKMAX;
263.  }
264.  
265.  int
266.  stone_luck(parameter)
267.  boolean parameter; /* So I can't think up of a good name.  So sue me. --KAA */
268.  {
269.  	register struct obj *otmp;
270.  	register long bonchance = 0;
271.  
272.  	for (otmp = invent; otmp; otmp = otmp->nobj)
273.  	    if (confers_luck(otmp)) {
274.  		if (otmp->cursed) bonchance -= otmp->quan;
275.  		else if (otmp->blessed) bonchance += otmp->quan;
276.  		else if (parameter) bonchance += otmp->quan;
277.  	    }
278.  
279.  	/* STEPHEN WHITE'S NEW CODE */
280.  	if (uarmh && uarmh->otyp == FEDORA && !uarmh->cursed) bonchance += 2;
281.  	
282.  	return sgn((int)bonchance);
283.  }
284.  
285.  /* there has just been an inventory change affecting a luck-granting item */
286.  void
287.  set_moreluck()
288.  {
289.  	int luckbon = stone_luck(TRUE);
290.  
291.  	if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0;
292.  	else if (luckbon >= 0) u.moreluck = LUCKADD;
293.  	else u.moreluck = -LUCKADD;
294.  }
295.  
296.  
297.  /* KMH, balance patch -- new function for healthstones */
298.  void
299.  recalc_health()
300.  {
301.  	register struct obj *otmp;
302.  
303.  
304.  	u.uhealbonus = 0;
305.  	for(otmp = invent; otmp; otmp=otmp->nobj)
306.  	    if (otmp->otyp == HEALTHSTONE)
307.  	    	u.uhealbonus += otmp->quan *
308.  	    			(otmp->blessed ? 2 : otmp->cursed ? -2 : 1);
309.  	return;
310.  }
311.  
312.  
313.  #endif /* OVLB */
314.  #ifdef OVL1
315.  
316.  void
317.  restore_attrib()
318.  {
319.  	int	i;
320.  
321.  	for(i = 0; i < A_MAX; i++) {	/* all temporary losses/gains */
322.  
323.  	   if(ATEMP(i) && ATIME(i)) {
324.  		if(!(--(ATIME(i)))) { /* countdown for change */
325.  		    ATEMP(i) += ATEMP(i) > 0 ? -1 : 1;
326.  
327.  		    if(ATEMP(i)) /* reset timer */
328.  			ATIME(i) = 100 / ACURR(A_CON);
329.  		}
330.  	    }
331.  	}
332.  	(void)encumber_msg();
333.  }
334.  
335.  #endif /* OVL1 */
336.  #ifdef OVLB
337.  
338.  #define AVAL	50		/* tune value for exercise gains */
339.  
340.  void
341.  exercise(i, inc_or_dec)
342.  int	i;
343.  boolean	inc_or_dec;
344.  {
345.  #ifdef DEBUG
346.  	pline("Exercise:");
347.  #endif
348.  	if (i == A_INT || i == A_CHA) return;	/* can't exercise these */
349.  
350.  	/* no physical exercise while polymorphed; the body's temporary */
351.  	if (Upolyd && i != A_WIS) return;
352.  
353.  	if(abs(AEXE(i)) < AVAL) {
354.  		/*
355.  		 *	Law of diminishing returns (Part I):
356.  		 *
357.  		 *	Gain is harder at higher attribute values.
358.  		 *	79% at "3" --> 0% at "18"
359.  		 *	Loss is even at all levels (50%).
360.  		 *
361.  		 *	Note: *YES* ACURR is the right one to use.
362.  		 */
363.  		AEXE(i) += (inc_or_dec) ? (rn2(19) > ACURR(i)) : -rn2(2);
364.  #ifdef DEBUG
365.  		pline("%s, %s AEXE = %d",
366.  			(i == A_STR) ? "Str" : (i == A_WIS) ? "Wis" :
367.  			(i == A_DEX) ? "Dex" : "Con",
368.  			(inc_or_dec) ? "inc" : "dec", AEXE(i));
369.  #endif
370.  	}
371.  	if (moves > 0 && (i == A_STR || i == A_CON)) (void)encumber_msg();
372.  }
373.  
374.  /* hunger values - from eat.c */
375.  #define SATIATED	0
376.  #define NOT_HUNGRY	1
377.  #define HUNGRY		2
378.  #define WEAK		3
379.  #define FAINTING	4
380.  #define FAINTED		5
381.  #define STARVED		6
382.  
383.  STATIC_OVL void
384.  exerper()
385.  {
386.  	if(!(moves % 10)) {
387.  		/* Hunger Checks */
388.  
389.  		int hs = (u.uhunger > 1000) ? SATIATED :
390.  			 (u.uhunger > 150) ? NOT_HUNGRY :
391.  			 (u.uhunger > 50) ? HUNGRY :
392.  			 (u.uhunger > 0) ? WEAK : FAINTING;
393.  
394.  #ifdef DEBUG
395.  		pline("exerper: Hunger checks");
396.  #endif
397.  		switch (hs) {
398.  		    case SATIATED:	exercise(A_DEX, FALSE);
399.  					if (Role_if(PM_MONK))
400.  					    exercise(A_WIS, FALSE);
401.  					break;
402.  		    case NOT_HUNGRY:	exercise(A_CON, TRUE); break;
403.  		    case WEAK:		exercise(A_STR, FALSE);
404.  					if (Role_if(PM_MONK))	/* fasting */
405.  					    exercise(A_WIS, TRUE);
406.  					break;
407.  		    case FAINTING:
408.  		    case FAINTED:	exercise(A_CON, FALSE); break;
409.  		}
410.  
411.  		/* Encumberance Checks */
412.  #ifdef DEBUG
413.  		pline("exerper: Encumber checks");
414.  #endif
415.  		switch (near_capacity()) {
416.  		    case MOD_ENCUMBER:	exercise(A_STR, TRUE); break;
417.  		    case HVY_ENCUMBER:	exercise(A_STR, TRUE);
418.  					exercise(A_DEX, FALSE); break;
419.  		    case EXT_ENCUMBER:	exercise(A_DEX, FALSE);
420.  					exercise(A_CON, FALSE); break;
421.  		}
422.  
423.  	}
424.  
425.  	/* status checks */
426.  	if(!(moves % 5)) {
427.  #ifdef DEBUG
428.  		pline("exerper: Status checks");
429.  #endif
430.  		/* KMH, intrinsic patch */
431.  		if ((HClairvoyant & (INTRINSIC|TIMEOUT)) &&
432.  			!BClairvoyant)                      exercise(A_WIS, TRUE);
433.  		if (HRegeneration)			exercise(A_STR, TRUE);
434.  
435.  		if(Sick || Vomiting)     exercise(A_CON, FALSE);
436.  		if(Confusion || Hallucination)		exercise(A_WIS, FALSE);
437.  		if((Wounded_legs 
438.  #ifdef STEED
439.  		    && !u.usteed
440.  #endif
441.  			    ) || Fumbling || HStun)	exercise(A_DEX, FALSE);
442.  	}
443.  }
444.  
445.  void
446.  exerchk()
447.  {
448.  	int	i, mod_val;
449.  
450.  	/*	Check out the periodic accumulations */
451.  	exerper();
452.  
453.  #ifdef DEBUG
454.  	if(moves >= next_check)
455.  		pline("exerchk: ready to test. multi = %d.", multi);
456.  #endif
457.  	/*	Are we ready for a test?	*/
458.  	if(moves >= next_check && !multi) {
459.  #ifdef DEBUG
460.  	    pline("exerchk: testing.");
461.  #endif
462.  	    /*
463.  	     *	Law of diminishing returns (Part II):
464.  	     *
465.  	     *	The effects of "exercise" and "abuse" wear
466.  	     *	off over time.  Even if you *don't* get an
467.  	     *	increase/decrease, you lose some of the
468.  	     *	accumulated effects.
469.  	     *
470.  	     *  Note that if you are polymorphed then the
471.  	     *  effects of any physical exercise done in your
472.  	     *  own body will just wear off with no checking
473.  	     *  until you return to your natural form.
474.  	     */
475.  	    for(i = 0; i < A_MAX; AEXE(i++) /= 2) {
476.  
477.  		if(Upolyd && i != A_WIS) continue;
478.  		if(ABASE(i) >= 18 || !AEXE(i)) continue;
479.  		if(i == A_INT || i == A_CHA) continue;/* can't exercise these */
480.  
481.  #ifdef DEBUG
482.  		pline("exerchk: testing %s (%d).",
483.  			(i == A_STR) ? "Str" : (i == A_WIS) ? "Wis" :
484.  			(i == A_DEX) ? "Dex" : "Con", AEXE(i));
485.  #endif
486.  		/*
487.  		 *	Law of diminishing returns (Part III):
488.  		 *
489.  		 *	You don't *always* gain by exercising.
490.  		 *	[MRS 92/10/28 - Treat Wisdom specially for balance.]
491.  		 */
492.  		if(rn2(AVAL) > ((i != A_WIS) ? abs(AEXE(i)*2/3) : abs(AEXE(i))))
493.  		    continue;
494.  		mod_val = sgn(AEXE(i));
495.  
496.  #ifdef DEBUG
497.  		pline("exerchk: changing %d.", i);
498.  #endif
499.  		if(adjattrib(i, mod_val, -1)) {
500.  #ifdef DEBUG
501.  		    pline("exerchk: changed %d.", i);
502.  #endif
503.  		    /* if you actually changed an attrib - zero accumulation */
504.  		    AEXE(i) = 0;
505.  		    /* then print an explanation */
506.  		    switch(i) {
507.  		    case A_STR: You((mod_val >0) ?
508.  				    "must have been exercising." :
509.  				    "must have been abusing your body.");
510.  				break;
511.  		    case A_WIS: You((mod_val >0) ?
512.  				    "must have been very observant." :
513.  				    "haven't been paying attention.");
514.  				break;
515.  		    case A_DEX: You((mod_val >0) ?
516.  				    "must have been working on your reflexes." :
517.  				    "haven't been working on reflexes lately.");
518.  				break;
519.  		    case A_CON: You((mod_val >0) ?
520.  				    "must be leading a healthy life-style." :
521.  				    "haven't been watching your health.");
522.  				break;
523.  		    }
524.  		}
525.  	    }
526.  	    next_check += rn1(2000,2000);
527.  #ifdef DEBUG
528.  	    pline("exerchk: next check at %ld.", next_check);
529.  #endif
530.  	}
531.  }
532.  
533.  /* next_check will otherwise have its initial 600L after a game restore */
534.  void
535.  reset_attribute_clock()
536.  {
537.  	if (moves > 600L) next_check = moves + rn1(50,800);
538.  }
539.  
540.  
541.  void
542.  init_attr(np)
543.  	register int	np;
544.  {
545.  	register int	i, x, tryct;
546.  
547.  
548.  	for(i = 0; i < A_MAX; i++) {
549.  	    ABASE(i) = AMAX(i) = urole.attrbase[i];
550.  	    ATEMP(i) = ATIME(i) = 0;
551.  	    np -= urole.attrbase[i];
552.  	}
553.  
554.  	tryct = 0;
555.  	while(np > 0 && tryct < 100) {
556.  
557.  	    x = rn2(100);
558.  	    for (i = 0; (i < A_MAX) && ((x -= urole.attrdist[i]) > 0); i++) ;
559.  	    if(i >= A_MAX) continue; /* impossible */
560.  
561.  	    if(ABASE(i) >= ATTRMAX(i)) {
562.  
563.  		tryct++;
564.  		continue;
565.  	    }
566.  	    tryct = 0;
567.  	    ABASE(i)++;
568.  	    AMAX(i)++;
569.  	    np--;
570.  	}
571.  
572.  	tryct = 0;
573.  	while(np < 0 && tryct < 100) {		/* for redistribution */
574.  
575.  	    x = rn2(100);
576.  	    for (i = 0; (i < A_MAX) && ((x -= urole.attrdist[i]) > 0); i++) ;
577.  	    if(i >= A_MAX) continue; /* impossible */
578.  
579.  	    if(ABASE(i) <= ATTRMIN(i)) {
580.  
581.  		tryct++;
582.  		continue;
583.  	    }
584.  	    tryct = 0;
585.  	    ABASE(i)--;
586.  	    AMAX(i)--;
587.  	    np++;
588.  	}
589.  }
590.  
591.  void
592.  redist_attr()
593.  {
594.  	register int i, tmp;
595.  
596.  	for(i = 0; i < A_MAX; i++) {
597.  	    if (i==A_INT || i==A_WIS) continue;
598.  		/* Polymorphing doesn't change your mind */
599.  	    tmp = AMAX(i);
600.  	    AMAX(i) += (rn2(5)-2);
601.  	    if (AMAX(i) > ATTRMAX(i)) AMAX(i) = ATTRMAX(i);
602.  	    if (AMAX(i) < ATTRMIN(i)) AMAX(i) = ATTRMIN(i);
603.  	    ABASE(i) = ABASE(i) * AMAX(i) / tmp;
604.  	    /* ABASE(i) > ATTRMAX(i) is impossible */
605.  	    if (ABASE(i) < ATTRMIN(i)) ABASE(i) = ATTRMIN(i);
606.  	}
607.  	(void)encumber_msg();
608.  }
609.  
610.  STATIC_OVL
611.  void
612.  postadjabil(ability)
613.  long *ability;
614.  {
615.  	if (!ability) return;
616.  	if (ability == &(HWarning) || ability == &(HSee_invisible))
617.  		see_monsters();
618.  }
619.  
620.  void
621.  adjabil(oldlevel,newlevel)
622.  int oldlevel, newlevel;
623.  {
624.  	register const struct innate *abil, *rabil;
625.  	long mask = FROMEXPER;
626.  
627.  	switch (Role_switch) {
628.  	case PM_ARCHEOLOGIST:   abil = arc_abil;	break;
629.  	case PM_BARBARIAN:      abil = bar_abil;	break;
630.  	case PM_CAVEMAN:        abil = cav_abil;	break;
631.  	case PM_FLAME_MAGE:	abil = fla_abil;	break;
632.  	case PM_HEALER:         abil = hea_abil;	break;
633.  	case PM_ICE_MAGE:	abil = ice_abil;	break;
634.  	case PM_KNIGHT:         abil = kni_abil;	break;
635.  	case PM_MONK:           abil = mon_abil;	break;
636.  	case PM_NECROMANCER:	abil = nec_abil;	break;
637.  	case PM_PRIEST:         abil = pri_abil;	break;
638.  	case PM_RANGER:         abil = ran_abil;	break;
639.  	case PM_ROGUE:          abil = rog_abil;	break;
640.  	case PM_SAMURAI:        abil = sam_abil;	break;
641.  #ifdef TOURIST
642.  	case PM_TOURIST:        abil = tou_abil;	break;
643.  #endif
644.  	case PM_UNDEAD_SLAYER:	abil = und_abil;	break;
645.  	case PM_VALKYRIE:       abil = val_abil;	break;
646.  	case PM_WIZARD:         abil = wiz_abil;	break;
647.  #ifdef YEOMAN
648.  	case PM_YEOMAN:		abil = yeo_abil;	break;
649.  #endif
650.  	default:                abil = 0;		break;
651.  	}
652.  
653.  	switch (Race_switch) {
654.  	case PM_DOPPELGANGER:	rabil = dop_abil;	break;
655.  #ifdef DWARF
656.  	case PM_DWARF:		rabil = dwa_abil;	break;
657.  #endif
658.  	case PM_DROW:
659.  	case PM_ELF:            rabil = elf_abil;	break;
660.  	case PM_GNOME:		rabil = gno_abil;	break;
661.  	case PM_HOBBIT:		rabil = hob_abil;	break;
662.  	case PM_ORC:            rabil = orc_abil;	break;
663.  	case PM_HUMAN_WEREWOLF:	rabil = lyc_abil;	break;
664.  	case PM_HUMAN:
665.  	case PM_VAMPIRE:
666.  	default:                rabil = 0;		break;
667.  	}
668.  
669.  	while (abil || rabil) {
670.  	    long prevabil;
671.  	    /* Have we finished with the intrinsics list? */
672.  	    if (!abil || !abil->ability) {
673.  	    	/* Try the race intrinsics */
674.  	    	if (!rabil || !rabil->ability) break;
675.  	    	abil = rabil;
676.  	    	rabil = 0;
677.  	    	mask = FROMRACE;
678.  	    }
679.  		prevabil = *(abil->ability);
680.  		if(oldlevel < abil->ulevel && newlevel >= abil->ulevel) {
681.  			/* Abilities gained at level 1 can never be lost
682.  			 * via level loss, only via means that remove _any_
683.  			 * sort of ability.  A "gain" of such an ability from
684.  			 * an outside source is devoid of meaning, so we set
685.  			 * FROMOUTSIDE to avoid such gains.
686.  			 */
687.  			if (abil->ulevel == 1)
688.  				*(abil->ability) |= (mask|FROMOUTSIDE);
689.  			else
690.  				*(abil->ability) |= mask;
691.  			if(!(*(abil->ability) & INTRINSIC & ~mask)) {
692.  			    if(*(abil->gainstr))
693.  				You_feel("%s!", abil->gainstr);
694.  			}
695.  		} else if (oldlevel >= abil->ulevel && newlevel < abil->ulevel) {
696.  			*(abil->ability) &= ~mask;
697.  			if(!(*(abil->ability) & INTRINSIC)) {
698.  			    if(*(abil->losestr))
699.  				You_feel("%s!", abil->losestr);
700.  			    else if(*(abil->gainstr))
701.  				You_feel("less %s!", abil->gainstr);
702.  			}
703.  		}
704.  	    if (prevabil != *(abil->ability))	/* it changed */
705.  		postadjabil(abil->ability);
706.  	    abil++;
707.  	}
708.  
709.  	if (oldlevel > 0) {
710.  	    if (newlevel > oldlevel)
711.  		add_weapon_skill(newlevel - oldlevel);
712.  	    else
713.  		lose_weapon_skill(oldlevel - newlevel);
714.  	}
715.  
716.  	/* ALI -- update Warn_of_mon */
717.  	HWarn_of_mon = HUndead_warning;
718.  	if (HUndead_warning)
719.  	    flags.warntype |= M2_UNDEAD;
720.  	else
721.  	    flags.warntype &= ~M2_UNDEAD;
722.  	
723.  	/* WAC -- adjust techniques */
724.  	adjtech(oldlevel, newlevel);
725.  }
726.  
727.  
728.  /* STEPHEN WHITE'S NEW CODE */
729.  int
730.  newhp()
731.  {
732.  	int	hp, conplus;
733.  
734.  	if(u.ulevel == 0) {
735.  	    /* Initialize hit points */
736.  	    hp = urole.hpadv.infix + urace.hpadv.infix;
737.  	    if (urole.hpadv.inrnd > 0) hp += rnd(urole.hpadv.inrnd);
738.  	    if (urace.hpadv.inrnd > 0) hp += rnd(urace.hpadv.inrnd);
739.  
740.  	    /* Initialize alignment stuff */
741.  	    u.ualign.type = aligns[flags.initalign].value;
742.  	    u.ualign.record = urole.initrecord;
743.  		return hp;
744.  	} else {
745.  	    if (u.ulevel < urole.xlev) {
746.  	    	hp = urole.hpadv.lofix + urace.hpadv.lofix;
747.  	    	if (urole.hpadv.lornd > 0) hp += rnd(urole.hpadv.lornd);
748.  	    	if (urace.hpadv.lornd > 0) hp += rnd(urace.hpadv.lornd);
749.  	    } else {
750.  	    	hp = urole.hpadv.hifix + urace.hpadv.hifix;
751.  	    	if (urole.hpadv.hirnd > 0) hp += rnd(urole.hpadv.hirnd);
752.  	    	if (urace.hpadv.hirnd > 0) hp += rnd(urace.hpadv.hirnd);
753.  	    }
754.  	}
755.  
756.  	if (ACURR(A_CON) <= 3) conplus = -2;
757.  	else if (ACURR(A_CON) <= 6) conplus = -1;
758.  	else if (ACURR(A_CON) <= 14) conplus = 0;
759.  	else if (ACURR(A_CON) <= 16) conplus = 1;
760.  	else if (ACURR(A_CON) == 17) conplus = 2;
761.  	else if (ACURR(A_CON) == 18) conplus = 3;
762.  	else conplus = 4;
763.  	
764.  	hp += conplus;
765.  	return((hp <= 0) ? 1 : hp);
766.  }
767.  
768.  #endif /* OVLB */
769.  #ifdef OVL0
770.  
771.  /* STEPHEN WHITE'S NEW CODE */   
772.  schar
773.  acurr(x)
774.  int x;
775.  {
776.  	register int tmp = (u.abon.a[x] + u.atemp.a[x] + u.acurr.a[x]);
777.  
778.  	if (x == A_STR) {
779.                  /* WAC twiddle so that wearing rings and gauntlets have
780.                          a bonus */
781.                  /* robe of weakness and gauntlets of power will cancel */
782.                  int base = u.acurr.a[x];
783.                  int bonus = tmp - base;
784.                  boolean nobonus = (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER
785.                          && uarm && uarm->otyp == ROBE_OF_WEAKNESS);
786.  
787.                  if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER && !nobonus) {
788.                          if ((uarmg->spe > 7)
789.                               || ((118 + bonus + uarmg->spe) > 125)
790.                               || ((tmp + uarmg->spe) > 125))
791.                                  return(125);
792.                          else if (base > 118) return (base + uarmg->spe + bonus);
793.                          else return(118 + uarmg->spe + bonus);
794.                  } else if (uarm && uarm->otyp == ROBE_OF_WEAKNESS && !nobonus)
795.                          return(3 + bonus);
796.  		else return((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp);
797.  	} else if (x == A_CHA) {
798.  		if (tmp < 18 && (youmonst.data->mlet == S_NYMPH ||
799.  		    u.umonnum == PM_SUCCUBUS || u.umonnum == PM_INCUBUS))
800.  		    tmp = 18;
801.  		if (uarmh && uarmh->otyp == FEDORA) tmp += 1;        
802.  		return((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp);
803.  	} else if (x == A_INT || x == A_WIS) {
804.  		/* yes, this may raise int/wis if player is sufficiently
805.  		 * stupid.  there are lower levels of cognition than "dunce".
806.  		 */
807.  		if (uarmh && uarmh->otyp == DUNCE_CAP) return(6);
808.  	}
809.  #ifdef WIN32_BUG
810.  	return(x=((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp));
811.  #else
812.  	return((schar)((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp));
813.  #endif
814.  }
815.  
816.  /* condense clumsy ACURR(A_STR) value into value that fits into game formulas
817.   */
818.  schar
819.  acurrstr()
820.  {
821.  	register int str = ACURR(A_STR);
822.  
823.  	if (str <= 18) return str;
824.  	if (str <= 121) return (19 + str / 50); /* map to 19-21 */
825.  	else return str - 100;
826.  }
827.  
828.  #endif /* OVL0 */
829.  #ifdef OVL2
830.  
831.  /* avoid possible problems with alignment overflow, and provide a centralized
832.   * location for any future alignment limits
833.   */
834.  void
835.  adjalign(n)
836.  register int n;
837.  {
838.  	register int newalign = u.ualign.record + n;
839.  
840.  	if (n < 0) {
841.  		if (newalign < u.ualign.record)
842.  			u.ualign.record = newalign;
843.  	} else
844.  		if (newalign > u.ualign.record) {
845.  			u.ualign.record = newalign;
846.  			if(u.ualign.record > ALIGNLIM)
847.  				u.ualign.record = ALIGNLIM;
848.  		}
849.  }
850.  
851.  #endif /* OVL2 */
852.  
853.  /*attrib.c*/