Przeglądaj źródła

- Follow up a8a4425 (bugreport:9062)
- Added check for item group ID usage on item bonus
- Moved this '(sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id, MAPID_TAEKWON)' to a macro 'pc_is_taekwon_ranker(sd)'

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>

Cydh Ramdh 11 lat temu
rodzic
commit
e7b654aaab
7 zmienionych plików z 54 dodań i 40 usunięć
  1. 29 20
      src/map/itemdb.c
  2. 3 3
      src/map/itemdb.h
  3. 1 1
      src/map/mob.c
  4. 14 10
      src/map/pc.c
  5. 2 0
      src/map/pc.h
  6. 1 1
      src/map/skill.c
  7. 4 5
      src/map/status.c

+ 29 - 20
src/map/itemdb.c

@@ -18,18 +18,28 @@
 #include <stdlib.h>
 #include <string.h>
 
-struct item_data *dummy_item; /// This is the default dummy item used for non-existant items. [Skotlex]
-
-static DBMap* itemdb; /// Item DB
+static DBMap *itemdb; /// Item DB
 static DBMap *itemdb_combo; /// Item Combo DB
 static DBMap *itemdb_group; /// Item Group DB
 
-DBMap * itemdb_get_combodb(){
-	return itemdb_combo;
+struct item_data *dummy_item; /// This is the default dummy item used for non-existant items. [Skotlex]
+
+/**
+* Check if combo exists
+* @param combo_id
+* @return NULL if not exist, or struct item_combo*
+*/
+struct item_combo *itemdb_combo_exists(unsigned short combo_id) {
+	return (struct item_combo *)idb_get(itemdb_combo, combo_id);
 }
 
-DBMap * itemdb_get_groupdb() {
-	return itemdb_group;
+/**
+* Check if item group exists
+* @param group_id
+* @return NULL if not exist, or s_item_group_db *
+*/
+struct s_item_group_db *itemdb_group_exists(unsigned short group_id) {
+	return (struct s_item_group_db *)idb_get(itemdb_group, group_id);
 }
 
 /**
@@ -44,17 +54,15 @@ static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap)
 	str = va_arg(ap,char *);
 	dst = va_arg(ap,struct item_data **);
 	dst2 = va_arg(ap,struct item_data **);
+
 	if (item == dummy_item)
 		return 0;
 
 	//Absolute priority to Aegis code name.
-	if (*dst != NULL)
-		return 0;
 	if (strcmpi(item->name,str) == 0)
 		*dst = item;
 
 	//Second priority to Client displayed name.
-	if (*dst2 != NULL) return 0;
 	if (strcmpi(item->jname,str) == 0)
 		*dst2 = item;
 	return 0;
@@ -67,8 +75,7 @@ static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap)
  *------------------------------------------*/
 struct item_data* itemdb_searchname(const char *str)
 {
-	struct item_data* item = NULL;
-	struct item_data* item2 = NULL;
+	struct item_data *item = NULL, * item2 = NULL;
 
 	itemdb->foreach(itemdb,itemdb_searchname_sub,str,&item,&item2);
 	return item ? item : item2;
@@ -82,8 +89,10 @@ static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap)
 	struct item_data *item = db_data2ptr(&data);
 	char *str;
 	str = va_arg(ap,char *);
-	if (item == dummy_item)
-		return 1; //Invalid item.
+
+	if (item && dummy_item)
+		return 1;
+
 	if (stristr(item->jname,str))
 		return 0;
 	if (stristr(item->name,str))
@@ -369,8 +378,7 @@ static void itemdb_jobid2mapid(unsigned int *bclass, unsigned int jobmask)
 /**
 * Create dummy item data
 */
-static void create_dummy_data(void)
-{
+static void create_dummy_data(void) {
 	CREATE(dummy_item, struct item_data, 1);
 
 	memset(dummy_item, 0, sizeof(struct item_data));
@@ -381,6 +389,7 @@ static void create_dummy_data(void)
 	safestrncpy(dummy_item->name, "UNKNOWN_ITEM", sizeof(dummy_item->name));
 	safestrncpy(dummy_item->jname, "Unknown Item", sizeof(dummy_item->jname));
 	dummy_item->view_id = UNKNOWN_ITEM_ID;
+	idb_put(itemdb, dummy_item->nameid, dummy_item);
 }
 
 /*==========================================
@@ -392,7 +401,8 @@ struct item_data* itemdb_search(unsigned short nameid) {
 	struct item_data* id = (struct item_data*)idb_get(itemdb, nameid);
 	if (id)
 		return id;
-	ShowWarning("itemdb_search: Item ID %hu does not exists in the item_db. Using dummy data.\n", nameid);
+	if (nameid != dummy_item->nameid) // Avoid previous item that assigned with dummy_item to shows this message again
+		ShowWarning("itemdb_search: Item ID %hu does not exists in the item_db. Using dummy data.\n", nameid);
 	return dummy_item;
 }
 
@@ -1674,10 +1684,10 @@ void itemdb_reload(void) {
 * Finalizing Item DB
 */
 void do_final_itemdb(void) {
+	db_destroy(itemdb_combo);
 	itemdb_group->destroy(itemdb_group, itemdb_group_free);
 	itemdb->destroy(itemdb, itemdb_final_sub);
 	destroy_item_data(dummy_item);
-	db_destroy(itemdb_combo);
 }
 
 /**
@@ -1687,7 +1697,6 @@ void do_init_itemdb(void) {
 	itemdb = idb_alloc(DB_OPT_BASE);
 	itemdb_combo = idb_alloc(DB_OPT_BASE);
 	itemdb_group = idb_alloc(DB_OPT_BASE);
-	create_dummy_data(); //Dummy data item.
-	
+	create_dummy_data(); //Dummy data item.	
 	itemdb_read();
 }

+ 3 - 3
src/map/itemdb.h

@@ -482,12 +482,12 @@ bool itemdb_isstackable2(struct item_data *id);
 uint64 itemdb_unique_id(int8 flag, int64 value); // Unique Item ID
 bool itemdb_isNoEquip(struct item_data *id, uint16 m);
 
+struct item_combo *itemdb_combo_exists(unsigned short combo_id);
+
+struct s_item_group_db *itemdb_group_exists(unsigned short group_id);
 char itemdb_pc_get_itemgroup(uint16 group_id, struct map_session_data *sd);
 uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, unsigned short nameid);
 
-DBMap * itemdb_get_combodb();
-DBMap * itemdb_get_groupdb();
-
 void itemdb_reload(void);
 
 void do_final_itemdb(void);

+ 1 - 1
src/map/mob.c

@@ -2436,7 +2436,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 			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
+				if ((sd->add_drop[i].race < RC_NONE_ && 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
 				{

+ 14 - 10
src/map/pc.c

@@ -401,7 +401,7 @@ void pc_addfame(struct map_session_data *sd,int count)
 }
 
 /**
- * Check whether a player ID is in the fame rankers' list of its job, returns his/her position if so, 0 else
+ * Check whether a player ID is in the fame rankers list of its job, returns his/her position if so, 0 else
  * @param sd
  * @param job Job use enum e_mapid
  * @return Rank
@@ -1654,7 +1654,7 @@ void pc_calc_skilltree(struct map_session_data *sd)
 		}
 	} while(flag);
 
-	if( c > 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && sd->status.skill_point == 0 && pc_famerank(sd->status.char_id, MAPID_TAEKWON) ) {
+	if( c > 0 && sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) ) {
 		/* Taekwon Ranker Bonus Skill Tree
 		============================================
 		- Grant All Taekwon Tree, but only as Bonus Skills in case they drop from ranking.
@@ -2031,10 +2031,16 @@ static void pc_bonus_addeff_onskill(struct s_addeffectonskill* effect, int max,
 static void pc_bonus_item_drop(struct s_add_drop *drop, const short max, unsigned short nameid, uint16 group, int class_, short race, int rate)
 {
 	uint8 i;
-	if (nameid && !group && !itemdb_exists(nameid)) {
+	struct s_item_group_db *group_ = NULL;
+	if (nameid && !itemdb_exists(nameid)) {
 		ShowWarning("pc_bonus_item_drop: Invalid item id %hu\n",nameid);
 		return;
 	}
+	if (!group || (group_ = itemdb_group_exists(group)) == NULL) {
+		ShowWarning("pc_bonus_item_drop: Invalid Item Group %hu\n",group);
+		return;
+	}
+
 	//Apply config rate adjustment settings.
 	if (rate >= 0) { //Absolute drop.
 		if (battle_config.item_rate_adddrop != 100)
@@ -3382,8 +3388,7 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
 		break;
 	case SP_ADD_ITEMGROUP_HEAL_RATE:
 		{
-			struct s_item_group_db *group = (struct s_item_group_db *) idb_get(itemdb_get_groupdb(), type2);
-			if (!group) {
+			if (!type2 || !itemdb_group_exists(type)) {
 				ShowError("pc_bonus2: SP_ADD_ITEMGROUP_HEAL_RATE Invalid item group with id %d\n", type2);
 				break;
 			}
@@ -6624,7 +6629,7 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id)
 		sd->status.skill_point--;
 		if( !skill_get_inf(skill_id) )
 			status_calc_pc(sd,SCO_NONE); // Only recalculate for passive skills.
-		else if( sd->status.skill_point == 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )
+		else if( sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) )
 			pc_calc_skilltree(sd); // Required to grant all TK Ranker skills.
 		else
 			pc_check_skilltree(sd, skill_id); // Check if a new skill can Lvlup
@@ -6866,11 +6871,10 @@ int pc_resetskill(struct map_session_data* sd, int flag)
 		return 0;
 
 	if( !(flag&2) ) { //Remove stuff lost when resetting skills.
-
 		/**
 		 * It has been confirmed on official servers that when you reset skills with a ranked Taekwon your skills are not reset (because you have all of them anyway)
 		 **/
-		if( (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )
+		if( pc_is_taekwon_ranker(sd) )
 			return 0;
 
 		if( pc_checkskill(sd, SG_DEVIL) &&  !pc_nextjobexp(sd) )
@@ -11012,8 +11016,8 @@ short pc_get_itemgroup_bonus(struct map_session_data* sd, unsigned short nameid)
 		return bonus;
 	for (i = 0; i < sd->itemgrouphealrate_count; i++) {
 		uint16 group_id = sd->itemgrouphealrate[i]->group_id, j;
-		struct s_item_group_db *group = (struct s_item_group_db *) idb_get(itemdb_get_groupdb(), group_id);
-		if (!group)
+		struct s_item_group_db *group = NULL;
+		if (!group_id || !(group = itemdb_group_exists(group_id)))
 			continue;
 		
 		for (j = 0; j < group->random[0].data_qty; j++) {

+ 2 - 0
src/map/pc.h

@@ -1107,6 +1107,8 @@ short pc_get_itemgroup_bonus(struct map_session_data* sd, unsigned short nameid)
 short pc_get_itemgroup_bonus_group(struct map_session_data* sd, uint16 group_id);
 
 bool pc_is_same_equip_index(enum equip_index eqi, int *equip_index, int8 index);
+/// Check if player is Taekwon Ranker and the level is >= 90 (battle_config.taekwon_ranker_min_lv)
+#define pc_is_taekwon_ranker(sd) (((sd)->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && (sd)->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank((sd)->status.char_id,MAPID_TAEKWON))
 
 #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
 int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_class, int type);

+ 1 - 1
src/map/skill.c

@@ -13917,7 +13917,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
 				status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
 				return false;
 			}
-			if(sc->data[SC_COMBO]->val1 != skill_id && !( sd && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )) {	//Cancel combo wait.
+			if(sc->data[SC_COMBO]->val1 != skill_id && !pc_is_taekwon_ranker(sd)) {	//Cancel combo wait.
 				unit_cancel_combo(&sd->bl);
 				return false;
 			}

+ 4 - 5
src/map/status.c

@@ -2609,7 +2609,7 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
 			bonus -= 100; //Default hprate is 100, so it should be add 0%
 
 			//+200% for top ranking Taekwons over level 90.
-			if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id,MAPID_TAEKWON))
+			if (pc_is_taekwon_ranker(sd))
 				bonus += 200;
 		}
 
@@ -2720,7 +2720,7 @@ static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
 				bonus += 2 * i;
 
 			//+200% for top ranking Taekwons over level 90.
-			if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
+			if (pc_is_taekwon_ranker(sd))
 				bonus += 200;
 		}
 
@@ -3050,13 +3050,12 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
 
 	// We've got combos to process and check
 	if( sd->combos.count ) {
-		DBMap *combo_db = itemdb_get_combodb();
 		for (i = 0; i < sd->combos.count; i++) {
 			uint8 j = 0;
 			bool no_run = false;
-			struct item_combo *combo = (struct item_combo *)idb_get(combo_db,sd->combos.id[i]);
+			struct item_combo *combo = NULL;
 
-			if (!sd->combos.bonus[i])
+			if (!sd->combos.bonus[i] || !(combo = itemdb_combo_exists(sd->combos.id[i])))
 				continue;
 			// Check combo items
 			while (j < combo->count) {