* Follow up 7cd82d0

-- Changed itemdb_array (array) to itemdb (DBMap)
-- Removed itemdb_other (DBMap)
-- Changed MAX_ITEMDB to MAX_ITEMID, by default limit is USHRT_MAX (65,535)
-- Changed item_drop_ratio_db (array) to mob_item_drop_ratio (DBMap)
-- Now all item datas stored in itemdb (DBMap) and mob item ratio datas in mob_item_drop_ratio (DBMap)

PS: I just realized that db/import/mob_item_ratio.txt doesn't work, because it loaded after mob_db.txt (another thing to do)
Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
Cydh Ramdh 2014-06-20 19:13:45 +07:00
parent 0fca530278
commit 6c5d4a730f
8 changed files with 128 additions and 211 deletions

View File

@ -92,7 +92,7 @@
75: War of Emperium is currently not in progress. 75: War of Emperium is currently not in progress.
76: All skills have been added to your skill tree. 76: All skills have been added to your skill tree.
77: The reference result of '%s' (name: id): 77: The reference result of '%s' (name: id):
78: %s: %d 78: - %s: %d
79: It is %d affair above. 79: It is %d affair above.
80: Give the display name or monster name/id please. 80: Give the display name or monster name/id please.
81: Your GM level doesn't authorize you to perform this action on the specified player. 81: Your GM level doesn't authorize you to perform this action on the specified player.

View File

@ -92,7 +92,7 @@
75: War of Emperium saat ini tidak sedang berjalan. 75: War of Emperium saat ini tidak sedang berjalan.
76: Semua skill telah ditambahkan ke skill tree. 76: Semua skill telah ditambahkan ke skill tree.
77: Hasil referensi dari '%s' (nama: id): 77: Hasil referensi dari '%s' (nama: id):
78: %s: %d 78: - %s: %d
79: Terdapat %d hal di atas. 79: Terdapat %d hal di atas.
80: Harap berikan nama tampilan atau nama/id monster. 80: Harap berikan nama tampilan atau nama/id monster.
81: Level GM kamu tidak diizinkan untuk untuk melakukan aksi ini pada pemain tertentu. 81: Level GM kamu tidak diizinkan untuk untuk melakukan aksi ini pada pemain tertentu.

View File

@ -2,7 +2,7 @@
// Overrides for global item_rate* values from conf/battle/drops.conf // Overrides for global item_rate* values from conf/battle/drops.conf
// //
// Structure of Database: // Structure of Database:
// ItemID,Ratio{,MonsterID} // ItemID,Ratio{,MonsterID1,...,MonsterID10}
// //
// Result: // Result:
// ItemID base drop rates defined in mob_db will not get multiplied // ItemID base drop rates defined in mob_db will not get multiplied
@ -28,4 +28,3 @@
// for different monsters, override drop rate with Ratio=100 and edit // for different monsters, override drop rate with Ratio=100 and edit
// base drop rates in mob_db. // base drop rates in mob_db.
// - This file is reloaded by @reloadmobdb. // - This file is reloaded by @reloadmobdb.

View File

@ -2,7 +2,7 @@
// Overrides for global item_rate* values from conf/battle/drops.conf // Overrides for global item_rate* values from conf/battle/drops.conf
// //
// Structure of Database: // Structure of Database:
// ItemID,Ratio{,MonsterID} // ItemID,Ratio{,MonsterID1,...,MonsterID10}
// //
// Result: // Result:
// ItemID base drop rates defined in mob_db will not get multiplied // ItemID base drop rates defined in mob_db will not get multiplied

View File

