Source:NetHack 3.3.0/exper.c

Below is the full text to exper.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.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.3	97/01/29	*/ 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(applec) 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		/* hit by drain life attack */ 114. {  115.  	register int num; 116.  117.  	if (resists_drli(&youmonst)) return; 118.  119.  	if(u.ulevel > 1) { 120. 		pline("%s level %d.", Goodbye, u.ulevel--); 121. 		/* remove intrinsic abilities */ 122. 		adjabil(u.ulevel + 1, u.ulevel); 123. 		reset_rndmonst(NON_PM);	/* new monster selection */ 124. 	} else 125. 		u.uhp = -1; 126. 	num = newhp; 127. 	u.uhp -= num; 128. 	u.uhpmax -= num; 129. 	if (u.ulevel < urole.xlev) 130. 	    num = rn1(u.ulevel/2 + urole.enadv.lornd + urace.enadv.lornd,  131.  	    		urole.enadv.lofix + urace.enadv.lofix); 132. 	else 133. 	    num = rn1(u.ulevel/2 + urole.enadv.hirnd + urace.enadv.hirnd,  134.  	    		urole.enadv.hifix + urace.enadv.hifix); 135. 	num = enermod(num);		/* M. Stephenson */ 136. 	u.uen -= num; 137. 	if (u.uen < 0)		u.uen = 0; 138. 	u.uenmax -= num; 139. 	if (u.uenmax < 0)	u.uenmax = 0; 140. 	u.uexp = newuexp(u.ulevel) - 1; 141. 	flags.botl = 1; 142. }  143.   144.  /*  145.   * Make experience gaining similar to AD&D(tm), whereby you can at most go  146. * up by one level at a time, extra expr possibly helping you along. 147.  * After all, how much real experience does one get shooting a wand of death 148.  * at a dragon created with a wand of polymorph?? 149.  */  150.  void 151. newexplevel 152. {  153.  	if (u.ulevel < MAXULEV && u.uexp >= newuexp(u.ulevel)) 154. 	    pluslvl(TRUE); 155. }  156.   157.  void 158. pluslvl(incr) 159. boolean incr;	/* true iff via incremental experience growth */ 160. {		/*	(false for potion of gain level)      */ 161. 	register int num; 162.  163.  	if (!incr) You_feel("more experienced."); 164. 	num = newhp; 165. 	u.uhpmax += num; 166. 	u.uhp += num; 167. 	if (u.ulevel < urole.xlev) 168. 	    num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.lornd + urace.enadv.lornd,  169.  	    		urole.enadv.lofix + urace.enadv.lofix); 170. 	else 171. 	    num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.hirnd + urace.enadv.hirnd,  172.  	    		urole.enadv.hifix + urace.enadv.hifix); 173. 	num = enermod(num);	/* M. Stephenson */ 174. 	u.uenmax += num; 175. 	u.uen += num; 176. 	if (u.ulevel < MAXULEV) { 177. 	    if (incr) { 178. 		long tmp = newuexp(u.ulevel + 1); 179. 		if (u.uexp >= tmp) u.uexp = tmp - 1; 180. 	    } else { 181. 		u.uexp = newuexp(u.ulevel); 182. 	    }  183.  	    ++u.ulevel; 184. 	    if (u.ulevelmax < u.ulevel) u.ulevelmax = u.ulevel; 185. 	    pline("Welcome to experience level %d.", u.ulevel); 186. 	    adjabil(u.ulevel - 1, u.ulevel);	/* give new intrinsics */ 187. 	    reset_rndmonst(NON_PM);		/* new monster selection */ 188. 	}  189.  	flags.botl = 1; 190. }  191.   192.  long 193. rndexp 194. {  195.  	long minexp, maxexp, diff, factor; 196.  197.  	minexp = (u.ulevel == 1) ? 0L : newuexp(u.ulevel - 1); 198. 	maxexp = newuexp(u.ulevel); 199. 	diff = maxexp - minexp,  factor = 1L; 200. 	while (diff >= (long)LARGEST_INT) 201. 	    diff /= 2L,  factor *= 2L; 202. 	return minexp + factor * (long)rn2((int)diff); 203. }  204.   205.  /*exper.c*/