Browse Source

- Items now store the top MAX_SEARCH drops from mobs and lists them through the new atcommand @whodrops. All merged from my server, of course =D

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5515 54d463be-8e91-2dee-dedb-b68131a5f0ec
skotlex 19 years ago
parent
commit
a2797c2755
6 changed files with 91 additions and 6 deletions
  1. 3 0
      Changelog-Trunk.txt
  2. 3 0
      conf-tmpl/atcommand_athena.conf
  3. 53 0
      src/map/atcommand.c
  4. 1 0
      src/map/atcommand.h
  5. 5 0
      src/map/itemdb.h
  6. 26 6
      src/map/mob.c

+ 3 - 0
Changelog-Trunk.txt

@@ -5,6 +5,9 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.  EV
 GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
 GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
 
 
 2006/03/08
 2006/03/08
+	* Added atcommand @whodrops which lists mobs with the top drop-rates for a
+	  given item. List of stored mobs and their dropchances is also defined by
+	  MAX_SEARCH on map.h [Skotlex]
 	* Modified atcommands @mobinfo and @iteminfo to display multiple matches
 	* Modified atcommands @mobinfo and @iteminfo to display multiple matches
 	  instead of just one. Max number of matches to display is set in map.h
 	  instead of just one. Max number of matches to display is set in map.h
 	  (MAX_SEARCH) which is currently 5. [Skotlex]
 	  (MAX_SEARCH) which is currently 5. [Skotlex]

+ 3 - 0
conf-tmpl/atcommand_athena.conf

@@ -71,6 +71,9 @@ mi: 1
 iteminfo: 1
 iteminfo: 1
 ii: 1
 ii: 1
 
 
+// Show who drops an item (mobs with highest drop rate)
+whodrops: 1
+
 // Syncs the position of the player on the client with the one stored in the server.
 // Syncs the position of the player on the client with the one stored in the server.
 refresh: 1
 refresh: 1
 
 

+ 53 - 0
src/map/atcommand.c

@@ -266,6 +266,7 @@ ACMD_FUNC(shuffle); // by MouseJstr
 ACMD_FUNC(rates); // by MouseJstr
 ACMD_FUNC(rates); // by MouseJstr
 
 
 ACMD_FUNC(iteminfo); // Lupus
 ACMD_FUNC(iteminfo); // Lupus
+ACMD_FUNC(whodrops); //Skotlex 
 ACMD_FUNC(mapflag); // Lupus
 ACMD_FUNC(mapflag); // Lupus
 ACMD_FUNC(me); //added by massdriller, code by lordalfa
 ACMD_FUNC(me); //added by massdriller, code by lordalfa
 ACMD_FUNC(monsterignore); // [Valaris]
 ACMD_FUNC(monsterignore); // [Valaris]
@@ -577,6 +578,7 @@ static AtCommandInfo atcommand_info[] = {
 
 
 	{ AtCommand_ItemInfo,			"@iteminfo",		 1, atcommand_iteminfo }, // [Lupus]
 	{ AtCommand_ItemInfo,			"@iteminfo",		 1, atcommand_iteminfo }, // [Lupus]
 	{ AtCommand_ItemInfo,			"@ii",			 1, atcommand_iteminfo }, // [Lupus]
 	{ AtCommand_ItemInfo,			"@ii",			 1, atcommand_iteminfo }, // [Lupus]
+	{ AtCommand_WhoDrops,			"@whodrops",	 1, atcommand_whodrops }, // [Skotlex]
 	{ AtCommand_MapFlag,			"@mapflag",			99, atcommand_mapflag }, // [Lupus]
 	{ AtCommand_MapFlag,			"@mapflag",			99, atcommand_mapflag }, // [Lupus]
 
 
 	{ AtCommand_Me,					"@me",			20, atcommand_me }, //added by massdriller, code by lordalfa
 	{ AtCommand_Me,					"@me",			20, atcommand_me }, //added by massdriller, code by lordalfa
@@ -9412,6 +9414,57 @@ int atcommand_iteminfo(
 	return -1;
 	return -1;
 }
 }
 
 
