Source:NetHack 3.1.0/attrib.c

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

Warning! This is the source code from an old release. For the latest release, see Source code

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