Selaa lähdekoodia

Combined most of the txt/sql mobdb reading code
- mob.c is now some 10kB less redundant (now using a common function)
- automatically filled in some missing parts of the txt part (view_range_rate, chase_range_rate, line counting, etc)
- also cleaned it up significantly

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9640 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage 18 vuotta sitten
vanhempi
commit
0a09549be2
2 muutettua tiedostoa jossa 283 lisäystä ja 532 poistoa
  1. 6 0
      Changelog-Trunk.txt
  2. 277 532
      src/map/mob.c

+ 6 - 0
Changelog-Trunk.txt

@@ -3,6 +3,12 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2007/01/10
+	* Combined most of the txt/sql mobdb reading code [ultramage]
+	- mob.c is now some 10kB less redundant (now using a common function)
+	- automatically filled in some missing parts of the txt part
+	  (view_range_rate, chase_range_rate, line counting, etc)
+	- also cleaned it up significantly
 2007/01/09
 	* Changes to script buildin functions: [FlavioJS]
 	- functions checking if a player is attached as soon as possible.

+ 277 - 532
src/map/mob.c

@@ -3166,6 +3166,225 @@ static unsigned int mob_drop_adjust(int rate, int rate_adjust, unsigned short ra
 		rate = rate*rate_adjust/100;
 	return cap_value(rate,rate_min,rate_max);
 }
