From ff75470f7085c3ca23a9b16be43881b6bc953345 Mon Sep 17 00:00:00 2001 From: hemagx Date: Sun, 26 Jun 2016 01:37:14 +0200 Subject: Fix EXP modifiers to match aegis modifiers calclution. - Now Renewal Level Penalty being calculated in pc_calcexp only - Now Guild Tax is being paid after experience modifiers and not before - Now Experience modifiers being calculated in right way as in aegis (Race modifiers -> PK modifiers -> Premium modifiers -> Buff modifiers) --- src/map/mob.c | 5 ---- src/map/party.c | 9 ------ src/map/pc.c | 86 ++++++++++++++++++++++++++++++++++++++++----------------- src/map/skill.c | 4 +-- 4 files changed, 63 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/map/mob.c b/src/map/mob.c index 19fee52a5..b6b36dd61 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2337,11 +2337,6 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { if(flag) { if(base_exp || job_exp) { if( md->dmglog[i].flag != MDLF_PET || battle_config.pet_attack_exp_to_master ) { -#ifdef RENEWAL_EXP - int rate = pc->level_penalty_mod(md->level - (tmpsd[i])->status.base_level, md->status.race, md->status.mode, 1); - base_exp = (unsigned int)cap_value(base_exp * rate / 100, 1, UINT_MAX); - job_exp = (unsigned int)cap_value(job_exp * rate / 100, 1, UINT_MAX); -#endif pc->gainexp(tmpsd[i], &md->bl, base_exp, job_exp, false); } } diff --git a/src/map/party.c b/src/map/party.c index c85e23e50..f19e1b475 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -993,15 +993,6 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b #endif for (i = 0; i < c; i++) { -#ifdef RENEWAL_EXP - struct mob_data *md = BL_CAST(BL_MOB, src); - if (md != NULL && md->db->mexp == 0) { - int rate = pc->level_penalty_mod(md->level - (sd[i])->status.base_level, md->status.race, md->status.mode, 1); - - base_exp = (unsigned int)cap_value(base_exp_bonus * rate / 100, 1, UINT_MAX); - job_exp = (unsigned int)cap_value(job_exp_bonus * rate / 100, 1, UINT_MAX); - } -#endif pc->gainexp(sd[i], src, base_exp, job_exp, false); if (zeny) // zeny from mobs [Valaris] diff --git a/src/map/pc.c b/src/map/pc.c index 460f44f4a..6dc10ae08 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -6663,37 +6663,72 @@ int pc_checkjoblevelup(struct map_session_data *sd) * Alters EXP based on self bonuses that do not get shared with the party **/ void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned int *job_exp, struct block_list *src) { - int bonus = 0; - struct status_data *st = status->get_status_data(src); + int buff_ratio = 0, buff_job_ratio = 0, race_ratio = 0, pk_ratio = 0; + int64 jexp, bexp; nullpo_retv(sd); nullpo_retv(base_exp); nullpo_retv(job_exp); - if (sd->expaddrace[st->race]) - bonus += sd->expaddrace[st->race]; - bonus += sd->expaddrace[(st->mode&MD_BOSS) ? RC_BOSS : RC_NONBOSS]; - if (battle_config.pk_mode - && (int)(status->get_lv(src) - sd->status.base_level) >= 20) - bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris] + jexp = *job_exp; + bexp = *base_exp; - if (sd->sc.data[SC_CASH_PLUSEXP]) - bonus += sd->sc.data[SC_CASH_PLUSEXP]->val1; - if (sd->sc.data[SC_OVERLAPEXPUP]) - bonus += sd->sc.data[SC_OVERLAPEXPUP]->val1; + if (src != NULL) { + const struct status_data *st = status->get_status_data(src); + +#ifdef RENEWAL_EXP //should happen first before we caluclate any modifiers + if (src->type == BL_MOB) { + const struct mob_data *md = BL_UCAST(BL_MOB, src); + int re_mod; + re_mod = pc->level_penalty_mod(md->level - sd->status.base_level, md->status.race, md->status.mode, 1); + jexp = apply_percentrate64(jexp, re_mod, 100); + bexp = apply_percentrate64(bexp, re_mod, 100); + } +#endif + + //Race modifier + if (sd->expaddrace[st->race]) + race_ratio += sd->expaddrace[st->race]; + race_ratio += sd->expaddrace[(st->mode&MD_BOSS) ? RC_BOSS : RC_NONBOSS]; + } + + + //PK modifier + /* this doesn't exist in Aegis, instead there's a CrazyKiller check which double all EXP from this point */ + if (battle_config.pk_mode && (int)(status->get_lv(src) - sd->status.base_level) >= 20) + pk_ratio += 15; // pk_mode additional exp if monster >20 levels [Valaris] - *base_exp = (unsigned int) cap_value(*base_exp + apply_percentrate64(*base_exp, bonus, 100), 1, UINT_MAX); + //Buffs modifier + if (sd->sc.data[SC_CASH_PLUSEXP]) { + buff_job_ratio += sd->sc.data[SC_CASH_PLUSEXP]->val1; + buff_ratio += sd->sc.data[SC_CASH_PLUSEXP]->val1; + } + if (sd->sc.data[SC_OVERLAPEXPUP]) { + buff_job_ratio += sd->sc.data[SC_OVERLAPEXPUP]->val1; + buff_ratio += sd->sc.data[SC_OVERLAPEXPUP]->val1; + } if (sd->sc.data[SC_CASH_PLUSONLYJOBEXP]) - bonus += sd->sc.data[SC_CASH_PLUSONLYJOBEXP]->val1; + buff_job_ratio += sd->sc.data[SC_CASH_PLUSONLYJOBEXP]->val1; - *job_exp = (unsigned int) cap_value(*job_exp + apply_percentrate64(*job_exp, bonus, 100), 1, UINT_MAX); + //Applying Race and PK modifier First then Premium (Perment modifier) and finally buff modifier + jexp += apply_percentrate64(jexp, race_ratio, 100); + jexp += apply_percentrate64(jexp, pk_ratio, 100); + + bexp += apply_percentrate64(bexp, race_ratio, 100); + bexp += apply_percentrate64(bexp, pk_ratio, 100); - if (sd->status.mod_exp != 100) { - *base_exp = (unsigned int) cap_value(apply_percentrate64(*base_exp, sd->status.mod_exp, 100), 1, UINT_MAX); - *job_exp = (unsigned int) cap_value(apply_percentrate64(*job_exp, sd->status.mod_exp, 100), 1, UINT_MAX); + if (sd->status.mod_exp != 100) { + jexp = apply_percentrate64(jexp, sd->status.mod_exp, 100); + bexp = apply_percentrate64(bexp, sd->status.mod_exp, 100); } + + bexp += apply_percentrate64(bexp, buff_ratio, 100); + jexp += apply_percentrate64(jexp, buff_ratio + buff_job_ratio, 100); + + *job_exp = (unsigned int)cap_value(jexp, 1, UINT_MAX); + *base_exp = (unsigned int)cap_value(bexp, 1, UINT_MAX); } /** @@ -6707,24 +6742,25 @@ bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in unsigned int nextb=0, nextj=0; nullpo_ret(sd); - if(sd->bl.prev == NULL || pc_isdead(sd)) + if (sd->bl.prev == NULL || pc_isdead(sd)) return false; - if(!battle_config.pvp_exp && map->list[sd->bl.m].flag.pvp) // [MouseJstr] + if (!battle_config.pvp_exp && map->list[sd->bl.m].flag.pvp) // [MouseJstr] return false; // no exp on pvp maps - if( pc_has_permission(sd,PC_PERM_DISABLE_EXP) ) + if (pc_has_permission(sd,PC_PERM_DISABLE_EXP)) return false; - if(sd->status.guild_id>0) - base_exp-=guild->payexp(sd,base_exp); + if (src) + pc->calcexp(sd, &base_exp, &job_exp, src); - if(src) pc->calcexp(sd, &base_exp, &job_exp, src); + if (sd->status.guild_id > 0) + base_exp -= guild->payexp(sd,base_exp); nextb = pc->nextbaseexp(sd); nextj = pc->nextjobexp(sd); - if(sd->state.showexp || battle_config.max_exp_gain_rate){ + if (sd->state.showexp || battle_config.max_exp_gain_rate) { if (nextb > 0) nextbp = (float) base_exp / (float) nextb; if (nextj > 0) diff --git a/src/map/skill.c b/src/map/skill.c index 51d0792e3..d641bee75 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -5455,7 +5455,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin heal_get_jobexp = heal_get_jobexp * battle_config.heal_exp / 100; if (heal_get_jobexp <= 0) heal_get_jobexp = 1; - pc->gainexp (sd, bl, 0, heal_get_jobexp, false); + pc->gainexp(sd, bl, 0, heal_get_jobexp, false); } } break; @@ -5531,7 +5531,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin if (jexp < 1) jexp = 1; } if(exp > 0 || jexp > 0) - pc->gainexp (sd, bl, exp, jexp, false); + pc->gainexp(sd, bl, exp, jexp, false); } } } -- cgit v1.2.3-60-g2f50