Fixed Level/Drop modifier based on level difference and created a db as suggested in pid:137564. (bugreport:6585)
git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16842 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
c182390854
commit
156446bf33
56
db/level_penalty.txt
Normal file
56
db/level_penalty.txt
Normal file
@ -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
|
@ -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)
|
if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
droprate = mob->dropitem[i].p;
|
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)
|
if (item_data->slot)
|
||||||
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_data->jname, item_data->slot, (float)droprate / 100);
|
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_data->jname, item_data->slot, (float)droprate / 100);
|
||||||
else
|
else
|
||||||
|
@ -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 ) {
|
if( md->dmglog[i].flag != MDLF_PET || battle_config.pet_attack_exp_to_master ) {
|
||||||
#ifdef RENEWAL_EXP
|
#ifdef RENEWAL_EXP
|
||||||
if(!md->db->mexp)
|
int rate = pc_level_penalty_mod(tmpsd[i], md, 1);
|
||||||
party_renewal_exp_mod(&base_exp,&job_exp,tmpsd[i]->status.base_level,md->level);
|
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
|
#endif
|
||||||
pc_gainexp(tmpsd[i], &md->bl, base_exp, job_exp, false);
|
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;
|
struct item_data* it = NULL;
|
||||||
int drop_rate;
|
int drop_rate;
|
||||||
#ifdef RENEWAL_DROP
|
#ifdef RENEWAL_DROP
|
||||||
int drop_modifier = mvp_sd ? party_renewal_drop_mod(mvp_sd->status.base_level - md->level) :
|
int drop_modifier = pc_level_penalty_mod(mvp_sd?mvp_sd:second_sd?second_sd:third_sd, md, 2);
|
||||||
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;
|
|
||||||
#endif
|
#endif
|
||||||
dlist->m = md->bl.m;
|
dlist->m = md->bl.m;
|
||||||
dlist->x = md->bl.x;
|
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%.
|
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));
|
drop_rate = max(drop_rate,cap_value((int)(0.5+drop_rate*(sd->sc.data[SC_ITEMBOOST]->val1)/100.),0,9000));
|
||||||
#ifdef RENEWAL_DROP
|
#ifdef RENEWAL_DROP
|
||||||
if(drop_modifier != 100 && !md->db->mexp) {
|
if( drop_modifier != 100 ) {
|
||||||
drop_rate = drop_rate * drop_modifier / 100;
|
drop_rate = drop_rate * drop_modifier / 100;
|
||||||
if( drop_rate < 1 )
|
if( drop_rate < 1 )
|
||||||
drop_rate = 1;
|
drop_rate = 1;
|
||||||
|
@ -905,66 +905,13 @@ int party_send_xy_clear(struct party_data *p)
|
|||||||
}
|
}
|
||||||
return 0;
|
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]
|
// 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)
|
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];
|
struct map_session_data* sd[MAX_PARTY];
|
||||||
unsigned int i, c;
|
unsigned int i, c;
|
||||||
#ifdef RENEWAL_EXP
|
|
||||||
int src_lvl = status_get_lv(src);
|
|
||||||
#endif
|
|
||||||
nullpo_ret(p);
|
nullpo_ret(p);
|
||||||
|
|
||||||
// count the number of players eligible for exp sharing
|
// 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++) {
|
for (i = 0; i < c; i++) {
|
||||||
#ifdef RENEWAL_EXP
|
#ifdef RENEWAL_EXP
|
||||||
unsigned int b_exp = base_exp, j_exp = job_exp;
|
if( !(src && src->type == BL_MOB && ((TBL_MOB*)src)->db->mexp) ){
|
||||||
if( !(src && src->type == BL_MOB && ((TBL_MOB*)src)->db->mexp) )
|
int rate = pc_level_penalty_mod(sd[i], (TBL_MOB*)src, 1);
|
||||||
party_renewal_exp_mod(&b_exp,&j_exp,sd[i]->status.base_level,src_lvl);
|
base_exp = (unsigned int)cap_value(base_exp * rate / 100, 1, UINT_MAX);
|
||||||
pc_gainexp(sd[i], src, b_exp, j_exp, false);
|
job_exp = (unsigned int)cap_value(job_exp * rate / 100, 1, UINT_MAX);
|
||||||
#else
|
}
|
||||||
pc_gainexp(sd[i], src, base_exp, job_exp, false);
|
|
||||||
#endif
|
#endif
|
||||||
|
pc_gainexp(sd[i], src, base_exp, job_exp, false);
|
||||||
|
|
||||||
if (zeny) // zeny from mobs [Valaris]
|
if (zeny) // zeny from mobs [Valaris]
|
||||||
pc_getzeny(sd[i],zeny);
|
pc_getzeny(sd[i],zeny);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
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);
|
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_ */
|
#endif /* _PARTY_H_ */
|
||||||
|
39
src/map/pc.c
39
src/map/pc.c
@ -51,6 +51,9 @@
|
|||||||
static unsigned int exp_table[CLASS_COUNT][2][MAX_LEVEL];
|
static unsigned int exp_table[CLASS_COUNT][2][MAX_LEVEL];
|
||||||
static unsigned int max_level[CLASS_COUNT][2];
|
static unsigned int max_level[CLASS_COUNT][2];
|
||||||
static unsigned int statp[MAX_LEVEL+1];
|
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]
|
// h-files are for declarations, not for implementations... [Shinomori]
|
||||||
struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
|
struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
|
||||||
@ -86,7 +89,6 @@ struct item_cd {
|
|||||||
short nameid[MAX_ITEMDELAYS];//skill id
|
short nameid[MAX_ITEMDELAYS];//skill id
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//Converts a class to its array index for CLASS_COUNT defined arrays.
|
//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
|
//Note that it does not do a validity check for speed purposes, where parsing
|
||||||
//player input make sure to use a pcdb_checkid first!
|
//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);
|
clif_talisman(sd, type);
|
||||||
return 0;
|
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 pc_split_str(char *str,char **val,int num)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -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);
|
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_ */
|
#endif /* _PC_H_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user