+
+int mob_parse_dbrow(char** str)
+{
+	struct mob_db *db;
+	struct status_data *status;
+	int class_, i, k;
+	double exp, maxhp;
+	struct mob_data data;
+	
+	class_ = str[0] ? atoi(str[0]) : 0;
+	if (class_ == 0)
+		return 0; //Leave blank lines alone... [Skotlex]
+	
+	if (class_ <= 1000 || class_ > MAX_MOB_DB) {
+		ShowWarning("Mob with ID: %d not loaded. ID must be in range [%d-%d]\n", class_, 1000, MAX_MOB_DB);
+		return 0;
+	}
+	if (pcdb_checkid(class_)) {
+		ShowWarning("Mob with ID: %d not loaded. That ID is reserved for player classes.\n");
+		return 0;
+	}
+	
+	if (mob_db_data[class_] == NULL)
+		mob_db_data[class_] = aCalloc(1, sizeof (struct mob_data));
+	
+	db = mob_db_data[class_];
+	status = &db->status;
+	
+	db->vd.class_ = class_;
+	memcpy(db->sprite, str[1], NAME_LENGTH-1);
+	memcpy(db->jname, str[2], NAME_LENGTH-1);
+	memcpy(db->name, str[3], NAME_LENGTH-1);
+	
+	db->lv = cap_value(atoi(str[4]), 1, USHRT_MAX);
+	
+	status->max_hp = atoi(str[5]);
+	status->max_sp = atoi(str[6]);
+	
+	exp = (double)atoi(str[7]) * (double)battle_config.base_exp_rate / 100.;
+	db->base_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+	
+	exp = (double)atoi(str[8]) * (double)battle_config.job_exp_rate / 100.;
+	db->job_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+	
+	status->rhw.range = atoi(str[9]);
+	status->rhw.atk = atoi(str[10]);
+	status->rhw.atk2 = atoi(str[11]);
+	status->def = atoi(str[12]);
+	status->mdef = atoi(str[13]);
+	
+	//All status should be min 1 to prevent divisions by zero from some skills. [Skotlex]
+	status->str = cap_value(atoi(str[14]), 1, USHRT_MAX);
+	status->agi = cap_value(atoi(str[15]), 1, USHRT_MAX);
+	status->vit = cap_value(atoi(str[16]), 1, USHRT_MAX);
+	status->int_ = cap_value(atoi(str[17]), 1, USHRT_MAX);
+	status->dex = cap_value(atoi(str[18]), 1, USHRT_MAX);
+	status->luk = cap_value(atoi(str[19]), 1, USHRT_MAX);
+	
+	db->range2 = atoi(str[20]);
+	db->range3 = atoi(str[21]);
+	if (battle_config.view_range_rate != 100) {
+		db->range2 = db->range2 * battle_config.view_range_rate / 100;
+		if (db->range2 < 1)
+			db->range2 = 1;
+	}
+	if (battle_config.chase_range_rate != 100) {
+		db->range3 = db->range3 * battle_config.chase_range_rate / 100;
+		if (db->range3 < db->range2)
+			db->range3 = db->range2;
+	}
+	
+	status->size = atoi(str[22]);
+	status->race = atoi(str[23]);
+	
+	i = atoi(str[24]); //Element
+	status->def_ele = i%10;
+	status->ele_lv = i/20;
+	if (status->def_ele >= ELE_MAX) {
+		ShowWarning("Mob with ID: %d has invalid element type %d (max element is %d)\n", class_, status->def_ele, ELE_MAX-1);
+		status->def_ele = ELE_NEUTRAL;
+	}
+	if (status->ele_lv < 1 || status->ele_lv > 4) {
+		ShowWarning("Mob with ID: %d has invalid element level %d (max is 4)\n", class_, status->ele_lv);
+		status->ele_lv = 1;
+	}
+	
+	status->mode = (int)strtol(str[25], NULL, 0);
+	if (!battle_config.monster_active_enable)
+		status->mode &= ~MD_AGGRESSIVE;
+	
+	status->speed = atoi(str[26]);
+	status->aspd_rate = 1000;
+	status->adelay = atoi(str[27]);
+	status->amotion = atoi(str[28]);
+	//If the attack animation is longer than the delay, the client crops the attack animation!
+	if (status->adelay < status->amotion)
+		status->adelay = status->amotion;
+	status->dmotion = atoi(str[29]);
+	if(battle_config.monster_damage_delay_rate != 100)
+		status->dmotion = status->dmotion * battle_config.monster_damage_delay_rate / 100;
+	
+	data.bl.type = BL_MOB;
+	data.level = db->lv;
+	memcpy(&data.status, status, sizeof(struct status_data));
+	status_calc_misc(&data.bl, status, db->lv);
+	
+	// MVP EXP Bonus, Chance: MEXP,ExpPer
+	db->mexp = atoi(str[30]) * battle_config.mvp_exp_rate / 100;
+	db->mexpper = atoi(str[31]);
+	
+	//Now that we know if it is an mvp or not, apply battle_config modifiers [Skotlex]
+	maxhp = (double)status->max_hp;
+	if (db->mexp > 0) //Mvp
+		if (battle_config.mvp_hp_rate != 100) 
+			maxhp = maxhp * (double)battle_config.mvp_hp_rate / 100.;
+	else //Normal mob
+		if (battle_config.monster_hp_rate != 100) 
+			maxhp = maxhp * (double)battle_config.monster_hp_rate / 100.;
+	
+	status->max_hp = (unsigned int)cap_value(maxhp, 1, UINT_MAX);
+	if(status->max_sp < 1) status->max_sp = 1;
+	
+	//Since mobs always respawn with full life...
+	status->hp = status->max_hp;
+	status->sp = status->max_sp;
+	
+	// MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per
+	for(i = 0; i < 3; i++) {
+		struct item_data *id;
+		db->mvpitem[i].nameid = atoi(str[32+i*2]);
+		if (!db->mvpitem[i].nameid) {
+			db->mvpitem[i].p = 0; //No item....
+			continue;
+		}
+		db->mvpitem[i].p = mob_drop_adjust(atoi(str[33+i*2]), battle_config.item_rate_mvp, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
+		
+		//calculate and store Max available drop chance of the MVP item
+		if (db->mvpitem[i].p) {
+			id = itemdb_search(db->mvpitem[i].nameid);
+			if (id->maxchance == 10000 || (id->maxchance < db->mvpitem[i].p/10 + 1) ) {
+				//item has bigger drop chance or sold in shops
+				id->maxchance = db->mvpitem[i].p/10 + 1; //reduce MVP drop info to not spoil common drop rate
+			}
+		}
+	}
+	
+	for(i = 0; i < MAX_MOB_DROP; i++) {
+		int rate = 0, rate_adjust, type;
+		unsigned short ratemin, ratemax;
+		struct item_data *id;
+		k = 38+i*2;
+		db->dropitem[i].nameid = atoi(str[k]);
+		if (!db->dropitem[i].nameid) {
+			db->dropitem[i].p = 0; //No drop.
+			continue;
+		}
+		type = itemdb_type(db->dropitem[i].nameid);
+		rate = atoi(str[k+1]);
+		if (class_ >= 1324 && class_ <= 1363)
+		{	//Treasure box drop rates [Skotlex]
+			rate_adjust = battle_config.item_rate_treasure;
+			ratemin = battle_config.item_drop_treasure_min;
+			ratemax = battle_config.item_drop_treasure_max;
+		}
+		else switch (type)
+		{ // Added suport to restrict normal drops of MVP's [Reddozen]
+		case IT_HEALING:
+			rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_heal_boss : battle_config.item_rate_heal;
+			ratemin = battle_config.item_drop_heal_min;
+			ratemax = battle_config.item_drop_heal_max;
+			break;
+		case IT_USABLE:
+			rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_use_boss : battle_config.item_rate_use;
+			ratemin = battle_config.item_drop_use_min;
+			ratemax = battle_config.item_drop_use_max;
+			break;
+		case IT_WEAPON:
+		case IT_ARMOR:
+		case IT_PETARMOR:
+			rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_equip_boss : battle_config.item_rate_equip;
+			ratemin = battle_config.item_drop_equip_min;
+			ratemax = battle_config.item_drop_equip_max;
+			break;
+		case IT_CARD:
+			rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_card_boss : battle_config.item_rate_card;
+			ratemin = battle_config.item_drop_card_min;
+			ratemax = battle_config.item_drop_card_max;
+			break;
+		default:
+			rate_adjust = (status->mode&MD_BOSS) ? battle_config.item_rate_common_boss : battle_config.item_rate_common;
+			ratemin = battle_config.item_drop_common_min;
+			ratemax = battle_config.item_drop_common_max;
+			break;
+		}
+		db->dropitem[i].p = mob_drop_adjust(rate, rate_adjust, ratemin, ratemax);
+		
+		//calculate and store Max available drop chance of the item
+		if (db->dropitem[i].p && (class_ < 1324 || class_ > 1363)) { //Skip treasure chests.
+			id = itemdb_search(db->dropitem[i].nameid);
+			if (id->maxchance == 10000 || (id->maxchance < db->dropitem[i].p) ) {
+				id->maxchance = db->dropitem[i].p; //item has bigger drop chance or sold in shops
+			}
+			for (k = 0; k< MAX_SEARCH; k++) {
+				if (id->mob[k].chance < db->dropitem[i].p && id->mob[k].id != class_)
+					break;
+			}
+			if (k == MAX_SEARCH)
+				continue;
+			
+			if (id->mob[k].id != class_)
+				memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
+			id->mob[k].chance = db->dropitem[i].p;
+			id->mob[k].id = class_;
+		}
+	}
+	
+	return 1;
+}
+
 /*==========================================
  * mob_db.txt reading
  *------------------------------------------
@@ -3175,291 +3394,85 @@ static int mob_readdb(void)
 	FILE *fp;
 	char line[1024];
 	char *filename[]={ "mob_db.txt","mob_db2.txt" };
-	struct status_data *status;
-	struct mob_db *db;
-	int class_, i, fi, k;
-	struct mob_data data;
-	memset(&data, 0, sizeof(struct mob_data));
-	data.bl.type = BL_MOB;
-	for(fi=0;fi<2;fi++){
+	int i, fi;
+	unsigned int ln = 0;
+	
+	for(fi = 0; fi < 2; fi++) {
 		sprintf(line, "%s/%s", db_path, filename[fi]);
-		fp=fopen(line,"r");
-		if(fp==NULL){
-			if(fi>0)
+		fp = fopen(line, "r");
+		if(fp == NULL) {
+			if(fi > 0)
 				continue;
 			return -1;
 		}
-		while(fgets(line,1020,fp)){
-			double exp, maxhp;
+		
+		while(fgets(line, 1020, fp))
+		{
 			char *str[38+2*MAX_MOB_DROP], *p, *np;
-
+			
 			if(line[0] == '/' && line[1] == '/')
 				continue;
-
-			for(i=0,p=line;i<38+2*MAX_MOB_DROP;i++){
-				if((np=strchr(p,','))!=NULL){
-					str[i]=p;
-					*np=0;
-					p=np+1;
+			
+			for(i = 0, p = line; i < 38 + 2*MAX_MOB_DROP; i++) {
+				if((np = strchr(p, ',')) != NULL) {
+					str[i] = p; *np = 0; p = np + 1;
 				} else
-					str[i]=p;
+					str[i] = p;
 			}
-			class_ = str[0]?atoi(str[0]):0;
-			if (class_ == 0)
-				continue; //Leave blank lines alone... [Skotlex]
-
-			if (class_ <= 1000 || class_ > MAX_MOB_DB)
-			{
-				ShowWarning("Mob with ID: %d not loaded. ID must be in range [%d-%d]\n", class_, 1000, MAX_MOB_DB);
-				continue;
-			} else if (pcdb_checkid(class_))
-			{
-				ShowWarning("Mob with ID: %d not loaded. That ID is reserved for player classes.\n");
+			
+			if(i < 38 + 2*MAX_MOB_DROP) {
+				ShowWarning("mob_readdb: Insufficient columns for mob with ID: %d\n", str[0] ? atoi(str[0]) : 0);
 				continue;
 			}
-			if(i < 38+2*MAX_MOB_DROP) {
-				ShowWarning("mob_readdb: Insufficient columns for mob with ID: %d\n", class_);
+			
+			if (!mob_parse_dbrow(str))
 				continue;
-			}
-			if (mob_db_data[class_] == NULL)
-				mob_db_data[class_] = aCalloc(1, sizeof (struct mob_data));
-			db = mob_db_data[class_];
-
-			db->vd.class_ = class_;
-			memcpy(db->sprite, str[1], NAME_LENGTH-1);
-			memcpy(db->jname, str[2], NAME_LENGTH-1);
-			memcpy(db->name, str[3], NAME_LENGTH-1);
-			db->lv = atoi(str[4]);
-			if (db->lv < 1)
-				db->lv = 1;
-
-			status = &db->status;
-
-			status->max_hp = atoi(str[5]);
-			status->max_sp = atoi(str[6]);
-
-			exp = (double)atoi(str[7]) * (double)battle_config.base_exp_rate / 100.;
-			if (exp < 0)
-				db->base_exp = 0;
-			if (exp > UINT_MAX)
-				db->base_exp = UINT_MAX;
-			else
-				db->base_exp = (unsigned int)exp;
-
-			exp = (double)atoi(str[8]) * (double)battle_config.job_exp_rate / 100.;
-			if (exp < 0)
-				db->job_exp = 0;
-			else if (exp > UINT_MAX)
-				db->job_exp = UINT_MAX;
-			else
-				db->job_exp = (unsigned int)exp;
 			
-			status->rhw.range=atoi(str[9]);
-			status->rhw.atk=atoi(str[10]);
-			status->rhw.atk2=atoi(str[11]);
-			status->def=atoi(str[12]);
-			status->mdef=atoi(str[13]);
-			status->str=atoi(str[14]);
-			status->agi=atoi(str[15]);
-			status->vit=atoi(str[16]);
-			status->int_=atoi(str[17]);
-			status->dex=atoi(str[18]);
-			status->luk=atoi(str[19]);
-			//All status should be min 1 to prevent divisions by zero from some skills. [Skotlex]
-			if (status->str < 1) status->str = 1;
-			if (status->agi < 1) status->agi = 1;
-			if (status->vit < 1) status->vit = 1;
-			if (status->int_< 1) status->int_= 1;
-			if (status->dex < 1) status->dex = 1;
-			if (status->luk < 1) status->luk = 1;
-
-			db->range2=atoi(str[20]);
-			db->range3=atoi(str[21]);
-			if (battle_config.view_range_rate!=100)
-			{
-				db->range2=
-					db->range2
-					*battle_config.view_range_rate/100;
-				if (db->range2<1)
-					db->range2=1;
-			}
-			if (battle_config.chase_range_rate!=100)
-			{
-				db->range3=
-					db->range3
-					*battle_config.chase_range_rate/100;
-				if (db->range3<db->range2)
-					db->range3=db->range2;
-			}
-			status->size=atoi(str[22]);
-			status->race=atoi(str[23]);
-			i = atoi(str[24]); //Element
-			status->def_ele = i%10;
-			status->ele_lv = i/20;
-			if (status->def_ele >= ELE_MAX)
-			{
-				ShowWarning("Mob with ID: %d has invalid element type %d (max element is %d)\n", class_, status->def_ele, ELE_MAX-1);
-				status->def_ele = ELE_NEUTRAL;
-			}
-			if (status->ele_lv < 1 || status->ele_lv > 4)
-			{
-				ShowWarning("Mob with ID: %d has invalid element level %d (max is 4)\n", class_, status->ele_lv);
-				status->ele_lv = 1;
-			}
-			status->mode=(int)strtol(str[25],NULL,0);
-			if (!battle_config.monster_active_enable)
-				status->mode&=~MD_AGGRESSIVE;
-			status->speed=atoi(str[26]);
-			status->aspd_rate = 1000;
-			status->adelay = atoi(str[27]);
-			status->amotion = atoi(str[28]);
-			//If the attack animation is longer than the delay, the client crops the attack animation!
-			if (status->adelay < status->amotion)
-				status->adelay = status->amotion;
-			status->dmotion=atoi(str[29]);
-			if(battle_config.monster_damage_delay_rate != 100)
-				status->dmotion = status->dmotion*battle_config.monster_damage_delay_rate/100;
-
-			data.level = db->lv;
-			memcpy(&data.status, status, sizeof(struct status_data));
-			status_calc_misc(&data.bl, status, db->lv);
-			// MVP EXP Bonus, Chance: MEXP,ExpPer
-			db->mexp=atoi(str[30])*battle_config.mvp_exp_rate/100;
-			db->mexpper=atoi(str[31]);
-			//Now that we know if it is an mvp or not,
-			//apply battle_config modifiers [Skotlex]
-			maxhp = (double)status->max_hp;
-			if (db->mexp > 0)
-			{	//Mvp
-				if (battle_config.mvp_hp_rate != 100) 
-					maxhp = maxhp * (double)battle_config.mvp_hp_rate /100.;
-			} else if (battle_config.monster_hp_rate != 100) //Normal mob
-				maxhp = maxhp * (double)battle_config.monster_hp_rate /100.;
-			if (maxhp > UINT_MAX) maxhp = UINT_MAX;
-			status->max_hp = (unsigned int)maxhp;
-
-			if(status->max_hp < 1) status->max_hp = 1;
-			if(status->max_sp < 1) status->max_sp = 1;
-			status->hp = status->max_hp;
-			status->sp = status->max_sp;
-
-			// MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per
-			for(i=0;i<3;i++){
-				struct item_data *id;
-				db->mvpitem[i].nameid=atoi(str[32+i*2]);
-				if (!db->mvpitem[i].nameid) {
-					//No item....
-					db->mvpitem[i].p = 0;
-					continue;
-				}
-				db->mvpitem[i].p= mob_drop_adjust(atoi(str[33+i*2]), battle_config.item_rate_mvp,
-					battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
-
-				//calculate and store Max available drop chance of the MVP item
-				if (db->mvpitem[i].p) {
-					id = itemdb_search(db->mvpitem[i].nameid);
-					if (id->maxchance==10000 || (id->maxchance < db->mvpitem[i].p/10+1) ) {
-					//item has bigger drop chance or sold in shops
-						id->maxchance = db->mvpitem[i].p/10+1; //reduce MVP drop info to not spoil common drop rate
-					}			
-				}
-			}
+			ln++; // counts the number of correctly parsed entries
+		}
+		fclose(fp);
+		ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, filename[fi]);
+		ln = 0;
+	}
+	return 0;
+}
 
-			for(i=0;i<MAX_MOB_DROP;i++){
-				int rate = 0,rate_adjust,type;
-				unsigned short ratemin,ratemax;
-				struct item_data *id;
-				k=38+i*2;
-				db->dropitem[i].nameid=atoi(str[k]);
-				if (!db->dropitem[i].nameid) {
-					//No drop.
-					db->dropitem[i].p = 0;
+#ifndef TXT_ONLY
+/*==========================================
+ * SQL reading
+ *------------------------------------------
+ */
+static int mob_read_sqldb(void)
+{
+	char *mob_db_name[] = { mob_db_db, mob_db2_db };
+	int fi;
+	unsigned int ln = 0;
+	
+	for (fi = 0; fi < 2; fi++) {
+		sprintf (tmp_sql, "SELECT * FROM `%s`", mob_db_name[fi]);
+		if (mysql_query(&mmysql_handle, tmp_sql)) {
+			ShowSQL("DB error (%s) - %s\n", mob_db_name[fi], mysql_error(&mmysql_handle));
+			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+			continue;
+		}
+		sql_res = mysql_store_result(&mmysql_handle);
+		if (sql_res) {
+			while((sql_row = mysql_fetch_row(sql_res))){
+				
+				if (!mob_parse_dbrow(sql_row))
 					continue;
-				}
-				type = itemdb_type(db->dropitem[i].nameid);
-				rate = atoi(str[k+1]);
-				if (class_ >= 1324 && class_ <= 1363)
-				{	//Treasure box drop rates [Skotlex]
-					rate_adjust = battle_config.item_rate_treasure;
-					ratemin = battle_config.item_drop_treasure_min;
-					ratemax = battle_config.item_drop_treasure_max;
-				}
-				else switch (type)	// Added suport to restrict normal drops of MVP's [Reddozen]
-				{
-				case IT_HEALING:
-					if (status->mode&MD_BOSS)
-						rate_adjust = battle_config.item_rate_heal_boss;
-					else
-						rate_adjust = battle_config.item_rate_heal;
-					ratemin = battle_config.item_drop_heal_min;
-					ratemax = battle_config.item_drop_heal_max;
-					break;
-				case IT_USABLE:
-					if (status->mode&MD_BOSS)
-						rate_adjust = battle_config.item_rate_use_boss;
-					else
-						rate_adjust = battle_config.item_rate_use;
-					ratemin = battle_config.item_drop_use_min;
-					ratemax = battle_config.item_drop_use_max;
-					break;
-				case IT_WEAPON:
-				case IT_ARMOR:
-				case IT_PETARMOR:		// Changed to include Pet Equip
-					if (status->mode&MD_BOSS)
-						rate_adjust = battle_config.item_rate_equip_boss;
-					else
-						rate_adjust = battle_config.item_rate_equip;
-					ratemin = battle_config.item_drop_equip_min;
-					ratemax = battle_config.item_drop_equip_max;
-					break;
-				case IT_CARD:
-					if (status->mode&MD_BOSS)
-						rate_adjust = battle_config.item_rate_card_boss;
-					else
-						rate_adjust = battle_config.item_rate_card;
-					ratemin = battle_config.item_drop_card_min;
-					ratemax = battle_config.item_drop_card_max;
-					break;
-				default:
-					if (status->mode&MD_BOSS)
-						rate_adjust = battle_config.item_rate_common_boss;
-					else {
-						rate_adjust = battle_config.item_rate_common;
-					}
-					ratemin = battle_config.item_drop_common_min;
-					ratemax = battle_config.item_drop_common_max;
-					break;
-				}
-				db->dropitem[i].p = mob_drop_adjust(rate, rate_adjust, ratemin, ratemax);
-
-				//calculate and store Max available drop chance of the item
-				if (db->dropitem[i].p &&
-					(class_ < 1324 || class_ > 1363) //Skip treasure chests.
-				) {
-					id = itemdb_search(db->dropitem[i].nameid);
-					if (id->maxchance==10000 || (id->maxchance < db->dropitem[i].p) ) {
-					//item has bigger drop chance or sold in shops
-						id->maxchance = db->dropitem[i].p;
-					}
-					for (k = 0; k< MAX_SEARCH; k++) {
-						if (id->mob[k].chance < db->dropitem[i].p && id->mob[k].id != class_)
-							break;
-					}
-					if (k == MAX_SEARCH)
-						continue;
 				
-					if (id->mob[k].id != class_)
-						memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
-					id->mob[k].chance = db->dropitem[i].p;
-					id->mob[k].id = class_;
-				}
+				ln++; // counts the number of correctly parsed entries
 			}
+			
+			mysql_free_result(sql_res);
+			ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, mob_db_name[fi]);
+			ln = 0;
 		}
-		fclose(fp);
-		ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",filename[fi]);
 	}
 	return 0;
 }
