Follow up 70a67d6c5790f9fa61edcf7f2eda339b5e8df9e0
* On EXP lost by death penalty. EXP will be shown as negative value. * Fixed check for EXP value on packet `0x07f6`. EXP is limited to INT_MIN until INT_MAX by client (so don't expect client to displays value more than this!) * Added EXP gained/lost message by `@showexp` on death penalty too. Signed-off-by: Cydh Ramdh <cydh@pservero.com>
This commit is contained in:
parent
70a67d6c57
commit
f2f135708b
@ -781,7 +781,11 @@
|
||||
739: Please enter a body style (usage: @bodystyle <body ID: %d-%d>).
|
||||
740: This job has no alternate body styles.
|
||||
|
||||
//741-899 free
|
||||
// @showexp
|
||||
741: Gained
|
||||
742: Lost
|
||||
743: Experience %s Base:%ld (%0.2f%%) Job:%ld (%0.2f%%)
|
||||
//744-899 free
|
||||
|
||||
//------------------------------------
|
||||
// More atcommands message
|
||||
@ -1358,8 +1362,8 @@
|
||||
1315: Available Flags:
|
||||
|
||||
// @showexp
|
||||
1316: Gained exp will not be shown.
|
||||
1317: Gained exp is now shown.
|
||||
1316: Gained/lost exp will not be shown.
|
||||
1317: Gained/lost exp is now shown.
|
||||
|
||||
// @showzeny
|
||||
1318: Gained zeny will not be shown.
|
||||
|
@ -16649,14 +16649,21 @@ void clif_party_show_picker(struct map_session_data * sd, struct item * item_dat
|
||||
}
|
||||
|
||||
|
||||
/// Display gained exp (ZC_NOTIFY_EXP).
|
||||
/// 07f6 <account id>.L <amount>.L <var id>.W <exp type>.W
|
||||
/// var id:
|
||||
/// SP_BASEEXP, SP_JOBEXP
|
||||
/// exp type:
|
||||
/// 0 = normal exp gain/loss
|
||||
/// 1 = quest exp gain/loss
|
||||
void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, bool quest)
|
||||
/** Display gained exp (ZC_NOTIFY_EXP).
|
||||
* 07f6 <account id>.L <amount>.L <var id>.W <exp type>.W
|
||||
* amount: INT32_MIN ~ INT32_MAX
|
||||
* var id:
|
||||
* SP_BASEEXP, SP_JOBEXP
|
||||
* exp type:
|
||||
* 0 = normal exp gained/lost
|
||||
* 1 = quest exp gained/lost
|
||||
* @param sd Player
|
||||
* @param exp EXP value gained/loss
|
||||
* @param type SP_BASEEXP, SP_JOBEXP
|
||||
* @param quest False:Normal EXP; True:Quest EXP (displayed in purple color)
|
||||
* @param lost True:if lossing EXP
|
||||
*/
|
||||
void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, bool quest, bool lost)
|
||||
{
|
||||
int fd;
|
||||
|
||||
@ -16667,7 +16674,7 @@ void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, b
|
||||
WFIFOHEAD(fd, packet_len(0x7f6));
|
||||
WFIFOW(fd,0) = 0x7f6;
|
||||
WFIFOL(fd,2) = sd->bl.id;
|
||||
WFIFOL(fd,6) = exp;
|
||||
WFIFOL(fd,6) = (int)min(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.
|
||||
WFIFOSET(fd,packet_len(0x7f6));
|
||||
|
@ -816,7 +816,7 @@ void clif_quest_delete(struct map_session_data * sd, int quest_id);
|
||||
void clif_quest_update_status(struct map_session_data * sd, int quest_id, bool active);
|
||||
void clif_quest_update_objective(struct map_session_data * sd, struct quest * qd, int mobid);
|
||||
void clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, short state, short color);
|
||||
void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, bool quest);
|
||||
void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, bool quest, bool lost);
|
||||
|
||||
int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target type);
|
||||
void do_init_clif(void);
|
||||
|
91
src/map/pc.c
91
src/map/pc.c
@ -6381,6 +6381,27 @@ static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsi
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show EXP gained by player in percentage by @showexp
|
||||
* @param sd Player
|
||||
* @param base_exp Base EXP gained/loss
|
||||
* @param next_base_exp Base EXP needed for next base level
|
||||
* @param job_exp Job EXP gained/loss
|
||||
* @param next_job_exp Job EXP needed for next job level
|
||||
* @param lost True:EXP penalty, lose EXP
|
||||
**/
|
||||
static 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) {
|
||||
char output[CHAT_SIZE_MAX];
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
sprintf(output, msg_txt(sd,743), // Experience %s Base:%ld (%0.2f%%) Job:%ld (%0.2f%%)
|
||||
(lost) ? msg_txt(sd,742) : msg_txt(sd,741),
|
||||
(long)base_exp * (lost ? -1 : 1), (base_exp / (float)next_base_exp * 100 * (lost ? -1 : 1)),
|
||||
(long)job_exp * (lost ? -1 : 1), (job_exp / (float)next_job_exp * 100 * (lost ? -1 : 1)));
|
||||
clif_disp_onlyself(sd, output, strlen(output));
|
||||
}
|
||||
|
||||
/**
|
||||
* Give Base or Job EXP to player, then calculate remaining exp for next lvl
|
||||
* @param sd Player
|
||||
@ -6394,7 +6415,7 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int
|
||||
{
|
||||
float nextbp = 0, nextjp = 0;
|
||||
unsigned int nextb = 0, nextj = 0;
|
||||
bool is_max_base = false, is_max_job = false; // True for player with max base/job level
|
||||
uint8 flag = 0; ///< 1: Base EXP given, 2: Job EXP given, 4: Max Base level, 8: Max Job Level
|
||||
|
||||
nullpo_ret(sd);
|
||||
|
||||
@ -6411,17 +6432,18 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int
|
||||
|
||||
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);
|
||||
|
||||
is_max_base = pc_is_maxbaselv(sd);
|
||||
is_max_job = pc_is_maxjoblv(sd);
|
||||
|
||||
// On Max Level and Max EXP, just set EXP 0 avoid unnecessary process. [Cydh]
|
||||
if (is_max_base && sd->status.base_exp >= MAX_LEVEL_BASE_EXP)
|
||||
if (flag&4 && sd->status.base_exp >= MAX_LEVEL_BASE_EXP)
|
||||
base_exp = 0;
|
||||
if (is_max_job && sd->status.job_exp >= MAX_LEVEL_JOB_EXP)
|
||||
if (flag&8 && sd->status.job_exp >= MAX_LEVEL_JOB_EXP)
|
||||
job_exp = 0;
|
||||
|
||||
if(sd->state.showexp || battle_config.max_exp_gain_rate){
|
||||
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)
|
||||
@ -6449,8 +6471,8 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int
|
||||
sd->status.base_exp = nextb;
|
||||
else
|
||||
sd->status.base_exp += base_exp;
|
||||
pc_checkbaselevelup(sd);
|
||||
clif_updatestatus(sd,SP_BASEEXP);
|
||||
if (!pc_checkbaselevelup(sd))
|
||||
clif_updatestatus(sd,SP_BASEEXP);
|
||||
}
|
||||
|
||||
// Give EXP for Job Level
|
||||
@ -6459,22 +6481,17 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int
|
||||
sd->status.job_exp = nextj;
|
||||
else
|
||||
sd->status.job_exp += job_exp;
|
||||
pc_checkjoblevelup(sd);
|
||||
clif_updatestatus(sd,SP_JOBEXP);
|
||||
if (!pc_checkjoblevelup(sd))
|
||||
clif_updatestatus(sd,SP_JOBEXP);
|
||||
}
|
||||
|
||||
// On Max Level, always send EXP as 0. [Cydh]
|
||||
if(base_exp)
|
||||
clif_displayexp(sd, (is_max_base) ? 0 : base_exp, SP_BASEEXP, quest);
|
||||
if(job_exp)
|
||||
clif_displayexp(sd, (is_max_job) ? 0 : job_exp, SP_JOBEXP, quest);
|
||||
if (flag&1)
|
||||
clif_displayexp(sd, (flag&4) ? 0 : base_exp, SP_BASEEXP, quest, false);
|
||||
if (flag&2)
|
||||
clif_displayexp(sd, (flag&8) ? 0 : job_exp, SP_JOBEXP, quest, false);
|
||||
|
||||
if(sd->state.showexp) {
|
||||
char output[CHAT_SIZE_MAX];
|
||||
sprintf(output,
|
||||
"Experience Gained Base:%u (%.2f%%) Job:%u (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100);
|
||||
clif_disp_onlyself(sd,output,strlen(output));
|
||||
}
|
||||
if (sd->state.showexp)
|
||||
pc_gainexp_disp(sd, base_exp, nextb, job_exp, nextj, false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -7508,7 +7525,6 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
|
||||
uint32 base_penalty = battle_config.death_penalty_base;
|
||||
uint32 job_penalty = battle_config.death_penalty_job;
|
||||
uint32 zeny_penalty = battle_config.zeny_penalty;
|
||||
bool is_max_level = pc_is_maxbaselv(sd);
|
||||
|
||||
#ifdef VIP_ENABLE
|
||||
if(pc_isvip(sd)){
|
||||
@ -7521,31 +7537,42 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((!is_max_level || battle_config.death_penalty_maxlv&1) && base_penalty > 0) {
|
||||
if ((battle_config.death_penalty_maxlv&1 || !pc_is_maxbaselv(sd)) && base_penalty > 0) {
|
||||
switch (battle_config.death_penalty_type) {
|
||||
case 1: base_penalty = (uint32) ( pc_nextbaseexp(sd) * ( base_penalty / 10000. ) ); break;
|
||||
case 2: base_penalty = (uint32) ( sd->status.base_exp * ( base_penalty / 10000. ) ); break;
|
||||
}
|
||||
if (base_penalty > 0){ //recheck after altering to speedup
|
||||
if (base_penalty){ //recheck after altering to speedup
|
||||
if (battle_config.pk_mode && src && src->type==BL_PC)
|
||||
base_penalty*=2;
|
||||
sd->status.base_exp -= u32min(sd->status.base_exp, base_penalty);
|
||||
base_penalty *= 2;
|
||||
base_penalty = u32min(sd->status.base_exp, base_penalty);
|
||||
sd->status.base_exp -= base_penalty;
|
||||
clif_displayexp(sd, base_penalty, SP_BASEEXP, false, true);
|
||||
clif_updatestatus(sd,SP_BASEEXP);
|
||||
}
|
||||
}
|
||||
else
|
||||
base_penalty = 0;
|
||||
|
||||
if ((!is_max_level || battle_config.death_penalty_maxlv&2) && job_penalty > 0) {
|
||||
if ((battle_config.death_penalty_maxlv&2 || !pc_is_maxjoblv(sd)) && job_penalty > 0) {
|
||||
switch (battle_config.death_penalty_type) {
|
||||
case 1: job_penalty = (uint32) ( pc_nextjobexp(sd) * ( job_penalty / 10000. ) ); break;
|
||||
case 2: job_penalty = (uint32) ( sd->status.job_exp * ( job_penalty /10000. ) ); break;
|
||||
}
|
||||
if(job_penalty) {
|
||||
if (job_penalty) {
|
||||
if (battle_config.pk_mode && src && src->type==BL_PC)
|
||||
job_penalty*=2;
|
||||
sd->status.job_exp -= u32min(sd->status.job_exp, job_penalty);
|
||||
job_penalty *= 2;
|
||||
job_penalty = u32min(sd->status.job_exp, job_penalty);
|
||||
sd->status.job_exp -= job_penalty;
|
||||
clif_displayexp(sd, job_penalty, SP_JOBEXP, false, true);
|
||||
clif_updatestatus(sd,SP_JOBEXP);
|
||||
}
|
||||
}
|
||||
else
|
||||
job_penalty = 0;
|
||||
|
||||
if (sd->state.showexp && (base_penalty || job_penalty))
|
||||
pc_gainexp_disp(sd, base_penalty, pc_nextbaseexp(sd), job_penalty, pc_nextjobexp(sd), true);
|
||||
|
||||
if( zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty) {
|
||||
zeny_penalty = (uint32)( sd->status.zeny * ( zeny_penalty / 10000. ) );
|
||||
|
Loading…
x
Reference in New Issue
Block a user