diff options
Diffstat (limited to 'src/map/itemdb.c')
-rw-r--r-- | src/map/itemdb.c | 562 |
1 files changed, 268 insertions, 294 deletions
diff --git a/src/map/itemdb.c b/src/map/itemdb.c index bfcc6f795..61b77748a 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -2,27 +2,32 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#include "../common/nullpo.h" -#include "../common/malloc.h" -#include "../common/random.h" -#include "../common/showmsg.h" -#include "../common/strlib.h" -#include "../common/utils.h" -#include "../common/conf.h" +#define HERCULES_CORE + +#include "../config/core.h" // DBPATH, RENEWAL #include "itemdb.h" -#include "map.h" -#include "battle.h" // struct battle_config -#include "script.h" // item script processing -#include "pc.h" // W_MUSICAL, W_WHIP #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "battle.h" // struct battle_config +#include "map.h" +#include "mob.h" // MAX_MOB_DB +#include "pc.h" // W_MUSICAL, W_WHIP +#include "script.h" // item script processing +#include "../common/conf.h" +#include "../common/malloc.h" +#include "../common/nullpo.h" +#include "../common/random.h" +#include "../common/showmsg.h" +#include "../common/strlib.h" +#include "../common/utils.h" + struct itemdb_interface itemdb_s; /** - * Search for item name + * Search for item name * name = item alias, so we should find items aliases first. if not found then look for "jname" (full name) * @see DBApply */ @@ -50,7 +55,7 @@ int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap) } /*========================================== - * Return item data from item name. (lookup) + * Return item data from item name. (lookup) *------------------------------------------*/ struct item_data* itemdb_searchname(const char *str) { struct item_data* item; @@ -251,7 +256,7 @@ void itemdb_package_item(struct map_session_data *sd, struct item_package *packa return; } /*========================================== - * Return a random item id from group. (takes into account % chance giving/tot group) + * Return a random item id from group. (takes into account % chance giving/tot group) *------------------------------------------*/ int itemdb_searchrandomid(struct item_group *group) { @@ -307,7 +312,7 @@ const char* itemdb_typename(int type) } /*========================================== - * Converts the jobid from the format in itemdb + * Converts the jobid from the format in itemdb * to the format used by the map server. [Skotlex] *------------------------------------------*/ void itemdb_jobid2mapid(unsigned int *bclass, unsigned int jobmask) @@ -465,8 +470,7 @@ int itemdb_isequip(int nameid) /*========================================== * Alternate version of itemdb_isequip *------------------------------------------*/ -int itemdb_isequip2(struct item_data *data) -{ +int itemdb_isequip2(struct item_data *data) { nullpo_ret(data); switch(data->type) { case IT_WEAPON: @@ -517,39 +521,39 @@ int itemdb_isstackable2(struct item_data *data) * Trade Restriction functions [Skotlex] *------------------------------------------*/ int itemdb_isdropable_sub(struct item_data *item, int gmlv, int unused) { - return (item && (!(item->flag.trade_restriction&1) || gmlv >= item->gm_lv_trade_override)); + return (item && (!(item->flag.trade_restriction&ITR_NODROP) || gmlv >= item->gm_lv_trade_override)); } int itemdb_cantrade_sub(struct item_data* item, int gmlv, int gmlv2) { - return (item && (!(item->flag.trade_restriction&2) || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override)); + return (item && (!(item->flag.trade_restriction&ITR_NOTRADE) || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override)); } int itemdb_canpartnertrade_sub(struct item_data* item, int gmlv, int gmlv2) { - return (item && (item->flag.trade_restriction&4 || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override)); + return (item && (item->flag.trade_restriction&ITR_PARTNEROVERRIDE || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override)); } int itemdb_cansell_sub(struct item_data* item, int gmlv, int unused) { - return (item && (!(item->flag.trade_restriction&8) || gmlv >= item->gm_lv_trade_override)); + return (item && (!(item->flag.trade_restriction&ITR_NOSELLTONPC) || gmlv >= item->gm_lv_trade_override)); } int itemdb_cancartstore_sub(struct item_data* item, int gmlv, int unused) { - return (item && (!(item->flag.trade_restriction&16) || gmlv >= item->gm_lv_trade_override)); + return (item && (!(item->flag.trade_restriction&ITR_NOCART) || gmlv >= item->gm_lv_trade_override)); } int itemdb_canstore_sub(struct item_data* item, int gmlv, int unused) { - return (item && (!(item->flag.trade_restriction&32) || gmlv >= item->gm_lv_trade_override)); + return (item && (!(item->flag.trade_restriction&ITR_NOSTORAGE) || gmlv >= item->gm_lv_trade_override)); } int itemdb_canguildstore_sub(struct item_data* item, int gmlv, int unused) { - return (item && (!(item->flag.trade_restriction&64) || gmlv >= item->gm_lv_trade_override)); + return (item && (!(item->flag.trade_restriction&ITR_NOGSTORAGE) || gmlv >= item->gm_lv_trade_override)); } int itemdb_canmail_sub(struct item_data* item, int gmlv, int unused) { - return (item && (!(item->flag.trade_restriction&128) || gmlv >= item->gm_lv_trade_override)); + return (item && (!(item->flag.trade_restriction&ITR_NOMAIL) || gmlv >= item->gm_lv_trade_override)); } int itemdb_canauction_sub(struct item_data* item, int gmlv, int unused) { - return (item && (!(item->flag.trade_restriction&256) || gmlv >= item->gm_lv_trade_override)); + return (item && (!(item->flag.trade_restriction&ITR_NOAUCTION) || gmlv >= item->gm_lv_trade_override)); } int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int)) @@ -597,39 +601,6 @@ int itemdb_isidentified2(struct item_data *data) { } } - -/*========================================== - * Search by name for the override flags available items - * (Give item another sprite) - *------------------------------------------*/ -bool itemdb_read_itemavail(char* str[], int columns, int current) -{// <nameid>,<sprite> - int nameid, sprite; - struct item_data *id; - - nameid = atoi(str[0]); - - if( ( id = itemdb->exists(nameid) ) == NULL ) - { - ShowWarning("itemdb_read_itemavail: Invalid item id %d.\n", nameid); - return false; - } - - sprite = atoi(str[1]); - - if( sprite > 0 ) - { - id->flag.available = 1; - id->view_id = sprite; - } - else - { - id->flag.available = 0; - } - - return true; -} - void itemdb_read_groups(void) { config_t item_group_conf; config_setting_t *itg = NULL, *it = NULL; @@ -818,7 +789,7 @@ bool itemdb_read_cached_packages(const char *config_filename) { hread(&random_qty,sizeof(random_qty),1,file); if( !(pdata = itemdb->exists(id)) ) - ShowWarning("itemdb_read_packages: unknown package item '%d', skipping..\n",id); + ShowWarning("itemdb_read_cached_packages: unknown package item '%d', skipping..\n",id); else pdata->package = &itemdb->packages[i]; @@ -848,7 +819,7 @@ bool itemdb_read_cached_packages(const char *config_filename) { hread(&named,sizeof(announce),1,file); if( !(data = itemdb->exists(mid)) ) - ShowWarning("itemdb_read_packages: unknown item '%d' in package '%s'!\n",mid,itemdb_name(package->id)); + ShowWarning("itemdb_read_cached_packages: unknown item '%d' in package '%s'!\n",mid,itemdb_name(package->id)); entry->id = data ? data->nameid : 0; entry->hours = hours; @@ -893,7 +864,7 @@ bool itemdb_read_cached_packages(const char *config_filename) { hread(&named,sizeof(announce),1,file); if( !(data = itemdb->exists(mid)) ) - ShowWarning("itemdb_read_packages: unknown item '%d' in package '%s'!\n",mid,itemdb_name(package->id)); + ShowWarning("itemdb_read_cached_packages: unknown item '%d' in package '%s'!\n",mid,itemdb_name(package->id)); entry->id = data ? data->nameid : 0; entry->rate = rate; @@ -932,7 +903,7 @@ void itemdb_read_packages(void) { if( HCache->check(config_filename) ) { if( itemdb->read_cached_packages(config_filename) ) return; - } + } if (libconfig->read_file(&item_packages_conf, config_filename)) { ShowError("can't read %s\n", config_filename); @@ -1119,7 +1090,7 @@ void itemdb_read_packages(void) { for( r = 0; r < itemdb->packages[count].random_qty; r++ ) { if( itemdb->packages[count].random_groups[r].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. + //item packages don't 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: in '%s' 'Random: %d' group has only 1 random option, drop rate will be 100%!\n",itemdb_name(itemdb->packages[count].id),r+1); itemdb->packages[count].random_groups[r].random_list[0].rate = 10000; } @@ -1214,163 +1185,6 @@ void itemdb_read_chains(void) { ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename); } - -/*========================================== - * Reads item trade restrictions [Skotlex] - *------------------------------------------*/ -bool itemdb_read_itemtrade(char* str[], int columns, int current) -{// <nameid>,<mask>,<gm level> - int nameid, flag, gmlv; - struct item_data *id; - - nameid = atoi(str[0]); - - if( ( id = itemdb->exists(nameid) ) == NULL ) - { - //ShowWarning("itemdb_read_itemtrade: Invalid item id %d.\n", nameid); - //return false; - // FIXME: item_trade.txt contains items, which are commented in item database. - return true; - } - - flag = atoi(str[1]); - gmlv = atoi(str[2]); - - if( flag < 0 || flag > 511 ) {//Check range - ShowWarning("itemdb_read_itemtrade: Invalid trading mask %d for item id %d.\n", flag, nameid); - return false; - } - if( gmlv < 1 ) - { - ShowWarning("itemdb_read_itemtrade: Invalid override GM level %d for item id %d.\n", gmlv, nameid); - return false; - } - - id->flag.trade_restriction = flag; - id->gm_lv_trade_override = gmlv; - - return true; -} - -/*========================================== - * Reads item delay amounts [Paradox924X] - *------------------------------------------*/ -bool itemdb_read_itemdelay(char* str[], int columns, int current) -{// <nameid>,<delay> - int nameid, delay; - struct item_data *id; - - nameid = atoi(str[0]); - - if( ( id = itemdb->exists(nameid) ) == NULL ) - { - ShowWarning("itemdb_read_itemdelay: Invalid item id %d.\n", nameid); - return false; - } - - delay = atoi(str[1]); - - if( delay < 0 ) - { - ShowWarning("itemdb_read_itemdelay: Invalid delay %d for item id %d.\n", id->delay, nameid); - return false; - } - - id->delay = delay; - - return true; -} - -/*================================================================== - * Reads item stacking restrictions - *----------------------------------------------------------------*/ -bool itemdb_read_stack(char* fields[], int columns, int current) -{// <item id>,<stack limit amount>,<type> - unsigned short nameid, amount; - unsigned int type; - struct item_data* id; - - nameid = (unsigned short)strtoul(fields[0], NULL, 10); - - if( ( id = itemdb->exists(nameid) ) == NULL ) - { - ShowWarning("itemdb_read_stack: Unknown item id '%hu'.\n", nameid); - return false; - } - - if( !itemdb->isstackable2(id) ) - { - ShowWarning("itemdb_read_stack: Item id '%hu' is not stackable.\n", nameid); - return false; - } - - amount = (unsigned short)strtoul(fields[1], NULL, 10); - type = (unsigned int)strtoul(fields[2], NULL, 10); - - if( !amount ) - {// ignore - return true; - } - - id->stack.amount = amount; - id->stack.inventory = (type&1)!=0; - id->stack.cart = (type&2)!=0; - id->stack.storage = (type&4)!=0; - id->stack.guildstorage = (type&8)!=0; - - return true; -} - - -/// Reads items allowed to be sold in buying stores -bool itemdb_read_buyingstore(char* fields[], int columns, int current) -{// <nameid> - int nameid; - struct item_data* id; - - nameid = atoi(fields[0]); - - if( ( id = itemdb->exists(nameid) ) == NULL ) - { - ShowWarning("itemdb_read_buyingstore: Invalid item id %d.\n", nameid); - return false; - } - - if( !itemdb->isstackable2(id) ) - { - ShowWarning("itemdb_read_buyingstore: Non-stackable item id %d cannot be enabled for buying store.\n", nameid); - return false; - } - - id->flag.buyingstore = true; - - return true; -} - -/******************************************* -** Item usage restriction (item_nouse.txt) -********************************************/ -bool itemdb_read_nouse(char* fields[], int columns, int current) -{// <nameid>,<flag>,<override> - int nameid, flag, override; - struct item_data* id; - - nameid = atoi(fields[0]); - - if( ( id = itemdb->exists(nameid) ) == NULL ) { - ShowWarning("itemdb_read_nouse: Invalid item id %d.\n", nameid); - return false; - } - - flag = atoi(fields[1]); - override = atoi(fields[2]); - - id->item_usage.flag = flag; - id->item_usage.override = override; - - return true; -} - /** * @return: amount of retrieved entries. **/ @@ -1440,7 +1254,7 @@ void itemdb_read_combos() { p++; str[1] = p; - p = strchr(p,','); + p = strchr(p,','); p++; if (str[1][0] != '{') { @@ -1478,7 +1292,7 @@ void itemdb_read_combos() { CREATE(combo, struct item_combo, 1); combo->count = retcount; - combo->script = script->parse(str[1], filepath, lines, 0); + combo->script = script->parse(str[1], filepath, lines, 0, NULL); combo->id = itemdb->combo_count - 1; /* populate ->nameid field */ for( v = 0; v < retcount; v++ ) { @@ -1574,7 +1388,8 @@ int itemdb_validate_entry(struct item_data *entry, int n, const char *source) { || (entry->type > IT_DELAYCONSUME && entry->type < IT_CASH ) || entry->type >= IT_MAX ) { // catch invalid item types - ShowWarning("itemdb_validate_entry: Invalid item type %d for item %d. IT_ETC will be used.\n", entry->type, entry->nameid); + ShowWarning("itemdb_validate_entry: Invalid item type %d for item %d in '%s'. IT_ETC will be used.\n", + entry->type, entry->nameid, source); entry->type = IT_ETC; } else if( entry->type == IT_DELAYCONSUME ) { //Items that are consumed only after target confirmation @@ -1592,21 +1407,61 @@ int itemdb_validate_entry(struct item_data *entry, int n, const char *source) { entry->value_sell = entry->value_buy / 2; } if( entry->value_buy/124. < entry->value_sell/75. ) { - ShowWarning("itemdb_validate_entry: Buying/Selling [%d/%d] price of item %d (%s) allows Zeny making exploit through buying/selling at discounted/overcharged prices!\n", - entry->value_buy, entry->value_sell, entry->nameid, entry->jname); + ShowWarning("itemdb_validate_entry: Buying/Selling [%d/%d] price of item %d (%s) in '%s' " + "allows Zeny making exploit through buying/selling at discounted/overcharged prices!\n", + entry->value_buy, entry->value_sell, entry->nameid, entry->jname, source); } if( entry->slot > MAX_SLOTS ) { - ShowWarning("itemdb_validate_entry: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", - entry->nameid, entry->jname, entry->slot, MAX_SLOTS, MAX_SLOTS); + ShowWarning("itemdb_validate_entry: Item %d (%s) in '%s' specifies %d slots, but the server only supports up to %d. Using %d slots.\n", + entry->nameid, entry->jname, source, entry->slot, MAX_SLOTS, MAX_SLOTS); entry->slot = MAX_SLOTS; } if (!entry->equip && itemdb->isequip2(entry)) { - ShowWarning("itemdb_validate_entry: Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", entry->nameid, entry->jname); + ShowWarning("itemdb_validate_entry: Item %d (%s) in '%s' is an equipment with no equip-field! Making it an etc item.\n", + entry->nameid, entry->jname, source); entry->type = IT_ETC; } + if (entry->flag.trade_restriction < 0 || entry->flag.trade_restriction > ITR_ALL) { + ShowWarning("itemdb_validate_entry: Invalid trade restriction flag 0x%x for item %d (%s) in '%s', defaulting to none.\n", + entry->flag.trade_restriction, entry->nameid, entry->jname, source); + entry->flag.trade_restriction = ITR_NONE; + } + + if (entry->gm_lv_trade_override < 0 || entry->gm_lv_trade_override > 100) { + ShowWarning("itemdb_validate_entry: Invalid trade-override GM level %d for item %d (%s) in '%s', defaulting to none.\n", + entry->gm_lv_trade_override, entry->nameid, entry->jname, source); + entry->gm_lv_trade_override = 0; + } + if (entry->gm_lv_trade_override == 0) { + // Default value if none or an ivalid one was specified + entry->gm_lv_trade_override = 100; + } + + if (entry->item_usage.flag > INR_ALL) { + ShowWarning("itemdb_validate_entry: Invalid nouse flag 0x%x for item %d (%s) in '%s', defaulting to none.\n", + entry->item_usage.flag, entry->nameid, entry->jname, source); + entry->item_usage.flag = INR_NONE; + } + + if (entry->item_usage.override > 100) { + ShowWarning("itemdb_validate_entry: Invalid nouse-override GM level %d for item %d (%s) in '%s', defaulting to none.\n", + entry->item_usage.override, entry->nameid, entry->jname, source); + entry->item_usage.override = 0; + } + if (entry->item_usage.override == 0) { + // Default value if none or an ivalid one was specified + entry->item_usage.override = 100; + } + + if (entry->stack.amount > 0 && !itemdb->isstackable2(entry)) { + ShowWarning("itemdb_validate_entry: Item %d (%s) of type %d is not stackable, ignoring stack settings in '%s'.\n", + entry->nameid, entry->jname, entry->type, source); + memset(&entry->stack, '\0', sizeof(entry->stack)); + } + entry->wlv = cap_value(entry->wlv, REFINE_TYPE_ARMOR, REFINE_TYPE_MAX); if( !entry->elvmax ) @@ -1617,8 +1472,11 @@ int itemdb_validate_entry(struct item_data *entry, int n, const char *source) { if( entry->type != IT_ARMOR && entry->type != IT_WEAPON && !entry->flag.no_refine ) entry->flag.no_refine = 1; - entry->flag.available = 1; - entry->view_id = 0; + if (entry->flag.available != 1) { + entry->flag.available = 1; + entry->view_id = 0; + } + entry->sex = itemdb->gendercheck(entry); //Apply gender filtering. // Validated. Finally insert it @@ -1681,6 +1539,15 @@ int itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) { * `refineable` tinyint(1) unsigned DEFAULT NULL * `view` smallint(3) unsigned DEFAULT NULL * `bindonequip` tinyint(1) unsigned DEFAULT NULL + * `buyingstore` tinyint(1) NOT NULL DEFAULT NULL + * `delay` mediumint(9) NOT NULL DEFAULT NULL + * `trade_flag` smallint(4) NOT NULL DEFAULT NULL + * `trade_group` smallint(4) NOT NULL DEFAULT NULL + * `nouse_flag` smallint(4) NOT NULL DEFAULT NULL + * `nouse_group` smallint(4) NOT NULL DEFAULT NULL + * `stack_amount` mediumint(6) NOT NULL DEFAULT NULL + * `stack_flag` smallint(2) NOT NULL DEFAULT NULL + * `sprite` mediumint(6) NOT NULL DEFAULT NULL * `script` text * `equip_script` text * `unequip_script` text @@ -1707,9 +1574,30 @@ int itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) { SQL->GetData(handle, 19, &data, NULL); id.flag.no_refine = data && atoi(data) ? 0 : 1; SQL->GetData(handle, 20, &data, NULL); id.look = data ? atoi(data) : 0; SQL->GetData(handle, 21, &data, NULL); id.flag.bindonequip = data && atoi(data) ? 1 : 0; - SQL->GetData(handle, 22, &data, NULL); id.script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; - SQL->GetData(handle, 23, &data, NULL); id.equip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; - SQL->GetData(handle, 24, &data, NULL); id.unequip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; + SQL->GetData(handle, 22, &data, NULL); id.flag.buyingstore = data && atoi(data) ? 1 : 0; + SQL->GetData(handle, 23, &data, NULL); id.delay = data ? atoi(data) : 0; + SQL->GetData(handle, 24, &data, NULL); id.flag.trade_restriction = data ? atoi(data) : ITR_NONE; + SQL->GetData(handle, 25, &data, NULL); id.gm_lv_trade_override = data ? atoi(data) : 0; + SQL->GetData(handle, 26, &data, NULL); id.item_usage.flag = data ? atoi(data) : INR_NONE; + SQL->GetData(handle, 27, &data, NULL); id.item_usage.override = data ? atoi(data) : 0; + SQL->GetData(handle, 28, &data, NULL); id.stack.amount = data ? atoi(data) : 0; + SQL->GetData(handle, 29, &data, NULL); + if (data) { + int stack_flag = atoi(data); + id.stack.inventory = (stack_flag&1)!=0; + id.stack.cart = (stack_flag&2)!=0; + id.stack.storage = (stack_flag&4)!=0; + id.stack.guildstorage = (stack_flag&8)!=0; + } + SQL->GetData(handle, 30, &data, NULL); + if (data) { + id.view_id = atoi(data); + if (id.view_id) + id.flag.available = 1; + } + SQL->GetData(handle, 31, &data, NULL); id.script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; + SQL->GetData(handle, 32, &data, NULL); id.equip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; + SQL->GetData(handle, 33, &data, NULL); id.unequip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; return itemdb->validate_entry(&id, n, source); } @@ -1754,10 +1642,30 @@ int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source) * Gender: Gender * Loc: Equip location * WeaponLv: Weapon Level - * EquipLv: Equip required level + * EquipLv: Equip required level or [min, max] * Refine: Refineable * View: View ID * BindOnEquip: (true or false) + * BuyingStore: (true or false) + * Delay: Delay to use item + * Trade: { + * override: Group to override + * nodrop: (true or false) + * notrade: (true or false) + * partneroverride: (true or false) + * noselltonpc: (true or false) + * nocart: (true or false) + * nostorage: (true or false) + * nogstorage: (true or false) + * nomail: (true or false) + * noauction: (true or false) + * } + * Nouse: { + * override: Group to override + * sitting: (true or false) + * } + * Stack: [Stackable Amount, Stack Type] + * Sprite: SpriteID * Script: <" * Script * (it can be multi-line) @@ -1874,14 +1782,124 @@ int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source) if( (t = libconfig->setting_get_member(it, "BindOnEquip")) ) id.flag.bindonequip = libconfig->setting_get_bool(t) ? 1 : 0; + if ( (t = libconfig->setting_get_member(it, "BuyingStore")) ) + id.flag.buyingstore = libconfig->setting_get_bool(t) ? 1 : 0; + + if (libconfig->setting_lookup_int(it, "Delay", &i32) && i32 >= 0) + id.delay = i32; + + if ( (t = libconfig->setting_get_member(it, "Trade")) ) { + if (config_setting_is_group(t)) { + config_setting_t *tt = NULL; + + if ((tt = libconfig->setting_get_member(t, "override"))) { + id.gm_lv_trade_override = libconfig->setting_get_int(tt); + } + + if ((tt = libconfig->setting_get_member(t, "nodrop"))) { + id.flag.trade_restriction &= ~ITR_NODROP; + if (libconfig->setting_get_bool(tt)) + id.flag.trade_restriction |= ITR_NODROP; + } + + if ((tt = libconfig->setting_get_member(t, "notrade"))) { + id.flag.trade_restriction &= ~ITR_NOTRADE; + if (libconfig->setting_get_bool(tt)) + id.flag.trade_restriction |= ITR_NOTRADE; + } + + if ((tt = libconfig->setting_get_member(t, "partneroverride"))) { + id.flag.trade_restriction &= ~ITR_PARTNEROVERRIDE; + if (libconfig->setting_get_bool(tt)) + id.flag.trade_restriction |= ITR_PARTNEROVERRIDE; + } + + if ((tt = libconfig->setting_get_member(t, "noselltonpc"))) { + id.flag.trade_restriction &= ~ITR_NOSELLTONPC; + if (libconfig->setting_get_bool(tt)) + id.flag.trade_restriction |= ITR_NOSELLTONPC; + } + + if ((tt = libconfig->setting_get_member(t, "nocart"))) { + id.flag.trade_restriction &= ~ITR_NOCART; + if (libconfig->setting_get_bool(tt)) + id.flag.trade_restriction |= ITR_NOCART; + } + + if ((tt = libconfig->setting_get_member(t, "nostorage"))) { + id.flag.trade_restriction &= ~ITR_NOSTORAGE; + if (libconfig->setting_get_bool(tt)) + id.flag.trade_restriction |= ITR_NOSTORAGE; + } + + if ((tt = libconfig->setting_get_member(t, "nogstorage"))) { + id.flag.trade_restriction &= ~ITR_NOGSTORAGE; + if (libconfig->setting_get_bool(tt)) + id.flag.trade_restriction |= ITR_NOGSTORAGE; + } + + if ((tt = libconfig->setting_get_member(t, "nomail"))) { + id.flag.trade_restriction &= ~ITR_NOMAIL; + if (libconfig->setting_get_bool(tt)) + id.flag.trade_restriction |= ITR_NOMAIL; + } + + if ((tt = libconfig->setting_get_member(t, "noauction"))) { + id.flag.trade_restriction &= ~ITR_NOAUCTION; + if (libconfig->setting_get_bool(tt)) + id.flag.trade_restriction |= ITR_NOAUCTION; + } + } else { // Fallback to int if it's not a group + id.flag.trade_restriction = libconfig->setting_get_int(t); + } + } + + if ((t = libconfig->setting_get_member(it, "Nouse"))) { + if (config_setting_is_group(t)) { + config_setting_t *nt = NULL; + + if ((nt = libconfig->setting_get_member(t, "override"))) { + id.item_usage.override = libconfig->setting_get_int(nt); + } + + if ((nt = libconfig->setting_get_member(t, "sitting"))) { + id.item_usage.flag &= ~INR_SITTING; + if (libconfig->setting_get_bool(nt)) + id.item_usage.flag |= INR_SITTING; + } + + } else { // Fallback to int if it's not a group + id.item_usage.flag = libconfig->setting_get_int(t); + } + } + + if ((t = libconfig->setting_get_member(it, "Stack"))) { + if (config_setting_is_aggregate(t) && libconfig->setting_length(t) >= 1) { + int stack_flag = libconfig->setting_get_int_elem(t, 1); + int stack_amount = libconfig->setting_get_int_elem(t, 0); + if (stack_amount >= 0) { + id.stack.amount = cap_value(stack_amount, 0, USHRT_MAX); + id.stack.inventory = (stack_flag&1)!=0; + id.stack.cart = (stack_flag&2)!=0; + id.stack.storage = (stack_flag&4)!=0; + id.stack.guildstorage = (stack_flag&8)!=0; + } + } + } + + if (libconfig->setting_lookup_int(it, "Sprite", &i32) && i32 >= 0) { + id.flag.available = 1; + id.view_id = i32; + } + if( libconfig->setting_lookup_string(it, "Script", &str) ) - id.script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; + id.script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; if( libconfig->setting_lookup_string(it, "OnEquipScript", &str) ) - id.equip_script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; + id.equip_script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; if( libconfig->setting_lookup_string(it, "OnUnequipScript", &str) ) - id.unequip_script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; + id.unequip_script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; return itemdb->validate_entry(&id, n, source); } @@ -1943,7 +1961,10 @@ int itemdb_readdb_sql(const char *tablename) { " `matk`, `defence`, `range`, `slots`," " `equip_jobs`, `equip_upper`, `equip_genders`, `equip_locations`," " `weapon_level`, `equip_level_min`, `equip_level_max`, `refineable`," - " `view`, `bindonequip`, `script`, `equip_script`, `unequip_script`" + " `view`, `bindonequip`, `buyingstore`, `delay`," + " `trade_flag`, `trade_group`, `nouse_flag`, `nouse_group`," + " `stack_amount`, `stack_flag`, `sprite`, `script`," + " `equip_script`, `unequip_script`" "FROM `%s`", tablename) ) { Sql_ShowDebug(map->mysql_handle); return 0; @@ -1966,44 +1987,10 @@ int itemdb_readdb_sql(const char *tablename) { /*========================================== * Unique item ID function * Only one operation by once -* Flag: -* 0 return new id -* 1 set new value, checked with current value -* 2 set new value bypassing anything -* 3/other return last value *------------------------------------------*/ -uint64 itemdb_unique_id(int8 flag, int64 value) { - static uint64 item_uid = 0; - - if(flag) - { - if(flag == 1) - { if(item_uid < value) - return (item_uid = value); - }else if(flag == 2) - return (item_uid = value); - - return item_uid; - } +uint64 itemdb_unique_id(struct map_session_data *sd) { - return ++item_uid; -} -int itemdb_uid_load() { - char * uid; - if (SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT `value` FROM `%s` WHERE `varname`='unique_id'",map->interreg_db)) - Sql_ShowDebug(map->mysql_handle); - - if( SQL_SUCCESS != SQL->NextRow(map->mysql_handle) ) { - ShowError("itemdb_uid_load: Unable to fetch unique_id data\n"); - SQL->FreeResult(map->mysql_handle); - return -1; - } - - SQL->GetData(map->mysql_handle, 0, &uid, NULL); - itemdb->unique_id(1, (uint64)strtoull(uid, NULL, 10)); - SQL->FreeResult(map->mysql_handle); - - return 0; + return ((uint64)sd->status.char_id << 32) | sd->status.uniqueitem_counter++; } /** @@ -2050,15 +2037,7 @@ void itemdb_read(bool minimal) { itemdb->read_groups(); itemdb->read_chains(); itemdb->read_packages(); - - sv->readdb(map->db_path, "item_avail.txt", ',', 2, 2, -1, itemdb->read_itemavail); - sv->readdb(map->db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, itemdb->read_itemtrade); - sv->readdb(map->db_path, DBPATH"item_delay.txt", ',', 2, 2, -1, itemdb->read_itemdelay); - sv->readdb(map->db_path, "item_stack.txt", ',', 3, 3, -1, itemdb->read_stack); - sv->readdb(map->db_path, DBPATH"item_buyingstore.txt", ',', 1, 1, -1, itemdb->read_buyingstore); - sv->readdb(map->db_path, "item_nouse.txt", ',', 3, 3, -1, itemdb->read_nouse); - - itemdb->uid_load(); + } /** @@ -2112,9 +2091,10 @@ int itemdb_final_sub(DBKey key, DBData *data, va_list ap) void itemdb_clear(bool total) { int i; // clear the previous itemdb data - for( i = 0; i < ARRAYLENGTH(itemdb->array); ++i ) + for( i = 0; i < ARRAYLENGTH(itemdb->array); ++i ) { if( itemdb->array[i] ) itemdb->destroy_item_data(itemdb->array[i], 1); + } for( i = 0; i < itemdb->group_count; i++ ) { if( itemdb->groups[i].nameid ) @@ -2155,7 +2135,8 @@ void itemdb_clear(bool total) { itemdb->package_count = 0; for(i = 0; i < itemdb->combo_count; i++) { - script->free_code(itemdb->combos[i]->script); + if( itemdb->combos[i]->script ) // Check if script was loaded + script->free_code(itemdb->combos[i]->script); aFree(itemdb->combos[i]); } if( itemdb->combos ) @@ -2245,7 +2226,7 @@ void itemdb_name_constants(void) { script->parser_current_file = NULL; #endif // ENABLE_CASE_CHECK - dbi_destroy(iter); + dbi_destroy(iter); } void do_final_itemdb(void) { itemdb->clear(true); @@ -2333,12 +2314,6 @@ void itemdb_defaults(void) { itemdb->isrestricted = itemdb_isrestricted; itemdb->isidentified = itemdb_isidentified; itemdb->isidentified2 = itemdb_isidentified2; - itemdb->read_itemavail = itemdb_read_itemavail; - itemdb->read_itemtrade = itemdb_read_itemtrade; - itemdb->read_itemdelay = itemdb_read_itemdelay; - itemdb->read_stack = itemdb_read_stack; - itemdb->read_buyingstore = itemdb_read_buyingstore; - itemdb->read_nouse = itemdb_read_nouse; itemdb->combo_split_atoi = itemdb_combo_split_atoi; itemdb->read_combos = itemdb_read_combos; itemdb->gendercheck = itemdb_gendercheck; @@ -2348,7 +2323,6 @@ void itemdb_defaults(void) { itemdb->readdb_libconfig = itemdb_readdb_libconfig; itemdb->readdb_sql = itemdb_readdb_sql; itemdb->unique_id = itemdb_unique_id; - itemdb->uid_load = itemdb_uid_load; itemdb->read = itemdb_read; itemdb->destroy_item_data = destroy_item_data; itemdb->final_sub = itemdb_final_sub; |