Source:NetHack 3.2.0/attrib.c

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

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

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