*** empty log message ***
This commit is contained in:
220
src/exper.c
Normal file
220
src/exper.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/* SCCS Id: @(#)exper.c 3.3 2000/07/23 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
STATIC_DCL long FDECL(newuexp, (int));
|
||||
STATIC_DCL int FDECL(enermod, (int));
|
||||
|
||||
STATIC_OVL long
|
||||
newuexp(lev)
|
||||
int lev;
|
||||
{
|
||||
if (lev < 10) return (10L * (1L << lev));
|
||||
if (lev < 20) return (10000L * (1L << (lev - 10)));
|
||||
return (10000000L * ((long)(lev - 19)));
|
||||
}
|
||||
|
||||
STATIC_OVL int
|
||||
enermod(en)
|
||||
int en;
|
||||
{
|
||||
switch (Role_switch) {
|
||||
case PM_PRIEST:
|
||||
case PM_WIZARD:
|
||||
return(2 * en);
|
||||
case PM_HEALER:
|
||||
case PM_KNIGHT:
|
||||
return((3 * en) / 2);
|
||||
case PM_BARBARIAN:
|
||||
case PM_VALKYRIE:
|
||||
return((3 * en) / 4);
|
||||
default:
|
||||
return (en);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
experience(mtmp, nk) /* return # of exp points for mtmp after nk killed */
|
||||
register struct monst *mtmp;
|
||||
register int nk;
|
||||
#if defined(applec)
|
||||
# pragma unused(nk)
|
||||
#endif
|
||||
{
|
||||
register struct permonst *ptr = mtmp->data;
|
||||
int i, tmp, tmp2;
|
||||
|
||||
tmp = 1 + mtmp->m_lev * mtmp->m_lev;
|
||||
|
||||
/* For higher ac values, give extra experience */
|
||||
if((i = find_mac(mtmp)) < 3) tmp += (7 - i) * (i < 0) ? 2 : 1;
|
||||
|
||||
/* For very fast monsters, give extra experience */
|
||||
if(ptr->mmove >= 12) tmp += (ptr->mmove >= 18) ? 5 : 3;
|
||||
|
||||
/* For each "special" attack type give extra experience */
|
||||
for(i = 0; i < NATTK; i++) {
|
||||
|
||||
tmp2 = ptr->mattk[i].aatyp;
|
||||
if(tmp2 > AT_BUTT) {
|
||||
|
||||
if(tmp2 == AT_WEAP) tmp += 5;
|
||||
else if(tmp2 == AT_MAGC) tmp += 10;
|
||||
else tmp += 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* For each "special" damage type give extra experience */
|
||||
for(i = 0; i < NATTK; i++) {
|
||||
tmp2 = ptr->mattk[i].adtyp;
|
||||
if(tmp2 > AD_PHYS && tmp2 < AD_BLND) tmp += 2*mtmp->m_lev;
|
||||
else if((tmp2 == AD_DRLI) || (tmp2 == AD_STON) ||
|
||||
(tmp2 == AD_SLIM)) tmp += 50;
|
||||
else if(tmp != AD_PHYS) tmp += mtmp->m_lev;
|
||||
/* extra heavy damage bonus */
|
||||
if((int)(ptr->mattk[i].damd * ptr->mattk[i].damn) > 23)
|
||||
tmp += mtmp->m_lev;
|
||||
if (tmp2 == AD_WRAP && ptr->mlet == S_EEL && !Amphibious)
|
||||
tmp += 1000;
|
||||
}
|
||||
|
||||
/* For certain "extra nasty" monsters, give even more */
|
||||
if (extra_nasty(ptr)) tmp += (7 * mtmp->m_lev);
|
||||
|
||||
/* For higher level monsters, an additional bonus is given */
|
||||
if(mtmp->m_lev > 8) tmp += 50;
|
||||
|
||||
#ifdef MAIL
|
||||
/* Mail daemons put up no fight. */
|
||||
if(mtmp->data == &mons[PM_MAIL_DAEMON]) tmp = 1;
|
||||
#endif
|
||||
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
void
|
||||
more_experienced(exp, rexp)
|
||||
register int exp, rexp;
|
||||
{
|
||||
u.uexp += exp;
|
||||
u.urexp += 4*exp + rexp;
|
||||
if(exp
|
||||
#ifdef SCORE_ON_BOTL
|
||||
|| flags.showscore
|
||||
#endif
|
||||
) flags.botl = 1;
|
||||
if (u.urexp >= (Role_if(PM_WIZARD) ? 1000 : 2000))
|
||||
flags.beginner = 0;
|
||||
}
|
||||
|
||||
void
|
||||
losexp(drainer) /* e.g., hit by drain life attack */
|
||||
const char *drainer; /* cause of death, if drain should be fatal */
|
||||
{
|
||||
register int num;
|
||||
|
||||
if (resists_drli(&youmonst)) return;
|
||||
|
||||
if (u.ulevel > 1) {
|
||||
pline("%s level %d.", Goodbye(), u.ulevel--);
|
||||
/* remove intrinsic abilities */
|
||||
adjabil(u.ulevel + 1, u.ulevel);
|
||||
reset_rndmonst(NON_PM); /* new monster selection */
|
||||
} else {
|
||||
if (drainer) {
|
||||
killer_format = KILLED_BY;
|
||||
killer = drainer;
|
||||
done(DIED);
|
||||
}
|
||||
/* no drainer or lifesaved */
|
||||
u.uexp = 0;
|
||||
}
|
||||
num = newhp();
|
||||
u.uhpmax -= num;
|
||||
if (u.uhpmax < 1) u.uhpmax = 1;
|
||||
u.uhp -= num;
|
||||
if (u.uhp < 1) u.uhp = 1;
|
||||
else if (u.uhp > u.uhpmax) u.uhp = u.uhpmax;
|
||||
|
||||
if (u.ulevel < urole.xlev)
|
||||
num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.lornd + urace.enadv.lornd,
|
||||
urole.enadv.lofix + urace.enadv.lofix);
|
||||
else
|
||||
num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.hirnd + urace.enadv.hirnd,
|
||||
urole.enadv.hifix + urace.enadv.hifix);
|
||||
num = enermod(num); /* M. Stephenson */
|
||||
u.uenmax -= num;
|
||||
if (u.uenmax < 0) u.uenmax = 0;
|
||||
u.uen -= num;
|
||||
if (u.uen < 0) u.uen = 0;
|
||||
else if (u.uen > u.uenmax) u.uen = u.uenmax;
|
||||
|
||||
if (u.uexp > 0)
|
||||
u.uexp = newuexp(u.ulevel) - 1;
|
||||
flags.botl = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make experience gaining similar to AD&D(tm), whereby you can at most go
|
||||
* up by one level at a time, extra expr possibly helping you along.
|
||||
* After all, how much real experience does one get shooting a wand of death
|
||||
* at a dragon created with a wand of polymorph??
|
||||
*/
|
||||
void
|
||||
newexplevel()
|
||||
{
|
||||
if (u.ulevel < MAXULEV && u.uexp >= newuexp(u.ulevel))
|
||||
pluslvl(TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
pluslvl(incr)
|
||||
boolean incr; /* true iff via incremental experience growth */
|
||||
{ /* (false for potion of gain level) */
|
||||
register int num;
|
||||
|
||||
if (!incr) You_feel("more experienced.");
|
||||
num = newhp();
|
||||
u.uhpmax += num;
|
||||
u.uhp += num;
|
||||
if (u.ulevel < urole.xlev)
|
||||
num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.lornd + urace.enadv.lornd,
|
||||
urole.enadv.lofix + urace.enadv.lofix);
|
||||
else
|
||||
num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.hirnd + urace.enadv.hirnd,
|
||||
urole.enadv.hifix + urace.enadv.hifix);
|
||||
num = enermod(num); /* M. Stephenson */
|
||||
u.uenmax += num;
|
||||
u.uen += num;
|
||||
if (u.ulevel < MAXULEV) {
|
||||
if (incr) {
|
||||
long tmp = newuexp(u.ulevel + 1);
|
||||
if (u.uexp >= tmp) u.uexp = tmp - 1;
|
||||
} else {
|
||||
u.uexp = newuexp(u.ulevel);
|
||||
}
|
||||
++u.ulevel;
|
||||
if (u.ulevelmax < u.ulevel) u.ulevelmax = u.ulevel;
|
||||
pline("Welcome to experience level %d.", u.ulevel);
|
||||
adjabil(u.ulevel - 1, u.ulevel); /* give new intrinsics */
|
||||
reset_rndmonst(NON_PM); /* new monster selection */
|
||||
}
|
||||
flags.botl = 1;
|
||||
}
|
||||
|
||||
long
|
||||
rndexp()
|
||||
{
|
||||
long minexp, maxexp, diff, factor;
|
||||
|
||||
minexp = (u.ulevel == 1) ? 0L : newuexp(u.ulevel - 1);
|
||||
maxexp = newuexp(u.ulevel);
|
||||
diff = maxexp - minexp, factor = 1L;
|
||||
while (diff >= (long)LARGEST_INT)
|
||||
diff /= 2L, factor *= 2L;
|
||||
return minexp + factor * (long)rn2((int)diff);
|
||||
}
|
||||
|
||||
/*exper.c*/
|
||||
Reference in New Issue
Block a user