From ce26e8cb2a9a912a7b580b75cd5e650b2f29fc9b Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Sun, 26 Jan 2014 19:23:40 +0700 Subject: [PATCH] Fixed bugreport:8550 http://rathena.org/board/tracker/issue-8550-baddmonsterdropitem-bug/ Signed-off-by: Cydh Ramdh --- src/map/itemdb.c | 6 ++-- src/map/itemdb.h | 2 +- src/map/mob.c | 33 +++++++++++---------- src/map/pc.c | 74 +++++++++++++++++++++++------------------------- src/map/pc.h | 9 ++++-- src/map/status.h | 5 ++-- 6 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/map/itemdb.c b/src/map/itemdb.c index b70ca5a46b..9ee0d26f8f 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -148,11 +148,11 @@ int itemdb_searchname_array(struct item_data** data, int size, const char *str) * @param sub_group: Default is 1 * @return nameid */ -unsigned short itemdb_searchrandomid(int group_id, uint8 sub_group) +unsigned short itemdb_searchrandomid(uint16 group_id, uint8 sub_group) { if (sub_group) sub_group -= 1; - if (group_id < 1 || group_id >= MAX_ITEMGROUP || !&itemgroup_db[group_id]) { + if (!group_id || group_id >= MAX_ITEMGROUP || !&itemgroup_db[group_id]) { ShowError("itemdb_searchrandomid: Invalid group id %d\n", group_id); return UNKNOWN_ITEM_ID; } @@ -179,7 +179,7 @@ uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, uint16 n uint16 i, amt = 1; if (sub_group) sub_group -= 1; - if (group_id < 1 || group_id >= MAX_ITEMGROUP || !&itemgroup_db[group_id]) { + if (!group_id || group_id >= MAX_ITEMGROUP || !&itemgroup_db[group_id]) { ShowError("itemdb_get_randgroupitem_count: Invalid group id %d\n", group_id); return amt; } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index a7ff9307cc..596e2734bd 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -426,7 +426,7 @@ struct item_data* itemdb_exists(int nameid); const char* itemdb_typename(enum item_types type); int itemdb_group_bonus(struct map_session_data* sd, int itemid); -unsigned short itemdb_searchrandomid(int group_id, uint8 sub_group); +unsigned short itemdb_searchrandomid(uint16 group_id, uint8 sub_group); #define itemdb_value_buy(n) itemdb_search(n)->value_buy #define itemdb_value_sell(n) itemdb_search(n)->value_sell diff --git a/src/map/mob.c b/src/map/mob.c index e905bf9822..d671f08acf 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2436,19 +2436,21 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) if(sd) { // process script-granted extra drop bonuses - int itemid = 0; - for (i = 0; i < ARRAYLENGTH(sd->add_drop) && (sd->add_drop[i].id || sd->add_drop[i].group); i++) { - if ( sd->add_drop[i].race == -md->mob_id - || (sd->add_drop[i].race && sd->add_drop[i].race&((1<race)|(1<add_drop[i].class_ && sd->add_drop[i].class_&((1<class_)|(1<add_drop[i].rate < 0) { - //it's negative, then it should be multiplied. e.g. for Mimic,Myst Case Cards, etc - // rate = base_rate * (mob_level/10) + 1 - drop_rate = -sd->add_drop[i].rate*(md->level/10)+1; - drop_rate = cap_value(drop_rate, battle_config.item_drop_adddrop_min, battle_config.item_drop_adddrop_max); - if (drop_rate > 10000) drop_rate = 10000; + uint16 dropid = 0; + + for (i = 0; i < ARRAYLENGTH(sd->add_drop); i++) { + if (!&sd->add_drop[i] || (!sd->add_drop[i].nameid && !sd->add_drop[i].group)) + continue; + if ((sd->add_drop[i].race < 0 && sd->add_drop[i].race == -md->mob_id) || //Race < 0, use mob_id + (sd->add_drop[i].race == RC_ALL || sd->add_drop[i].race == status->race) || //Matched race + (sd->add_drop[i].class_ == CLASS_ALL || sd->add_drop[i].class_ == status->class_)) //Matched class + { + //Check if the bonus item drop rate should be multiplied with mob level/10 [Lupus] + if (sd->add_drop[i].rate < 0) { + //It's negative, then it should be multiplied. with mob_level/10 + //rate = base_rate * (mob_level/10) + 1 + drop_rate = (-sd->add_drop[i].rate) * md->level / 10 + 1; + drop_rate = cap_value(drop_rate, max(battle_config.item_drop_adddrop_min,1), min(battle_config.item_drop_adddrop_max,10000)); } else //it's positive, then it goes as it is @@ -2456,8 +2458,9 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) if (rnd()%10000 >= drop_rate) continue; - itemid = (sd->add_drop[i].id > 0) ? sd->add_drop[i].id : itemdb_searchrandomid(sd->add_drop[i].group,1); - mob_item_drop(md, dlist, mob_setdropitem(itemid,1), 0, drop_rate, homkillonly); + dropid = (sd->add_drop[i].nameid > 0) ? sd->add_drop[i].nameid : itemdb_searchrandomid(sd->add_drop[i].group,1); + + mob_item_drop(md, dlist, mob_setdropitem(dropid,1), 0, drop_rate, homkillonly); } } diff --git a/src/map/pc.c b/src/map/pc.c index d6cabb95e7..c3f178e86e 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1903,18 +1903,21 @@ static int pc_bonus_addeff_onskill(struct s_addeffectonskill* effect, int max, e } /** Adjust/add drop rate modifier for player -* @param drop: sd->add_drop (struct s_add_drop) -* @param max: max stacked bonus -* @param id: item id that will be dropped +* @param drop: Player's sd->add_drop (struct s_add_drop) +* @param max: Max bonus can be received +* @param nameid: item id that will be dropped * @param group: group id * @param class_: target class -* @param race: target race -* @param rate: rate value -* @return true/false: false if max limit is reached +* @param race: target race. if < 0, means monster_id +* @param rate: rate value: 1 ~ 10000. If < 0, it will be multiplied with mob level/10 */ -static void pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id, short group, int class_, int race, int rate) +static void pc_bonus_item_drop(struct s_add_drop *drop, const short max, uint16 nameid, uint16 group, int class_, int race, int rate) { - int i; + uint8 i; + if (nameid && !group && !itemdb_exists(nameid)) { + ShowWarning("pc_bonus_item_drop: Invalid item id\n",nameid); + return; + } //Apply config rate adjustment settings. if (rate >= 0) { //Absolute drop. if (battle_config.item_rate_adddrop != 100) @@ -1929,42 +1932,35 @@ static void pc_bonus_item_drop(struct s_add_drop *drop, const short max, short i if (rate > -1) rate = -1; } - for(i = 0; i < max && (drop[i].id || drop[i].group); i++) { - if( - ((id && drop[i].id == id) || (group && drop[i].group == group)) && - ((race > RC_NONE_ && race < RC_MAX) || (class_ > CLASS_NONE && class_ < CLASS_MAX)) - ) { - if(race > RC_NONE_ && race < RC_MAX) - drop[i].race |= 1< CLASS_NONE && class_ < CLASS_MAX) - drop[i].class_ |= 1< 0 && rate > 0) - { //Both are absolute rates. - if (drop[i].rate < rate) - drop[i].rate = rate; - } else if(drop[i].rate < 0 && rate < 0) { - //Both are relative rates. - if (drop[i].rate > rate) - drop[i].rate = rate; - } else if (rate < 0) //Give preference to relative rate. - drop[i].rate = rate; - return; + + //Find match entry, and adjust the rate only + for (i = 0; i < max; i++) { + if (!&drop[i] || (!drop[i].nameid && !drop[i].group)) + continue; + if (drop[i].nameid == nameid && + drop[i].group == group && + drop[i].race == race && + drop[i].class_ == class_ + ) + { + //Adjust the rate if it has same classification + if ((rate < 0 && drop[i].rate < 0) || + (rate > 0 && drop[i].rate > 0)) + { + drop[i].rate += rate; + return; + } } } - if(i == max) { - ShowWarning("pc_bonus: Reached max (%d) number of added drops per character!\n", max); + ARR_FIND(0,max,i,!&drop[i] || (drop[i].nameid == 0 && drop[i].group == 0)); + if (i >= max) { + ShowWarning("pc_bonus_item_drop: Reached max (%d) number of added drops per character! (nameid:%d group:%d class_:%d race:%d rate:%d)\n",max,nameid,group,class_,race,rate); return; } - drop[i].id = id; + drop[i].nameid = nameid; drop[i].group = group; - if(race>RC_NONE_ && raceCLASS_NONE && class_