diff options
-rw-r--r-- | db/level_penalty.txt | 56 | ||||
-rw-r--r-- | src/map/atcommand.c | 5 | ||||
-rw-r--r-- | src/map/mob.c | 11 | ||||
-rw-r--r-- | src/map/party.c | 70 | ||||
-rw-r--r-- | src/map/party.h | 7 | ||||
-rw-r--r-- | src/map/pc.c | 39 | ||||
-rw-r--r-- | src/map/pc.h | 3 |
7 files changed, 112 insertions, 79 deletions
diff --git a/db/level_penalty.txt b/db/level_penalty.txt new file mode 100644 index 000000000..1b9b15c37 --- /dev/null +++ b/db/level_penalty.txt @@ -0,0 +1,56 @@ +// Experience & Drop Rate Modifier Database
+//
+// Structure of Database:
+// Type,Race,Level difference,Rate
+//
+// TYPE:
+// 1=experience, 2=item drop
+// RACE:
+// 0=Formless, 1=Undead, 2=Brute, 3=Plant, 4=Insect,
+// 5=Fish, 6=Demon, 7=Demi-Human, 8=Angel, 9=Dragon,
+// 10=Boss monsters, 11=Normal monsters
+//
+// Note: RENEWAL_DROP and/or RENEWAL_EXP must be enabled.
+
+// EXP modifiers due to level difference
+1,11,16,40
+1,11,15,115
+1,11,14,120
+1,11,13,125
+1,11,12,130
+1,11,11,135
+1,11,10,140
+1,11,9,135
+1,11,8,130
+1,11,7,125
+1,11,6,120
+1,11,5,115
+1,11,4,110
+1,11,3,105
+1,11,0,100
+1,11,11,100
+1,11,-6,95
+1,11,-11,90
+1,11,-16,85
+1,11,-21,60
+1,11,-26,35
+1,11,-31,10
+
+// Boss Type
+1,10,0,100
+
+// Drop rate modifiers due to level difference
+2,11,16,50
+2,11,13,60
+2,11,10,70
+2,11,7,80
+2,11,4,90
+2,11,0,100
+2,11,-4,90
+2,11,-7,80
+2,11,-10,70
+2,11,-13,60
+2,11,-16,50
+
+// Boss Type
+2,10,0,100
\ No newline at end of file diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 09a148a1b..0d92ef156 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -6752,10 +6752,7 @@ ACMD_FUNC(mobinfo) if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL) continue; droprate = mob->dropitem[i].p; -#ifdef RENEWAL_DROP - if( battle_config.atcommand_mobinfo_type ) - droprate = droprate * party_renewal_drop_mod(sd->status.base_level - mob->lv) / 100; -#endif + if (item_data->slot) sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_data->jname, item_data->slot, (float)droprate / 100); else diff --git a/src/map/mob.c b/src/map/mob.c index f5ecac8be..ddb138d68 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2298,8 +2298,9 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { if( md->dmglog[i].flag != MDLF_PET || battle_config.pet_attack_exp_to_master ) { #ifdef RENEWAL_EXP - if(!md->db->mexp) - party_renewal_exp_mod(&base_exp,&job_exp,tmpsd[i]->status.base_level,md->level); + int rate = pc_level_penalty_mod(tmpsd[i], md, 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); } @@ -2325,9 +2326,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) struct item_data* it = NULL; int drop_rate; #ifdef RENEWAL_DROP - int drop_modifier = mvp_sd ? party_renewal_drop_mod(mvp_sd->status.base_level - md->level) : - second_sd ? party_renewal_drop_mod(second_sd->status.base_level - md->level) : - third_sd ? party_renewal_drop_mod(third_sd->status.base_level - md->level) : 100; + int drop_modifier = pc_level_penalty_mod(mvp_sd?mvp_sd:second_sd?second_sd:third_sd, md, 2); #endif dlist->m = md->bl.m; dlist->x = md->bl.x; @@ -2371,7 +2370,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) if (sd && sd->sc.data[SC_ITEMBOOST]) // now rig the drop rate to never be over 90% unless it is originally >90%. drop_rate = max(drop_rate,cap_value((int)(0.5+drop_rate*(sd->sc.data[SC_ITEMBOOST]->val1)/100.),0,9000)); #ifdef RENEWAL_DROP - if(drop_modifier != 100 && !md->db->mexp) { + if( drop_modifier != 100 ) { drop_rate = drop_rate * drop_modifier / 100; if( drop_rate < 1 ) drop_rate = 1; diff --git a/src/map/party.c b/src/map/party.c index 4e23302db..9cb8adf64 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -905,66 +905,13 @@ int party_send_xy_clear(struct party_data *p) } return 0; } -#ifdef RENEWAL_DROP -/** - * Renewal Drop Modifier - **/ -int party_renewal_drop_mod(int diff) { - if( diff >= -10 && diff <= 5 ) - return 100;//no change. - if( diff > 0 ) { - if( diff > 5 && diff < 10 ) - return 90; - if( diff > 9 && diff < 15 ) - return 75; - if( diff > 14 && diff < 30 ) - return 60; - } else { - if( diff <= -10 && diff <= -14 ) - return 75;//75% - } - //other chances: 50% - return 50; -} -#endif -#ifdef RENEWAL_EXP -/** - * Renewal Experience Earning Mode - **/ -void party_renewal_exp_mod(unsigned int *base_exp, unsigned int *job_exp, int lvl, int moblvl) { - int diff = lvl - moblvl, boost = 0; - //-2 ~ +5: 100% - if( diff >= -2 && diff <= 5 ) - return;//we don't change anything, it's 100% boost - //-3 ~ -10: +5% boost for each - if( diff >= -10 && diff <= -3 ) - boost = 100 + (( -diff * 5 ) - 15 ); - // 40% boost if difference is <= -10 - else if ( diff <= -10 ) - boost = 40; - else { - boost = ( diff > 5 && diff < 11 ) ? 95 : - ( diff > 10 && diff < 16 ) ? 90 : - ( diff > 15 && diff < 21 ) ? 85 : - ( diff > 20 && diff < 26 ) ? 60 : - ( diff > 25 && diff < 31 ) ? 35 : - 10; - } - if( *base_exp ) - *base_exp = (unsigned int)cap_value(*base_exp * boost / 100, 1, UINT_MAX); - if( *job_exp ) - *job_exp = (unsigned int)cap_value(*job_exp * boost / 100, 1, UINT_MAX); - return; -} -#endif + // exp share and added zeny share [Valaris] int party_exp_share(struct party_data* p, struct block_list* src, unsigned int base_exp, unsigned int job_exp, int zeny) { struct map_session_data* sd[MAX_PARTY]; unsigned int i, c; -#ifdef RENEWAL_EXP - int src_lvl = status_get_lv(src); -#endif + nullpo_ret(p); // count the number of players eligible for exp sharing @@ -993,13 +940,14 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b for (i = 0; i < c; i++) { #ifdef RENEWAL_EXP - unsigned int b_exp = base_exp, j_exp = job_exp; - if( !(src && src->type == BL_MOB && ((TBL_MOB*)src)->db->mexp) ) - party_renewal_exp_mod(&b_exp,&j_exp,sd[i]->status.base_level,src_lvl); - pc_gainexp(sd[i], src, b_exp, j_exp, false); -#else - pc_gainexp(sd[i], src, base_exp, job_exp, false); + if( !(src && src->type == BL_MOB && ((TBL_MOB*)src)->db->mexp) ){ + int rate = pc_level_penalty_mod(sd[i], (TBL_MOB*)src, 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(sd[i], src, base_exp, job_exp, false); + if (zeny) // zeny from mobs [Valaris] pc_getzeny(sd[i],zeny); } diff --git a/src/map/party.h b/src/map/party.h index c87e0300b..9fde5a6a4 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -92,11 +92,4 @@ void party_booking_update(struct map_session_data *sd, short* job); void party_booking_search(struct map_session_data *sd, short level, short mapid, short job, unsigned long lastindex, short resultcount); bool party_booking_delete(struct map_session_data *sd); -#ifdef RENEWAL_EXP - void party_renewal_exp_mod(unsigned int *base_exp, unsigned int *job_exp, int lvl, int moblvl); -#endif -#ifdef RENEWAL_DROP - int party_renewal_drop_mod(int diff); -#endif - #endif /* _PARTY_H_ */ diff --git a/src/map/pc.c b/src/map/pc.c index 7dd648715..e827e760e 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -51,6 +51,9 @@ static unsigned int exp_table[CLASS_COUNT][2][MAX_LEVEL]; static unsigned int max_level[CLASS_COUNT][2]; static unsigned int statp[MAX_LEVEL+1]; +#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) +static unsigned int level_penalty[3][RC_MAX][MAX_LEVEL*2+1]; +#endif // h-files are for declarations, not for implementations... [Shinomori] struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE]; @@ -86,7 +89,6 @@ struct item_cd { short nameid[MAX_ITEMDELAYS];//skill id }; - //Converts a class to its array index for CLASS_COUNT defined arrays. //Note that it does not do a validity check for speed purposes, where parsing //player input make sure to use a pcdb_checkid first! @@ -9105,7 +9107,42 @@ int pc_del_talisman(struct map_session_data *sd,int count,int type) clif_talisman(sd, type); return 0; } +#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) +/*========================================== + * Renewal EXP/Itemdrop rate modifier base on level penalty + * 1=exp 2=itemdrop + *------------------------------------------*/ +int pc_level_penalty_mod(struct map_session_data *sd, struct mob_data *md, int type) +{ + int diff, rate = 100, i; + + nullpo_ret(sd); + nullpo_ret(md); + + diff = md->level - sd->status.base_level; + + if( diff < 0 ) + diff = MAX_LEVEL + ( ~diff + 1 ); + + for(i=0; i<RC_MAX; i++){ + int tmp; + if( md->status.race != i ){ + if( md->status.mode&MD_BOSS && i < RC_BOSS ) + i = RC_BOSS; + else if( i <= RC_BOSS ) + continue; + } + + if( (tmp=level_penalty[type][i][diff]) > 0 ){ + rate = tmp; + break; + } + } + + return rate; +} +#endif int pc_split_str(char *str,char **val,int num) { int i; diff --git a/src/map/pc.h b/src/map/pc.h index bf5c62d5d..bbaf5bd7c 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -904,4 +904,7 @@ int pc_del_talisman(struct map_session_data *sd,int count,int type); void pc_baselevelchanged(struct map_session_data *sd); +#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) +int pc_level_penalty_mod(struct map_session_data *sd, struct mob_data * md, int type); +#endif #endif /* _PC_H_ */ |