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.c562
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;