From 9442d178d287050bf9f3c42a520a5d85d6081e3e Mon Sep 17 00:00:00 2001 From: gepard1984 Date: Thu, 26 Jan 2012 15:55:42 +0000 Subject: * Modified drop system to allow overriding global item drop rates on per-item basis. For detailed explanation read source:trunk/db/mob_item_ratio.txt (topic:56118). * Added missing update to `logs.sql` (follow-up to r15519). git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@15521 54d463be-8e91-2dee-dedb-b68131a5f0ec --- db/mob_item_ratio.txt | 29 +++++++++++++++++++ sql-files/logs.sql | 4 +-- src/map/itemdb.c | 5 ---- src/map/itemdb.h | 3 ++ src/map/mob.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 db/mob_item_ratio.txt diff --git a/db/mob_item_ratio.txt b/db/mob_item_ratio.txt new file mode 100644 index 000000000..f21edb347 --- /dev/null +++ b/db/mob_item_ratio.txt @@ -0,0 +1,29 @@ +// Overrides for global item_rate* values from conf/battle/drops.conf + +// Database format: +// ItemID,Ratio{,MonsterID} + +// Result: +// ItemID base drop rates defined in mob_db will not get multiplied +// by global item_rate* values (aka drop rates) from +// conf/battle/drops.conf. Instead Ratio will be used (100 = 1x). +// If no MonsterID is specified, all monsters will be affected, +// otherwise only listed ones. + +// Examples: +// 909,100 // Jellopies from monsters will drop with 1x drop rate regardless of global drop rate +// 909,1000 // Jellopies from monsters will drop with 10x drop rate regardless of global drop rate +// 909,100,1002 // Jellopies from Porings will drop with 1x drop rate. Other monsters that drop Jellopies are unaffected (use global drop rate). + +// Notes: +// - By default you can list up to 10 MonsterIDs per ItemID. +// It can be changed in src/map/mob.c by adjusting MAX_ITEMRATIO_MOBS. +// - Only ItemIDs up to MAX_ITEMDB are supported (default: 32768). +// - Does not override item_drop_*_min/max settings. +// - Does not affect card/item-granted drops. To adjust card/item-granted +// drops, edit them in item_db. +// - Does affect MVP prizes and Treasure Boxes. +// - You can add only ONE line per ItemID. If you need various ratios +// for different monsters, override drop rate with Ratio=100 and edit +// base drop rates in mob_db. +// - This file is reloaded by @reloadmobdb. diff --git a/sql-files/logs.sql b/sql-files/logs.sql index b031c566c..ff864d47a 100644 --- a/sql-files/logs.sql +++ b/sql-files/logs.sql @@ -2,7 +2,7 @@ # Players (T)rade Give/Take, Players (V)ending Sell/Take, (S)hop Sell/Take, (N)PC Give/Take, # (C)onsumable Items, (A)dministrators Create/Delete, Sto(R)age, (G)uild Storage, # (E)mail attachment,(B)uying Store, Pr(O)duced Items/Ingredients, Auct(I)oned Items, -# (X) Other +# (X) Other, (D) Stolen from mobs, (U) MVP Prizes #Database: log #Table: picklog @@ -10,7 +10,7 @@ CREATE TABLE `picklog` ( `id` int(11) NOT NULL auto_increment, `time` datetime NOT NULL default '0000-00-00 00:00:00', `char_id` int(11) NOT NULL default '0', - `type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X') NOT NULL default 'P', + `type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U') NOT NULL default 'P', `nameid` int(11) NOT NULL default '0', `amount` int(11) NOT NULL default '1', `refine` tinyint(3) unsigned NOT NULL default '0', diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 8043c965d..6ab88f872 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -16,11 +16,6 @@ #include #include -// 32k array entries (the rest goes to the db) -#define MAX_ITEMDB 0x8000 - - - static struct item_data* itemdb_array[MAX_ITEMDB]; static DBMap* itemdb_other;// int nameid -> struct item_data* diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 0ea5574ad..79fc3aa5f 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -7,6 +7,9 @@ #include "../common/mmo.h" // ITEM_NAME_LENGTH #include "map.h" //REMODE +// 32k array entries in array (the rest goes to the db) +#define MAX_ITEMDB 0x8000 + #define MAX_RANDITEM 11000 // The maximum number of item delays diff --git a/src/map/mob.c b/src/map/mob.c index 123ae1c7f..f25c9ba8a 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -64,6 +64,14 @@ struct mob_db *mob_db(int index) { if (index < 0 || index > MAX_MOB_DB || mob_db struct mob_chat *mob_chat_db[MAX_MOB_CHAT+1]; struct mob_chat *mob_chat(short id) { if(id<=0 || id>MAX_MOB_CHAT || mob_chat_db[id]==NULL) return (struct mob_chat*)NULL; return mob_chat_db[id]; } +//Dynamic item drop ratio database for per-item drop ratio modifiers overriding global drop ratios. +#define MAX_ITEMRATIO_MOBS 10 +struct item_drop_ratio { + int drop_ratio; + int mob_id[MAX_ITEMRATIO_MOBS]; +}; +static struct item_drop_ratio *item_drop_ratio_db[MAX_ITEMDB]; + static struct eri *item_drop_ers; //For loot drops delay structures. static struct eri *item_drop_list_ers; @@ -3441,6 +3449,27 @@ static unsigned int mob_drop_adjust(int baserate, int rate_adjust, unsigned shor return (unsigned int)cap_value(rate,rate_min,rate_max); } +/** + * Check if global item drop rate is overriden for given item + * in db/mob_item_ratio.txt + * @param nameid ID of the item + * @param mob_id ID of the monster + * @param rate_adjust pointer to store ratio if found + */ +static void item_dropratio_adjust(int nameid, int mob_id, int *rate_adjust) +{ + int i; + if( item_drop_ratio_db[nameid] ) { + if( item_drop_ratio_db[nameid]->mob_id[0] ) { // only for listed mobs + ARR_FIND(0, MAX_ITEMRATIO_MOBS, i, item_drop_ratio_db[nameid]->mob_id[i] == mob_id); + if(i < MAX_ITEMRATIO_MOBS) // found + *rate_adjust = item_drop_ratio_db[nameid]->drop_ratio; + } + else // for all mobs + *rate_adjust = item_drop_ratio_db[nameid]->drop_ratio; + } +} + /*========================================== * processes one mobdb entry *------------------------------------------*/ @@ -3583,12 +3612,14 @@ static bool mob_parse_dbrow(char** str) // MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per for(i = 0; i < 3; i++) { struct item_data *id; + int rate_adjust = battle_config.item_rate_mvp;; 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); + item_dropratio_adjust(db->mvpitem[i].nameid, class_, &rate_adjust); + db->mvpitem[i].p = mob_drop_adjust(atoi(str[33+i*2]), rate_adjust, 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) { @@ -3650,6 +3681,7 @@ static bool mob_parse_dbrow(char** str) ratemax = battle_config.item_drop_common_max; break; } + item_dropratio_adjust(id->nameid, class_, &rate_adjust); db->dropitem[i].p = mob_drop_adjust(rate, rate_adjust, ratemin, ratemax); //calculate and store Max available drop chance of the item @@ -4384,11 +4416,40 @@ static bool mob_readdb_race2(char* fields[], int columns, int current) return true; } +/** + * Read mob_item_ratio.txt + */ +static bool mob_readdb_itemratio(char* str[], int columns, int current) +{ + int nameid, ratio, i; + struct item_data *id; + + nameid = atoi(str[0]); + + if( ( id = itemdb_exists(nameid) ) == NULL ) + { + ShowWarning("itemdb_read_itemratio: Invalid item id %d.\n", nameid); + return false; + } + + ratio = atoi(str[1]); + + if(item_drop_ratio_db[nameid] == NULL) + item_drop_ratio_db[nameid] = (struct item_drop_ratio*)aCalloc(1, sizeof(struct item_drop_ratio)); + + item_drop_ratio_db[nameid]->drop_ratio = ratio; + for(i = 0; i < columns-2; i++) + item_drop_ratio_db[nameid]->mob_id[i] = atoi(str[i+2]); + + return true; +} + /** * read all mob-related databases */ static void mob_load(void) { + sv_readdb(db_path, "mob_item_ratio.txt", ',', 2, 2+MAX_ITEMRATIO_MOBS, -1, &mob_readdb_itemratio); // must be read before mobdb if (db_use_sqldbs) { mob_read_sqldb(); @@ -4417,6 +4478,14 @@ void mob_reload(void) mob_db_data[i]->maxskill=0; } + // Clear item_drop_ratio_db + for (i = 0; i < MAX_ITEMDB; i++) { + if (item_drop_ratio_db[i]) { + aFree(item_drop_ratio_db[i]); + item_drop_ratio_db[i] = NULL; + } + } + mob_load(); } @@ -4481,6 +4550,14 @@ int do_final_mob(void) mob_chat_db[i] = NULL; } } + for (i = 0; i <= MAX_ITEMDB; i++) + { + if (item_drop_ratio_db[i] != NULL) + { + aFree(item_drop_ratio_db[i]); + item_drop_ratio_db[i] = NULL; + } + } ers_destroy(item_drop_ers); ers_destroy(item_drop_list_ers); return 0; -- cgit v1.2.3-60-g2f50