Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,14 @@ long get_set_exp(int level, int race, int class_num, int zone)
int cfactor = 100;
int sfactor = 100;
int zfactor = 100;
/* all current zones have a factor of 100, so skip this */
/*
for (zfactor = 0; zfactor <= top_of_zone_table; zfactor++) {
if (zone == zone_table[zfactor].number)
break;
}
zfactor = zone_table[zfactor].zone_factor;
*/
/*zfactor = 100; */

/*The cfactor is the factor of class to adjust exp number is percentage
Expand Down Expand Up @@ -557,7 +560,7 @@ void boot_db(void) {

log(" Skills.");
init_skills();

log("Assigning skills and spells to classes.");
assign_class_skills();

Expand Down
1 change: 1 addition & 0 deletions src/db.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ int real_quest(unsigned short vnum);
char *fread_string(FILE *fl, const char *error);
int vnum_room(char *searchname, CharData *ch);
int vnum_zone(char *searchname, CharData *ch);
long get_set_exp(int level, int race, int class_num, int zone);

void init_player(CharData *ch);
CharData *create_char(void);
Expand Down
13 changes: 12 additions & 1 deletion src/players.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,17 @@ int load_player(const char *name, CharData *ch) {
}
reset_height_weight(ch);

/* Fix up experience totals to account for level curve change */
/* This has the beneficial side effect of mitigating the exp */
/* quirk of the Bard class change */
if (GET_LEVEL(ch) < LVL_IMMORT) {
long new_exp = adjust_exp_to_level(GET_LEVEL(ch), GET_CLASS(ch), GET_EXP(ch));
if (new_exp != GET_EXP(ch)) {
log("Adjusting {} (level {:d}) exp from {:d} to {:d} on load", GET_NAME(ch), GET_LEVEL(ch), GET_EXP(ch), new_exp);
GET_EXP(ch) = new_exp;
}
}

fclose(fl);
return (id);
}
Expand Down Expand Up @@ -1436,4 +1447,4 @@ void send_save_description(CharData *ch, CharData *dest, bool entering) {
} else {
log(LogSeverity::Stat, std::max(LVL_IMMORT, GET_INVIS_LEV(ch)), buf);
}
}
}
61 changes: 58 additions & 3 deletions src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ int monk_weight_penalty(CharData *ch) {
}

static int exp_table[LVL_IMPL + 1];
static int old_exp_table[LVL_IMPL + 1];

void init_exp_table(void) {
void init_old_exp_table(void) {
long exp, last_exp;
int lvl, i;

Expand Down Expand Up @@ -81,7 +82,7 @@ void init_exp_table(void) {
if (lvl < 9)
exp = ((lvl * lvl) + lvl) / 2 * 5500;

else if (lvl < 99) { /*(lvl <= LVL_IMMORT) { */
else if (lvl < 99) { /*(lvl <= LVL_IMMORT) {} */
for (i = 0; lvl >= eval[i].level; ++i)
;
--i;
Expand Down Expand Up @@ -109,11 +110,43 @@ void init_exp_table(void) {
else
exp = 300000001 + 2 * (lvl - LVL_IMMORT - 1);

exp_table[lvl] = exp;
old_exp_table[lvl] = exp;
last_exp = exp;
}
}

void init_exp_table(void) {
static const long MAX_MORTAL_EXP = 105806000;
long last_exp = 0;

init_old_exp_table();

exp_table[0] = 0;

for (int lvl = 1; lvl < LVL_IMMORT; lvl++) {
// Base the experience to level up on the experience gained from
// defeating a human rogue mob of the same level. (Chosen because humans
// and rogues have no experience modifier.)
// The factor of 6.615 was chosen to make ** close to MAX_MORTAL_EXP.
long exp = get_set_exp(lvl, RACE_HUMAN, CLASS_ROGUE, -1);
last_exp += long((6.615 * exp) / 100) * 100;
exp_table[lvl] = last_exp;
}

// Shift everything to make ** exactly equal to MAX_MORTAL_EXP
long adj = exp_table[LVL_IMMORT - 1] - MAX_MORTAL_EXP;
for (int lvl = 1; lvl < LVL_IMMORT; lvl++) {
exp_table[lvl] -= adj;
}

// Exp for immortal levels is irrelevant, so just pick a big number.
// Levels need to be at least 2 exp apart to avoid breaking things when
// calculating the exp cap for the level.
for (int lvl = LVL_IMMORT; lvl <= LVL_IMPL; lvl++) {
exp_table[lvl] = 300000001 + 2 * (lvl - LVL_IMMORT - 1);
}
}

long exp_next_level(int level, int class_num) {
double gain_factor;

Expand All @@ -131,6 +164,28 @@ long exp_next_level(int level, int class_num) {
return exp_table[level] * gain_factor;
}

long adjust_exp_to_level(int level, int class_num, long exp)
{
if (level < 1 || level >= LVL_IMMORT) {
return exp;
}

long prev_level = exp_next_level(level - 1, class_num);
long next_level = exp_next_level(level, class_num) - 1;
if (exp < prev_level || exp > next_level) {
long old_prev = EXP_GAIN_FACTOR(class_num) * old_exp_table[level - 1];
long old_next = EXP_GAIN_FACTOR(class_num) * old_exp_table[level] - 1;
if (exp < old_prev) {
return prev_level;
} else if (exp > old_next) {
return next_level;
}
float frac = float(exp - old_prev) / float(old_next - old_prev);
return prev_level + long(frac * (next_level - prev_level));
}
return exp;
}

/* the "touch" command, essentially. */
int touch(const char *path) {
FILE *fl;
Expand Down
1 change: 1 addition & 0 deletions src/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ int find_zone(int num);
int parse_obj_name(CharData *ch, const char *arg, const char *objname, int numobjs, void *objects, int objsize);
void init_flagvectors();
long exp_next_level(int level, int class_num);
long adjust_exp_to_level(int level, int class_num, long exp);
void init_exp_table(void);
CharData *is_playing(char *vict_name);

Expand Down