+/*==========================================
+ * Show who drops the item.
+ *------------------------------------------
+ */
+int atcommand_whodrops(
+	const int fd, struct map_session_data* sd,
+	const char* command, const char* message)
+{
+	struct item_data *item_data, *item_array[MAX_SEARCH];
+	int i, count = 1;
+
+	if (!message || !*message) {
+		clif_displaymessage(fd, "Please, enter Item name or its ID (usage: @whodrops <item_name_or_ID>).");
+		return -1;
+	}
+	if ((item_array[0] = itemdb_exists(atoi(message))) == NULL)
+		count = itemdb_searchname_array(item_array, MAX_SEARCH, message);
+
+	if (!count) {
+		clif_displaymessage(fd, "Item not found.");
+		return -1;
+	}
+
+	if (count > MAX_SEARCH) {
+		sprintf(atcmd_output, msg_table[269], MAX_SEARCH, count);
+		clif_displaymessage(fd, atcmd_output);
+		count = MAX_SEARCH;
+	}
+	for (i = 0; i < MAX_SEARCH; i++) {
+		item_data = item_array[i];
+		sprintf(atcmd_output, "Item: '%s'[%d]",
+			item_data->jname,item_data->slot);
+		clif_displaymessage(fd, atcmd_output);
+
+		if (item_data->mob[0].chance == 0) {
+			strcpy(atcmd_output, " - Item is not dropped by mobs.");
+			clif_displaymessage(fd, atcmd_output);
+		} else {
+			sprintf(atcmd_output, "- Common mobs with highest drop chance (only max %d are listed):", MAX_SEARCH);
+			clif_displaymessage(fd, atcmd_output);
+		
+			for (i=0; i < MAX_SEARCH && item_data->mob[i].chance > 0; i++)
+			{
+				sprintf(atcmd_output, "- %s (%02.02f%%)", mob_db(item_data->mob[i].id)->jname, item_data->mob[i].chance/100.);
+				clif_displaymessage(fd, atcmd_output);
+			}
+		}
+	}
+	return 0;
+}
+
 /*==========================================
 /*==========================================
  * @adopt by [Veider]
  * @adopt by [Veider]
  *
  *

+ 1 - 0
src/map/atcommand.h

@@ -245,6 +245,7 @@ enum AtCommandType {
 	AtCommand_Rates, // MouseJstr
 	AtCommand_Rates, // MouseJstr
 
 
 	AtCommand_ItemInfo, // Lupus
 	AtCommand_ItemInfo, // Lupus
+	AtCommand_WhoDrops, // Skotlex
 	AtCommand_MapFlag, // Lupus
 	AtCommand_MapFlag, // Lupus
 	AtCommand_MonsterIgnore, // [Valaris]
 	AtCommand_MonsterIgnore, // [Valaris]
 	AtCommand_FakeName, // [Valaris]
 	AtCommand_FakeName, // [Valaris]

+ 5 - 0
src/map/itemdb.h

@@ -15,6 +15,11 @@ struct item_data {
 	int value_sell;
 	int value_sell;
 	int type;
 	int type;
 	int maxchance; //For logs, for external game info, for scripts: Max drop chance of this item (e.g. 0.01% , etc.. if it = 0, then monsters don't drop it) [Lupus]
 	int maxchance; //For logs, for external game info, for scripts: Max drop chance of this item (e.g. 0.01% , etc.. if it = 0, then monsters don't drop it) [Lupus]
+	struct {
+		unsigned short chance;
+		int id;
+	} mob[MAX_SEARCH]; //Holds the mobs that have the highest drop rate for this item. [Skotlex]
+
 	int sex;
 	int sex;
 	int equip;
 	int equip;
 	int weight;
 	int weight;

+ 26 - 6
src/map/mob.c

@@ -4296,7 +4296,7 @@ static int mob_readdb(void)
 	FILE *fp;
 	FILE *fp;
 	char line[1024];
 	char line[1024];
 	char *filename[]={ "mob_db.txt","mob_db2.txt" };
 	char *filename[]={ "mob_db.txt","mob_db2.txt" };
-	int class_, i, fi;
+	int class_, i, fi, k;
 
 
 	for(fi=0;fi<2;fi++){
 	for(fi=0;fi<2;fi++){
 		sprintf(line, "%s/%s", db_path, filename[fi]);
 		sprintf(line, "%s/%s", db_path, filename[fi]);
@@ -4433,12 +4433,22 @@ static int mob_readdb(void)
 				mob_db_data[class_]->dropitem[i].p = mob_drop_adjust(rate, rate_adjust, ratemin, ratemax);
 				mob_db_data[class_]->dropitem[i].p = mob_drop_adjust(rate, rate_adjust, ratemin, ratemax);
 
 
 				//calculate and store Max available drop chance of the item
 				//calculate and store Max available drop chance of the item
-				id = itemdb_search(mob_db_data[class_]->dropitem[i].nameid);
 				if (mob_db_data[class_]->dropitem[i].p) {
 				if (mob_db_data[class_]->dropitem[i].p) {
+					id = itemdb_search(mob_db_data[class_]->dropitem[i].nameid);
 					if (id->maxchance==10000 || (id->maxchance < mob_db_data[class_]->dropitem[i].p) ) {
 					if (id->maxchance==10000 || (id->maxchance < mob_db_data[class_]->dropitem[i].p) ) {
 					//item has bigger drop chance or sold in shops
 					//item has bigger drop chance or sold in shops
 						id->maxchance = mob_db_data[class_]->dropitem[i].p;
 						id->maxchance = mob_db_data[class_]->dropitem[i].p;
-					}			
+					}
+					for (k = 0; k< MAX_SEARCH; k++) {
+						if (id->mob[k].chance < mob_db_data[class_]->dropitem[i].p && id->mob[k].id != class_)
+							break;
+					}
+					if (k == MAX_SEARCH)
+						continue;
+				
+					memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
+					id->mob[k].chance = mob_db_data[class_]->dropitem[i].p;
+					id->mob[k].id = class_;
 				}
 				}
 			}
 			}
 			// MVP EXP Bonus, Chance: MEXP,ExpPer
 			// MVP EXP Bonus, Chance: MEXP,ExpPer
@@ -4470,8 +4480,8 @@ static int mob_readdb(void)
 					battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
 					battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
 
 
 				//calculate and store Max available drop chance of the MVP item
 				//calculate and store Max available drop chance of the MVP item
-				id = itemdb_search(mob_db_data[class_]->mvpitem[i].nameid);
 				if (mob_db_data[class_]->mvpitem[i].p) {
 				if (mob_db_data[class_]->mvpitem[i].p) {
+					id = itemdb_search(mob_db_data[class_]->mvpitem[i].nameid);
 					if (id->maxchance==10000 || (id->maxchance < mob_db_data[class_]->mvpitem[i].p/10+1) ) {
 					if (id->maxchance==10000 || (id->maxchance < mob_db_data[class_]->mvpitem[i].p/10+1) ) {
 					//item has bigger drop chance or sold in shops
 					//item has bigger drop chance or sold in shops
 						id->maxchance = mob_db_data[class_]->mvpitem[i].p/10+1; //reduce MVP drop info to not spoil common drop rate
 						id->maxchance = mob_db_data[class_]->mvpitem[i].p/10+1; //reduce MVP drop info to not spoil common drop rate
@@ -4910,7 +4920,7 @@ static int mob_readdb_race(void)
 static int mob_read_sqldb(void)
 static int mob_read_sqldb(void)
 {
 {
 	const char unknown_str[NAME_LENGTH] ="unknown";
 	const char unknown_str[NAME_LENGTH] ="unknown";
-	int i, fi, class_;
+	int i, fi, class_, k;
 	double exp, maxhp;
 	double exp, maxhp;
 	long unsigned int ln = 0;
 	long unsigned int ln = 0;
 	char *mob_db_name[] = { mob_db_db, mob_db2_db };
 	char *mob_db_name[] = { mob_db_db, mob_db2_db };
@@ -5039,12 +5049,22 @@ static int mob_read_sqldb(void)
 					mob_db_data[class_]->dropitem[i].p = mob_drop_adjust(rate, rate_adjust, ratemin, ratemax);
 					mob_db_data[class_]->dropitem[i].p = mob_drop_adjust(rate, rate_adjust, ratemin, ratemax);
 
 
 					//calculate and store Max available drop chance of the item
 					//calculate and store Max available drop chance of the item
-					id = itemdb_search(mob_db_data[class_]->dropitem[i].nameid);
 					if (mob_db_data[class_]->dropitem[i].p) {
 					if (mob_db_data[class_]->dropitem[i].p) {
+						id = itemdb_search(mob_db_data[class_]->dropitem[i].nameid);
 						if (id->maxchance==10000 || (id->maxchance < mob_db_data[class_]->dropitem[i].p) ) {
 						if (id->maxchance==10000 || (id->maxchance < mob_db_data[class_]->dropitem[i].p) ) {
 						//item has bigger drop chance or sold in shops
 						//item has bigger drop chance or sold in shops
 							id->maxchance = mob_db_data[class_]->dropitem[i].p;
 							id->maxchance = mob_db_data[class_]->dropitem[i].p;
 						}			
 						}			
+						for (k = 0; k< MAX_SEARCH; k++) {
+							if (id->mob[k].chance < mob_db_data[class_]->dropitem[i].p && id->mob[k].id != class_)
+								break;
+						}
+						if (k == MAX_SEARCH)
+							continue;
+					
+						memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
+						id->mob[k].chance = mob_db_data[class_]->dropitem[i].p;
+						id->mob[k].id = class_;
 					}
 					}
 				}
 				}
 				// MVP EXP Bonus, Chance: MEXP,ExpPer
 				// MVP EXP Bonus, Chance: MEXP,ExpPer