Source:SLASH'EM 0.0.7E7F2/attrib.c

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.

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