Fixed bugreport:8550 http://rathena.org/board/tracker/issue-8550-baddmonsterdropitem-bug/
Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
parent
34ac3bf3bc
commit
ce26e8cb2a
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<<status->race)|(1<<RC_ALL)))
|
||||
|| (sd->add_drop[i].class_ && sd->add_drop[i].class_&((1<<status->class_)|(1<<CLASS_ALL)))
|
||||
) {
|
||||
//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. 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
74
src/map/pc.c
74
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<<race;
|
||||
if(class_ > CLASS_NONE && class_ < CLASS_MAX)
|
||||
drop[i].class_ |= 1<<class_;
|
||||
if(drop[i].rate > 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_ && race<RC_MAX)
|
||||
drop[i].race = 1<<race;
|
||||
else
|
||||
drop[i].race = race;
|
||||
if(class_>CLASS_NONE && class_<CLASS_MAX)
|
||||
drop[i].class_ = 1<<class_;
|
||||
else
|
||||
drop[i].class_ = class_;
|
||||
drop[i].race = race;
|
||||
drop[i].class_ = class_;
|
||||
drop[i].rate = rate;
|
||||
}
|
||||
|
||||
|
@ -112,10 +112,13 @@ struct s_addeffectonskill {
|
||||
unsigned char target;
|
||||
};
|
||||
|
||||
///Struct of add drop item/group rate
|
||||
struct s_add_drop {
|
||||
short id, group;
|
||||
int rate;
|
||||
int race, class_; //bitwise value of 1<<x
|
||||
uint16 nameid, ///Item ID
|
||||
group; ///Group ID
|
||||
int rate; ///Rate, 1 ~ 10000, -1 ~ -100000
|
||||
char race, ///Target Race, bitwise value of 1<<x. if < 0 means Monster ID
|
||||
class_; ///Target Class, bitwise value of 1<<x
|
||||
};
|
||||
|
||||
struct s_autobonus {
|
||||
|
@ -1747,8 +1747,9 @@ struct status_data {
|
||||
|
||||
unsigned char
|
||||
def_ele, ele_lv,
|
||||
size, race,
|
||||
class_; /// Class_Normal, Class_Boss, Class_Guardian
|
||||
size,
|
||||
race, /// see enum e_race
|
||||
class_; /// see enum e_classAE
|
||||
|
||||
struct weapon_atk rhw, lhw; //Right Hand/Left Hand Weapon.
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user