summaryrefslogtreecommitdiff
path: root/src/map/itemdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/itemdb.c')
-rw-r--r--src/map/itemdb.c641
1 files changed, 529 insertions, 112 deletions
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 859b19aac..5fae29500 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -8,6 +8,7 @@
#include "../common/showmsg.h"
#include "../common/strlib.h"
#include "../common/utils.h"
+#include "../common/conf.h"
#include "itemdb.h"
#include "map.h"
#include "battle.h" // struct battle_config
@@ -52,14 +53,12 @@ static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap)
/*==========================================
* Return item data from item name. (lookup)
*------------------------------------------*/
-struct item_data* itemdb_searchname(const char *str)
-{
+struct item_data* itemdb_searchname(const char *str) {
struct item_data* item;
struct item_data* item2=NULL;
int i;
- for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
- {
+ for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i ) {
item = itemdb_array[i];
if( item == NULL )
continue;
@@ -77,6 +76,10 @@ struct item_data* itemdb_searchname(const char *str)
itemdb_other->foreach(itemdb_other,itemdb_searchname_sub,str,&item,&item2);
return item?item:item2;
}
+/* name to item data */
+struct item_data* itemdb_name2id(const char *str) {
+ return strdb_get(itemdb->names,str);
+}
/**
* @see DBMatcher
@@ -98,8 +101,7 @@ static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap)
/*==========================================
* Founds up to N matches. Returns number of matches [Skotlex]
*------------------------------------------*/
-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;
@@ -132,38 +134,130 @@ int itemdb_searchname_array(struct item_data** data, int size, const char *str)
}
return count;
}
-
-
-/*==========================================
- * Return a random item id from group. (takes into account % chance giving/tot group)
- *------------------------------------------*/
-int itemdb_searchrandomid(int group)
-{
- if(group<1 || group>=MAX_ITEMGROUP) {
- ShowError("itemdb_searchrandomid: Invalid group id %d\n", group);
+/* [Ind/Hercules] */
+int itemdb_chain_item(unsigned short chain_id, int *rate) {
+ struct item_chain_entry *entry;
+ int i = 0;
+
+ if( chain_id >= itemdb->chain_count ) {
+ ShowError("itemdb_chain_item: unknown chain id %d\n", chain_id);
return UNKNOWN_ITEM_ID;
}
- if (itemgroup_db[group].qty)
- return itemgroup_db[group].nameid[rnd()%itemgroup_db[group].qty];
- ShowError("itemdb_searchrandomid: No item entries for group id %d\n", group);
- return UNKNOWN_ITEM_ID;
+ entry = &itemdb->chains[chain_id].items[ rnd()%itemdb->chains[chain_id].qty ];
+
+ for( i = 0; i < itemdb->chains[chain_id].qty; i++ ) {
+ if( rnd()%10000 >= entry->rate ) {
+ entry = entry->next;
+ continue;
+ } else {
+ if( rate )
+ rate[0] = entry->rate;
+ return entry->id;
+ }
+ }
+
+ return 0;
}
+/* [Ind/Hercules] */
+void itemdb_package_item(struct map_session_data *sd, struct item_package *package) {
+ int i = 0, get_count, j, flag;
+
+ for( i = 0; i < package->must_qty; i++ ) {
+ struct item it;
+ memset(&it, 0, sizeof(it));
+ it.nameid = package->must_items[i].id;
+ it.identify = 1;
+
+ if( package->must_items[i].hours ) {
+ it.expire_time = (unsigned int)(time(NULL) + ((package->must_items[i].hours*60)*60));
+ }
+
+ if( package->must_items[i].named ) {
+ it.card[0] = CARD0_FORGE;
+ it.card[1] = 0;
+ it.card[2] = GetWord(sd->status.char_id, 0);
+ it.card[3] = GetWord(sd->status.char_id, 1);
+ }
+
+ if( package->must_items[i].announce )
+ clif->package_announce(sd,package->must_items[i].id,package->id);
+
+ get_count = itemdb_isstackable(package->must_items[i].id) ? package->must_items[i].qty : 1;
+
+ it.amount = get_count == 1 ? 1 : get_count;
+
+ for( j = 0; j < package->must_items[i].qty; j += get_count ) {
+ if ( ( flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT) ) )
+ clif->additem(sd, 0, 0, flag);
+ }
+ }
+
+ if( package->random_qty ) {
+ struct item_package_rand_entry *entry;
+
+ entry = &package->random_list[rnd()%package->random_qty];
+
+ while( 1 ) {
+ if( rnd()%10000 >= entry->rate ) {
+ entry = entry->next;
+ continue;
+ } else {
+ struct item it;
+ memset(&it, 0, sizeof(it));
+
+ it.nameid = entry->id;
+ it.identify = 1;
+
+ if( entry->hours ) {
+ it.expire_time = (unsigned int)(time(NULL) + ((entry->hours*60)*60));
+ }
+
+ if( entry->named ) {
+ it.card[0] = CARD0_FORGE;
+ it.card[1] = 0;
+ it.card[2] = GetWord(sd->status.char_id, 0);
+ it.card[3] = GetWord(sd->status.char_id, 1);
+ }
+
+ if( entry->announce )
+ clif->package_announce(sd,entry->id,package->id);
+
+ get_count = itemdb_isstackable(entry->id) ? entry->qty : 1;
+
+ it.amount = get_count == 1 ? 1 : get_count;
+
+ for( j = 0; j < entry->qty; j += get_count ) {
+ if ( ( flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT) ) )
+ clif->additem(sd, 0, 0, flag);
+ }
+ break;
+ }
+ }
+ }
+
+ return;
+}
/*==========================================
- * Calculates total item-group related bonuses for the given item
+ * Return a random item id from group. (takes into account % chance giving/tot group)
*------------------------------------------*/
-int itemdb_group_bonus(struct map_session_data* sd, int itemid)
-{
- int bonus = 0, i, j;
- for (i=0; i < MAX_ITEMGROUP; i++) {
- if (!sd->itemgrouphealrate[i])
- continue;
- ARR_FIND( 0, itemgroup_db[i].qty, j, itemgroup_db[i].nameid[j] == itemid );
- if( j < itemgroup_db[i].qty )
- bonus += sd->itemgrouphealrate[i];
- }
- return bonus;
+int itemdb_searchrandomid(struct item_group *group) {
+
+ if (group->qty)
+ return group->nameid[rnd()%group->qty];
+
+ ShowError("itemdb_searchrandomid: No item entries for group id %d\n", group->id);
+ return UNKNOWN_ITEM_ID;
+}
+bool itemdb_in_group(struct item_group *group, int nameid) {
+ int i;
+
+ for( i = 0; i < group->qty; i++ )
+ if( group->nameid[i] == nameid )
+ return true;
+
+ return false;
}
/// Searches for the item_data.
@@ -499,7 +593,7 @@ static bool itemdb_read_itemavail(char* str[], int columns, int current)
nameid = atoi(str[0]);
- if( ( id = itemdb_exists(nameid) ) == NULL )
+ if( ( id = itemdb->exists(nameid) ) == NULL )
{
ShowWarning("itemdb_read_itemavail: Invalid item id %d.\n", nameid);
return false;
@@ -520,82 +614,303 @@ static bool itemdb_read_itemavail(char* str[], int columns, int current)
return true;
}
-/*==========================================
- * read item group data
- *------------------------------------------*/
-static unsigned int itemdb_read_itemgroup_sub(const char* filename) {
- FILE *fp;
- char line[1024];
- int ln=0;
- unsigned int count = 0;
- int groupid,j,k,nameid;
- char *str[3],*p;
- char w1[1024], w2[1024];
-
- if( (fp=fopen(filename,"r"))==NULL ){
- ShowError("can't read %s\n", filename);
- return 0;
- }
+void itemdb_read_groups(void) {
+ config_t item_group_conf;
+ config_setting_t *itg = NULL, *it = NULL;
+#ifdef RENEWAL
+ const char *config_filename = "db/re/item_group.conf"; // FIXME hardcoded name
+#else
+ const char *config_filename = "db/pre-re/item_group.conf"; // FIXME hardcoded name
+#endif
+ const char *itname;
+ int i = 0, count = 0, c;
+ unsigned int *gsize = NULL;
- while(fgets(line, sizeof(line), fp))
- {
- ln++;
- if(line[0]=='/' && line[1]=='/')
+ if (conf_read_file(&item_group_conf, config_filename)) {
+ ShowError("can't read %s\n", config_filename);
+ return;
+ }
+
+ gsize = aMalloc( config_setting_length(item_group_conf.root) * sizeof(unsigned int) );
+
+ for(i = 0; i < config_setting_length(item_group_conf.root); i++)
+ gsize[i] = 0;
+
+ i = 0;
+ while( (itg = config_setting_get_elem(item_group_conf.root,i++)) ) {
+ const char *name = config_setting_name(itg);
+
+ if( !itemdb->name2id(name) ) {
+ ShowWarning("itemdb_read_groups: unknown group item '%s', skipping..\n",name);
+ config_setting_remove(item_group_conf.root, name);
+ --i;
continue;
- if(strstr(line,"import")) {
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2 &&
- strcmpi(w1, "import") == 0) {
- count += itemdb_read_itemgroup_sub(w2);
- continue;
- }
}
- memset(str,0,sizeof(str));
- for(j=0,p=line;j<3 && p;j++){
- str[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
+
+ c = 0;
+ while( (it = config_setting_get_elem(itg,c++)) ) {
+ if( config_setting_is_list(it) )
+ gsize[ i - 1 ] += config_setting_get_int_elem(it,1);
+ else
+ gsize[ i - 1 ] += 1;
}
- if(str[0]==NULL)
- continue;
- if (j<3) {
- if (j>1) //Or else it barks on blank lines...
- ShowWarning("itemdb_read_itemgroup: Insufficient fields for entry at %s:%d\n", filename, ln);
- continue;
+
+ }
+
+ i = 0;
+ CREATE(itemdb->groups, struct item_group, config_setting_length(item_group_conf.root));
+ itemdb->group_count = (unsigned short)config_setting_length(item_group_conf.root);
+
+ while( (itg = config_setting_get_elem(item_group_conf.root,i++)) ) {
+ struct item_data *data = itemdb->name2id(config_setting_name(itg));
+ int ecount = 0;
+
+ data->group = &itemdb->groups[count];
+
+ itemdb->groups[count].id = data->nameid;
+ itemdb->groups[count].qty = config_setting_length(itg);
+
+ CREATE(itemdb->groups[count].nameid, unsigned short, gsize[ count ] + 1);
+
+ c = 0;
+ while( (it = config_setting_get_elem(itg,c++)) ) {
+ int repeat = 1;
+ if( config_setting_is_list(it) ) {
+ itname = config_setting_get_string_elem(it,0);
+ repeat = config_setting_get_int_elem(it,1);
+ } else
+ itname = config_setting_get_string_elem(itg,c - 1);
+
+ if( !( data = itemdb->name2id(itname) ) )
+ ShowWarning("itemdb_read_groups: unknown item '%s' in group '%s'!\n",itname,config_setting_name(itg));
+
+ itemdb->groups[count].nameid[ecount] = data ? data->nameid : 0;
+ if( repeat > 1 ) {
+ //memset would be better? I failed to get the following to work though hu
+ //memset(&itemdb->groups[count].nameid[ecount+1],itemdb->groups[count].nameid[ecount],sizeof(itemdb->groups[count].nameid[0])*repeat);
+ int z;
+ for( z = ecount+1; z < ecount+repeat; z++ )
+ itemdb->groups[count].nameid[z] = itemdb->groups[count].nameid[ecount];
+ }
+ ecount += repeat;
}
- groupid = atoi(str[0]);
- if (groupid < 0 || groupid >= MAX_ITEMGROUP) {
- ShowWarning("itemdb_read_itemgroup: Invalid group %d in %s:%d\n", groupid, filename, ln);
+
+ count++;
+ }
+
+ config_destroy(&item_group_conf);
+ aFree(gsize);
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename);
+}
+
+void itemdb_read_packages(void) {
+ config_t item_packages_conf;
+ config_setting_t *itg = NULL, *it = NULL, *t = NULL;
+#ifdef RENEWAL
+ const char *config_filename = "db/re/item_packages.conf"; // FIXME hardcoded name
+#else
+ const char *config_filename = "db/pre-re/item_packages.conf"; // FIXME hardcoded name
+#endif
+ const char *itname;
+ int i = 0, count = 0, c = 0;
+ unsigned int *must = NULL, *random = NULL;
+
+ if (conf_read_file(&item_packages_conf, config_filename)) {
+ ShowError("can't read %s\n", config_filename);
+ return;
+ }
+
+ must = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int) );
+ random = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int) );
+
+ for(i = 0; i < config_setting_length(item_packages_conf.root); i++) {
+ must[i] = 0;
+ random[i] = 0;
+ }
+
+ i = 0;
+ while( (itg = config_setting_get_elem(item_packages_conf.root,i++)) ) {
+ const char *name = config_setting_name(itg);
+
+ if( !itemdb->name2id(name) ) {
+ ShowWarning("itemdb_read_packages: unknown package item '%s', skipping..\n",name);
+ config_setting_remove(item_packages_conf.root, name);
+ --i;
continue;
}
- nameid = atoi(str[1]);
- if (!itemdb_exists(nameid)) {
- ShowWarning("itemdb_read_itemgroup: Non-existant item %d in %s:%d\n", nameid, filename, ln);
- continue;
+
+ c = 0;
+ while( (it = config_setting_get_elem(itg,c++)) ) {
+ if( ( t = config_setting_get_member(it, "Random")) && !config_setting_get_bool(t) )
+ must[ i - 1 ] += 1;
+ else
+ random[ i - 1 ] += 1;
}
- k = atoi(str[2]);
- if (itemgroup_db[groupid].qty+k >= MAX_RANDITEM) {
- ShowWarning("itemdb_read_itemgroup: Group %d is full (%d entries) in %s:%d\n", groupid, MAX_RANDITEM, filename, ln);
- continue;
+
+ }
+
+ CREATE(itemdb->packages, struct item_package, config_setting_length(item_packages_conf.root));
+ itemdb->package_count = (unsigned short)config_setting_length(item_packages_conf.root);
+
+ i = 0;
+ while( (itg = config_setting_get_elem(item_packages_conf.root,i++)) ) {
+ struct item_data *data = itemdb->name2id(config_setting_name(itg));
+ struct item_package_rand_entry *prev = NULL;
+ int r = 0, m = 0;
+
+ data->package = &itemdb->packages[count];
+
+ itemdb->packages[count].id = data->nameid;
+ itemdb->packages[count].random_list = NULL;
+ itemdb->packages[count].must_items = NULL;
+ itemdb->packages[count].random_qty = random[ i - 1 ];
+ itemdb->packages[count].must_qty = must[ i - 1 ];
+
+ if( itemdb->packages[count].random_qty )
+ CREATE(itemdb->packages[count].random_list, struct item_package_rand_entry, itemdb->packages[count].random_qty);
+ if( itemdb->packages[count].must_qty )
+ CREATE(itemdb->packages[count].must_items, struct item_package_must_entry, itemdb->packages[count].must_qty);
+
+ c = 0;
+ while( (it = config_setting_get_elem(itg,c++)) ) {
+ int icount = 1, expire = 0, rate = 10000;
+ bool announce = false, named = false;
+
+ itname = config_setting_name(it);
+
+ if( !( data = itemdb->name2id(itname) ) )
+ ShowWarning("itemdb_read_packages: unknown item '%s' in package '%s'!\n",itname,config_setting_name(itg));
+
+ if( ( t = config_setting_get_member(it, "Count")) )
+ icount = config_setting_get_int(t);
+
+ if( ( t = config_setting_get_member(it, "Expire")) )
+ expire = config_setting_get_int(t);
+
+ if( ( t = config_setting_get_member(it, "Rate")) ) {
+ if( (rate = (unsigned short)config_setting_get_int(t)) > 10000 ) {
+ ShowWarning("itemdb_read_packages: invalid rate (%d) for item '%s' in package '%s'!\n",itname,config_setting_name(itg));
+ rate = 10000;
+ }
+ }
+
+ if( ( t = config_setting_get_member(it, "Announce")) && config_setting_get_bool(t) )
+ announce = true;
+
+ if( ( t = config_setting_get_member(it, "Named")) && config_setting_get_bool(t) )
+ named = true;
+
+ if( ( t = config_setting_get_member(it, "Random")) && !config_setting_get_bool(t) ) {
+ itemdb->packages[count].must_items[m].id = data ? data->nameid : 0;
+ itemdb->packages[count].must_items[m].qty = icount;
+ itemdb->packages[count].must_items[m].hours = expire;
+ itemdb->packages[count].must_items[m].announce = announce == true ? 1 : 0;
+ itemdb->packages[count].must_items[m].named = named == true ? 1 : 0;
+ m++;
+ } else {
+ if( prev )
+ prev->next = &itemdb->packages[count].random_list[r];
+
+ itemdb->packages[count].random_list[r].id = data ? data->nameid : 0;
+ itemdb->packages[count].random_list[r].qty = icount;
+ if( (itemdb->packages[count].random_list[r].rate = rate) == 10000 ) {
+ ShowWarning("itemdb_read_packages: item '%s' in '%s' has 100% drop rate!! set this item as 'Random: false' or other items won't drop!!!\n",itname,config_setting_name(itg));
+ }
+ itemdb->packages[count].random_list[r].hours = expire;
+ itemdb->packages[count].random_list[r].announce = announce == true ? 1 : 0;
+ itemdb->packages[count].random_list[r].named = named == true ? 1 : 0;
+
+ prev = &itemdb->packages[count].random_list[r];
+
+ r++;
+ }
+
+ }
+
+ if( prev )
+ prev->next = &itemdb->packages[count].random_list[0];
+
+ if( itemdb->packages[count].random_qty == 1 ) {
+ //item packages dont stop looping until something comes out of them, so if you have only one item in it the drop is guaranteed.
+ ShowWarning("itemdb_read_packages: '%s' has only 1 random option, drop rate will be 100%!\n",itemdb_name(itemdb->packages[count].id));
+ itemdb->packages[count].random_list[0].rate = 10000;
}
- for(j=0;j<k;j++)
- itemgroup_db[groupid].nameid[itemgroup_db[groupid].qty++] = nameid;
+
count++;
}
- fclose(fp);
- return count;
+
+
+ config_destroy(&item_packages_conf);
+ aFree(must);
+ aFree(random);
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename);
}
-static void itemdb_read_itemgroup(void)
-{
- char path[256];
- unsigned int count;
- snprintf(path, 255, "%s/"DBPATH"item_group_db.txt", iMap->db_path);
- memset(&itemgroup_db, 0, sizeof(itemgroup_db));
- count = itemdb_read_itemgroup_sub(path);
- ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, "item_group_db.txt");
- return;
+void itemdb_read_chains(void) {
+ config_t item_chain_conf;
+ config_setting_t *itc = NULL, *entry = NULL;
+#ifdef RENEWAL
+ const char *config_filename = "db/re/item_chain.conf"; // FIXME hardcoded name
+#else
+ const char *config_filename = "db/pre-re/item_chain.conf"; // FIXME hardcoded name
+#endif
+ int i = 0, count = 0;
+
+ if (conf_read_file(&item_chain_conf, config_filename)) {
+ ShowError("can't read %s\n", config_filename);
+ return;
+ }
+
+ CREATE(itemdb->chains, struct item_chain, config_setting_length(item_chain_conf.root));
+ itemdb->chain_count = (unsigned short)config_setting_length(item_chain_conf.root);
+
+ while( (itc = config_setting_get_elem(item_chain_conf.root,i++)) ) {
+ struct item_data *data = NULL;
+ struct item_chain_entry *prev = NULL;
+ const char *name = config_setting_name(itc);
+ int c = 0;
+
+ script->set_constant2(name,i-1,0);
+ itemdb->chains[count].qty = (unsigned short)config_setting_length(itc);
+
+ CREATE(itemdb->chains[count].items, struct item_chain_entry, config_setting_length(itc));
+
+ while( (entry = config_setting_get_elem(itc,c++)) ) {
+ const char *itname = config_setting_name(entry);
+ if( itname[0] == 'I' && itname[1] == 'D' && strlen(itname) < 7 ) {
+ if( !( data = itemdb->exists(atoi(itname+2)) ) )
+ ShowWarning("itemdb_read_chains: unknown item ID '%d' in chain '%s'!\n",atoi(itname+2),name);
+ } else if( !( data = itemdb->name2id(itname) ) )
+ ShowWarning("itemdb_read_chains: unknown item '%s' in chain '%s'!\n",itname,name);
+
+ if( prev )
+ prev->next = &itemdb->chains[count].items[c - 1];
+
+ itemdb->chains[count].items[c - 1].id = data ? data->nameid : 0;
+ itemdb->chains[count].items[c - 1].rate = data ? config_setting_get_int(entry) : 0;
+
+ prev = &itemdb->chains[count].items[c - 1];
+ }
+
+ if( prev )
+ prev->next = &itemdb->chains[count].items[0];
+
+ count++;
+ }
+
+ config_destroy(&item_chain_conf);
+
+ if( !script->get_constant("ITMCHAIN_ORE",&i) )
+ ShowWarning("itemdb_read_chains: failed to find 'ITMCHAIN_ORE' chain to link to cache!\n");
+ else
+ itemdb->chain_cache[ECC_ORE] = i;
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename);
}
+
/*==========================================
* Reads item trade restrictions [Skotlex]
*------------------------------------------*/
@@ -606,7 +921,7 @@ static bool itemdb_read_itemtrade(char* str[], int columns, int current)
nameid = atoi(str[0]);
- if( ( id = itemdb_exists(nameid) ) == NULL )
+ if( ( id = itemdb->exists(nameid) ) == NULL )
{
//ShowWarning("itemdb_read_itemtrade: Invalid item id %d.\n", nameid);
//return false;
@@ -643,7 +958,7 @@ static bool itemdb_read_itemdelay(char* str[], int columns, int current)
nameid = atoi(str[0]);
- if( ( id = itemdb_exists(nameid) ) == NULL )
+ if( ( id = itemdb->exists(nameid) ) == NULL )
{
ShowWarning("itemdb_read_itemdelay: Invalid item id %d.\n", nameid);
return false;
@@ -673,7 +988,7 @@ static bool itemdb_read_stack(char* fields[], int columns, int current)
nameid = (unsigned short)strtoul(fields[0], NULL, 10);
- if( ( id = itemdb_exists(nameid) ) == NULL )
+ if( ( id = itemdb->exists(nameid) ) == NULL )
{
ShowWarning("itemdb_read_stack: Unknown item id '%hu'.\n", nameid);
return false;
@@ -711,7 +1026,7 @@ static bool itemdb_read_buyingstore(char* fields[], int columns, int current)
nameid = atoi(fields[0]);
- if( ( id = itemdb_exists(nameid) ) == NULL )
+ if( ( id = itemdb->exists(nameid) ) == NULL )
{
ShowWarning("itemdb_read_buyingstore: Invalid item id %d.\n", nameid);
return false;
@@ -738,7 +1053,7 @@ static bool itemdb_read_nouse(char* fields[], int columns, int current)
nameid = atoi(fields[0]);
- if( ( id = itemdb_exists(nameid) ) == NULL ) {
+ if( ( id = itemdb->exists(nameid) ) == NULL ) {
ShowWarning("itemdb_read_nouse: Invalid item id %d.\n", nameid);
return false;
}
@@ -847,7 +1162,7 @@ void itemdb_read_combos() {
/* validate */
for(v = 0; v < retcount; v++) {
- if( !itemdb_exists(items[v]) ) {
+ if( !itemdb->exists(items[v]) ) {
ShowError("itemdb_read_combos: line %d of \"%s\" contains unknown item ID %d, skipping.\n", lines, path,items[v]);
break;
}
@@ -856,7 +1171,7 @@ void itemdb_read_combos() {
if( v < retcount )
continue;
- id = itemdb_exists(items[0]);
+ id = itemdb->exists(items[0]);
idx = id->combos_count;
@@ -885,7 +1200,7 @@ void itemdb_read_combos() {
struct item_data * it;
int index;
- it = itemdb_exists(items[v]);
+ it = itemdb->exists(items[v]);
index = it->combos_count;
@@ -1095,6 +1410,7 @@ int itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt)
if (*str[21+offset])
id->unequip_script = parse_script(str[21+offset], source, line, scriptopt);
+ strdb_put(itemdb->names, id->name, id);
return id->nameid;
}
@@ -1321,14 +1637,16 @@ int itemdb_uid_load() {
* read all item-related databases
*------------------------------------*/
static void itemdb_read(void) {
-
if (iMap->db_use_sqldbs)
itemdb_read_sqldb();
else
itemdb_readdb();
itemdb_read_combos();
- itemdb_read_itemgroup();
+ itemdb->read_groups();
+ itemdb->read_chains();
+ itemdb->read_packages();
+
sv->readdb(iMap->db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail);
sv->readdb(iMap->db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade);
sv->readdb(iMap->db_path, "item_delay.txt", ',', 2, 2, -1, &itemdb_read_itemdelay);
@@ -1336,6 +1654,9 @@ static void itemdb_read(void) {
sv->readdb(iMap->db_path, DBPATH"item_buyingstore.txt", ',', 1, 1, -1, &itemdb_read_buyingstore);
sv->readdb(iMap->db_path, "item_nouse.txt", ',', 3, 3, -1, &itemdb_read_nouse);
+
+ itemdb->name_constants();
+
itemdb_uid_load();
}
@@ -1388,8 +1709,7 @@ static int itemdb_final_sub(DBKey key, DBData *data, va_list ap)
return 0;
}
-void itemdb_reload(void)
-{
+void itemdb_reload(void) {
struct s_mapiterator* iter;
struct map_session_data* sd;
@@ -1400,9 +1720,46 @@ void itemdb_reload(void)
if( itemdb_array[i] )
destroy_item_data(itemdb_array[i], 1);
+ for( i = 0; i < itemdb->group_count; i++ ) {
+ if( itemdb->groups[i].nameid )
+ aFree(itemdb->groups[i].nameid);
+ }
+
+ if( itemdb->groups )
+ aFree(itemdb->groups);
+
+ itemdb->groups = NULL;
+ itemdb->group_count = 0;
+
+ for( i = 0; i < itemdb->chain_count; i++ ) {
+ if( itemdb->chains[i].items )
+ aFree(itemdb->chains[i].items);
+ }
+
+ if( itemdb->chains )
+ aFree(itemdb->chains);
+
+ itemdb->chains = NULL;
+ itemdb->chain_count = 0;
+
+ for( i = 0; i < itemdb->package_count; i++ ) {
+ if( itemdb->packages[i].random_list )
+ aFree(itemdb->packages[i].random_list);
+ if( itemdb->packages[i].must_items )
+ aFree(itemdb->packages[i].must_items);
+ }
+
+ if( itemdb->packages )
+ aFree(itemdb->packages);
+
+ itemdb->packages = NULL;
+ itemdb->package_count = 0;
+
itemdb_other->clear(itemdb_other, itemdb_final_sub);
-
+
memset(itemdb_array, 0, sizeof(itemdb_array));
+
+ db_clear(itemdb->names);
// read new data
itemdb_read();
@@ -1454,34 +1811,94 @@ void itemdb_reload(void)
}
mapit->free(iter);
}
+void itemdb_name_constants(void) {
+ DBIterator *iter = db_iterator(itemdb->names);
+ struct item_data *data;
+
+ for( data = dbi_first(iter); dbi_exists(iter); data = dbi_next(iter) )
+ script->set_constant2(data->name,data->nameid,0);
-void do_final_itemdb(void)
-{
+ dbi_destroy(iter);
+}
+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], 1);
+ for( i = 0; i < itemdb->group_count; i++ ) {
+ if( itemdb->groups[i].nameid )
+ aFree(itemdb->groups[i].nameid);
+ }
+
+ if( itemdb->groups )
+ aFree(itemdb->groups);
+
+ for( i = 0; i < itemdb->chain_count; i++ ) {
+ if( itemdb->chains[i].items )
+ aFree(itemdb->chains[i].items);
+ }
+
+ if( itemdb->chains )
+ aFree(itemdb->chains);
+
+ for( i = 0; i < itemdb->package_count; i++ ) {
+ if( itemdb->packages[i].random_list )
+ aFree(itemdb->packages[i].random_list);
+ if( itemdb->packages[i].must_items )
+ aFree(itemdb->packages[i].must_items);
+ }
+
+ if( itemdb->packages )
+ aFree(itemdb->packages);
+
itemdb_other->destroy(itemdb_other, itemdb_final_sub);
destroy_item_data(&dummy_item, 0);
+ db_destroy(itemdb->names);
}
-int do_init_itemdb(void) {
+void do_init_itemdb(void) {
memset(itemdb_array, 0, sizeof(itemdb_array));
itemdb_other = idb_alloc(DB_OPT_BASE);
+ itemdb->names = strdb_alloc(DB_OPT_BASE,ITEM_NAME_LENGTH);
create_dummy_data(); //Dummy data item.
itemdb_read();
clif->cashshop_load();
-
- return 0;
}
/* incomplete */
void itemdb_defaults(void) {
itemdb = &itemdb_s;
- itemdb->reload = itemdb_reload;//incomplet=e
+ itemdb->init = do_init_itemdb;
+ itemdb->final = do_final_itemdb;
+ itemdb->reload = itemdb_reload;//incomplete
+ itemdb->name_constants = itemdb_name_constants;
+ /* */
+ itemdb->groups = NULL;
+ itemdb->group_count = 0;
+ /* */
+ itemdb->chains = NULL;
+ itemdb->chain_count = 0;
+ /* */
+ itemdb->packages = NULL;
+ itemdb->package_count = 0;
+ /* */
+ itemdb->names = NULL;
+ /* */
+ itemdb->read_groups = itemdb_read_groups;
+ itemdb->read_chains = itemdb_read_chains;
+ itemdb->read_packages = itemdb_read_packages;
/* */
+ itemdb->search_name = itemdb_searchname;
+ itemdb->search_name_array = itemdb_searchname_array;
+ itemdb->load = itemdb_load;
+ itemdb->search = itemdb_search;
itemdb->parse_dbrow = itemdb_parse_dbrow;
itemdb->exists = itemdb_exists;//incomplete
+ itemdb->name2id = itemdb_name2id;
+ itemdb->in_group = itemdb_in_group;
+ itemdb->group_item = itemdb_searchrandomid;
+ itemdb->chain_item = itemdb_chain_item;
+ itemdb->package_item = itemdb_package_item;
}