From 6791b26d7865c38129abd80f8e8a6a62872238f4 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Tue, 3 Oct 2017 05:11:45 +0300 Subject: Add packets for 64 bit exp. Also update some functions for support 64 bit exp calculation. --- src/map/clif.c | 73 ++++++++++++++++++++++++++++++++++++------------ src/map/clif.h | 2 +- src/map/guild.c | 3 +- src/map/guild.h | 2 +- src/map/pc.c | 86 +++++++++++++++++++++++++++++++++++++++------------------ src/map/pc.h | 14 +++++----- src/map/skill.c | 4 +-- 7 files changed, 127 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index de0f0573f..a17210cf4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3033,27 +3033,50 @@ void clif_updatestatus(struct map_session_data *sd,int type) WFIFOL(fd,4)=sd->status.zeny; len = packet_len(0xb1); break; +// [4144] unconfirment exact version can be from 20170405 to 20170913 +#if PACKETVER >= 20170830 case SP_BASEEXP: - WFIFOW(fd,0)=0xb1; - WFIFOL(fd,4)=(uint32)(sd->status.base_exp); + WFIFOW(fd, 0) = 0xacb; + WFIFOQ(fd, 4) = sd->status.base_exp; + len = packet_len(0xacb); + break; + case SP_JOBEXP: + WFIFOW(fd, 0) = 0xacb; + WFIFOQ(fd, 4) = sd->status.job_exp; + len = packet_len(0xacb); + break; + case SP_NEXTBASEEXP: + WFIFOW(fd, 0) = 0xacb; + WFIFOQ(fd, 4) = pc->nextbaseexp(sd); + len = packet_len(0xacb); + break; + case SP_NEXTJOBEXP: + WFIFOW(fd, 0) = 0xacb; + WFIFOQ(fd, 4) = pc->nextjobexp(sd); + len = packet_len(0xacb); + break; +#else + case SP_BASEEXP: + WFIFOW(fd, 0) = 0xb1; + WFIFOL(fd, 4) = (uint32)(sd->status.base_exp); len = packet_len(0xb1); break; case SP_JOBEXP: - WFIFOW(fd,0)=0xb1; - WFIFOL(fd,4)=(uint32)(sd->status.job_exp); + WFIFOW(fd, 0) = 0xb1; + WFIFOL(fd, 4) = (uint32)(sd->status.job_exp); len = packet_len(0xb1); break; case SP_NEXTBASEEXP: - WFIFOW(fd,0)=0xb1; - WFIFOL(fd,4)=pc->nextbaseexp(sd); + WFIFOW(fd, 0) = 0xb1; + WFIFOL(fd, 4) = (uint32)pc->nextbaseexp(sd); len = packet_len(0xb1); break; case SP_NEXTJOBEXP: - WFIFOW(fd,0)=0xb1; - WFIFOL(fd,4)=pc->nextjobexp(sd); + WFIFOW(fd, 0) = 0xb1; + WFIFOL(fd, 4) = (uint32)pc->nextjobexp(sd); len = packet_len(0xb1); break; - +#endif /** * SP_U are used to update the amount of points necessary to increase that stat **/ @@ -14027,7 +14050,7 @@ void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd) /* it sends the request when the criteria doesn't match (and of course we let it fail) */ /* so restoring the old parse_globalmes method. */ if ((sd->job & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) { - unsigned int next = pc->nextbaseexp(sd); + uint64 next = pc->nextbaseexp(sd); if( next == 0 ) next = pc->thisbaseexp(sd); if( next ) { int percent = (int)( ( (float)sd->status.base_exp/(float)next )*1000. ); @@ -16697,20 +16720,34 @@ void clif_party_show_picker(struct map_session_data * sd, struct item * item_dat /// 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 is_quest) { +void clif_displayexp(struct map_session_data *sd, uint64 exp, char type, bool is_quest) +{ int fd; +// [4144] unconfirment exact version can be from 20170405 to 20170913 +#if PACKETVER >= 20170830 + const int cmd = 0xacc; +#else + const int cmd = 0x7f6; +#endif nullpo_retv(sd); fd = sd->fd; - WFIFOHEAD(fd, packet_len(0x7f6)); - WFIFOW(fd,0) = 0x7f6; - WFIFOL(fd,2) = sd->bl.id; - WFIFOL(fd,6) = exp; - WFIFOW(fd,10) = type; - WFIFOW(fd,12) = is_quest?1:0;// Normal exp is shown in yellow, quest exp is shown in purple. - WFIFOSET(fd,packet_len(0x7f6)); + WFIFOHEAD(fd, packet_len(cmd)); + WFIFOW(fd, 0) = cmd; + WFIFOL(fd, 2) = sd->bl.id; +// [4144] unconfirment exact version can be from 20170405 to 20170913 +#if PACKETVER >= 20170830 + WFIFOQ(fd, 6) = exp; + WFIFOW(fd, 14) = type; + WFIFOW(fd, 16) = is_quest ? 1 : 0; // Normal exp is shown in yellow, quest exp is shown in purple. +#else + WFIFOL(fd, 6) = (uint32)exp; + WFIFOW(fd, 10) = type; + WFIFOW(fd, 12) = is_quest ? 1 : 0; // Normal exp is shown in yellow, quest exp is shown in purple. +#endif + WFIFOSET(fd, packet_len(cmd)); } /// Displays digital clock digits on top of the screen (ZC_SHOWDIGIT). diff --git a/src/map/clif.h b/src/map/clif.h index 73cb72128..be7bdd2d6 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -784,7 +784,7 @@ struct clif_interface { void (*equiptickack) (struct map_session_data* sd, int flag); void (*viewequip_ack) (struct map_session_data* sd, struct map_session_data* tsd); void (*equpcheckbox) (struct map_session_data* sd); - void (*displayexp) (struct map_session_data *sd, unsigned int exp, char type, bool is_quest); + void (*displayexp) (struct map_session_data *sd, uint64 exp, char type, bool is_quest); void (*font) (struct map_session_data *sd); void (*progressbar) (struct map_session_data * sd, unsigned int color, unsigned int second); void (*progressbar_abort) (struct map_session_data * sd); diff --git a/src/map/guild.c b/src/map/guild.c index 092e066c3..bb0484477 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -1282,7 +1282,8 @@ struct DBData create_expcache(union DBKey key, va_list args) /*==================================================== * Return taxed experience from player sd to guild *---------------------------------------------------*/ -unsigned int guild_payexp(struct map_session_data *sd,unsigned int exp) { +uint64 guild_payexp(struct map_session_data *sd, uint64 exp) +{ struct guild *g; struct guild_expcache *c; int per; diff --git a/src/map/guild.h b/src/map/guild.h index 71e989870..9296f9ec0 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -100,7 +100,7 @@ struct guild_interface { struct map_session_data *(*getavailablesd) (struct guild *g); int (*getindex) (const struct guild *g, int account_id, int char_id); int (*getposition) (struct guild *g, struct map_session_data *sd); - unsigned int (*payexp) (struct map_session_data *sd,unsigned int exp); + uint64 (*payexp) (struct map_session_data *sd, uint64 exp); int (*getexp) (struct map_session_data *sd,int exp); // [Celest] /* */ int (*create) (struct map_session_data *sd, const char *name); diff --git a/src/map/pc.c b/src/map/pc.c index a4a32545b..760519298 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -6698,8 +6698,9 @@ int pc_follow(struct map_session_data *sd,int target_id) { return 0; } -int pc_checkbaselevelup(struct map_session_data *sd) { - unsigned int next = pc->nextbaseexp(sd); +int pc_checkbaselevelup(struct map_session_data *sd) +{ + uint64 next = pc->nextbaseexp(sd); nullpo_ret(sd); if (!next || sd->status.base_exp < next) @@ -6763,7 +6764,7 @@ void pc_baselevelchanged(struct map_session_data *sd) { int pc_checkjoblevelup(struct map_session_data *sd) { - unsigned int next = pc->nextjobexp(sd); + uint64 next = pc->nextjobexp(sd); nullpo_ret(sd); if(!next || sd->status.job_exp < next) @@ -6796,7 +6797,7 @@ 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) { +void pc_calcexp(struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src) { int buff_ratio = 0, buff_job_ratio = 0, race_ratio = 0, pk_ratio = 0; int64 jexp, bexp; @@ -6861,8 +6862,8 @@ void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned in 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); + *job_exp = cap_value(jexp, 1, UINT64_MAX); + *base_exp = cap_value(bexp, 1, UINT64_MAX); } /** @@ -6871,9 +6872,10 @@ void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned in * @param is_quest Used to let client know that the EXP was from a quest (clif->displayexp) PACKETVER >= 20091027 * @retval true success **/ -bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int base_exp,unsigned int job_exp,bool is_quest) { - float nextbp=0, nextjp=0; - unsigned int nextb=0, nextj=0; +bool pc_gainexp(struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, bool is_quest) +{ + float nextbp = 0, nextjp = 0; + uint64 nextb = 0, nextj = 0; nullpo_ret(sd); if (sd->bl.prev == NULL || pc_isdead(sd)) @@ -6889,7 +6891,7 @@ bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in pc->calcexp(sd, &base_exp, &job_exp, src); if (sd->status.guild_id > 0) - base_exp -= guild->payexp(sd,base_exp); + base_exp -= guild->payexp(sd, base_exp); nextb = pc->nextbaseexp(sd); nextj = pc->nextjobexp(sd); @@ -6900,16 +6902,16 @@ bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in if (nextj > 0) nextjp = (float) job_exp / (float) nextj; - if(battle_config.max_exp_gain_rate) { + 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] - base_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextb); + base_exp = (uint64)(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.) { - job_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextj); + job_exp = (uint64)(battle_config.max_exp_gain_rate / 1000. * nextj); if (sd->state.showexp) nextjp = (float) job_exp / (float) nextj; } @@ -6919,23 +6921,23 @@ bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in // Cap exp to the level up requirement of the previous level when you are at max level, // otherwise cap at UINT_MAX (this is required for some S. Novice bonuses). [Skotlex] if (base_exp) { - nextb = nextb?UINT_MAX:pc->thisbaseexp(sd); - if(sd->status.base_exp > nextb - base_exp) + nextb = nextb ? UINT64_MAX : pc->thisbaseexp(sd); + if (sd->status.base_exp > nextb - base_exp) sd->status.base_exp = nextb; else sd->status.base_exp += base_exp; pc->checkbaselevelup(sd); - clif->updatestatus(sd,SP_BASEEXP); + clif->updatestatus(sd, SP_BASEEXP); } if (job_exp) { - nextj = nextj?UINT_MAX:pc->thisjobexp(sd); - if(sd->status.job_exp > nextj - job_exp) + nextj = nextj ? UINT64_MAX : pc->thisjobexp(sd); + if (sd->status.job_exp > nextj - job_exp) sd->status.job_exp = nextj; else sd->status.job_exp += job_exp; pc->checkjoblevelup(sd); - clif->updatestatus(sd,SP_JOBEXP); + clif->updatestatus(sd, SP_JOBEXP); } #if PACKETVER >= 20091027 @@ -6948,7 +6950,8 @@ bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in if(sd->state.showexp) { char output[256]; sprintf(output, - "Experience Gained Base:%u (%.2f%%) Job:%u (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100); + "Experience Gained Base:%"PRIu64" (%.2f%%) Job:%"PRIu64" (%.2f%%)", + base_exp, nextbp * (float)100, job_exp, nextjp * (float)100); clif_disp_onlyself(sd, output); } @@ -6973,7 +6976,7 @@ int pc_maxjoblv(const struct map_session_data *sd) *------------------------------------------*/ //Base exp needed for next level. -unsigned int pc_nextbaseexp(const struct map_session_data *sd) +uint64 pc_nextbaseexp(const struct map_session_data *sd) { nullpo_ret(sd); @@ -6984,7 +6987,7 @@ unsigned int pc_nextbaseexp(const struct map_session_data *sd) } //Base exp needed for this level. -unsigned int pc_thisbaseexp(const struct map_session_data *sd) +uint64 pc_thisbaseexp(const struct map_session_data *sd) { if (sd->status.base_level > pc->maxbaselv(sd) || sd->status.base_level <= 1) return 0; @@ -7000,7 +7003,7 @@ unsigned int pc_thisbaseexp(const struct map_session_data *sd) *------------------------------------------*/ //Job exp needed for next level. -unsigned int pc_nextjobexp(const struct map_session_data *sd) +uint64 pc_nextjobexp(const struct map_session_data *sd) { nullpo_ret(sd); @@ -7010,7 +7013,7 @@ unsigned int pc_nextjobexp(const struct map_session_data *sd) } //Job exp needed for this level. -unsigned int pc_thisjobexp(const struct map_session_data *sd) +uint64 pc_thisjobexp(const struct map_session_data *sd) { if (sd->status.job_level > pc->maxjoblv(sd) || sd->status.job_level <= 1) return 0; @@ -7958,7 +7961,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { // activate Steel body if a super novice dies at 99+% exp [celest] if ((sd->job & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && !sd->state.snovice_dead_flag) { - unsigned int next = pc->nextbaseexp(sd); + uint64 next = pc->nextbaseexp(sd); if( next == 0 ) next = pc->thisbaseexp(sd); if (get_percentage64(sd->status.base_exp, next) >= 99) { sd->state.snovice_dead_flag = 1; @@ -10988,6 +10991,35 @@ int pc_split_atoui(char* str, unsigned int* val, char sep, int max) return i; } +int pc_split_atoui64(char* str, uint64* val, char sep, int max) +{ + static int warning=0; + int i,j; + nullpo_ret(val); + for (i=0; i UINT64_MAX) { + val[i] = UINT64_MAX; + if (!warning) { + warning = 1; + ShowWarning("pc_readdb (exp.txt): Required exp per level is capped to %"PRIu64"\n", UINT64_MAX); + } + } else + val[i] = (uint64)f; + str = strchr(str,sep); + if (str) + *str++=0; + } + //Zero up the remaining. + for(j=i; j < max; j++) + val[j] = 0; + return i; +} + /** * Parses the skill tree config file. * @@ -11295,7 +11327,7 @@ int pc_readdb(void) { count++; job = jobs[0] = pc->class2idx(job_id); //We send one less and then one more because the last entry in the exp array should hold 0. - pc->max_level[job][type] = pc_split_atoui(split[3], pc->exp_table[job][type],',',maxlv-1)+1; + pc->max_level[job][type] = pc_split_atoui64(split[3], pc->exp_table[job][type], ',', maxlv - 1) + 1; //Reverse check in case the array has a bunch of trailing zeros... [Skotlex] //The reasoning behind the -2 is this... if the max level is 5, then the array //should look like this: @@ -11932,7 +11964,7 @@ bool pc_process_chat_message(struct map_session_data *sd, const char *message) */ void pc_check_supernovice_call(struct map_session_data *sd, const char *message) { - unsigned int next = pc->nextbaseexp(sd); + uint64 next = pc->nextbaseexp(sd); int percent = 0; nullpo_retv(sd); diff --git a/src/map/pc.h b/src/map/pc.h index 46aafa5e5..50cb1b68e 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -829,7 +829,7 @@ struct pc_interface { /* */ BEGIN_ZEROED_BLOCK; /* Everything within this block will be memset to 0 when status_defaults() is executed */ - unsigned int exp_table[CLASS_COUNT][2][MAX_LEVEL]; + uint64 exp_table[CLASS_COUNT][2][MAX_LEVEL]; int max_level[CLASS_COUNT][2]; unsigned int statp[MAX_LEVEL+1]; unsigned int level_penalty[3][RC_MAX][MAX_LEVEL*2+1]; @@ -949,11 +949,11 @@ END_ZEROED_BLOCK; /* End */ int (*maxjoblv) (const struct map_session_data *sd); int (*checkbaselevelup) (struct map_session_data *sd); int (*checkjoblevelup) (struct map_session_data *sd); - bool (*gainexp) (struct map_session_data *sd, struct block_list *src, unsigned int base_exp, unsigned int job_exp, bool is_quest); - unsigned int (*nextbaseexp) (const struct map_session_data *sd); - unsigned int (*thisbaseexp) (const struct map_session_data *sd); - unsigned int (*nextjobexp) (const struct map_session_data *sd); - unsigned int (*thisjobexp) (const struct map_session_data *sd); + bool (*gainexp) (struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, bool is_quest); + uint64 (*nextbaseexp) (const struct map_session_data *sd); + uint64 (*thisbaseexp) (const struct map_session_data *sd); + uint64 (*nextjobexp) (const struct map_session_data *sd); + uint64 (*thisjobexp) (const struct map_session_data *sd); int (*gets_status_point) (int level); int (*need_status_point) (struct map_session_data *sd,int type,int val); int (*maxparameterincrease) (struct map_session_data* sd, int type); @@ -1079,7 +1079,7 @@ END_ZEROED_BLOCK; /* End */ int (*bonus_addeff) (struct s_addeffect* effect, int max, enum sc_type id, int16 rate, int16 arrow_rate, uint8 flag, uint16 duration); int (*bonus_addeff_onskill) (struct s_addeffectonskill* effect, int max, enum sc_type id, short rate, short skill_id, unsigned char target); int (*bonus_item_drop) (struct s_add_drop *drop, const short max, short id, short group, int race, int rate); - void (*calcexp) (struct map_session_data *sd, unsigned int *base_exp, unsigned int *job_exp, struct block_list *src); + void (*calcexp) (struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src); int (*respawn_timer) (int tid, int64 tick, int id, intptr_t data); int (*jobchange_killclone) (struct block_list *bl, va_list ap); int (*getstat) (struct map_session_data* sd, int type); diff --git a/src/map/skill.c b/src/map/skill.c index a84955377..a8ced2ccf 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -13832,8 +13832,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id break; case PR_REDEMPTIO: { - int exp; - if( ((exp = pc->nextbaseexp(sd)) > 0 && get_percentage64(sd->status.base_exp, exp) < 1) || + int64 exp; + if (((exp = pc->nextbaseexp(sd)) > 0 && get_percentage64(sd->status.base_exp, exp) < 1) || ((exp = pc->nextjobexp(sd)) > 0 && get_percentage64(sd->status.job_exp, exp) < 1)) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); //Not enough exp. return 0; -- cgit v1.2.3-70-g09d2