+#endif /* not TXT_ONLY */
 
 /*==========================================
  * MOB display graphic change data reading
@@ -3898,274 +3911,6 @@ static int mob_readdb_race(void)
 	return 0;
 }
 
-#ifndef TXT_ONLY
-/*==========================================
- * SQL reading
- *------------------------------------------
- */
-static int mob_read_sqldb(void)
-{
-	const char unknown_str[NAME_LENGTH] ="unknown";
-	int i, fi, class_, k;
-	double exp, maxhp;
-	long unsigned int ln = 0;
-	struct status_data *status;
-	struct mob_db *db;
-	char *mob_db_name[] = { mob_db_db, mob_db2_db };
-	struct mob_data data;
-	memset(&data, 0, sizeof(struct mob_data));
-	data.bl.type = BL_MOB;
-
-	//For easier handling of converting. [Skotlex]
-#define TO_INT(a) (sql_row[a]==NULL?0:atoi(sql_row[a]))
-#define TO_STR(a) (sql_row[a]==NULL?unknown_str:sql_row[a])
-	
-    for (fi = 0; fi < 2; fi++) {
-		sprintf (tmp_sql, "SELECT * FROM `%s`", mob_db_name[fi]);
-		if (mysql_query(&mmysql_handle, tmp_sql)) {
-			ShowSQL("DB error (%s) - %s\n", mob_db_name[fi], mysql_error(&mmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			continue;
-		}
-		sql_res = mysql_store_result(&mmysql_handle);
-		if (sql_res) {
-			while((sql_row = mysql_fetch_row(sql_res))){
-				class_ = TO_INT(0);
-				if (class_ <= 1000 || class_ > MAX_MOB_DB)
-				{
-					ShowWarning("Mob with ID: %d not loaded. ID must be in range [%d-%d]\n", class_, 1000, MAX_MOB_DB);
-					continue;
-				} else if (pcdb_checkid(class_))
-				{
-					ShowWarning("Mob with ID: %d not loaded. That ID is reserved for Upper Classes.\n");
-					continue;
-				}
-				if (mob_db_data[class_] == NULL)
-					mob_db_data[class_] = aCalloc(1, sizeof (struct mob_data));
-				db = mob_db_data[class_];
-				ln++;
-
-				db->vd.class_ = class_;
-				memcpy(db->sprite, TO_STR(1), NAME_LENGTH-1);
-				memcpy(db->jname, TO_STR(2), NAME_LENGTH-1);
-				memcpy(db->name, TO_STR(3), NAME_LENGTH-1);
-				db->lv = TO_INT(4);
-				if (db->lv < 1)
-					db->lv = 1;
-
-				status = &db->status;
-				status->max_hp = TO_INT(5);
-				status->max_sp = TO_INT(6);
-
-				exp = (double)TO_INT(7) * (double)battle_config.base_exp_rate / 100.;
-				if (exp < 0)
-					db->base_exp = 0;
-				else if (exp > UINT_MAX)
-					db->base_exp = UINT_MAX;
-				else
-					db->base_exp = (unsigned int)exp;
-
-				exp = (double)TO_INT(8) * (double)battle_config.job_exp_rate / 100.;
-				if (exp < 0)
-					db->job_exp = 0;
-				else if (exp > UINT_MAX)
-					db->job_exp = UINT_MAX;
-				else
-					db->job_exp = (unsigned int)exp;
-				
-				status->rhw.range = TO_INT(9);
-				status->rhw.atk = TO_INT(10);
-				status->rhw.atk2 = TO_INT(11);
-				status->def = TO_INT(12);
-				status->mdef = TO_INT(13);
-				status->str = TO_INT(14);
-				status->agi = TO_INT(15);
-				status->vit = TO_INT(16);
-				status->int_ = TO_INT(17);
-				status->dex = TO_INT(18);
-				status->luk = TO_INT(19);
-				//All status should be min 1 to prevent divisions by zero from some skills. [Skotlex]
-				if (status->str < 1) status->str = 1;
-				if (status->agi < 1) status->agi = 1;
-				if (status->vit < 1) status->vit = 1;
-				if (status->int_< 1) status->int_= 1;
-				if (status->dex < 1) status->dex = 1;
-				if (status->luk < 1) status->luk = 1;
-
-				db->range2 = TO_INT(20);
-				db->range3 = TO_INT(21);
-				status->size = TO_INT(22);
-				status->race = TO_INT(23);
-				i = TO_INT(24); //Element
-				status->def_ele = i%10;
-				status->ele_lv = i/20;
-				if (status->def_ele >= ELE_MAX)
-				{
-					ShowWarning("Mob with ID: %d has invalid element type %d (max element is %d)\n", class_, status->def_ele, ELE_MAX-1);
-					status->def_ele = ELE_NEUTRAL;
-				}
-				if (status->ele_lv < 1 || status->ele_lv > 4)
-				{
-					ShowWarning("Mob with ID: %d has invalid elemnt level %d (max is 4)\n", class_, status->ele_lv);
-					status->ele_lv = 1;
-				}
-				status->mode = TO_INT(25);
-				if (!battle_config.monster_active_enable)
-					status->mode&=~MD_AGGRESSIVE;
-				status->speed = TO_INT(26);
-				status->aspd_rate = 1000;
-				status->adelay = TO_INT(27);
-				status->amotion = TO_INT(28);
-				//If the attack animation is longer than the delay, the client crops the attack animation!
-				if (status->adelay < status->amotion)
-					status->adelay = status->amotion;
-				status->dmotion = TO_INT(29);
-				if(battle_config.monster_damage_delay_rate != 100)
-					status->dmotion = status->dmotion*battle_config.monster_damage_delay_rate/100;
-
-				data.level = db->lv;
-				memcpy(&data.status, status, sizeof(struct status_data));
-				status_calc_misc(&data.bl, status, db->lv);
-				
-				// MVP EXP Bonus, Chance: MEXP,ExpPer
-				db->mexp = TO_INT(30) * battle_config.mvp_exp_rate / 100;
-				db->mexpper = TO_INT(31);
-				//Now that we know if it is an mvp or not,
-				//apply battle_config modifiers [Skotlex]
-				maxhp = (double)status->max_hp;
-				if (db->mexp > 0)
-				{	//Mvp
-					if (battle_config.mvp_hp_rate != 100) 
-						maxhp = maxhp * (double)battle_config.mvp_hp_rate /100.;
-				} else if (battle_config.monster_hp_rate != 100) //Normal mob
-					maxhp = maxhp * (double)battle_config.monster_hp_rate /100.;
-				if (maxhp > UINT_MAX) maxhp = UINT_MAX;
-				status->max_hp = (unsigned int)maxhp;
-
-				if(status->max_hp < 1) status->max_hp = 1;
-				if(status->max_sp < 1) status->max_sp = 1;
-				//Since mobs always respawn with full life...
-				status->hp = status->max_hp;
-				status->sp = status->max_sp;
-
-				// MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per
-				for (i=0; i<3; i++) {
-					struct item_data *id;
-					db->mvpitem[i].nameid = TO_INT(32+i*2);
-					if (!db->mvpitem[i].nameid) {
-						//No item....
-						db->mvpitem[i].p = 0;
-						continue;
-					}
-					db->mvpitem[i].p = mob_drop_adjust(TO_INT(33+i*2),
-						battle_config.item_rate_mvp, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
-
-					//calculate and store Max available drop chance of the MVP item
-					id = itemdb_search(db->mvpitem[i].nameid);
-					if (db->mvpitem[i].p) {
-						if (id->maxchance==10000 || (id->maxchance < db->mvpitem[i].p/10+1) ) {
-						//item has bigger drop chance or sold in shops
-							id->maxchance = db->mvpitem[i].p/10+1; //reduce MVP drop info to not spoil common drop rate
-						}			
-					}
-				}
-
-				for (i = 0; i < MAX_MOB_DROP; i++){ // 8 -> 10 Lupus
-					int rate = 0, rate_adjust, type;
-					unsigned short ratemin, ratemax;
-					struct item_data *id;
-					k=38+i*2;
-					db->dropitem[i].nameid=TO_INT(k);
-					if (!db->dropitem[i].nameid) {
-						//No drop.
-						db->dropitem[i].p = 0;
-						continue;
-					}
-					type = itemdb_type(db->dropitem[i].nameid);
-					rate = TO_INT(k+1);
-					if (class_ >= 1324 && class_ <= 1363)
-					{	//Treasure box drop rates [Skotlex]
-						rate_adjust = battle_config.item_rate_treasure;
-						ratemin = battle_config.item_drop_treasure_min;
-						ratemax = battle_config.item_drop_treasure_max;
-					}
-					else switch (type)	// Added suport to restrict normal drops of MVP's [Reddozen]
-					{
-					case IT_HEALING:	// Val added heal restrictions
-						if (status->mode&MD_BOSS)
-							rate_adjust = battle_config.item_rate_heal_boss;
-						else
-							rate_adjust = battle_config.item_rate_heal;
-						ratemin = battle_config.item_drop_heal_min;
-						ratemax = battle_config.item_drop_heal_max;
-						break;
-					case IT_USABLE:
-						if (status->mode&MD_BOSS)
-							rate_adjust = battle_config.item_rate_use_boss;
-						else
-							rate_adjust = battle_config.item_rate_use;
-						ratemin = battle_config.item_drop_use_min;
-						ratemax = battle_config.item_drop_use_max;
-						break;
-					case IT_WEAPON:
-					case IT_ARMOR:
-					case IT_PETARMOR:		// Changed to include Pet Equip
-						if (status->mode&MD_BOSS)
-							rate_adjust = battle_config.item_rate_equip_boss;
-						else
-							rate_adjust = battle_config.item_rate_equip;
-						ratemin = battle_config.item_drop_equip_min;
-						ratemax = battle_config.item_drop_equip_max;
-						break;
-					case IT_CARD:
-						if (status->mode&MD_BOSS)
-							rate_adjust = battle_config.item_rate_card_boss;
-						else
-							rate_adjust = battle_config.item_rate_card;
-						ratemin = battle_config.item_drop_card_min;
-						ratemax = battle_config.item_drop_card_max;
-						break;
-					default:
-						if (status->mode&MD_BOSS)
-							rate_adjust = battle_config.item_rate_common_boss;
-						else
-							rate_adjust = battle_config.item_rate_common;
-						ratemin = battle_config.item_drop_common_min;
-						ratemax = battle_config.item_drop_common_max;
-						break;
-					}
-					db->dropitem[i].p = mob_drop_adjust(rate, rate_adjust, ratemin, ratemax);
-
-					//calculate and store Max available drop chance of the item
-					if (db->dropitem[i].p) {
-						id = itemdb_search(db->dropitem[i].nameid);
-						if (id->maxchance==10000 || (id->maxchance < db->dropitem[i].p) ) {
-						//item has bigger drop chance or sold in shops
-							id->maxchance = db->dropitem[i].p;
-						}			
-						for (k = 0; k< MAX_SEARCH; k++) {
-							if (id->mob[k].chance < db->dropitem[i].p && id->mob[k].id != class_)
-								break;
-						}
-						if (k == MAX_SEARCH)
-							continue;
-						if (id->mob[k].id != class_)
-							memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
-						id->mob[k].chance = db->dropitem[i].p;
-						id->mob[k].id = class_;
-					}
-				}
-			}
-
-			mysql_free_result(sql_res);
-			ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, mob_db_name[fi]);
-			ln = 0;
-		}
-	}
-	return 0;
-}
-#endif /* not TXT_ONLY */
-
 void mob_reload(void)
 {
 	int i;