* Official EXP-Giving Script
* Fixed #980. * Job Quest EXP always be shown in yellow color. * Miracle Tonic (12259) and Leap of Fantasy (12261) give fixed EXP through `pc_setparam` that ignore EXP item bonuses and exp rates. Not as Quest EXP from `getexp` script. * If given EXP is 0 by `getexp`, it won't be notified in client EXP log. * If given EXP for base/job that reach max level, client will be notified as 0 EXP gained. * Follow up 20588abcd83fab53f9e52deafc08bfcddfe1658a * Some clean up on `pc_gainexp`. Signed-off-by: Cydh Ramdh <cydh@pservero.com>
This commit is contained in:
parent
71cdcb3a0a
commit
9ebf59c37b
@ -6270,9 +6270,9 @@
|
||||
12256,PRO_Gift_Box,PRO Gift Box,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{}
|
||||
12257,Cold_Medicine,Cold Medicine,0,20,,100,,,,,0xFFFFFFFF,63,2,,,50,,,{ percentheal 25,25; },{},{}
|
||||
12258,Bombring_Box,Bomb Poring Box,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ if(strcharinfo(3)=="job3_rang02") { monster "this",-1,-1,"--ja--",1904,1,""; } },{},{}
|
||||
12259,Miracle_Medicine,Miracle Tonic,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ getexp 3000000,1500000; },{},{}
|
||||
12259,Miracle_Medicine,Miracle Tonic,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ BaseExp += 3000000; JobExp += 1500000; },{},{}
|
||||
12260,Cool_Summer_Outfit,Cool Summer Outfit,2,0,,100,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_SUMMER,600000,0; },{},{}
|
||||
12261,Secret_Medicine,Leap of Fantasy,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ getexp 2000000,1000000; },{},{}
|
||||
12261,Secret_Medicine,Leap of Fantasy,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ BaseExp += 2000000; JobExp += 1000000; },{},{}
|
||||
12262,Inspector_Certificate_,Authoritative Badge,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_SPEEDUP0,540000,25; },{},{}
|
||||
12263,Comp_Battle_Manual,Field Manual,2,2,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_EXPBOOST,1800000,50; },{},{}
|
||||
12264,Comp_Bubble_Gum,Bubble Gum,2,2,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_ITEMBOOST,1800000,200; },{},{}
|
||||
|
@ -16697,7 +16697,7 @@ void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, b
|
||||
WFIFOL(fd,2) = sd->bl.id;
|
||||
WFIFOL(fd,6) = (int)umin(exp, INT_MAX) * (lost ? -1 : 1);
|
||||
WFIFOW(fd,10) = type;
|
||||
WFIFOW(fd,12) = quest?1:0;// Normal exp is shown in yellow, quest exp is shown in purple.
|
||||
WFIFOW(fd,12) = (quest && type != SP_JOBEXP) ? 1 : 0; // NOTE: Somehow JobEXP always in yellow color
|
||||
WFIFOSET(fd,packet_len(0x7f6));
|
||||
}
|
||||
|
||||
|
118
src/map/pc.c
118
src/map/pc.c
@ -1296,6 +1296,16 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_
|
||||
sd->bonus_script.head = NULL;
|
||||
sd->bonus_script.count = 0;
|
||||
|
||||
// Check EXP overflow, since in previous revision EXP on Max Level can be more than 'official' Max EXP
|
||||
if (pc_is_maxbaselv(sd) && sd->status.base_exp > MAX_LEVEL_BASE_EXP) {
|
||||
sd->status.base_exp = MAX_LEVEL_BASE_EXP;
|
||||
clif_updatestatus(sd, SP_BASEEXP);
|
||||
}
|
||||
if (pc_is_maxjoblv(sd) && sd->status.job_exp > MAX_LEVEL_JOB_EXP) {
|
||||
sd->status.job_exp = MAX_LEVEL_JOB_EXP;
|
||||
clif_updatestatus(sd, SP_JOBEXP);
|
||||
}
|
||||
|
||||
// Request all registries (auth is considered completed whence they arrive)
|
||||
intif_request_registry(sd,7);
|
||||
return true;
|
||||
@ -6394,13 +6404,19 @@ static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsi
|
||||
bonus += ( sd->sc.data[SC_EXPBOOST]->val1 / battle_config.vip_bm_increase );
|
||||
}
|
||||
|
||||
*base_exp = (unsigned int) cap_value(*base_exp + (double)*base_exp * (bonus + vip_bonus_base)/100., 1, UINT_MAX);
|
||||
if (*base_exp) {
|
||||
unsigned int exp = (unsigned int)(*base_exp + (double)*base_exp * (bonus + vip_bonus_base)/100.);
|
||||
*base_exp = cap_value(exp, 1, UINT_MAX);
|
||||
}
|
||||
|
||||
// Give JEXPBOOST for quests even if src is NULL.
|
||||
if (&sd->sc && sd->sc.data[SC_JEXPBOOST])
|
||||
bonus += sd->sc.data[SC_JEXPBOOST]->val1;
|
||||
|
||||
*job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * (bonus + vip_bonus_job)/100., 1, UINT_MAX);
|
||||
if (*job_exp) {
|
||||
unsigned int exp = (unsigned int)(*job_exp + (double)*job_exp * (bonus + vip_bonus_job)/100.);
|
||||
*job_exp = cap_value(exp, 1, UINT_MAX);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -6437,7 +6453,6 @@ void pc_gainexp_disp(struct map_session_data *sd, unsigned int base_exp, unsigne
|
||||
**/
|
||||
int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int base_exp, unsigned int job_exp, bool quest)
|
||||
{
|
||||
float nextbp = 0, nextjp = 0;
|
||||
unsigned int nextb = 0, nextj = 0;
|
||||
uint8 flag = 0; ///< 1: Base EXP given, 2: Job EXP given, 4: Max Base level, 8: Max Job Level
|
||||
|
||||
@ -6452,16 +6467,16 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int
|
||||
if(sd->status.guild_id>0)
|
||||
base_exp-=guild_payexp(sd,base_exp);
|
||||
|
||||
flag = ((base_exp) ? 1 : 0) |
|
||||
((job_exp) ? 2 : 0) |
|
||||
((pc_is_maxbaselv(sd)) ? 4 : 0) |
|
||||
((pc_is_maxjoblv(sd)) ? 8 : 0);
|
||||
|
||||
pc_calcexp(sd, &base_exp, &job_exp, src);
|
||||
|
||||
nextb = pc_nextbaseexp(sd);
|
||||
nextj = pc_nextjobexp(sd);
|
||||
|
||||
flag = ((base_exp) ? 1 : 0) |
|
||||
((job_exp) ? 2 : 0) |
|
||||
(pc_is_maxbaselv(sd) ? 4 : 0) |
|
||||
(pc_is_maxjoblv(sd) ? 8 : 0);
|
||||
|
||||
if (flag&4){
|
||||
if( sd->status.base_exp >= MAX_LEVEL_BASE_EXP )
|
||||
base_exp = 0;
|
||||
@ -6475,25 +6490,18 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int
|
||||
job_exp = MAX_LEVEL_JOB_EXP - sd->status.job_exp;
|
||||
}
|
||||
|
||||
if ((base_exp || job_exp) && (sd->state.showexp || battle_config.max_exp_gain_rate)){
|
||||
if (nextb > 0)
|
||||
nextbp = (float) base_exp / (float) nextb;
|
||||
if (nextj > 0)
|
||||
nextjp = (float) job_exp / (float) nextj;
|
||||
|
||||
if(battle_config.max_exp_gain_rate) {
|
||||
if (nextbp > battle_config.max_exp_gain_rate/1000.) {
|
||||
//Note that this value should never be greater than the original
|
||||
//base_exp, therefore no overflow checks are needed. [Skotlex]
|
||||
if (battle_config.max_exp_gain_rate && (base_exp || job_exp)) {
|
||||
//Note that this value should never be greater than the original
|
||||
//therefore no overflow checks are needed. [Skotlex]
|
||||
if (nextb > 0) {
|
||||
float nextbp = (float) base_exp / (float) nextb;
|
||||
if (nextbp > battle_config.max_exp_gain_rate/1000.)
|
||||
base_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextb);
|
||||
if (sd->state.showexp)
|
||||
nextbp = (float) base_exp / (float) nextb;
|
||||
}
|
||||
if (nextjp > battle_config.max_exp_gain_rate/1000.) {
|
||||
}
|
||||
if (nextj > 0) {
|
||||
float nextjp = (float) job_exp / (float) nextj;
|
||||
if (nextjp > battle_config.max_exp_gain_rate/1000.)
|
||||
job_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextj);
|
||||
if (sd->state.showexp)
|
||||
nextjp = (float) job_exp / (float) nextj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7923,23 +7931,55 @@ bool pc_setparam(struct map_session_data *sd,int type,int val)
|
||||
sd->status.zeny = cap_value(val, 0, MAX_ZENY);
|
||||
break;
|
||||
case SP_BASEEXP:
|
||||
if(pc_nextbaseexp(sd) > 0) {
|
||||
if( pc_is_maxbaselv(sd) )
|
||||
sd->status.base_exp = u32min(val,MAX_LEVEL_BASE_EXP);
|
||||
else
|
||||
sd->status.base_exp = val;
|
||||
if (!pc_checkbaselevelup(sd))
|
||||
clif_updatestatus(sd, SP_BASEEXP);
|
||||
{
|
||||
unsigned int exp = sd->status.base_exp;
|
||||
unsigned int next = pc_nextbaseexp(sd);
|
||||
bool isLost = false;
|
||||
bool isMax = false;
|
||||
|
||||
val = cap_value(val, 0, INT_MAX);
|
||||
sd->status.base_exp = val;
|
||||
|
||||
if ((unsigned int)val < exp) { // Lost
|
||||
exp -= val;
|
||||
isLost = true;
|
||||
}
|
||||
else { // Gained
|
||||
if ((isMax = pc_is_maxbaselv(sd)) && sd->status.base_exp >= MAX_LEVEL_BASE_EXP)
|
||||
exp = 0;
|
||||
else
|
||||
exp = val-exp;
|
||||
pc_checkbaselevelup(sd);
|
||||
}
|
||||
clif_displayexp(sd, isMax ? 0 : exp, SP_BASEEXP, false, isLost);
|
||||
if (sd->state.showexp)
|
||||
pc_gainexp_disp(sd, exp, next, 0, pc_nextjobexp(sd), isLost);
|
||||
}
|
||||
break;
|
||||
case SP_JOBEXP:
|
||||
if(pc_nextjobexp(sd) > 0) {
|
||||
if( pc_is_maxjoblv(sd) )
|
||||
sd->status.job_exp = u32min(val,MAX_LEVEL_JOB_EXP);
|
||||
else
|
||||
sd->status.job_exp = val;
|
||||
if (!pc_checkjoblevelup(sd))
|
||||
clif_updatestatus(sd, SP_JOBEXP);
|
||||
{
|
||||
unsigned int exp = sd->status.job_exp;
|
||||
unsigned int next = pc_nextjobexp(sd);
|
||||
bool isLost = false;
|
||||
bool isMax = false;
|
||||
|
||||
val = cap_value(val, 0, INT_MAX);
|
||||
sd->status.job_exp = val;
|
||||
|
||||
if ((unsigned int)val < exp) { // Lost
|
||||
exp -= val;
|
||||
isLost = true;
|
||||
}
|
||||
else { // Gained
|
||||
if ((isMax = pc_is_maxjoblv(sd)) && sd->status.job_exp >= MAX_LEVEL_JOB_EXP)
|
||||
exp = 0;
|
||||
else
|
||||
exp = val-exp;
|
||||
pc_checkjoblevelup(sd);
|
||||
}
|
||||
clif_displayexp(sd, isMax ? 0 : exp, SP_JOBEXP, false, isLost);
|
||||
if (sd->state.showexp)
|
||||
pc_gainexp_disp(sd, 0, pc_nextbaseexp(sd), exp, next, isLost);
|
||||
}
|
||||
break;
|
||||
case SP_SEX:
|
||||
|
@ -1008,7 +1008,7 @@ bool pc_is_maxbaselv(struct map_session_data *sd);
|
||||
bool pc_is_maxjoblv(struct map_session_data *sd);
|
||||
int pc_checkbaselevelup(struct map_session_data *sd);
|
||||
int pc_checkjoblevelup(struct map_session_data *sd);
|
||||
int pc_gainexp(struct map_session_data*,struct block_list*,unsigned int,unsigned int, bool);
|
||||
int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int base_exp, unsigned int job_exp, bool quest);
|
||||
void pc_gainexp_disp(struct map_session_data *sd, unsigned int base_exp, unsigned int next_base_exp, unsigned int job_exp, unsigned int next_job_exp, bool lost);
|
||||
unsigned int pc_nextbaseexp(struct map_session_data *sd);
|
||||
unsigned int pc_nextjobexp(struct map_session_data *sd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user