Source:NetHack 3.4.3/src/attrib.c

From NetHackWiki
Revision as of 09:37, 22 June 2006 by Jaytbot (talk | contribs) (Automated source code upload)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Below is the full text to src/attrib.c from NetHack 3.4.3. To link to a particular line, write [[attrib.c#line123]], for example.

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.    

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.

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