@ -18,12 +18,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static struct item_data* itemdb_array[MAX_ITEMDB]; struct item_data *dummy_item; /// This is the default dummy item used for non-existant items. [Skotlex]
struct item_data dummy_item; //This is the default dummy item used for non-existant items. [Skotlex]
static DBMap* itemdb_other;// unsigned short nameid -> struct item_data* static DBMap* itemdb; /// Item DB
static DBMap *itemdb_combo; static DBMap *itemdb_combo; /// Item Combo DB
static DBMap *itemdb_group; static DBMap *itemdb_group; /// Item Group DB
DBMap * itemdb_get_combodb(){ DBMap * itemdb_get_combodb(){
return itemdb_combo; return itemdb_combo;
@ -42,50 +41,37 @@ static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap)
{ {
struct item_data *item = db_data2ptr(data), **dst, **dst2; struct item_data *item = db_data2ptr(data), **dst, **dst2;
char *str; char *str;
str=va_arg(ap,char *); str = va_arg(ap,char *);
dst=va_arg(ap,struct item_data **); dst = va_arg(ap,struct item_data **);
dst2=va_arg(ap,struct item_data **); dst2 = va_arg(ap,struct item_data **);
if(item == &dummy_item) return 0; if (item == dummy_item)
return 0;
//Absolute priority to Aegis code name. //Absolute priority to Aegis code name.
if (*dst != NULL) return 0; if (*dst != NULL)
if( strcmpi(item->name,str)==0 ) return 0;
*dst=item; if (strcmpi(item->name,str) == 0)
*dst = item;
//Second priority to Client displayed name. //Second priority to Client displayed name.
if (*dst2 != NULL) return 0; if (*dst2 != NULL) return 0;
if( strcmpi(item->jname,str)==0 ) if (strcmpi(item->jname,str) == 0)
*dst2=item; *dst2 = item;
return 0; return 0;
} }
/*========================================== /*==========================================
* Return item data from item name. (lookup) * Return item data from item name. (lookup)
* @param str Item Name
* @return item data
*------------------------------------------*/ *------------------------------------------*/
struct item_data* itemdb_searchname(const char *str) struct item_data* itemdb_searchname(const char *str)
{ {
struct item_data* item; struct item_data* item = NULL;
struct item_data* item2=NULL; struct item_data* item2 = NULL;
int i;
for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i ) itemdb->foreach(itemdb,itemdb_searchname_sub,str,&item,&item2);
{ return item ? item : item2;
item = itemdb_array[i];
if( item == NULL )
continue;
// Absolute priority to Aegis code name.
if( strcasecmp(item->name,str) == 0 )
return item;
//Second priority to Client displayed name.
if( strcasecmp(item->jname,str) == 0 )
item2 = item;
}
item = NULL;
itemdb_other->foreach(itemdb_other,itemdb_searchname_sub,str,&item,&item2);
return item?item:item2;
} }
/** /**
@ -95,51 +81,32 @@ static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap)
{ {
struct item_data *item = db_data2ptr(&data); struct item_data *item = db_data2ptr(&data);
char *str; char *str;
str=va_arg(ap,char *); str = va_arg(ap,char *);
if (item == &dummy_item) if (item == dummy_item)
return 1; //Invalid item. return 1; //Invalid item.
if(stristr(item->jname,str)) if (stristr(item->jname,str))
return 0; return 0;
if(stristr(item->name,str)) if (stristr(item->name,str))
return 0; return 0;
return strcmpi(item->jname,str); return strcmpi(item->jname,str);
} }
/*========================================== /*==========================================
* Founds up to N matches. Returns number of matches [Skotlex] * Founds up to N matches. Returns number of matches [Skotlex]
* @param *data
* @param size
* @param str
* @return Number of matches item
*------------------------------------------*/ *------------------------------------------*/
int itemdb_searchname_array(struct item_data** data, int size, const char *str) int itemdb_searchname_array(struct item_data** data, int size, const char *str)
{ {
struct item_data* item;
int i;
int count=0;
// Search in the array
for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
{
item = itemdb_array[i];
if( item == NULL )
continue;
if( stristr(item->jname,str) || stristr(item->name,str) )
{
if( count < size )
data[count] = item;
++count;
}
}
// search in the db
if( count < size )
{
DBData *db_data[MAX_SEARCH]; DBData *db_data[MAX_SEARCH];
int db_count = 0; int i, count = 0, db_count;
size -= count;
db_count = itemdb_other->getall(itemdb_other, (DBData**)&db_data, size, itemdb_searchname_array_sub, str); db_count = itemdb->getall(itemdb, (DBData**)&db_data, size, itemdb_searchname_array_sub, str);
for (i = 0; i < db_count; i++) for (i = 0; i < db_count && count < size; i++)
data[count++] = db_data2ptr(db_data[i]); data[count++] = db_data2ptr(db_data[i]);
count += db_count;
}
return count; return count;
} }
@ -280,18 +247,12 @@ char itemdb_pc_get_itemgroup(uint16 group_id, struct map_session_data *sd) {
return 0; return 0;
} }
/// Searches for the item_data. /** Searches for the item_data. Use this to check if item exists or not.
/// Returns the item_data or NULL if it does not exist. * @param nameid
struct item_data* itemdb_exists(unsigned short nameid) * @return *item_data if item is exist, or NULL if not
{ */
struct item_data* item; struct item_data* itemdb_exists(unsigned short nameid) {
return ((struct item_data*)idb_get(itemdb,nameid));
if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) )
return itemdb_array[nameid];
item = (struct item_data*)idb_get(itemdb_other,nameid);
if( item == &dummy_item )
return NULL;// dummy data, doesn't exist
return item;
} }
/// Returns name type of ammunition [Cydh] /// Returns name type of ammunition [Cydh]
@ -405,70 +366,34 @@ static void itemdb_jobid2mapid(unsigned int *bclass, unsigned int jobmask)
bclass[1] |= 1<<MAPID_GUNSLINGER; bclass[1] |= 1<<MAPID_GUNSLINGER;
} }
/**
* Create dummy item data
*/
static void create_dummy_data(void) static void create_dummy_data(void)
{ {
memset(&dummy_item, 0, sizeof(struct item_data)); CREATE(dummy_item, struct item_data, 1);
dummy_item.nameid=500;
dummy_item.weight=1;
dummy_item.value_sell=1;
dummy_item.type=IT_ETC; //Etc item
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;
}
static struct item_data* create_item_data(unsigned short nameid) memset(dummy_item, 0, sizeof(struct item_data));
{ dummy_item->nameid = 500;
struct item_data *id; dummy_item->weight = 1;
CREATE(id, struct item_data, 1); dummy_item->value_sell = 1;
id->nameid = nameid; dummy_item->type = IT_ETC; //Etc item
id->weight = 1; safestrncpy(dummy_item->name, "UNKNOWN_ITEM", sizeof(dummy_item->name));
id->type = IT_ETC; safestrncpy(dummy_item->jname, "Unknown Item", sizeof(dummy_item->jname));
return id; dummy_item->view_id = UNKNOWN_ITEM_ID;
}
/*==========================================
* Loads (and creates if not found) an item from the db.
*------------------------------------------*/
struct item_data* itemdb_load(unsigned short nameid)
{
struct item_data *id;
if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) )
{
id = itemdb_array[nameid];
if( id == NULL || id == &dummy_item )
id = itemdb_array[nameid] = create_item_data(nameid);
return id;
}
id = (struct item_data*)idb_get(itemdb_other, nameid);
if( id == NULL || id == &dummy_item )
{
id = create_item_data(nameid);
idb_put(itemdb_other, nameid, id);
}
return id;
} }
/*========================================== /*==========================================
* Loads an item from the db. If not found, it will return the dummy item. * Loads an item from the db. If not found, it will return the dummy item.
* @param nameid
* @return *item_data or *dummy_item if item not found
*------------------------------------------*/ *------------------------------------------*/
struct item_data* itemdb_search(unsigned short nameid) struct item_data* itemdb_search(unsigned short nameid) {
{ struct item_data* id = (struct item_data*)idb_get(itemdb, nameid);
struct item_data* id; if (id)
if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) )
id = itemdb_array[nameid];
else
id = (struct item_data*)idb_get(itemdb_other, nameid);
if( id == NULL )
{
ShowWarning("itemdb_search: Item ID %hu does not exists in the item_db. Using dummy data.\n", nameid);
id = &dummy_item;
dummy_item.nameid = nameid;
}
return id; return id;
ShowWarning("itemdb_search: Item ID %hu does not exists in the item_db. Using dummy data.\n", nameid);
return dummy_item;
} }
/** Checks if item is equip type or not /** Checks if item is equip type or not
@ -692,11 +617,16 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
// Checking item // Checking item
trim(str[1]); trim(str[1]);
if (ISDIGIT(str[1][0]) && itemdb_exists((nameid = atoi(str[1])))) if (ISDIGIT(str[1][0])) {
if (itemdb_exists((nameid = atoi(str[1]))))
found = true; found = true;
else if (itemdb_searchname(str[1])) { }
else {
struct item_data *id = itemdb_searchname(str[1]);
if (id) {
nameid = id->nameid;
found = true; found = true;
nameid = itemdb_searchname(str[1])->nameid; }
} }
if (!found) { if (!found) {
ShowWarning("itemdb_read_itemgroup: Non-existant item '%s' in %s:%d\n", str[1], filename, ln); ShowWarning("itemdb_read_itemgroup: Non-existant item '%s' in %s:%d\n", str[1], filename, ln);
@ -1190,15 +1120,17 @@ static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scr
unsigned short nameid; unsigned short nameid;
struct item_data* id; struct item_data* id;
nameid = atoi(str[0]); if( atoi(str[0]) <= 0 || atoi(str[0]) >= MAX_ITEMID )
if( nameid <= 0 )
{ {
ShowWarning("itemdb_parse_dbrow: Invalid id %hu in line %d of \"%s\", skipping.\n", nameid, line, source); ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", atoi(str[0]), line, source);
return false; return false;
} }
nameid = atoi(str[0]);
//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
id = itemdb_load(nameid); if (!(id = itemdb_exists(nameid)))
CREATE(id, struct item_data, 1);
safestrncpy(id->name, str[1], sizeof(id->name)); safestrncpy(id->name, str[1], sizeof(id->name));
safestrncpy(id->jname, str[2], sizeof(id->jname)); safestrncpy(id->jname, str[2], sizeof(id->jname));
@ -1306,6 +1238,10 @@ static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scr
if (*str[21]) if (*str[21])
id->unequip_script = parse_script(str[21], source, line, scriptopt); id->unequip_script = parse_script(str[21], source, line, scriptopt);
if (!id->nameid) {
id->nameid = nameid;
idb_put(itemdb, nameid, id);
}
return true; return true;
} }
@ -1609,7 +1545,7 @@ static void itemdb_read(void) {
/** /**
* Destroys the item_data. * Destroys the item_data.
*/ */
static void destroy_item_data(struct item_data* self, bool free_self) { static void destroy_item_data(struct item_data* self) {
if( self == NULL ) if( self == NULL )
return; return;
// free scripts // free scripts
@ -1636,7 +1572,6 @@ static void destroy_item_data(struct item_data* self, bool free_self) {
memset(self, 0xDD, sizeof(struct item_data)); memset(self, 0xDD, sizeof(struct item_data));
#endif #endif
// free self // free self
if( free_self )
aFree(self); aFree(self);
} }
@ -1647,9 +1582,7 @@ static int itemdb_final_sub(DBKey key, DBData *data, va_list ap)
{ {
struct item_data *id = db_data2ptr(data); struct item_data *id = db_data2ptr(data);
if( id != &dummy_item ) destroy_item_data(id);
destroy_item_data(id, true);
return 0; return 0;
} }
@ -1680,18 +1613,10 @@ void itemdb_reload(void) {
int i,d,k; int i,d,k;
// clear the previous itemdb data
for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i ) {
if( itemdb_array[i] )
destroy_item_data(itemdb_array[i], true);
}
itemdb_group->clear(itemdb_group, itemdb_group_free); itemdb_group->clear(itemdb_group, itemdb_group_free);
itemdb_other->clear(itemdb_other, itemdb_final_sub); itemdb->clear(itemdb, itemdb_final_sub);
db_clear(itemdb_combo); db_clear(itemdb_combo);
memset(itemdb_array, 0, sizeof(itemdb_array));
// read new data // read new data
itemdb_read(); itemdb_read();
cashshop_reloaddb(); cashshop_reloaddb();
@ -1749,15 +1674,9 @@ void itemdb_reload(void) {
* Finalizing Item DB * Finalizing Item DB
*/ */
void do_final_itemdb(void) { void do_final_itemdb(void) {
int i;
for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
if( itemdb_array[i] )
destroy_item_data(itemdb_array[i], true);
itemdb_group->destroy(itemdb_group, itemdb_group_free); itemdb_group->destroy(itemdb_group, itemdb_group_free);
itemdb_other->destroy(itemdb_other, itemdb_final_sub); itemdb->destroy(itemdb, itemdb_final_sub);
destroy_item_data(&dummy_item, false); destroy_item_data(dummy_item);
db_destroy(itemdb_combo); db_destroy(itemdb_combo);
} }
@ -1765,8 +1684,7 @@ void do_final_itemdb(void) {
* Initializing Item DB * Initializing Item DB
*/ */
void do_init_itemdb(void) { void do_init_itemdb(void) {
memset(itemdb_array, 0, sizeof(itemdb_array)); itemdb = idb_alloc(DB_OPT_BASE);
itemdb_other = idb_alloc(DB_OPT_BASE);
itemdb_combo = idb_alloc(DB_OPT_BASE); itemdb_combo = idb_alloc(DB_OPT_BASE);
itemdb_group = idb_alloc(DB_OPT_BASE); itemdb_group = idb_alloc(DB_OPT_BASE);
create_dummy_data(); //Dummy data item. create_dummy_data(); //Dummy data item.

View File

@ -8,8 +8,8 @@
#include "../common/mmo.h" // ITEM_NAME_LENGTH #include "../common/mmo.h" // ITEM_NAME_LENGTH
#include "map.h" #include "map.h"
/// 65,535 entries in array (the rest goes to the db) ///Maximum allowed Item ID (range: 1 ~ 65,534)
#define MAX_ITEMDB 0x10000 #define MAX_ITEMID USHRT_MAX
///Use apple for unknown items. ///Use apple for unknown items.
#define UNKNOWN_ITEM_ID 512 #define UNKNOWN_ITEM_ID 512
/// The maximum number of item delays /// The maximum number of item delays
@ -418,7 +418,6 @@ struct item_data {
struct item_data* itemdb_searchname(const char *name); struct item_data* itemdb_searchname(const char *name);
int itemdb_searchname_array(struct item_data** data, int size, const char *str); int itemdb_searchname_array(struct item_data** data, int size, const char *str);
struct item_data* itemdb_load(unsigned short nameid);
struct item_data* itemdb_search(unsigned short nameid); struct item_data* itemdb_search(unsigned short nameid);
struct item_data* itemdb_exists(unsigned short nameid); struct item_data* itemdb_exists(unsigned short nameid);
#define itemdb_name(n) itemdb_search(n)->name #define itemdb_name(n) itemdb_search(n)->name

View File

@ -319,7 +319,7 @@ void log_mvpdrop(struct map_session_data* sd, int monster_id, unsigned int* log_
return; return;
time(&curtime); time(&curtime);
strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime)); strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime));
fprintf(logfp,"%s - %s[%d:%d]\t%d\t%hu,%d\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1]); fprintf(logfp,"%s - %s[%d:%d]\t%d\t%hu,%u\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, (unsigned short)log_mvp[0], log_mvp[1]);
fclose(logfp); fclose(logfp);
} }
} }

