Bläddra i källkod

Fixed bugreport:8550 http://rathena.org/board/tracker/issue-8550-baddmonsterdropitem-bug/

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
Cydh Ramdh 11 år sedan
förälder
incheckning
ce26e8cb2a
6 ändrade filer med 66 tillägg och 63 borttagningar
  1. 3 3
      src/map/itemdb.c
  2. 1 1
      src/map/itemdb.h
  3. 18 15
      src/map/mob.c
  4. 35 39
      src/map/pc.c
  5. 6 3
      src/map/pc.h
  6. 3 2
      src/map/status.h

+ 3 - 3
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;
 	}

+ 1 - 1
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

+ 18 - 15
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<<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);
 				}
 			}
 

+ 35 - 39
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;
 }
 

+ 6 - 3
src/map/pc.h

@@ -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 {

+ 3 - 2
src/map/status.h

@@ -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.
 };