Wikihack
Advertisement

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.

Top of file[]

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.
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.   

innate[]

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.  

adjattrib[]

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.  

gainstr[]

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.  

losestr[]

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.  

change_luck[]

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.  

stone_luck[]

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.  

set_moreluck[]

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 */

restore_attrib[]

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 */

exercise[]

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.  

exercise() is called whenever one of Hero's attributes is being exercised. This means there's a change that attribute will go up or down. Takes two parameters, first is the attribute to exercise (A_STR, A_WIS, A_DEX or A_CON) and the second is TRUE if it should go up or FALSE if down.

exerper[]

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.  

exerchk[]

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.  

reset_attribute_clock[]

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.  

init_attr[]

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.  

redist_attr[]

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.  

postadjabil[]

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.  

adjabil[]

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.  

newhp[]

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 */

acurr[]

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.  

acurrstr[]

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 */

adjalign[]

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*/
Advertisement