View File

@ -67,11 +67,12 @@ struct mob_chat *mob_chat(short id) { if(id<=0 || id>MAX_MOB_CHAT || mob_chat_db
//Dynamic item drop ratio database for per-item drop ratio modifiers overriding global drop ratios. //Dynamic item drop ratio database for per-item drop ratio modifiers overriding global drop ratios.
#define MAX_ITEMRATIO_MOBS 10 #define MAX_ITEMRATIO_MOBS 10
struct item_drop_ratio { struct s_mob_item_drop_ratio {
unsigned short nameid;
int drop_ratio; int drop_ratio;
int mob_id[MAX_ITEMRATIO_MOBS]; unsigned short mob_id[MAX_ITEMRATIO_MOBS];
}; };
static struct item_drop_ratio *item_drop_ratio_db[MAX_ITEMDB]; static DBMap *mob_item_drop_ratio;
static struct eri *item_drop_ers; //For loot drops delay structures. static struct eri *item_drop_ers; //For loot drops delay structures.
static struct eri *item_drop_list_ers; static struct eri *item_drop_list_ers;
@ -1643,7 +1644,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
else { // Attack once and find a new random target else { // Attack once and find a new random target
int search_size = (view_range < md->status.rhw.range) ? view_range : md->status.rhw.range; int search_size = (view_range < md->status.rhw.range) ? view_range : md->status.rhw.range;
unit_attack(&md->bl, tbl->id, 0); unit_attack(&md->bl, tbl->id, 0);
if (tbl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md), search_size)) { if ((tbl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md), search_size))) {
md->target_id = tbl->id; md->target_id = tbl->id;
md->min_chase = md->db->range3; md->min_chase = md->db->range3;
} }
@ -3671,15 +3672,16 @@ static unsigned int mob_drop_adjust(int baserate, int rate_adjust, unsigned shor
*/ */
static void item_dropratio_adjust(unsigned short nameid, int mob_id, int *rate_adjust) static void item_dropratio_adjust(unsigned short nameid, int mob_id, int *rate_adjust)
{ {
if( item_drop_ratio_db[nameid] ) { struct s_mob_item_drop_ratio *item_ratio = (struct s_mob_item_drop_ratio *)idb_get(mob_item_drop_ratio, nameid);
if( item_drop_ratio_db[nameid]->mob_id[0] ) { // only for listed mobs if( item_ratio) {
if( item_ratio->mob_id[0] ) { // only for listed mobs
int i; int i;
ARR_FIND(0, MAX_ITEMRATIO_MOBS, i, item_drop_ratio_db[nameid]->mob_id[i] == mob_id); ARR_FIND(0, MAX_ITEMRATIO_MOBS, i, item_ratio->mob_id[i] == mob_id);
if(i < MAX_ITEMRATIO_MOBS) // found if( i < MAX_ITEMRATIO_MOBS ) // found
*rate_adjust = item_drop_ratio_db[nameid]->drop_ratio; *rate_adjust = item_ratio->drop_ratio;
} }
else // for all mobs else // for all mobs
*rate_adjust = item_drop_ratio_db[nameid]->drop_ratio; *rate_adjust = item_ratio->drop_ratio;
} }
} }
@ -4532,26 +4534,36 @@ static bool mob_readdb_itemratio(char* str[], int columns, int current)
{ {
unsigned short nameid; unsigned short nameid;
int ratio, i; int ratio, i;
struct s_mob_item_drop_ratio *item_ratio;
nameid = atoi(str[0]); nameid = atoi(str[0]);
if( itemdb_exists(nameid) == NULL ) if (itemdb_exists(nameid) == NULL) {
{
ShowWarning("itemdb_read_itemratio: Invalid item id %hu.\n", nameid); ShowWarning("itemdb_read_itemratio: Invalid item id %hu.\n", nameid);
return false; return false;
} }
ratio = atoi(str[1]); ratio = atoi(str[1]);
if(item_drop_ratio_db[nameid] == NULL) if (!(item_ratio = (struct s_mob_item_drop_ratio *)idb_get(mob_item_drop_ratio,nameid)))
item_drop_ratio_db[nameid] = (struct item_drop_ratio*)aCalloc(1, sizeof(struct item_drop_ratio)); CREATE(item_ratio, struct s_mob_item_drop_ratio, 1);
item_drop_ratio_db[nameid]->drop_ratio = ratio; item_ratio->drop_ratio = ratio;
for(i = 0; i < columns-2; i++) memset(item_ratio->mob_id, 0, sizeof(item_ratio->mob_id));
item_drop_ratio_db[nameid]->mob_id[i] = atoi(str[i+2]); for (i = 0; i < columns-2; i++)
item_ratio->mob_id[i] = atoi(str[i+2]);
if (!item_ratio->nameid)
idb_put(mob_item_drop_ratio, nameid, item_ratio);
return true; return true;
} }
static int mob_item_drop_ratio_free(DBKey key, DBData *data, va_list ap) {
struct s_mob_item_drop_ratio *item_ratio = db_data2ptr(data);
aFree(item_ratio);
return 0;
}
/** /**
* read all mob-related databases * read all mob-related databases
*/ */
@ -4602,19 +4614,15 @@ void mob_reload(void) {
int i; int i;
//Mob skills need to be cleared before re-reading them. [Skotlex] //Mob skills need to be cleared before re-reading them. [Skotlex]
for (i = 0; i < MAX_MOB_DB; i++) for (i = 0; i < MAX_MOB_DB; i++) {
if (mob_db_data[i]) { if (mob_db_data[i]) {
memset(&mob_db_data[i]->skill,0,sizeof(mob_db_data[i]->skill)); memset(&mob_db_data[i]->skill,0,sizeof(mob_db_data[i]->skill));
mob_db_data[i]->maxskill=0; mob_db_data[i]->maxskill=0;
} }
}
// Clear item_drop_ratio_db // Clear item_drop_ratio_db
for (i = 0; i < MAX_ITEMDB; i++) { mob_item_drop_ratio->clear(mob_item_drop_ratio, mob_item_drop_ratio_free);
if (item_drop_ratio_db[i]) {
aFree(item_drop_ratio_db[i]);
item_drop_ratio_db[i] = NULL;
}
}
mob_load(); mob_load();
} }
@ -4636,7 +4644,7 @@ void do_init_mob(void){
mob_makedummymobdb(0); //The first time this is invoked, it creates the dummy mob mob_makedummymobdb(0); //The first time this is invoked, it creates the dummy mob
item_drop_ers = ers_new(sizeof(struct item_drop),"mob.c::item_drop_ers",ERS_OPT_NONE); item_drop_ers = ers_new(sizeof(struct item_drop),"mob.c::item_drop_ers",ERS_OPT_NONE);
item_drop_list_ers = ers_new(sizeof(struct item_drop_list),"mob.c::item_drop_list_ers",ERS_OPT_NONE); item_drop_list_ers = ers_new(sizeof(struct item_drop_list),"mob.c::item_drop_list_ers",ERS_OPT_NONE);
mob_item_drop_ratio = idb_alloc(DB_OPT_BASE);
mob_load(); mob_load();
add_timer_func_list(mob_delayspawn,"mob_delayspawn"); add_timer_func_list(mob_delayspawn,"mob_delayspawn");
@ -4676,14 +4684,7 @@ void do_final_mob(void){
mob_chat_db[i] = NULL; mob_chat_db[i] = NULL;
} }
} }
for (i = 0; i < MAX_ITEMDB; i++) mob_item_drop_ratio->destroy(mob_item_drop_ratio,mob_item_drop_ratio_free);
{
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_ers);
ers_destroy(item_drop_list_ers); ers_destroy(item_drop_list_ers);
} }