Source:NetHack 3.4.0/exper.c

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

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

1.   /*	SCCS Id: @(#)exper.c	3.4	2002/01/15	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   STATIC_DCL long FDECL(newuexp, (int)); 8.   STATIC_DCL int FDECL(enermod, (int)); 9.    10.   STATIC_OVL long 11.  newuexp(lev) 12.  int lev; 13.  {  14.   	if (lev < 10) return (10L * (1L << lev)); 15.  	if (lev < 20) return (10000L * (1L << (lev - 10))); 16.  	return (10000000L * ((long)(lev - 19))); 17.  }  18.    19.   STATIC_OVL int 20.  enermod(en) 21.  int en; 22.  {  23.   	switch (Role_switch) { 24.  	case PM_PRIEST: 25.  	case PM_WIZARD: 26.  	    return(2 * en); 27.  	case PM_HEALER: 28.  	case PM_KNIGHT: 29.  	    return((3 * en) / 2); 30.  	case PM_BARBARIAN: 31.  	case PM_VALKYRIE: 32.  	    return((3 * en) / 4); 33.  	default: 34.  	    return (en); 35.  	}  36.   }  37.    38.   int 39.  experience(mtmp, nk)	/* return # of exp points for mtmp after nk killed */ 40.  	register struct	monst *mtmp; 41.  	register int	nk; 42.  #if defined(macintosh) && (defined(__SC__) || defined(__MRC__)) 43.  # pragma unused(nk) 44.  #endif 45.  {  46.   	register struct permonst *ptr = mtmp->data; 47.  	int	i, tmp, tmp2; 48.   49.   	tmp = 1 + mtmp->m_lev * mtmp->m_lev; 50.   51.   /*	For higher ac values, give extra experience */ 52.  	if((i = find_mac(mtmp)) < 3) tmp += (7 - i) * (i < 0) ? 2 : 1; 53.    54.   /*	For very fast monsters, give extra experience */ 55.  	if(ptr->mmove >= 12) tmp += (ptr->mmove >= 18) ? 5 : 3; 56.    57.   /*	For each "special" attack type give extra experience */ 58.  	for(i = 0; i < NATTK; i++) { 59.   60.   	    tmp2 = ptr->mattk[i].aatyp; 61.  	    if(tmp2 > AT_BUTT) { 62.   63.   		if(tmp2 == AT_WEAP) tmp += 5; 64.  		else if(tmp2 == AT_MAGC) tmp += 10; 65.  		else tmp += 3; 66.  	    }  67.   	}  68.    69.   /*	For each "special" damage type give extra experience */ 70.  	for(i = 0; i < NATTK; i++) { 71.  	    tmp2 = ptr->mattk[i].adtyp; 72.  	    if(tmp2 > AD_PHYS && tmp2 < AD_BLND) tmp += 2*mtmp->m_lev; 73.  	    else if((tmp2 == AD_DRLI) || (tmp2 == AD_STON) ||  74.   	    		(tmp2 == AD_SLIM)) tmp += 50; 75.  	    else if(tmp != AD_PHYS) tmp += mtmp->m_lev; 76.  		/* extra heavy damage bonus */ 77.  	    if((int)(ptr->mattk[i].damd * ptr->mattk[i].damn) > 23) 78.  		tmp += mtmp->m_lev; 79.  	    if (tmp2 == AD_WRAP && ptr->mlet == S_EEL && !Amphibious) 80.  		tmp += 1000; 81.  	}  82.    83.   /*	For certain "extra nasty" monsters, give even more */ 84.  	if (extra_nasty(ptr)) tmp += (7 * mtmp->m_lev); 85.   86.   /*	For higher level monsters, an additional bonus is given */ 87.  	if(mtmp->m_lev > 8) tmp += 50; 88.   89.   #ifdef MAIL 90.  	/* Mail daemons put up no fight. */ 91.   	if(mtmp->data == &mons[PM_MAIL_DAEMON]) tmp = 1; 92.  #endif 93.   94.   	return(tmp); 95.  }  96.    97.   void 98.  more_experienced(exp, rexp) 99.  	register int exp, rexp; 100. {  101.  	u.uexp += exp; 102. 	u.urexp += 4*exp + rexp; 103. 	if(exp  104.  #ifdef SCORE_ON_BOTL  105.  	   || flags.showscore  106.  #endif  107.  	   ) flags.botl = 1; 108. 	if (u.urexp >= (Role_if(PM_WIZARD) ? 1000 : 2000)) 109.  		flags.beginner = 0; 110. }  111.   112.  void 113. losexp(drainer)		/* e.g., hit by drain life attack */ 114. const char *drainer;	/* cause of death, if drain should be fatal */ 115. {  116.  	register int num; 117.  118.  	if (resists_drli(&youmonst)) return; 119.  120.  	if (u.ulevel > 1) { 121. 		pline("%s level %d.", Goodbye, u.ulevel--); 122. 		/* remove intrinsic abilities */ 123. 		adjabil(u.ulevel + 1, u.ulevel); 124. 		reset_rndmonst(NON_PM);	/* new monster selection */ 125. 	} else { 126. 		if (drainer) { 127. 			killer_format = KILLED_BY; 128. 			killer = drainer; 129. 			done(DIED); 130. 		}  131.  		/* no drainer or lifesaved */ 132. 		u.uexp = 0; 133. 	}  134.  	num = newhp; 135. 	u.uhpmax -= num; 136. 	if (u.uhpmax < 1) u.uhpmax = 1; 137. 	u.uhp -= num; 138. 	if (u.uhp < 1) u.uhp = 1; 139. 	else if (u.uhp > u.uhpmax) u.uhp = u.uhpmax; 140.  141.  	if (u.ulevel < urole.xlev) 142. 	    num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.lornd + urace.enadv.lornd,  143.  	    		urole.enadv.lofix + urace.enadv.lofix); 144. 	else 145. 	    num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.hirnd + urace.enadv.hirnd,  146.  	    		urole.enadv.hifix + urace.enadv.hifix); 147. 	num = enermod(num);		/* M. Stephenson */ 148. 	u.uenmax -= num; 149. 	if (u.uenmax < 0) u.uenmax = 0; 150. 	u.uen -= num; 151. 	if (u.uen < 0) u.uen = 0; 152. 	else if (u.uen > u.uenmax) u.uen = u.uenmax; 153.  154.  	if (u.uexp > 0) 155. 		u.uexp = newuexp(u.ulevel) - 1; 156. 	flags.botl = 1; 157. }  158.   159.  /*  160.   * Make experience gaining similar to AD&D(tm), whereby you can at most go  161. * up by one level at a time, extra expr possibly helping you along. 162.  * After all, how much real experience does one get shooting a wand of death 163.  * at a dragon created with a wand of polymorph?? 164.  */  165.  void 166. newexplevel 167. {  168.  	if (u.ulevel < MAXULEV && u.uexp >= newuexp(u.ulevel)) 169. 	    pluslvl(TRUE); 170. }  171.   172.  void 173. pluslvl(incr) 174. boolean incr;	/* true iff via incremental experience growth */ 175. {		/*	(false for potion of gain level)      */ 176. 	register int num; 177.  178.  	if (!incr) You_feel("more experienced."); 179. 	num = newhp; 180. 	u.uhpmax += num; 181. 	u.uhp += num; 182. 	if (Upolyd) { 183. 	    num = rnd(8); 184. 	    u.mhmax += num; 185. 	    u.mh += num; 186. 	}  187.  	if (u.ulevel < urole.xlev) 188. 	    num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.lornd + urace.enadv.lornd,  189.  			urole.enadv.lofix + urace.enadv.lofix); 190. 	else 191. 	    num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.hirnd + urace.enadv.hirnd,  192.  			urole.enadv.hifix + urace.enadv.hifix); 193. 	num = enermod(num);	/* M. Stephenson */ 194. 	u.uenmax += num; 195. 	u.uen += num; 196. 	if (u.ulevel < MAXULEV) { 197. 	    if (incr) { 198. 		long tmp = newuexp(u.ulevel + 1); 199. 		if (u.uexp >= tmp) u.uexp = tmp - 1; 200. 	    } else { 201. 		u.uexp = newuexp(u.ulevel); 202. 	    }  203.  	    ++u.ulevel; 204. 	    if (u.ulevelmax < u.ulevel) u.ulevelmax = u.ulevel; 205. 	    pline("Welcome to experience level %d.", u.ulevel); 206. 	    adjabil(u.ulevel - 1, u.ulevel);	/* give new intrinsics */ 207. 	    reset_rndmonst(NON_PM);		/* new monster selection */ 208. 	}  209.  	flags.botl = 1; 210. }  211.   212.  long 213. rndexp 214. {  215.  	long minexp, maxexp, diff, factor; 216.  217.  	minexp = (u.ulevel == 1) ? 0L : newuexp(u.ulevel - 1); 218. 	maxexp = newuexp(u.ulevel); 219. 	diff = maxexp - minexp,  factor = 1L; 220. 	while (diff >= (long)LARGEST_INT) 221. 	    diff /= 2L,  factor *= 2L; 222. 	return minexp + factor * (long)rn2((int)diff); 223. }  224.   225.  /*exper.c*/