1 /* NetHack 3.6 exper.c $NHDT-Date: 1553296396 2019/03/22 23:13:16 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.32 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2007. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
9 /* JNetHack may be freely redistributed. See license for details. */
16 STATIC_DCL int FDECL(enermod, (int));
23 return (10L * (1L << lev));
25 return (10000L * (1L << (lev - 10)));
26 return (10000000L * ((long) (lev - 19)));
33 switch (Role_switch) {
39 return ((3 * en) / 2);
42 return ((3 * en) / 4);
48 /* calculate spell power/energy points for new level */
52 int en = 0, enrnd, enfix;
55 en = urole.enadv.infix + urace.enadv.infix;
56 if (urole.enadv.inrnd > 0)
57 en += rnd(urole.enadv.inrnd);
58 if (urace.enadv.inrnd > 0)
59 en += rnd(urace.enadv.inrnd);
61 enrnd = (int) ACURR(A_WIS) / 2;
62 if (u.ulevel < urole.xlev) {
63 enrnd += urole.enadv.lornd + urace.enadv.lornd;
64 enfix = urole.enadv.lofix + urace.enadv.lofix;
66 enrnd += urole.enadv.hirnd + urace.enadv.hirnd;
67 enfix = urole.enadv.hifix + urace.enadv.hifix;
69 en = enermod(rn1(enrnd, enfix));
73 if (u.ulevel < MAXULEV)
74 u.ueninc[u.ulevel] = (xchar) en;
78 /* return # of exp points for mtmp after nk killed */
81 register struct monst *mtmp;
84 register struct permonst *ptr = mtmp->data;
87 tmp = 1 + mtmp->m_lev * mtmp->m_lev;
89 /* For higher ac values, give extra experience */
90 if ((i = find_mac(mtmp)) < 3)
91 tmp += (7 - i) * ((i < 0) ? 2 : 1);
93 /* For very fast monsters, give extra experience */
94 if (ptr->mmove > NORMAL_SPEED)
95 tmp += (ptr->mmove > (3 * NORMAL_SPEED / 2)) ? 5 : 3;
97 /* For each "special" attack type give extra experience */
98 for (i = 0; i < NATTK; i++) {
99 tmp2 = ptr->mattk[i].aatyp;
100 if (tmp2 > AT_BUTT) {
103 else if (tmp2 == AT_MAGC)
110 /* For each "special" damage type give extra experience */
111 for (i = 0; i < NATTK; i++) {
112 tmp2 = ptr->mattk[i].adtyp;
113 if (tmp2 > AD_PHYS && tmp2 < AD_BLND)
114 tmp += 2 * mtmp->m_lev;
115 else if ((tmp2 == AD_DRLI) || (tmp2 == AD_STON) || (tmp2 == AD_SLIM))
117 else if (tmp2 != AD_PHYS)
119 /* extra heavy damage bonus */
120 if ((int) (ptr->mattk[i].damd * ptr->mattk[i].damn) > 23)
122 if (tmp2 == AD_WRAP && ptr->mlet == S_EEL && !Amphibious)
126 /* For certain "extra nasty" monsters, give even more */
127 if (extra_nasty(ptr))
128 tmp += (7 * mtmp->m_lev);
130 /* For higher level monsters, an additional bonus is given */
135 /* Mail daemons put up no fight. */
136 if (mtmp->data == &mons[PM_MAIL_DAEMON])
140 if (mtmp->mrevived || mtmp->mcloned) {
142 * Reduce experience awarded for repeated killings of
143 * "the same monster". Kill count includes all of this
144 * monster's type which have been killed--including the
145 * current monster--regardless of how they were created.
146 * 1.. 20 full experience
154 for (i = 0, tmp2 = 20; nk > tmp2 && tmp > 1; ++i) {
166 more_experienced(exper, rexp)
167 register int exper, rexp;
169 long oldexp = u.uexp,
171 newexp = oldexp + exper,
172 rexpincr = 4 * exper + rexp,
173 newrexp = oldrexp + rexpincr;
175 /* cap experience and score on wraparound */
176 if (newexp < 0 && exper > 0)
178 if (newrexp < 0 && rexpincr > 0)
181 if (newexp != oldexp) {
186 /* newrexp will always differ from oldrexp unless they're LONG_MAX */
187 if (newrexp != oldrexp) {
194 if (u.urexp >= (Role_if(PM_WIZARD) ? 1000 : 2000))
198 /* e.g., hit by drain life attack */
201 const char *drainer; /* cause of death, if drain should be fatal */
205 /* override life-drain resistance when handling an explicit
206 wizard mode request to reduce level; never fatal though */
207 if (drainer && !strcmp(drainer, "#levelchange"))
209 else if (resists_drli(&youmonst))
214 pline("%s level %d.", Goodbye(), u.ulevel--);
216 pline("
\82³
\82æ
\82¤
\82È
\82ç
\83\8c\83x
\83\8b%d
\81D", u.ulevel--);
217 /* remove intrinsic abilities */
218 adjabil(u.ulevel + 1, u.ulevel);
219 reset_rndmonst(NON_PM); /* new monster selection */
222 killer.format = KILLED_BY;
223 if (killer.name != drainer)
224 Strcpy(killer.name, drainer);
227 /* no drainer or lifesaved */
230 num = (int) u.uhpinc[u.ulevel];
237 else if (u.uhp > u.uhpmax)
240 num = (int) u.ueninc[u.ulevel];
247 else if (u.uen > u.uenmax)
251 u.uexp = newuexp(u.ulevel) - 1;
254 num = monhp_per_lvl(&youmonst);
265 * Make experience gaining similar to AD&D(tm), whereby you can at most go
266 * up by one level at a time, extra expr possibly helping you along.
267 * After all, how much real experience does one get shooting a wand of death
268 * at a dragon created with a wand of polymorph??
273 if (u.ulevel < MAXULEV && u.uexp >= newuexp(u.ulevel))
279 boolean incr; /* true iff via incremental experience growth */
280 { /* (false for potion of gain level) */
285 You_feel("more experienced.");
287 You("
\82æ
\82è
\8co
\8c±
\82ð
\82Â
\82ñ
\82¾
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
289 /* increase hit points (when polymorphed, do monster form first
290 in order to retain normal human/whatever increase for later) */
292 hpinc = monhp_per_lvl(&youmonst);
300 /* increase spell power/energy points */
305 /* increase level (unless already maxxed) */
306 if (u.ulevel < MAXULEV) {
307 /* increase experience points to reflect new level */
309 long tmp = newuexp(u.ulevel + 1);
313 u.uexp = newuexp(u.ulevel);
317 pline("Welcome %sto experience level %d.",
318 u.ulevelmax < u.ulevel ? "" : "back ",
321 pline("%s
\83\8c\83x
\83\8b%d
\82É
\82æ
\82¤
\82±
\82»
\81D",
322 u.ulevelmax < u.ulevel ? "" : "
\8dÄ
\82Ñ",
325 if (u.ulevelmax < u.ulevel)
326 u.ulevelmax = u.ulevel;
327 adjabil(u.ulevel - 1, u.ulevel); /* give new intrinsics */
328 reset_rndmonst(NON_PM); /* new monster selection */
333 /* compute a random amount of experience points suitable for the hero's
334 experience level: base number of points needed to reach the current
335 level plus a random portion of what it takes to get to the next level */
338 boolean gaining; /* gaining XP via potion vs setting XP for polyself */
340 long minexp, maxexp, diff, factor, result;
342 minexp = (u.ulevel == 1) ? 0L : newuexp(u.ulevel - 1);
343 maxexp = newuexp(u.ulevel);
344 diff = maxexp - minexp, factor = 1L;
345 /* make sure that `diff' is an argument which rn2() can handle */
346 while (diff >= (long) LARGEST_INT)
347 diff /= 2L, factor *= 2L;
348 result = minexp + factor * (long) rn2((int) diff);
349 /* 3.4.1: if already at level 30, add to current experience
350 points rather than to threshold needed to reach the current
351 level; otherwise blessed potions of gain level can result
352 in lowering the experience points instead of raising them */
353 if (u.ulevel == MAXULEV && gaining) {
354 result += (u.uexp - minexp);
355 /* avoid wrapping (over 400 blessed potions needed for that...) */