|
|
|
@ -8,51 +8,51 @@
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static int enermod(int);
|
|
|
|
|
static int enermod(int en);
|
|
|
|
|
|
|
|
|
|
long
|
|
|
|
|
newuexp(int lev)
|
|
|
|
|
long newuexp(int lev)
|
|
|
|
|
{
|
|
|
|
|
if (lev < 1) /* for newuexp(u.ulevel - 1) when u.ulevel is 1 */
|
|
|
|
|
return 0L;
|
|
|
|
|
if (lev < 10)
|
|
|
|
|
return (10L * (1L << lev));
|
|
|
|
|
return (10L * (1L << lev)); // Experience calculation for levels 1-9
|
|
|
|
|
if (lev < 20)
|
|
|
|
|
return (10000L * (1L << (lev - 10)));
|
|
|
|
|
return (10000000L * ((long) (lev - 19)));
|
|
|
|
|
return (10000L * (1L << (lev - 10))); // Experience calculation for levels 10-19
|
|
|
|
|
return (10000000L * ((long) (lev - 19))); // Experience calculation for levels 20 and above
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
enermod(int en)
|
|
|
|
|
static int enermod(int en)
|
|
|
|
|
{
|
|
|
|
|
switch (Role_switch) {
|
|
|
|
|
case PM_CLERIC:
|
|
|
|
|
case PM_WIZARD:
|
|
|
|
|
return (2 * en);
|
|
|
|
|
return (2 * en); // Energy modification for Clerics and Wizards
|
|
|
|
|
case PM_HEALER:
|
|
|
|
|
case PM_KNIGHT:
|
|
|
|
|
return ((3 * en) / 2);
|
|
|
|
|
return ((3 * en) / 2); // Energy modification for Healers and Knights
|
|
|
|
|
case PM_BARBARIAN:
|
|
|
|
|
case PM_VALKYRIE:
|
|
|
|
|
return ((3 * en) / 4);
|
|
|
|
|
return ((3 * en) / 4); // Energy modification for Barbarians and Valkyries
|
|
|
|
|
default:
|
|
|
|
|
return en;
|
|
|
|
|
return en; // No modification for other roles
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* calculate spell power/energy points for new level */
|
|
|
|
|
int
|
|
|
|
|
newpw(void)
|
|
|
|
|
int newpw(void)
|
|
|
|
|
{
|
|
|
|
|
int en = 0, enrnd, enfix;
|
|
|
|
|
|
|
|
|
|
if (u.ulevel == 0) {
|
|
|
|
|
// For level 0 characters (starting level), calculate initial en based on role and race
|
|
|
|
|
en = gu.urole.enadv.infix + gu.urace.enadv.infix;
|
|
|
|
|
if (gu.urole.enadv.inrnd > 0)
|
|
|
|
|
en += rnd(gu.urole.enadv.inrnd);
|
|
|
|
|
if (gu.urace.enadv.inrnd > 0)
|
|
|
|
|
en += rnd(gu.urace.enadv.inrnd);
|
|
|
|
|
} else {
|
|
|
|
|
// For higher levels, calculate en based on attributes and role/race modifiers
|
|
|
|
|
enrnd = (int) ACURR(A_WIS) / 2;
|
|
|
|
|
if (u.ulevel < gu.urole.xlev) {
|
|
|
|
|
enrnd += gu.urole.enadv.lornd + gu.urace.enadv.lornd;
|
|
|
|
@ -61,23 +61,26 @@ newpw(void)
|
|
|
|
|
enrnd += gu.urole.enadv.hirnd + gu.urace.enadv.hirnd;
|
|
|
|
|
enfix = gu.urole.enadv.hifix + gu.urace.enadv.hifix;
|
|
|
|
|
}
|
|
|
|
|
en = enermod(rn1(enrnd, enfix));
|
|
|
|
|
en = enermod(rn1(enrnd, enfix)); // Apply energy modifier based on role
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (en <= 0)
|
|
|
|
|
en = 1;
|
|
|
|
|
en = 1; // If en is negative or zero, set it to 1
|
|
|
|
|
|
|
|
|
|
if (u.ulevel < MAXULEV) {
|
|
|
|
|
/* remember increment; future level drain could take it away again */
|
|
|
|
|
u.ueninc[u.ulevel] = (xint16) en;
|
|
|
|
|
u.ueninc[u.ulevel] = (xint16) en; // Store the energy increment for the current level
|
|
|
|
|
} else {
|
|
|
|
|
/* after level 30, throttle energy gains from extra experience;
|
|
|
|
|
once max reaches 600, further increments will be just 1 more */
|
|
|
|
|
char lim = 4 - u.uenmax / 200;
|
|
|
|
|
char lim = 4 - u.uenmax / 200; // Calculate the maximum limit for energy gain
|
|
|
|
|
|
|
|
|
|
lim = max(lim, 1);
|
|
|
|
|
lim = max(lim, 1); // Make sure the limit is at least 1
|
|
|
|
|
if (en > lim)
|
|
|
|
|
en = lim;
|
|
|
|
|
en = lim; // Cap the energy gain to the calculated limit
|
|
|
|
|
}
|
|
|
|
|
return en;
|
|
|
|
|
|
|
|
|
|
return en; // Return the maximum power points (en)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* return # of exp points for mtmp after nk killed */
|
|
|
|
@ -112,19 +115,28 @@ experience(register struct monst *mtmp, register int nk)
|
|
|
|
|
|
|
|
|
|
/* 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 (tmp2 != 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;
|
|
|
|
|
tmp2 = ptr->mattk[i].adtyp; // Get the attack type of the monster's attack
|
|
|
|
|
|
|
|
|
|
// Check various conditions and add the corresponding damage bonus
|
|
|
|
|
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 (tmp2 != AD_PHYS) {
|
|
|
|
|
tmp += mtmp->m_lev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for an extra heavy damage bonus
|
|
|
|
|
if ((int) (ptr->mattk[i].damd * ptr->mattk[i].damn) > 23) {
|
|
|
|
|
tmp += mtmp->m_lev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add an additional bonus for specific conditions
|
|
|
|
|
if (tmp2 == AD_WRAP && ptr->mlet == S_EEL && !Amphibious) {
|
|
|
|
|
tmp += 1000;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* For certain "extra nasty" monsters, give even more */
|
|
|
|
|
if (extra_nasty(ptr))
|
|
|
|
@ -252,37 +264,37 @@ losexp(
|
|
|
|
|
we don't allow it to go up because that contradicts assumptions
|
|
|
|
|
elsewhere (such as healing wielder who drains with Stormbringer) */
|
|
|
|
|
if (u.uhpmax > olduhpmax)
|
|
|
|
|
setuhpmax(olduhpmax);
|
|
|
|
|
|
|
|
|
|
u.uhp -= num;
|
|
|
|
|
if (u.uhp < 1)
|
|
|
|
|
u.uhp = 1;
|
|
|
|
|
else if (u.uhp > u.uhpmax)
|
|
|
|
|
u.uhp = u.uhpmax;
|
|
|
|
|
|
|
|
|
|
num = (int) u.ueninc[u.ulevel];
|
|
|
|
|
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;
|
|
|
|
|
setuhpmax(olduhpmax); // If the maximum hit points (u.uhpmax) is greater than the previous maximum (olduhpmax), set it to the old maximum
|
|
|
|
|
|
|
|
|
|
u.uhp -= num; // Subtract 'num' from the current hit points (u.uhp)
|
|
|
|
|
if (u.uhp < 1)
|
|
|
|
|
u.uhp = 1; // If the hit points are less than 1, set them to 1 (minimum value)
|
|
|
|
|
else if (u.uhp > u.uhpmax)
|
|
|
|
|
u.uhp = u.uhpmax; // If the hit points are greater than the maximum hit points, set them to the maximum hit points
|
|
|
|
|
|
|
|
|
|
num = (int) u.ueninc[u.ulevel]; // Get the energy increment for the current player level
|
|
|
|
|
u.uenmax -= num; // Subtract 'num' from the maximum energy points (u.uenmax)
|
|
|
|
|
if (u.uenmax < 0)
|
|
|
|
|
u.uenmax = 0; // If the maximum energy points are less than 0, set them to 0 (minimum value)
|
|
|
|
|
u.uen -= num; // Subtract 'num' from the current energy points (u.uen)
|
|
|
|
|
if (u.uen < 0)
|
|
|
|
|
u.uen = 0; // If the energy points are less than 0, set them to 0 (minimum value)
|
|
|
|
|
else if (u.uen > u.uenmax)
|
|
|
|
|
u.uen = u.uenmax; // If the energy points are greater than the maximum energy points, set them to the maximum energy points
|
|
|
|
|
|
|
|
|
|
if (u.uexp > 0)
|
|
|
|
|
u.uexp = newuexp(u.ulevel) - 1; // If the experience points (u.uexp) are greater than 0, update them based on the current player level
|
|
|
|
|
|
|
|
|
|
if (Upolyd) {
|
|
|
|
|
num = monhp_per_lvl(&gy.youmonst); // Calculate the hit points per level for the current polymorphed form
|
|
|
|
|
u.mhmax -= num; // Subtract 'num' from the maximum monster hit points (u.mhmax)
|
|
|
|
|
u.mh -= num; // Subtract 'num' from the current monster hit points (u.mh)
|
|
|
|
|
if (u.mh <= 0)
|
|
|
|
|
rehumanize(); // If the monster hit points are less than or equal to 0, change back to the player form
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Upolyd) {
|
|
|
|
|
num = monhp_per_lvl(&gy.youmonst);
|
|
|
|
|
u.mhmax -= num;
|
|
|
|
|
u.mh -= num;
|
|
|
|
|
if (u.mh <= 0)
|
|
|
|
|
rehumanize();
|
|
|
|
|
}
|
|
|
|
|
gc.context.botl = TRUE; // Set a flag to indicate that the status line needs to be updated
|
|
|
|
|
|
|
|
|
|
gc.context.botl = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make experience gaining similar to AD&D(tm), whereby you can at most go
|
|
|
|
|