From c5c3381b0b8b0b59c669d474acf749db82d7edb1 Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Thu, 10 Oct 2013 12:25:22 -0300
Subject: Introducing Bank Support

http://hercules.ws/board/topic/2455-introducing-bank-support/
Thanks to Yommy, Haru!

Signed-off-by: shennetsind <ind@henn.et>
---
 sql-files/main.sql | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index 0e9dc5b67..dcb735129 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -657,6 +657,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1362794218);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1364409316);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1366075474);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1366078541);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1381354728);
 
 --
 -- Table structure for table `sstatus`
@@ -691,6 +692,10 @@ CREATE TABLE IF NOT EXISTS `storage` (
   KEY `account_id` (`account_id`)
 ) ENGINE=MyISAM;
 
+--
+-- Table structure for table `interreg`
+--
+
 CREATE TABLE IF NOT EXISTS `interreg` (
   `varname` varchar(11) NOT NULL,
   `value` varchar(20) NOT NULL,
@@ -698,3 +703,14 @@ CREATE TABLE IF NOT EXISTS `interreg` (
 ) ENGINE=InnoDB;
 INSERT INTO `interreg` (`varname`, `value`) VALUES
 ('unique_id', '0');
+
+--
+-- Table structure for table `account_data`
+--
+
+CREATE TABLE IF NOT EXISTS `account_data` (
+  `account_id` int(11) unsigned NOT NULL default '0',
+  `bank_vault` int(11) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`account_id`)
+) ENGINE=MyISAM; 
+
-- 
cgit v1.2.3-70-g09d2


From 80dfb11513812c7007f55c4b4b72c7f1cbee47f4 Mon Sep 17 00:00:00 2001
From: Streusel <m.me1@live.de>
Date: Thu, 10 Oct 2013 11:03:04 -0700
Subject: Follow up c5c3381

Thanks to QQfoolsorellina
---
 sql-files/main.sql | 1 +
 1 file changed, 1 insertion(+)

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index dcb735129..1f654ed14 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -658,6 +658,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1364409316);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1366075474);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1366078541);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1381354728);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1381423003);
 
 --
 -- Table structure for table `sstatus`
-- 
cgit v1.2.3-70-g09d2


From baef78f7954fa4e6fa2449f2c7de92a901c7f5f3 Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Sun, 27 Oct 2013 14:58:44 -0200
Subject: Shadows System Base

http://hercules.ws/board/topic/581-implement-the-shadows-system/

Special Thanks to Yommy for all the client data, Haru for making it possible to get it out and rosfus for the details on the feature.
Shadows Feature requires packetver 20120925 or newer.

----------
Also: Updated all packets related to the shadows system, improved memory/processing of inventory/cart/storage/viewequip packets

Signed-off-by: shennetsind <ind@henn.et>
---
 doc/item_db.txt                          |   6 +
 sql-files/main.sql                       |   9 +-
 sql-files/upgrades/2013-10-27--16-47.sql |   6 +
 sql-files/upgrades/index.txt             |   3 +-
 src/char/char.c                          |   8 +-
 src/common/mmo.h                         |  10 +-
 src/map/clif.c                           | 614 ++++++++++++-------------------
 src/map/clif.h                           |  27 +-
 src/map/packets_struct.h                 | 255 ++++++++++++-
 src/map/pc.c                             |  22 +-
 src/map/pc.h                             |  43 ++-
 src/map/pet.c                            |   2 +-
 12 files changed, 584 insertions(+), 421 deletions(-)
 create mode 100644 sql-files/upgrades/2013-10-27--16-47.sql

(limited to 'sql-files/main.sql')

diff --git a/doc/item_db.txt b/doc/item_db.txt
index 1cf92977c..145a17a33 100644
--- a/doc/item_db.txt
+++ b/doc/item_db.txt
@@ -105,6 +105,12 @@ Loc: Equipment's placement. Values are:
 	2^11 2048 = Costume Mid Headgear
 	2^12 4096 = Costume Low Headgear
 	2^13 8192 = Costume Garment/Robe
+	2^16 65536 = Shadow Armor 
+	2^17 131072 = Shadow Weapon 
+	2^18 262144 = Shadow Shield 
+	2^18 524288 = Shadow Shoes 
+	2^20 1048576 = Shadow Accessory 2 
+	2^21 2097152 = Shadow Accessory 1 
 
 wLV: Weapon level.
 
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 1f654ed14..8bd28c414 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -34,7 +34,7 @@ CREATE TABLE IF NOT EXISTS `cart_inventory` (
   `char_id` int(11) NOT NULL default '0',
   `nameid` int(11) NOT NULL default '0',
   `amount` int(11) NOT NULL default '0',
-  `equip` mediumint(8) unsigned NOT NULL default '0',
+  `equip` int(11) unsigned NOT NULL default '0',
   `identify` smallint(6) NOT NULL default '0',
   `refine` tinyint(3) unsigned NOT NULL default '0',
   `attribute` tinyint(4) NOT NULL default '0',
@@ -332,7 +332,7 @@ CREATE TABLE IF NOT EXISTS `guild_storage` (
   `guild_id` int(11) unsigned NOT NULL default '0',
   `nameid` int(11) unsigned NOT NULL default '0',
   `amount` int(11) unsigned NOT NULL default '0',
-  `equip` mediumint(8) unsigned NOT NULL default '0',
+  `equip` int(11) unsigned NOT NULL default '0',
   `identify` smallint(6) unsigned NOT NULL default '0',
   `refine` tinyint(3) unsigned NOT NULL default '0',
   `attribute` tinyint(4) unsigned NOT NULL default '0',
@@ -395,7 +395,7 @@ CREATE TABLE IF NOT EXISTS `inventory` (
   `char_id` int(11) unsigned NOT NULL default '0',
   `nameid` int(11) unsigned NOT NULL default '0',
   `amount` int(11) unsigned NOT NULL default '0',
-  `equip` mediumint(8) unsigned NOT NULL default '0',
+  `equip` int(11) unsigned NOT NULL default '0',
   `identify` smallint(6) NOT NULL default '0',
   `refine` tinyint(3) unsigned NOT NULL default '0',
   `attribute` tinyint(4) unsigned NOT NULL default '0',
@@ -659,6 +659,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1366075474);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1366078541);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1381354728);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1381423003);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1382892428);
 
 --
 -- Table structure for table `sstatus`
@@ -679,7 +680,7 @@ CREATE TABLE IF NOT EXISTS `storage` (
   `account_id` int(11) unsigned NOT NULL default '0',
   `nameid` int(11) unsigned NOT NULL default '0',
   `amount` smallint(11) unsigned NOT NULL default '0',
-  `equip` mediumint(8) unsigned NOT NULL default '0',
+  `equip` int(11) unsigned NOT NULL default '0',
   `identify` smallint(6) unsigned NOT NULL default '0',
   `refine` tinyint(3) unsigned NOT NULL default '0',
   `attribute` tinyint(4) unsigned NOT NULL default '0',
diff --git a/sql-files/upgrades/2013-10-27--16-47.sql b/sql-files/upgrades/2013-10-27--16-47.sql
new file mode 100644
index 000000000..e1a4a28f2
--- /dev/null
+++ b/sql-files/upgrades/2013-10-27--16-47.sql
@@ -0,0 +1,6 @@
+#1382892428
+ALTER TABLE `inventory` MODIFY `equip` int(11) unsigned NOT NULL default '0';
+ALTER TABLE `storage` MODIFY `equip` int(11) unsigned NOT NULL default '0';
+ALTER TABLE `cart_inventory` MODIFY `equip` int(11) unsigned NOT NULL default '0';
+ALTER TABLE `guild_storage` MODIFY `equip` int(11) unsigned NOT NULL default '0';
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1382892428);
\ No newline at end of file
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 2996a07f0..4afcc5a0d 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -5,4 +5,5 @@
 2013-03-09--01-56.sql
 2013-04-16--01-24.sql
 2013-10-09--21-38.sql
-2013-10-10--16-36.sql
\ No newline at end of file
+2013-10-10--16-36.sql
+2013-10-27--16-47.sql
\ No newline at end of file
diff --git a/src/char/char.c b/src/char/char.c
index 0b35c0143..950211894 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -742,7 +742,7 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 	SQL->StmtBindColumn(stmt, 0, SQLDT_INT,       &item.id,          0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT,     &item.nameid,      0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT,     &item.amount,      0, NULL, NULL);
-	SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT,    &item.equip,       0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 3, SQLDT_UINT,      &item.equip,       0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR,      &item.identify,    0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,      &item.refine,      0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
@@ -886,7 +886,7 @@ int inventory_to_sql(const struct item items[], int max, int id) {
 	SQL->StmtBindColumn(stmt, 0, SQLDT_INT,       &item.id,          0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT,     &item.nameid,      0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT,     &item.amount,      0, NULL, NULL);
-	SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT,    &item.equip,       0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 3, SQLDT_UINT,      &item.equip,       0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR,      &item.identify,    0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,      &item.refine,      0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
@@ -1241,7 +1241,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT,       &tmp_item.id, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT,     &tmp_item.nameid, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT,     &tmp_item.amount, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT,    &tmp_item.equip, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_UINT,      &tmp_item.equip, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR,      &tmp_item.identify, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,      &tmp_item.refine, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &tmp_item.attribute, 0, NULL, NULL)
@@ -1272,7 +1272,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT,         &tmp_item.id, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT,       &tmp_item.nameid, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT,       &tmp_item.amount, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT,      &tmp_item.equip, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_UINT,        &tmp_item.equip, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR,        &tmp_item.identify, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,        &tmp_item.refine, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,        &tmp_item.attribute, 0, NULL, NULL)
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 7977042d8..9281314dc 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -216,7 +216,7 @@ struct item {
 	int id;
 	short nameid;
 	short amount;
-	unsigned short equip; // Location(s) where item is equipped (using enum equip_pos for bitmasking).
+	unsigned int equip; // Location(s) where item is equipped (using enum equip_pos for bitmasking).
 	char identify;
 	char refine;
 	char attribute;
@@ -838,6 +838,14 @@ enum ammo_type {
 	A_THROWWEAPON	//9
 };
 
+/* packet size constant for itemlist */
+#if MAX_INVENTORY > MAX_STORAGE && MAX_INVENTORY > MAX_CART
+#define MAX_ITEMLIST MAX_INVENTORY
+#elif MAX_CART > MAX_INVENTORY && MAX_CART > MAX_STORAGE
+#define MAX_ITEMLIST MAX_CART
+#else
+#define MAX_ITEMLIST MAX_STORAGE
+#endif
 
 // sanity checks...
 #if MAX_ZENY > INT_MAX
diff --git a/src/map/clif.c b/src/map/clif.c
index 94fc6f7a7..a5cbbfd22 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -56,6 +56,13 @@
 
 struct clif_interface clif_s;
 
+/* re-usable */
+static struct packet_itemlist_normal itemlist_normal;
+static struct packet_itemlist_equip itemlist_equip;
+static struct packet_storelist_normal storelist_normal;
+static struct packet_storelist_equip storelist_equip;
+static struct packet_viewequip_ack viewequip_list;
+
 //#define DUMP_UNKNOWN_PACKET
 //#define DUMP_INVALID_PACKET
 
@@ -707,7 +714,7 @@ void clif_dropflooritem(struct flooritem_data* fitem) {
 #if PACKETVER >= 20130000 /* not sure date */
 	p.type = itemtype(itemdb_type(fitem->item_data.nameid));
 #endif
-	p.IsIdentified = fitem->item_data.identify;
+	p.IsIdentified = fitem->item_data.identify ? 1 : 0;
 	p.xPos = fitem->bl.x;
 	p.yPos = fitem->bl.y;
 	p.subX = fitem->subx;
@@ -900,7 +907,7 @@ void clif_set_unit_idle2(struct block_list* bl, struct map_session_data *tsd, en
 	p.GEmblemVer = status->get_emblem_id(bl);
 	p.honor = (sd) ? sd->status.manner : 0;
 	p.virtue = (sc) ? sc->opt3 : 0;
-	p.isPKModeON = (sd) ? sd->status.karma : 0;
+	p.isPKModeON = (sd && sd->status.karma) ? 1 : 0;
 	p.sex = vd->sex;
 	WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl));
 	p.xSize = p.ySize = (sd) ? 5 : 0;
@@ -965,7 +972,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
 	p.GEmblemVer = status->get_emblem_id(bl);
 	p.honor = (sd) ? sd->status.manner : 0;
 	p.virtue = (sc) ? sc->opt3 : 0;
-	p.isPKModeON = (sd) ? sd->status.karma : 0;
+	p.isPKModeON = (sd && sd->status.karma) ? 1 : 0;
 	p.sex = vd->sex;
 	WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl));
 	p.xSize = p.ySize = (sd) ? 5 : 0;
@@ -1034,7 +1041,7 @@ void clif_spawn_unit2(struct block_list* bl, enum send_target target) {
 	p.headpalette = vd->hair_color;
 	p.bodypalette = vd->cloth_color;
 	p.headDir = (sd)? sd->head_dir : 0;
-	p.isPKModeON = (sd) ? sd->status.karma : 0;
+	p.isPKModeON = (sd && sd->status.karma) ? 1 : 0;
 	p.sex = vd->sex;
 	WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl));
 	p.xSize = p.ySize = (sd) ? 5 : 0;
@@ -1094,7 +1101,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
 	p.GEmblemVer = status->get_emblem_id(bl);
 	p.honor = (sd) ? sd->status.manner : 0;
 	p.virtue = (sc) ? sc->opt3 : 0;
-	p.isPKModeON = (sd) ? sd->status.karma : 0;
+	p.isPKModeON = (sd && sd->status.karma) ? 1 : 0;
 	p.sex = vd->sex;
 	WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl));
 	p.xSize = p.ySize = (sd) ? 5 : 0;
@@ -1172,7 +1179,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
 	p.GEmblemVer = status->get_emblem_id(bl);
 	p.honor = (sd) ? sd->status.manner : 0;
 	p.virtue = (sc) ? sc->opt3 : 0;
-	p.isPKModeON = (sd) ? sd->status.karma : 0;
+	p.isPKModeON = (sd && sd->status.karma) ? 1 : 0;
 	p.sex = vd->sex;
 	WBUFPOS2(&p.MoveData[0],0,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
 	p.xSize = p.ySize = (sd) ? 5 : 0;
@@ -2198,8 +2205,8 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
 		else
 			p.nameid = sd->status.inventory[n].nameid;
 		
-		p.IsIdentified = sd->status.inventory[n].identify;
-		p.IsDamaged = sd->status.inventory[n].attribute;
+		p.IsIdentified = sd->status.inventory[n].identify ? 1 : 0;
+		p.IsDamaged = sd->status.inventory[n].attribute ? 1 : 0;
 		p.refiningLevel =sd->status.inventory[n].refine;
 		clif->addcards2(&p.slot.card[0], &sd->status.inventory[n]);
 		p.location = pc->equippoint(sd,n);
@@ -2290,311 +2297,220 @@ void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *
 	}
 
 }
-//Unified inventory function which sends all of the inventory (requires two packets, one for equipable items and one for stackable ones. [Skotlex]
-void clif_inventorylist(struct map_session_data *sd) {
-	int i,n,ne,arrow=-1;
-	unsigned char *buf;
-	unsigned char *bufe;
+void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *i, struct item_data *id, int eqp_pos) {
 
-#if PACKETVER < 5
-	const int s = 10; //Entry size.
-#elif PACKETVER < 20080102
-	const int s = 18;
-#else
-	const int s = 22;
-#endif
-#if PACKETVER < 20071002
-	const int se = 20;
-#elif PACKETVER < 20100629
-	const int se = 26;
-#else
-	const int se = 28;
-#endif
+	p->index = idx;
+	
+	if (id->view_id > 0)
+		p->ITID = id->view_id;
+	else
+		p->ITID = i->nameid;
 
-	buf = (unsigned char*)aMalloc(MAX_INVENTORY * s + 4);
-	bufe = (unsigned char*)aMalloc(MAX_INVENTORY * se + 4);
+	p->type = itemtype(id->type);
 
-	for( i = 0, n = 0, ne = 0; i < MAX_INVENTORY; i++ )
-	{
-		if( sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL )
-			continue;
+#if PACKETVER < 20120925
+	p->IsIdentified = i->identify ? 1 : 0;
+#endif
+	
+	p->location = eqp_pos;
+	p->WearState = i->equip;
+	
+#if PACKETVER < 20120925
+	p->IsDamaged = i->attribute ? 1 : 0;
+#endif
+	p->RefiningLevel = i->refine;
+	
+	clif->addcards2(&p->slot.card[0], i);
 
-		if( !itemdb->isstackable2(sd->inventory_data[i]) )
-		{	//Non-stackable (Equippable)
-			WBUFW(bufe,ne*se+4)=i+2;
-			clif->item_sub(bufe, ne*se+6, &sd->status.inventory[i], sd->inventory_data[i], pc->equippoint(sd,i));
-			clif->addcards(WBUFP(bufe, ne*se+16), &sd->status.inventory[i]);
 #if PACKETVER >= 20071002
-			WBUFL(bufe,ne*se+24)=sd->status.inventory[i].expire_time;
-			WBUFW(bufe,ne*se+28)=0; //Unknown
+	p->HireExpireDate = i->expire_time;
+#endif
+	
+#if PACKETVER >= 20080102
+	p->bindOnEquipType = 0;
 #endif
+
 #if PACKETVER >= 20100629
-			if (sd->inventory_data[i]->equip&EQP_VISIBLE)
-				WBUFW(bufe,ne*se+30)= sd->inventory_data[i]->look;
-			else
-				WBUFW(bufe,ne*se+30)=0;
+	p->wItemSpriteNumber = id->equip&EQP_VISIBLE ? id->look : 0;
 #endif
-			ne++;
-		}
-		else
-		{ //Stackable.
-			WBUFW(buf,n*s+4)=i+2;
-			clif->item_sub(buf, n*s+6, &sd->status.inventory[i], sd->inventory_data[i], -2);
-			if( sd->inventory_data[i]->equip == EQP_AMMO && sd->status.inventory[i].equip )
-				arrow=i;
+
+#if PACKETVER >= 20120925
+	p->Flag.IsIdentified = i->identify ? 1 : 0;
+	p->Flag.IsDamaged    = i->attribute ? 1 : 0;
+	p->Flag.PlaceETCTab  = i->favorite ? 1 : 0;
+	p->Flag.SpareBits    = 0;
+#endif
+}
+void clif_item_normal(short idx, struct NORMALITEM_INFO *p, struct item *i, struct item_data *id) {
+	p->index = idx;
+
+	if (id->view_id > 0)
+		p->ITID = id->view_id;
+	else
+		p->ITID = i->nameid;
+	
+	p->type = itemtype(id->type);
+	
+#if PACKETVER < 20120925
+	p->IsIdentified = i->identify ? 1 : 0;
+#endif
+	
+	p->count = i->amount;
+	p->WearState = id->equip;
+	
 #if PACKETVER >= 5
-			clif->addcards(WBUFP(buf, n*s+14), &sd->status.inventory[i]);
+	clif->addcards2(&p->slot.card[0], i);
 #endif
+	
 #if PACKETVER >= 20080102
-			WBUFL(buf,n*s+22)=sd->status.inventory[i].expire_time;
+	p->HireExpireDate = i->expire_time;
 #endif
-			n++;
-		}
-	}
-	if( n ) {
-#if PACKETVER < 5
-		WBUFW(buf,0)=0xa3;
-#elif PACKETVER < 20080102
-		WBUFW(buf,0)=0x1ee;
-#else
-		WBUFW(buf,0)=0x2e8;
+
+#if PACKETVER >= 20120925
+	p->Flag.IsIdentified = i->identify ? 1 : 0;
+	p->Flag.PlaceETCTab  = i->favorite ? 1 : 0;
+	p->Flag.SpareBits    = 0;
 #endif
-		WBUFW(buf,2)=4+n*s;
-		clif->send(buf, WBUFW(buf,2), &sd->bl, SELF);
+}
+void clif_inventorylist(struct map_session_data *sd) {
+	int i, normal = 0, equip = 0;
+		
+	for( i = 0; i < MAX_INVENTORY; i++ ) {
+		
+		if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL )
+			continue;
+		if( !itemdb->isstackable2(sd->inventory_data[i]) ) //Non-stackable (Equippable)
+			clif_item_equip(i+2,&itemlist_equip.list[equip++],&sd->status.inventory[i],sd->inventory_data[i],pc->equippoint(sd,i));
+		else //Stackable (Normal)
+			clif_item_normal(i+2,&itemlist_normal.list[normal++],&sd->status.inventory[i],sd->inventory_data[i]);
+	}
+	
+	if( normal ) {
+		itemlist_normal.PacketType   = inventorylistnormalType;
+		itemlist_normal.PacketLength = 4 + (sizeof(struct NORMALITEM_INFO) * normal);
+		
+		clif->send(&itemlist_normal, itemlist_normal.PacketLength, &sd->bl, SELF);
 	}
-	if( arrow >= 0 )
-		clif->arrowequip(sd,arrow);
+	
+	if( sd->equip_index[EQI_AMMO] >= 0 )
+		clif->arrowequip(sd,sd->equip_index[EQI_AMMO]);
+	
+	if( equip ) {
+		itemlist_equip.PacketType  = inventorylistequipType;
+		itemlist_equip.PacketLength = 4 + (sizeof(struct EQUIPITEM_INFO) * equip);
 
-	if( ne ) {
-#if PACKETVER < 20071002
-		WBUFW(bufe,0)=0xa4;
-#else
-		WBUFW(bufe,0)=0x2d0;
-#endif
-		WBUFW(bufe,2)=4+ne*se;
-		clif->send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
+		clif->send(&itemlist_equip, itemlist_equip.PacketLength, &sd->bl, SELF);
 	}
-#if PACKETVER >= 20111122
+/* on 20120925 onwards this is a field on clif_item_equip/normal */
+#if PACKETVER >= 20111122 && PACKETVER < 20120925
 	for( i = 0; i < MAX_INVENTORY; i++ ) {
 		if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL )
 			continue;
-
+		
 		if ( sd->status.inventory[i].favorite )
 			clif->favorite_item(sd, i);
 	}
 #endif
-
-	if( buf ) aFree(buf);
-	if( bufe ) aFree(bufe);
 }
 
 //Required when items break/get-repaired. Only sends equippable item list.
-void clif_equiplist(struct map_session_data *sd)
-{
-	int i,n,fd = sd->fd;
-	unsigned char *buf;
-#if PACKETVER < 20071002
-	const int cmd = 20;
-#elif PACKETVER < 20100629
-	const int cmd = 26;
-#else
-	const int cmd = 28;
-#endif
-
-	WFIFOHEAD(fd, MAX_INVENTORY * cmd + 4);
-	buf = WFIFOP(fd,0);
-
-	for(i=0,n=0;i<MAX_INVENTORY;i++){
-		if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL)
+void clif_equiplist(struct map_session_data *sd) {
+	int i, equip = 0;
+	
+	for( i = 0; i < MAX_INVENTORY; i++ ) {
+		
+		if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL )
 			continue;
-
-		if(itemdb->isstackable2(sd->inventory_data[i]))
+		if( !itemdb->isstackable2(sd->inventory_data[i]) ) //Non-stackable (Equippable)
+			clif_item_equip(i+2,&itemlist_equip.list[equip++],&sd->status.inventory[i],sd->inventory_data[i],pc->equippoint(sd,i));
+	}
+		
+	if( equip ) {
+		itemlist_equip.PacketType  = inventorylistequipType;
+		itemlist_equip.PacketLength = 4 + (sizeof(struct EQUIPITEM_INFO) * equip);
+		
+		clif->send(&itemlist_equip, itemlist_equip.PacketLength, &sd->bl, SELF);
+	}
+	
+	/* on 20120925 onwards this is a field on clif_item_equip */
+#if PACKETVER >= 20111122 && PACKETVER < 20120925
+	for( i = 0; i < MAX_INVENTORY; i++ ) {
+		if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL )
 			continue;
-		//Equippable
-		WBUFW(buf,n*cmd+4)=i+2;
-		clif->item_sub(buf, n*cmd+6, &sd->status.inventory[i], sd->inventory_data[i], pc->equippoint(sd,i));
-		clif->addcards(WBUFP(buf, n*cmd+16), &sd->status.inventory[i]);
-#if PACKETVER >= 20071002
-		WBUFL(buf,n*cmd+24)=sd->status.inventory[i].expire_time;
-		WBUFW(buf,n*cmd+28)=0; //Unknown
-#endif
-#if PACKETVER >= 20100629
-		if (sd->inventory_data[i]->equip&EQP_VISIBLE)
-			WBUFW(buf,n*cmd+30)= sd->inventory_data[i]->look;
-		else
-			WBUFW(buf,n*cmd+30)=0;
-#endif
-		n++;
+		
+		if ( sd->status.inventory[i].favorite )
+			clif->favorite_item(sd, i);
 	}
-	if (n) {
-#if PACKETVER < 20071002
-		WBUFW(buf,0)=0xa4;
-#else
-		WBUFW(buf,0)=0x2d0;
 #endif
-		WBUFW(buf,2)=4+n*cmd;
-		WFIFOSET(fd,WFIFOW(fd,2));
-	}
 }
 
-void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length)
-{
+void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length) {
+	int i, normal = 0, equip = 0;
 	struct item_data *id;
-	int i,n,ne;
-	unsigned char *buf;
-	unsigned char *bufe;
-#if PACKETVER < 5
-	const int s = 10; //Entry size.
-#elif PACKETVER < 20080102
-	const int s = 18;
-#else
-	const int s = 22;
-#endif
-#if PACKETVER < 20071002
-	const int cmd = 20;
-#elif PACKETVER < 20100629
-	const int cmd = 26;
-#else
-	const int cmd = 28;
-#endif
-
-	buf = (unsigned char*)aMalloc(items_length * s + 4);
-	bufe = (unsigned char*)aMalloc(items_length * cmd + 4);
-
-	for( i = 0, n = 0, ne = 0; i < items_length; i++ )
-	{
+	
+	for( i = 0; i < items_length; i++ ) {
+		
 		if( items[i].nameid <= 0 )
 			continue;
+		
 		id = itemdb->search(items[i].nameid);
-		if( !itemdb->isstackable2(id) )
-		{ //Equippable
-			WBUFW(bufe,ne*cmd+4)=i+1;
-			clif->item_sub(bufe, ne*cmd+6, &items[i], id, id->equip);
-			clif->addcards(WBUFP(bufe, ne*cmd+16), &items[i]);
-#if PACKETVER >= 20071002
-			WBUFL(bufe,ne*cmd+24)=items[i].expire_time;
-			WBUFW(bufe,ne*cmd+28)=0; //Unknown
-#endif
-			ne++;
-		}
-		else
-		{ //Stackable
-			WBUFW(buf,n*s+4)=i+1;
-			clif->item_sub(buf, n*s+6, &items[i], id,-1);
-#if PACKETVER >= 5
-			clif->addcards(WBUFP(buf,n*s+14), &items[i]);
-#endif
-#if PACKETVER >= 20080102
-			WBUFL(buf,n*s+22)=items[i].expire_time;
-#endif
-			n++;
-		}
+		if( !itemdb->isstackable2(id) ) //Non-stackable (Equippable)
+			clif_item_equip(i+1,&storelist_equip.list[equip++],&items[i],id,id->equip);
+		else //Stackable (Normal)
+			clif_item_normal(i+1,&storelist_normal.list[normal++],&items[i],id);
 	}
-	if( n )
-	{
-#if PACKETVER < 5
-		WBUFW(buf,0)=0xa5;
-#elif PACKETVER < 20080102
-		WBUFW(buf,0)=0x1f0;
-#else
-		WBUFW(buf,0)=0x2ea;
-#endif
-		WBUFW(buf,2)=4+n*s;
-		clif->send(buf, WBUFW(buf,2), &sd->bl, SELF);
+	
+	if( normal ) {
+		storelist_normal.PacketType   = storagelistnormalType;
+		storelist_normal.PacketLength =  ( sizeof( storelist_normal ) - ARRAYLENGTH( storelist_normal.list ) ) + (sizeof(struct NORMALITEM_INFO) * normal);
+#if PACKETVER >= 20120925
+		safestrncpy(storelist_normal.name, "Storage", NAME_LENGTH);
+#endif		
+		clif->send(&storelist_normal, storelist_normal.PacketLength, &sd->bl, SELF);
 	}
-	if( ne )
-	{
-#if PACKETVER < 20071002
-		WBUFW(bufe,0)=0xa6;
-#else
-		WBUFW(bufe,0)=0x2d1;
+		
+	if( equip ) {
+		storelist_equip.PacketType   = storagelistequipType;
+		storelist_equip.PacketLength = ( sizeof( storelist_equip ) - ARRAYLENGTH( storelist_equip.list ) ) + (sizeof(struct EQUIPITEM_INFO) * equip);
+
+#if PACKETVER >= 20120925
+		safestrncpy(storelist_equip.name, "Storage", NAME_LENGTH);
 #endif
-		WBUFW(bufe,2)=4+ne*cmd;
-		clif->send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
+		
+		clif->send(&storelist_equip, storelist_equip.PacketLength, &sd->bl, SELF);
 	}
-
-	if( buf ) aFree(buf);
-	if( bufe ) aFree(bufe);
 }
 
-void clif_cartlist(struct map_session_data *sd)
-{
+void clif_cartlist(struct map_session_data *sd) {
+	int i, normal = 0, equip = 0;
 	struct item_data *id;
-	int i,n,ne;
-	unsigned char *buf;
-	unsigned char *bufe;
-#if PACKETVER < 5
-	const int s = 10; //Entry size.
-#elif PACKETVER < 20080102
-	const int s = 18;
-#else
-	const int s = 22;
-#endif
-#if PACKETVER < 20071002
-	const int cmd = 20;
-#elif PACKETVER < 20100629
-	const int cmd = 26;
-#else
-	const int cmd = 28;
-#endif
-
-	buf = (unsigned char*)aMalloc(MAX_CART * s + 4);
-	bufe = (unsigned char*)aMalloc(MAX_CART * cmd + 4);
-
-	for( i = 0, n = 0, ne = 0; i < MAX_CART; i++ )
-	{
+	
+	for( i = 0; i < MAX_CART; i++ ) {
+		
 		if( sd->status.cart[i].nameid <= 0 )
 			continue;
+		
 		id = itemdb->search(sd->status.cart[i].nameid);
-		if( !itemdb->isstackable2(id) )
-		{ //Equippable
-			WBUFW(bufe,ne*cmd+4)=i+2;
-			clif->item_sub(bufe, ne*cmd+6, &sd->status.cart[i], id, id->equip);
-			clif->addcards(WBUFP(bufe, ne*cmd+16), &sd->status.cart[i]);
-#if PACKETVER >= 20071002
-			WBUFL(bufe,ne*cmd+24)=sd->status.cart[i].expire_time;
-			WBUFW(bufe,ne*cmd+28)=0; //Unknown
-#endif
-			ne++;
-		}
-		else
-		{ //Stackable
-			WBUFW(buf,n*s+4)=i+2;
-			clif->item_sub(buf, n*s+6, &sd->status.cart[i], id,-1);
-#if PACKETVER >= 5
-			clif->addcards(WBUFP(buf,n*s+14), &sd->status.cart[i]);
-#endif
-#if PACKETVER >= 20080102
-			WBUFL(buf,n*s+22)=sd->status.cart[i].expire_time;
-#endif
-			n++;
-		}
+		
+		if( !itemdb->isstackable2(id) ) //Non-stackable (Equippable)
+			clif_item_equip(i+2,&itemlist_equip.list[equip++],&sd->status.cart[i],id,id->equip);
+		else //Stackable (Normal)
+			clif_item_normal(i+2,&itemlist_normal.list[normal++],&sd->status.cart[i],id);
 	}
-	if( n )
-	{
-#if PACKETVER < 5
-		WBUFW(buf,0)=0x123;
-#elif PACKETVER < 20080102
-		WBUFW(buf,0)=0x1ef;
-#else
-		WBUFW(buf,0)=0x2e9;
-#endif
-		WBUFW(buf,2)=4+n*s;
-		clif->send(buf, WBUFW(buf,2), &sd->bl, SELF);
+	
+	if( normal ) {
+		itemlist_normal.PacketType   = cartlistnormalType;
+		itemlist_normal.PacketLength = 4 + (sizeof(struct NORMALITEM_INFO) * normal);
+		
+		clif->send(&itemlist_normal, itemlist_normal.PacketLength, &sd->bl, SELF);
 	}
-	if( ne )
-	{
-#if PACKETVER < 20071002
-	WBUFW(bufe,0)=0x122;
-#else
-	WBUFW(bufe,0)=0x2d2;
-#endif
-		WBUFW(bufe,2)=4+ne*cmd;
-		clif->send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
+		
+	if( equip ) {
+		itemlist_equip.PacketType  = cartlistequipType;
+		itemlist_equip.PacketLength = 4 + (sizeof(struct EQUIPITEM_INFO) * equip);
+		
+		clif->send(&itemlist_equip, itemlist_equip.PacketLength, &sd->bl, SELF);
 	}
-
-	if( buf ) aFree(buf);
-	if( bufe ) aFree(bufe);
 }
 
 
@@ -3528,52 +3444,39 @@ void clif_statusupack(struct map_session_data *sd,int type,int ok,int val)
 /// Notifies the client about the result of a request to equip an item (ZC_REQ_WEAR_EQUIP_ACK).
 /// 00aa <index>.W <equip location>.W <result>.B
 /// 00aa <index>.W <equip location>.W <view id>.W <result>.B (PACKETVER >= 20100629)
-/// result:
-///     0 = failure
-///     1 = success
-///     2 = failure due to low level
-void clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok)
-{
-	int fd;
+void clif_equipitemack(struct map_session_data *sd,int n,int pos,enum e_EQUIP_ITEM_ACK result) {
+	struct packet_equipitem_ack p;
 
 	nullpo_retv(sd);
 
-	fd=sd->fd;
-	WFIFOHEAD(fd,packet_len(0xaa));
-	WFIFOW(fd,0)=0xaa;
-	WFIFOW(fd,2)=n+2;
-	WFIFOW(fd,4)=pos;
-#if PACKETVER < 20100629
-	WFIFOB(fd,6)=ok;
-#else
-	if (ok && sd->inventory_data[n]->equip&EQP_VISIBLE)
-		WFIFOW(fd,6)=sd->inventory_data[n]->look;
+	p.PacketType = equipitemackType;
+	p.index = n+2;
+	p.wearLocation = pos;
+#if PACKETVER >= 20100629
+	if (result == EIA_SUCCESS && sd->inventory_data[n]->equip&EQP_VISIBLE)
+		p.wItemSpriteNumber = sd->inventory_data[n]->look;
 	else
-		WFIFOW(fd,6)=0;
-	WFIFOB(fd,8)=ok;
+		p.wItemSpriteNumber = 0;
 #endif
-	WFIFOSET(fd,packet_len(0xaa));
+	p.result = (unsigned char)result;
+	
+	clif->send(&p, sizeof(p), &sd->bl, SELF);
 }
 
 
 /// Notifies the client about the result of a request to take off an item (ZC_REQ_TAKEOFF_EQUIP_ACK).
 /// 00ac <index>.W <equip location>.W <result>.B
-/// result:
-///     0 = failure
-///     1 = success
-void clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok)
-{
-	int fd;
+void clif_unequipitemack(struct map_session_data *sd,int n,int pos,enum e_UNEQUIP_ITEM_ACK result) {
+	struct packet_unequipitem_ack p;
 
 	nullpo_retv(sd);
 
-	fd=sd->fd;
-	WFIFOHEAD(fd,packet_len(0xac));
-	WFIFOW(fd,0)=0xac;
-	WFIFOW(fd,2)=n+2;
-	WFIFOW(fd,4)=pos;
-	WFIFOB(fd,6)=ok;
-	WFIFOSET(fd,packet_len(0xac));
+	p.PacketType = unequipitemackType;
+	p.index = n+2;
+	p.wearLocation = pos;
+	p.result = (unsigned char)result;
+	
+	clif->send(&p, sizeof(p), &sd->bl, SELF);
 }
 
 
@@ -8951,69 +8854,41 @@ void clif_equpcheckbox(struct map_session_data* sd)
 /// 02d7 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE, PACKETVER >= 20100629)
 /// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE2, PACKETVER >= 20101124)
 /// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <robe>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE2, PACKETVER >= 20110111)
-void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd)
-{
-	uint8* buf;
-	int i, n, fd, offset = 0;
-#if PACKETVER < 20100629
-	const int s = 26;
-#else
-	const int s = 28;
-#endif
+void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd) {
+	int i, k, equip = 0;
+	
 	nullpo_retv(sd);
 	nullpo_retv(tsd);
-	fd = sd->fd;
-
-	WFIFOHEAD(fd, MAX_INVENTORY * s + 43);
-	buf = WFIFOP(fd,0);
+	
+	for( i = 0; i < EQI_MAX; i++ ) {
+		if( (k = tsd->equip_index[i]) >= 0 ) {
+			
+			if (tsd->status.inventory[k].nameid <= 0 || tsd->inventory_data[k] == NULL)	// Item doesn't exist
+				continue;
+			
+			clif_item_equip(k+2,&viewequip_list.list[equip++],&tsd->status.inventory[k],tsd->inventory_data[k],pc->equippoint(tsd,k));
 
-#if PACKETVER < 20101124
-	WBUFW(buf, 0) = 0x2d7;
-#else
-	WBUFW(buf, 0) = 0x859;
-#endif
-	safestrncpy((char*)WBUFP(buf, 4), tsd->status.name, NAME_LENGTH);
-	WBUFW(buf,28) = tsd->status.class_;
-	WBUFW(buf,30) = tsd->vd.hair_style;
-	WBUFW(buf,32) = tsd->vd.head_bottom;
-	WBUFW(buf,34) = tsd->vd.head_mid;
-	WBUFW(buf,36) = tsd->vd.head_top;
+		}
+	}
+		
+	viewequip_list.PacketType = viewequipackType;
+	viewequip_list.PacketLength = ( sizeof( viewequip_list ) - ARRAYLENGTH( viewequip_list.list ) ) + ( sizeof(struct EQUIPITEM_INFO) * equip );
+	
+	safestrncpy(viewequip_list.characterName, tsd->status.name, NAME_LENGTH);
+	
+	viewequip_list.job         = tsd->status.class_;
+	viewequip_list.head        = tsd->vd.hair_style;
+	viewequip_list.accessory   = tsd->vd.head_bottom;
+	viewequip_list.accessory2  = tsd->vd.head_mid;
+	viewequip_list.accessory3  = tsd->vd.head_top;
 #if PACKETVER >= 20110111
-	WBUFW(buf,38) = tsd->vd.robe;
-	offset+= 2;
-	buf = WBUFP(buf,2);
+	viewequip_list.robe        = tsd->vd.robe;
 #endif
-	WBUFW(buf,38) = tsd->vd.hair_color;
-	WBUFW(buf,40) = tsd->vd.cloth_color;
-	WBUFB(buf,42) = tsd->vd.sex;
-
-	for(i=0,n=0; i < MAX_INVENTORY; i++)
-	{
-		if (tsd->status.inventory[i].nameid <= 0 || tsd->inventory_data[i] == NULL)	// Item doesn't exist
-			continue;
-		if (!itemdb->isequip2(tsd->inventory_data[i])) // Is not equippable
-			continue;
-
-		// Inventory position
-		WBUFW(buf, n*s+43) = i + 2;
-		// Add refine, identify flag, element, etc.
-		clif->item_sub(WBUFP(buf,0), n*s+45, &tsd->status.inventory[i], tsd->inventory_data[i], pc->equippoint(tsd, i));
-		// Add cards
-		clif->addcards(WBUFP(buf, n*s+55), &tsd->status.inventory[i]);
-		// Expiration date stuff, if all of those are set to 0 then the client doesn't show anything related (6 bytes)
-		WBUFL(buf, n*s+63) = tsd->status.inventory[i].expire_time;
-		WBUFW(buf, n*s+67) = 0;
-#if PACKETVER >= 20100629
-		if (tsd->inventory_data[i]->equip&EQP_VISIBLE)
-			WBUFW(buf, n*s+69) = tsd->inventory_data[i]->look;
-		else
-			WBUFW(buf, n*s+69) = 0;
-#endif
-		n++;
-	}
-
-	WFIFOW(fd, 2) = 43+offset+n*s;	// Set length
-	WFIFOSET(fd, WFIFOW(fd, 2));
+	viewequip_list.headpalette = tsd->vd.hair_color;
+	viewequip_list.bodypalette = tsd->vd.cloth_color;
+	viewequip_list.sex         = tsd->vd.sex;
+	
+	clif->send(&viewequip_list, viewequip_list.PacketLength, &sd->bl, SELF);
 }
 
 
@@ -10653,18 +10528,19 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd)
 
 /// Request to equip an item (CZ_REQ_WEAR_EQUIP).
 /// 00a9 <index>.W <position>.W
-void clif_parse_EquipItem(int fd,struct map_session_data *sd)
-{
-	int index;
+/// 0998 <index>.W <position>.L
+void clif_parse_EquipItem(int fd,struct map_session_data *sd) {
+	struct packet_equip_item *p = P2PTR(fd);
 
 	if(pc_isdead(sd)) {
 		clif->clearunit_area(&sd->bl,CLR_DEAD);
 		return;
 	}
-	index = RFIFOW(fd,2)-2;
-	if (index < 0 || index >= MAX_INVENTORY)
-		return; //Out of bounds check.
 
+	p->index = p->index - 2;
+	if (p->index >= MAX_INVENTORY)
+		return; //Out of bounds check.
+	
 	if( sd->npc_id ) {
 		if ( !sd->npc_item_flag )
 			return;
@@ -10673,16 +10549,16 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd)
 	else if ( pc_cant_act2(sd) || sd->state.prerefining )
 		return;
 
-	if(!sd->status.inventory[index].identify) {
-		clif->equipitemack(sd,index,0,0);	// fail
+	if(!sd->status.inventory[p->index].identify) {
+		clif->equipitemack(sd,p->index,0,EIA_FAIL);// fail
 		return;
 	}
 
-	if(!sd->inventory_data[index])
+	if(!sd->inventory_data[p->index])
 		return;
 
-	if(sd->inventory_data[index]->type == IT_PETARMOR){
-		pet->equipitem(sd,index);
+	if(sd->inventory_data[p->index]->type == IT_PETARMOR){
+		pet->equipitem(sd,p->index);
 		return;
 	}
 
@@ -10690,10 +10566,10 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd)
 		sd->idletime = last_tick;
 	
 	//Client doesn't send the position for ammo.
-	if(sd->inventory_data[index]->type == IT_AMMO)
-		pc->equipitem(sd,index,EQP_AMMO);
+	if(sd->inventory_data[p->index]->type == IT_AMMO)
+		pc->equipitem(sd,p->index,EQP_AMMO);
 	else
-		pc->equipitem(sd,index,RFIFOW(fd,4));
+		pc->equipitem(sd,p->index,p->wearLocation);
 }
 
 void clif_hercules_chsys_delete(struct hChSysCh *channel) {
diff --git a/src/map/clif.h b/src/map/clif.h
index 6d0fc0fc1..57e55c3f7 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -426,6 +426,29 @@ enum e_BANKING_WITHDRAW_ACK {
 	BWA_UNKNOWN_ERROR = 0x2,
 };
 
+/* because the client devs were replaced by monkeys. */
+enum e_EQUIP_ITEM_ACK {
+#if PACKETVER >= 20120925
+	EIA_SUCCESS = 0x0,
+	EIA_FAIL_LV = 0x1,
+	EIA_FAIL    = 0x2,
+#else
+	EIA_SUCCESS = 0x1,
+	EIA_FAIL_LV = 0x2,
+	EIA_FAIL    = 0x0,
+#endif
+};
+
+/* and again. because the client devs were replaced by monkeys. */
+enum e_UNEQUIP_ITEM_ACK {
+#if PACKETVER >= 20120925
+	UIA_SUCCESS = 0x0,
+	UIA_FAIL    = 0x1,
+#else
+	UIA_SUCCESS = 0x1,
+	UIA_FAIL    = 0x0,
+#endif
+};
 
 /**
  * Structures
@@ -529,8 +552,8 @@ struct clif_interface {
 	void (*use_card) (struct map_session_data *sd,int idx);
 	void (*cart_additem) (struct map_session_data *sd,int n,int amount,int fail);
 	void (*cart_delitem) (struct map_session_data *sd,int n,int amount);
-	void (*equipitemack) (struct map_session_data *sd,int n,int pos,int ok);
-	void (*unequipitemack) (struct map_session_data *sd,int n,int pos,int ok);
+	void (*equipitemack) (struct map_session_data *sd,int n,int pos,enum e_EQUIP_ITEM_ACK result);
+	void (*unequipitemack) (struct map_session_data *sd,int n,int pos,enum e_UNEQUIP_ITEM_ACK result);
 	void (*useitemack) (struct map_session_data *sd,int index,int amount,bool ok);
 	void (*addcards) (unsigned char* buf, struct item* item);
 	void (*addcards2) (unsigned short *cards, struct item* item);
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 9d7282c92..e9a582582 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -8,12 +8,6 @@
 
 #include "../common/mmo.h"
 
-/**
- * structs for data
- */
-struct EQUIPSLOTINFO {
-	unsigned short card[4];
-};
 /**
  *
  **/
@@ -110,6 +104,82 @@ enum packet_headers {
 	dropflooritemType = 0x84b,
 #else
 	dropflooritemType = 0x9e,
+#endif
+#if PACKETVER >= 20120925
+	inventorylistnormalType = 0x991,
+#elif PACKETVER >= 20080102
+	inventorylistnormalType = 0x2e8,
+#elif PACKETVER >= 20071002
+	inventorylistnormalType = 0x1ee,
+#else
+	inventorylistnormalType = 0xa3,
+#endif
+#if PACKETVER >= 20120925
+	inventorylistequipType = 0x992,
+#elif PACKETVER >= 20080102
+	inventorylistequipType = 0x2d0,
+#elif PACKETVER >= 20071002
+	inventorylistequipType = 0x295,
+#else
+	inventorylistequipType = 0xa4,
+#endif
+#if PACKETVER >= 20120925
+	storagelistnormalType = 0x995,
+#elif PACKETVER >= 20080102
+	storagelistnormalType = 0x2ea,
+#elif PACKETVER >= 20071002
+	storagelistnormalType = 0x295,
+#else
+	storagelistnormalType = 0xa5,
+#endif
+#if PACKETVER >= 20120925
+	storagelistequipType = 0x996,
+#elif PACKETVER >= 20080102
+	storagelistequipType = 0x2d1,
+#elif PACKETVER >= 20071002
+	storagelistequipType = 0x296,
+#else
+	storagelistequipType = 0xa6,
+#endif
+#if PACKETVER >= 20120925
+	cartlistnormalType = 0x993,
+#elif PACKETVER >= 20080102
+	cartlistnormalType = 0x2e9,
+#elif PACKETVER >= 20071002
+	cartlistnormalType = 0x1ef,
+#else
+	cartlistnormalType = 0x123,
+#endif
+#if PACKETVER >= 20120925
+	cartlistequipType = 0x994,
+#elif PACKETVER >= 20080102
+	cartlistequipType = 0x2d2,
+#elif PACKETVER >= 20071002
+	cartlistequipType = 0x297,
+#else
+	cartlistequipType = 0x122,
+#endif
+#if PACKETVER >= 20120925
+	equipitemType = 0x998,
+#else
+	equipitemType = 0xa9,
+#endif
+#if PACKETVER >= 20120925
+	equipitemackType = 0x999,
+#else
+	equipitemackType = 0xaa,
+#endif
+#if PACKETVER >= 20120925
+	unequipitemackType = 0x99a,
+#else
+	unequipitemackType = 0xac,
+#endif
+#if PACKETVER >= 20120925
+	viewequipackType = 0x997,
+#elif PACKETVER >= 20101124
+	viewequipackType = 0x859,
+#else
+	viewequipackType = 0x2d7,
 #endif
 	monsterhpType = 0x977,
 	maptypeproperty2Type = 0x99b,
@@ -117,6 +187,79 @@ enum packet_headers {
 
 #pragma pack(push, 1)
 
+/**
+ * structs for data
+ */
+struct EQUIPSLOTINFO {
+	unsigned short card[4];
+} __attribute__((packed));
+
+struct NORMALITEM_INFO {
+	short index;
+	unsigned short ITID;
+	unsigned char type;
+#if PACKETVER < 20120925
+	uint8 IsIdentified;
+#endif
+	short count;
+#if PACKETVER >= 20120925
+	unsigned int WearState;
+#else
+	unsigned short WearState;
+#endif
+#if PACKETVER >= 5
+	struct EQUIPSLOTINFO slot;
+#endif
+#if PACKETVER >= 20080102
+	int HireExpireDate;
+#endif
+#if PACKETVER >= 20120925
+	struct {
+		unsigned int IsIdentified : 1;
+		unsigned int PlaceETCTab : 1;
+		unsigned int SpareBits : 6;
+	} Flag;
+#endif
+} __attribute__((packed));
+
+struct EQUIPITEM_INFO {
+	short index;
+	unsigned short ITID;
+	unsigned char type;
+#if PACKETVER < 20120925
+	uint8 IsIdentified;
+#endif
+#if PACKETVER >= 20120925
+	unsigned int location;
+	unsigned int WearState;
+#else
+	unsigned short location;
+	unsigned short WearState;
+#endif
+#if PACKETVER < 20120925
+	uint8 IsDamaged;
+#endif
+	unsigned char RefiningLevel;
+	struct EQUIPSLOTINFO slot;
+#if PACKETVER >= 20071002
+	int HireExpireDate;
+#endif
+#if PACKETVER >= 20080102
+    unsigned short bindOnEquipType;
+#endif
+#if PACKETVER >= 20100629
+    unsigned short wItemSpriteNumber;
+#endif
+#if PACKETVER >= 20120925
+	struct {
+		unsigned int IsIdentified : 1;
+		unsigned int IsDamaged : 1;
+		unsigned int PlaceETCTab : 1;
+		unsigned int SpareBits : 5;
+	} Flag;
+#endif
+} __attribute__((packed));
+
 struct packet_authok {
 	short PacketType;
 	unsigned int startTime;
@@ -147,8 +290,8 @@ struct packet_additem {
 	unsigned short Index;
 	unsigned short count;
 	unsigned short nameid;
-	bool IsIdentified;
-	bool IsDamaged;
+	uint8 IsIdentified;
+	uint8 IsDamaged;
 	unsigned char refiningLevel;
 	struct EQUIPSLOTINFO slot;
 #if PACKETVER >= 20120925
@@ -173,7 +316,7 @@ struct packet_dropflooritem {
 #if PACKETVER >= 20130000 /* not sure date */
 	unsigned short type;
 #endif
-	bool IsIdentified;
+	uint8 IsIdentified;
 	short xPos;
 	short yPos;
 	unsigned char subX;
@@ -205,7 +348,7 @@ struct packet_idle_unit2 {
 	short GEmblemVer;
 	short honor;
 	short virtue;
-	bool isPKModeON;
+	uint8 isPKModeON;
 	unsigned char sex;
 	unsigned char PosDir[3];
 	unsigned char xSize;
@@ -233,7 +376,7 @@ struct packet_spawn_unit2 {
 	short headpalette;
 	short bodypalette;
 	short headDir;
-	bool isPKModeON;
+	uint8 isPKModeON;
 	unsigned char sex;
 	unsigned char PosDir[3];
 	unsigned char xSize;
@@ -282,7 +425,7 @@ struct packet_spawn_unit {
 #else
 	short virtue;
 #endif
-	bool isPKModeON;
+	uint8 isPKModeON;
 	unsigned char sex;
 	unsigned char PosDir[3];
 	unsigned char xSize;
@@ -343,7 +486,7 @@ struct packet_unit_walking {
 #else
 	short virtue;
 #endif
-	bool isPKModeON;
+	uint8 isPKModeON;
 	unsigned char sex;
 	unsigned char MoveData[6];
 	unsigned char xSize;
@@ -401,7 +544,7 @@ struct packet_idle_unit {
 #else
 	short virtue;
 #endif
-	bool isPKModeON;
+	uint8 isPKModeON;
 	unsigned char sex;
 	unsigned char PosDir[3];
 	unsigned char xSize;
@@ -578,6 +721,90 @@ struct packet_banking_withdraw_ack {
 	int Balance;
 } __attribute__((packed));
 
+struct packet_itemlist_normal {
+	short PacketType;
+	short PacketLength;
+	struct NORMALITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct packet_itemlist_equip {
+	short PacketType;
+	short PacketLength;
+	struct EQUIPITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct packet_storelist_normal {
+	short PacketType;
+	short PacketLength;
+#if PACKETVER >= 20120925
+	char name[NAME_LENGTH];
+#endif
+	struct NORMALITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct packet_storelist_equip {
+	short PacketType;
+	short PacketLength;
+#if PACKETVER >= 20120925
+	char name[NAME_LENGTH];
+#endif
+	struct EQUIPITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct packet_equip_item {
+	short PacketType;
+	unsigned short index;
+#if PACKETVER >= 20120925
+	unsigned int wearLocation;
+#else
+	unsigned short wearLocation;
+#endif
+} __attribute__((packed));
+
+struct packet_equipitem_ack {
+	short PacketType;
+	unsigned short index;
+#if PACKETVER >= 20120925
+	unsigned int wearLocation;
+#else
+	unsigned short wearLocation;
+#endif
+#if PACKETVER >= 20100629
+	unsigned short wItemSpriteNumber;
+#endif
+	unsigned char result;
+} __attribute__((packed));
+
+struct packet_unequipitem_ack {
+	short PacketType;
+	unsigned short index;
+#if PACKETVER >= 20120925
+	unsigned int wearLocation;
+#else
+	unsigned short wearLocation;
+#endif
+	unsigned char result;
+} __attribute__((packed));
+
+struct packet_viewequip_ack {
+	short PacketType;
+	short PacketLength;
+	char characterName[NAME_LENGTH];
+	short job;
+	short head;
+	short accessory;
+	short accessory2;
+	short accessory3;
+#if PACKETVER >= 20101124
+	short robe;
+#endif
+	short headpalette;
+	short bodypalette;
+	unsigned char sex;
+	struct EQUIPITEM_INFO list[MAX_INVENTORY];
+} __attribute__((packed));
+
+
 #pragma pack(pop)
 
 #endif /* _PACKETS_STRUCT_H_ */
diff --git a/src/map/pc.c b/src/map/pc.c
index b39ae1c59..cbc1ed1d4 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -611,6 +611,8 @@ int pc_equippoint(struct map_session_data *sd,int n)
 		if(ep == EQP_HAND_R && (pc->checkskill(sd,AS_LEFT) > 0 || (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN ||
 			(sd->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO))//Kagerou and Oboro can dual wield daggers. [Rytech]
 			return EQP_ARMS;
+		if( ep == EQP_SHADOW_SHIELD )/* are there conditions for those? */
+			return EQP_SHADOW_WEAPON|EQP_SHADOW_SHIELD;
 	}
 	return ep;
 }
@@ -8526,13 +8528,13 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
 	nullpo_ret(sd);
 
 	if( n < 0 || n >= MAX_INVENTORY ) {
-		clif->equipitemack(sd,0,0,0);
+		clif->equipitemack(sd,0,0,EIA_FAIL);
 		return 0;
 	}
 
 	if( DIFF_TICK(sd->canequip_tick,timer->gettick()) > 0 )
 	{
-		clif->equipitemack(sd,n,0,0);
+		clif->equipitemack(sd,n,0,EIA_FAIL);
 		return 0;
 	}
 
@@ -8543,13 +8545,13 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
 		ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id?id->equip:0,req_pos);
 	if(!pc->isequip(sd,n) || !(pos&req_pos) || sd->status.inventory[n].equip != 0 || sd->status.inventory[n].attribute==1 ) { // [Valaris]
 		// FIXME: pc->isequip: equip level failure uses 2 instead of 0
-		clif->equipitemack(sd,n,0,0);	// fail
+		clif->equipitemack(sd,n,0,EIA_FAIL);	// fail
 		return 0;
 	}
 
 	if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER])
 	{
-		clif->equipitemack(sd,n,0,0);	// fail
+		clif->equipitemack(sd,n,0,EIA_FAIL);	// fail
 		return 0;
 	}
 
@@ -8589,7 +8591,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
 		clif->arrow_fail(sd,3);
 	}
 	else
-		clif->equipitemack(sd,n,pos,1);
+		clif->equipitemack(sd,n,pos,EIA_SUCCESS);
 
 	sd->status.inventory[n].equip=pos;
 
@@ -8738,20 +8740,20 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
 	nullpo_ret(sd);
 
 	if( n < 0 || n >= MAX_INVENTORY ) {
-		clif->unequipitemack(sd,0,0,0);
+		clif->unequipitemack(sd,0,0,UIA_FAIL);
 		return 0;
 	}
 
 	// if player is berserk then cannot unequip
 	if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER]))
 	{
-		clif->unequipitemack(sd,n,0,0);
+		clif->unequipitemack(sd,n,0,UIA_FAIL);
 		return 0;
 	}
 
 	if( !(flag&2) && sd->sc.count && sd->sc.data[SC_KYOUGAKU] )
 	{
-		clif->unequipitemack(sd,n,0,0);
+		clif->unequipitemack(sd,n,0,UIA_FAIL);
 		return 0;
 	}
 
@@ -8759,7 +8761,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
 		ShowInfo("unequip %d %x:%x\n",n,pc->equippoint(sd,n),sd->status.inventory[n].equip);
 
 	if(!sd->status.inventory[n].equip){ //Nothing to unequip
-		clif->unequipitemack(sd,n,0,0);
+		clif->unequipitemack(sd,n,0,UIA_FAIL);
 		return 0;
 	}
 	for(i=0;i<EQI_MAX;i++) {
@@ -8821,7 +8823,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
 		clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe);
 	}
 	
-	clif->unequipitemack(sd,n,sd->status.inventory[n].equip,1);
+	clif->unequipitemack(sd,n,sd->status.inventory[n].equip,UIA_SUCCESS);
 
 	if((sd->status.inventory[n].equip & EQP_ARMS) &&
 		sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_TK_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!)
diff --git a/src/map/pc.h b/src/map/pc.h
index ff6246b22..8d031bc04 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -47,6 +47,12 @@ enum equip_index {
 	EQI_COSTUME_MID,
 	EQI_COSTUME_LOW,
 	EQI_COSTUME_GARMENT,
+	EQI_SHADOW_ARMOR,
+	EQI_SHADOW_WEAPON,
+	EQI_SHADOW_SHIELD,
+	EQI_SHADOW_SHOES,
+	EQI_SHADOW_ACC_R,
+	EQI_SHADOW_ACC_L,
 	EQI_AMMO,
 	EQI_MAX
 };
@@ -526,21 +532,28 @@ struct map_session_data {
 
 //Equip position constants
 enum equip_pos {
-	EQP_HEAD_LOW         = 0x0001,
-	EQP_HEAD_MID         = 0x0200, //512
-	EQP_HEAD_TOP         = 0x0100, //256
-	EQP_HAND_R           = 0x0002, //2
-	EQP_HAND_L           = 0x0020, //32
-	EQP_ARMOR            = 0x0010, //16
-	EQP_SHOES            = 0x0040, //64
-	EQP_GARMENT          = 0x0004, //4
-	EQP_ACC_L            = 0x0008, //8
-	EQP_ACC_R            = 0x0080, //128
-	EQP_COSTUME_HEAD_TOP = 0x0400, //1024
-	EQP_COSTUME_HEAD_MID = 0x0800, //2048
-	EQP_COSTUME_HEAD_LOW = 0x1000, //4096
-	EQP_COSTUME_GARMENT	 = 0x2000, //8192
-	EQP_AMMO             = 0x8000, //32768
+	EQP_HEAD_LOW           = 0x000001,
+	EQP_HEAD_MID           = 0x000200, //512
+	EQP_HEAD_TOP           = 0x000100, //256
+	EQP_HAND_R             = 0x000002, //2
+	EQP_HAND_L             = 0x000020, //32
+	EQP_ARMOR              = 0x000010, //16
+	EQP_SHOES              = 0x000040, //64
+	EQP_GARMENT            = 0x000004, //4
+	EQP_ACC_L              = 0x000008, //8
+	EQP_ACC_R              = 0x000080, //128
+	EQP_COSTUME_HEAD_TOP   = 0x000400, //1024
+	EQP_COSTUME_HEAD_MID   = 0x000800, //2048
+	EQP_COSTUME_HEAD_LOW   = 0x001000, //4096
+	EQP_COSTUME_GARMENT	   = 0x002000, //8192
+	//UNUSED_COSTUME_FLOOR = 0x004000, //16384
+	EQP_AMMO               = 0x008000, //32768
+	EQP_SHADOW_ARMOR       = 0x010000, //65536
+	EQP_SHADOW_WEAPON      = 0x020000, //131072
+	EQP_SHADOW_SHIELD      = 0x040000, //262144
+	EQP_SHADOW_SHOES       = 0x080000, //524288
+	EQP_SHADOW_ACC_R       = 0x100000, //1048576
+	EQP_SHADOW_ACC_L       = 0x200000, //2097152
 };
 
 #define EQP_WEAPON EQP_HAND_R
diff --git a/src/map/pet.c b/src/map/pet.c
index 023059a6b..21ee488d0 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -656,7 +656,7 @@ int pet_equipitem(struct map_session_data *sd,int index) {
 	nameid = sd->status.inventory[index].nameid;
 	
 	if(pd->petDB->AcceID == 0 || nameid != pd->petDB->AcceID || pd->pet.equip != 0) {
-		clif->equipitemack(sd,0,0,0);
+		clif->equipitemack(sd,0,0,EIA_FAIL);
 		return 1;
 	}
 
-- 
cgit v1.2.3-70-g09d2


From 4340bf74d5fa64d8205bc86a3d2c0592b7a542c7 Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Wed, 30 Oct 2013 19:39:40 -0200
Subject: Official Font Support

Fonts are now relog-persistent.
Font items are now toggle-on/off, they no longer go away on use, they go away when their rental duration is over (and the font effect goes back to original).
Special Thanks to Yommy for all the data!

Signed-off-by: shennetsind <ind@henn.et>
---
 db/pre-re/item_db.txt                    | 18 +++++-----
 db/re/item_db.txt                        | 18 +++++-----
 sql-files/main.sql                       |  2 ++
 sql-files/upgrades/2013-10-30--21-12.sql |  3 ++
 sql-files/upgrades/index.txt             |  3 +-
 src/char/char.c                          | 17 +++++-----
 src/common/mmo.h                         |  2 ++
 src/map/atcommand.c                      |  8 ++---
 src/map/clif.c                           | 10 +++---
 src/map/itemdb.h                         |  9 +++++
 src/map/pc.c                             | 56 +++++++++++++++++++++++++++++++-
 src/map/pc.h                             |  1 -
 src/map/script.c                         |  6 ++--
 13 files changed, 112 insertions(+), 41 deletions(-)
 create mode 100644 sql-files/upgrades/2013-10-30--21-12.sql

(limited to 'sql-files/main.sql')

diff --git a/db/pre-re/item_db.txt b/db/pre-re/item_db.txt
index 4a8161dbc..6f6fee45c 100644
--- a/db/pre-re/item_db.txt
+++ b/db/pre-re/item_db.txt
@@ -4833,9 +4833,9 @@
 12284,Internet_Cafe3,Internet Cafe3,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ sc_start SC_INCINT,5400000,8; sc_start SC_INCVIT,5400000,4; sc_start SC_INCDEX,5400000,6; sc_start SC_PLUSMAGICPOWER,5400000,40; },{},{}
 12285,Internet_Cafe4,Internet Cafe4,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ sc_start SC_INCDEX,5400000,8; sc_start SC_INCLUK,5400000,4; sc_start SC_INCAGI,5400000,6; sc_start SC_PLUSATTACKPOWER,5400000,24; sc_start SC_PLUSMAGICPOWER,5400000,24; },{},{}
 12286,Masquerade_Ball_Box2,Masquerade Ball Box2,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ getrandgroupitem 12286,1; },{},{}
-12287,Love_Angel,Love Angel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 1; },{},{}
-12288,Squirrel,Squirrel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 2; },{},{}
-12289,Gogo,Gogo Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 3; },{},{}
+12287,Love_Angel,Love Angel Magic Powder,11,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 1; },{},{}
+12288,Squirrel,Squirrel Magic Powder,11,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 2; },{},{}
+12289,Gogo,Gogo Magic Powder,11,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 3; },{},{}
 12290,Mysterious_Can,Mysterious Can Magic Powder,2,10,,100,,,,,0xFFFFFFFF,7,2,,,,,,{ percentheal 5,0; skilleffect AL_BLESSING,0; sc_start SC_BLESSING,120000,5; },{},{}
 12291,Mysterious_PET_Bottle,Mysterious PET Bottle,2,10,,100,,,,,0xFFFFFFFF,7,2,,,,,,{ percentheal 5,0; skilleffect AL_INCAGI,0; sc_start SC_INC_AGI,120000,5; },{},{}
 12292,Unripe_Fruit,Unripe Fruit,0,500,,200,,,,,0xFFFFFFFF,7,2,,,,,,{ percentheal 20,0; },{},{}
@@ -4850,12 +4850,12 @@
 12301,Doppelganger_Scroll,Doppelganger Contract,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ mercenary_create 1966,1800000; },{},{}
 12302,Ygnizem_Scroll,Egnigem Cenia Contract,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ mercenary_create 1967,1800000; },{},{}
 12303,Water_Of_Blessing,Blessing Of Water,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{},{},{}
-12304,Picture_Diary,Diary Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 4; },{},{}
-12305,Mini_Heart,Mini Heart Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 5; },{},{}
-12306,Newcomer,Freshman Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 6; },{},{}
-12307,Kid,Kid Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 7; },{},{}
-12308,Magic_Castle,Magic Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 8; },{},{}
-12309,Bulging_Head,JJangu Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 9; },{},{}
+12304,Picture_Diary,Diary Magic Powder,11,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 4; },{},{}
+12305,Mini_Heart,Mini Heart Magic Powder,11,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 5; },{},{}
+12306,Newcomer,Freshman Magic Powder,11,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 6; },{},{}
+12307,Kid,Kid Magic Powder,11,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 7; },{},{}
+12308,Magic_Castle,Magic Magic Powder,11,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 8; },{},{}
+12309,Bulging_Head,JJangu Magic Powder,11,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 9; },{},{}
 12310,Spray_Of_Flowers,Spray Of Flowers,2,0,,50,,,,,0xFFFFFFFF,7,2,,,,,,{ sc_start SC_INCFLEE,600000,10; },{},{}
 12311,Large_Spray_Of_Flowers,Huge Spray Of Flowers,11,0,,100,,,,,0xFFFFFFFF,7,2,,,,,,{ itemskill ALL_PARTYFLEE,1; },{},{}
 12312,Thick_Manual50,Thick Battle Manual,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ sc_start SC_CASH_PLUSEXP,3600000,50; },{},{}
diff --git a/db/re/item_db.txt b/db/re/item_db.txt
index 5825034c8..98166f8bb 100644
--- a/db/re/item_db.txt
+++ b/db/re/item_db.txt
@@ -5609,9 +5609,9 @@
 12284,Internet_Cafe3,Internet Cafe3,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_INCINT,5400000,8; sc_start SC_INCVIT,5400000,4; sc_start SC_INCDEX,5400000,6; sc_start SC_PLUSMAGICPOWER,5400000,40; },{},{}
 12285,Internet_Cafe4,Internet Cafe4,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_INCDEX,5400000,8; sc_start SC_INCLUK,5400000,4; sc_start SC_INCAGI,5400000,6; sc_start SC_PLUSATTACKPOWER,5400000,24; sc_start SC_PLUSMAGICPOWER,5400000,24; },{},{}
 12286,Masquerade_Ball_Box2,Masquerade Ball Box2,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ getrandgroupitem 12286,1; },{},{}
-12287,Love_Angel,Love Angel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 1; },{},{}
-12288,Squirrel,Squirrel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 2; },{},{}
-12289,Gogo,Gogo Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 3; },{},{}
+12287,Love_Angel,Love Angel Magic Powder,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 1; },{},{}
+12288,Squirrel,Squirrel Magic Powder,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 2; },{},{}
+12289,Gogo,Gogo Magic Powder,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 3; },{},{}
 12290,Mysterious_Can,Mysterious Can Magic Powder,2,10,,100,,,,,0xFFFFFFFF,63,2,,,,,,{ percentheal 5,0; skilleffect AL_BLESSING,0; sc_start SC_BLESSING,120000,5; },{},{}
 12291,Mysterious_PET_Bottle,Mysterious PET Bottle,2,10,,100,,,,,0xFFFFFFFF,63,2,,,,,,{ percentheal 5,0; skilleffect AL_INCAGI,0; sc_start SC_INC_AGI,120000,5; },{},{}
 12292,Unripe_Fruit,Unripe Yggdrasilberry,0,500,,200,,,,,0xFFFFFFFF,63,2,,,,,,{ percentheal 20,0; },{},{}
@@ -5626,12 +5626,12 @@
 12301,Doppelganger_Scroll,Doppelganger Contract,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ mercenary_create 1966,1800000; },{},{}
 12302,Ygnizem_Scroll,Egnigem Cenia Contract,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ mercenary_create 1967,1800000; },{},{}
 12303,Water_Of_Blessing,Blessing Of Water,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{}
-12304,Picture_Diary,Diary Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 4; },{},{}
-12305,Mini_Heart,Mini Heart Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 5; },{},{}
-12306,Newcomer,Freshman Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 6; },{},{}
-12307,Kid,Kid Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 7; },{},{}
-12308,Magic_Castle,Magic Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 8; },{},{}
-12309,Bulging_Head,JJangu Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 9; },{},{}
+12304,Picture_Diary,Diary Magic Powder,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 4; },{},{}
+12305,Mini_Heart,Mini Heart Magic Powder,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 5; },{},{}
+12306,Newcomer,Freshman Magic Powder,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 6; },{},{}
+12307,Kid,Kid Magic Powder,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 7; },{},{}
+12308,Magic_Castle,Magic Magic Powder,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 8; },{},{}
+12309,Bulging_Head,JJangu Magic Powder,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 9; },{},{}
 12310,Spray_Of_Flowers,Spray Of Flowers,2,0,,50,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_INCFLEE,600000,10; },{},{}
 12311,Large_Spray_Of_Flowers,Huge Spray Of Flowers,11,0,,100,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill ALL_PARTYFLEE,1; },{},{}
 12312,Thick_Manual50,Thick Battle Manual,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_CASH_PLUSEXP,3600000,50; },{},{}
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 8bd28c414..2c91d58b1 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -108,6 +108,7 @@ CREATE TABLE IF NOT EXISTS `char` (
   `delete_date` INT(11) unsigned NOT NULL DEFAULT '0',
   `slotchange` SMALLINT(3) unsigned NOT NULL default '0',
   `char_opt` INT( 11 ) unsigned NOT NULL default '0',
+  `font` TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT  '0',
   PRIMARY KEY  (`char_id`),
   UNIQUE KEY `name_key` (`name`),
   KEY `account_id` (`account_id`),
@@ -660,6 +661,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1366078541);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1381354728);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1381423003);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1382892428);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383167577);
 
 --
 -- Table structure for table `sstatus`
diff --git a/sql-files/upgrades/2013-10-30--21-12.sql b/sql-files/upgrades/2013-10-30--21-12.sql
new file mode 100644
index 000000000..fdc16f418
--- /dev/null
+++ b/sql-files/upgrades/2013-10-30--21-12.sql
@@ -0,0 +1,3 @@
+#1383167577
+ALTER TABLE  `char` ADD  `font` TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT  '0';
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383167577);
\ No newline at end of file
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 4afcc5a0d..ca06e9c31 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -6,4 +6,5 @@
 2013-04-16--01-24.sql
 2013-10-09--21-38.sql
 2013-10-10--16-36.sql
-2013-10-27--16-47.sql
\ No newline at end of file
+2013-10-27--16-47.sql
+2013-10-30--21-12.sql
\ No newline at end of file
diff --git a/src/char/char.c b/src/char/char.c
index 310163e3a..4a04c521d 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -463,7 +463,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		(p->ele_id != cp->ele_id) || (p->shield != cp->shield) || (p->head_top != cp->head_top) ||
 		(p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || (p->delete_date != cp->delete_date) ||
 		(p->rename != cp->rename) || (p->slotchange != cp->slotchange) || (p->robe != cp->robe) ||
-		(p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party)
+		(p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font)
 	) {	//Save status
 		unsigned int opt = 0;
 		
@@ -479,7 +479,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 			"`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`elemental_id`='%d',"
 			"`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
 			"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
-			"`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u'"
+			"`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u'"
 			" WHERE  `account_id`='%d' AND `char_id` = '%d'",
 			char_db, p->base_level, p->job_level,
 			p->base_exp, p->job_exp, p->zeny,
@@ -490,7 +490,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 			mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y,
 			mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
 			(unsigned long)p->delete_date,  // FIXME: platform-dependent size
-			p->robe,p->slotchange,opt,
+			p->robe,p->slotchange,opt,p->font,
 			p->account_id, p->char_id) )
 		{
 			Sql_ShowDebug(sql_handle);
@@ -1052,7 +1052,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 30, SQLDT_SHORT,  &p.head_mid, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 31, SQLDT_SHORT,  &p.head_bottom, 0, NULL, NULL)
 	||  SQL_ERROR == SQL->StmtBindColumn(stmt, 32, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 33, SQLDT_USHORT,	&p.rename, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 33, SQLDT_USHORT, &p.rename, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 34, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 35, SQLDT_SHORT,  &p.robe, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 36, SQLDT_USHORT, &p.slotchange, 0, NULL, NULL)
@@ -1115,7 +1115,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 		"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,"
 		"`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
 		"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`,`slotchange`,"
-		"`char_opt`"
+		"`char_opt`,`font`"
 		" FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
 	||	SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0)
 	||	SQL_ERROR == SQL->StmtExecute(stmt)
@@ -1148,7 +1148,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 26, SQLDT_INT,    &p->guild_id, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 27, SQLDT_INT,    &p->pet_id, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 28, SQLDT_INT,    &p->hom_id, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 29, SQLDT_INT,	&p->ele_id, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 29, SQLDT_INT,    &p->ele_id, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 30, SQLDT_SHORT,  &p->hair, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 31, SQLDT_SHORT,  &p->hair_color, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 32, SQLDT_SHORT,  &p->clothes_color, 0, NULL, NULL)
@@ -1168,11 +1168,12 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 46, SQLDT_INT,    &p->mother, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 47, SQLDT_INT,    &p->child, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 48, SQLDT_INT,    &p->fame, 0, NULL, NULL)
-	||  SQL_ERROR == SQL->StmtBindColumn(stmt, 49, SQLDT_USHORT,	&p->rename, 0, NULL, NULL)
+	||  SQL_ERROR == SQL->StmtBindColumn(stmt, 49, SQLDT_USHORT, &p->rename, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 50, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 51, SQLDT_SHORT,  &p->robe, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 52, SQLDT_USHORT, &p->slotchange, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 53, SQLDT_UINT,	&opt, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 53, SQLDT_UINT,   &opt, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 54, SQLDT_UCHAR,  &p->font, 0, NULL, NULL)
 	)
 	{
 		SqlStmt_ShowDebug(stmt);
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 9281314dc..5f75f35da 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -414,6 +414,8 @@ struct mmo_charstatus {
 	unsigned short slotchange;
 
 	time_t delete_date;
+
+	unsigned char font;
 };
 
 typedef enum mail_status {
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 7ec589956..146159c63 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -8111,9 +8111,9 @@ ACMD(font) {
 	font_id = atoi(message);
 	if( font_id == 0 )
 	{
-		if( sd->user_font )
+		if( sd->status.font )
 		{
-			sd->user_font = 0;
+			sd->status.font = 0;
 			clif->message(fd, msg_txt(1356)); // Returning to normal font.
 			clif->font(sd);
 		}
@@ -8125,9 +8125,9 @@ ACMD(font) {
 	}
 	else if( font_id < 0 || font_id > 9 )
 		clif->message(fd, msg_txt(1359)); // Invalid font. Use a value from 0 to 9.
-	else if( font_id != sd->user_font )
+	else if( font_id != sd->status.font )
 	{
-		sd->user_font = font_id;
+		sd->status.font = font_id;
 		clif->font(sd);
 		clif->message(fd, msg_txt(1360)); // Font changed.
 	}
diff --git a/src/map/clif.c b/src/map/clif.c
index 957f75d99..c1e7cb1c9 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -611,7 +611,7 @@ void clif_authok(struct map_session_data *sd)
 	p.xSize = p.ySize = 5; /* not-used */
 	
 #if PACKETVER >= 20080102
-	p.font = sd->user_font;  // FIXME: Font is currently not saved.
+	p.font = sd->status.font;
 #endif
 	
 	clif->send(&p,sizeof(p),&sd->bl,SELF);
@@ -982,7 +982,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
 	p.state = vd->dead_sit;
 	p.clevel = clif_setlevel(bl);
 #if PACKETVER >= 20080102
-	p.font = (sd) ? sd->user_font : 0;
+	p.font = (sd) ? sd->status.font : 0;
 #endif
 #if PACKETVER >= 20140000 //actual 20120221
 	if( bl->type == BL_MOB ) {
@@ -1110,7 +1110,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
 	p.xSize = p.ySize = (sd) ? 5 : 0;
 	p.clevel = clif_setlevel(bl);
 #if PACKETVER >= 20080102
-	p.font = (sd) ? sd->user_font : 0;
+	p.font = (sd) ? sd->status.font : 0;
 #endif
 #if PACKETVER >= 20140000 //actual 20120221
 	if( bl->type == BL_MOB ) {
@@ -1188,7 +1188,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
 	p.xSize = p.ySize = (sd) ? 5 : 0;
 	p.clevel = clif_setlevel(bl);
 #if PACKETVER >= 20080102
-	p.font = (sd) ? sd->user_font : 0;
+	p.font = (sd) ? sd->status.font : 0;
 #endif
 #if PACKETVER >= 20140000 //actual 20120221
 	if( bl->type == BL_MOB ) {
@@ -16101,7 +16101,7 @@ void clif_font(struct map_session_data *sd)
 	nullpo_retv(sd);
 	WBUFW(buf,0) = 0x2ef;
 	WBUFL(buf,2) = sd->bl.id;
-	WBUFW(buf,6) = sd->user_font;
+	WBUFW(buf,6) = sd->status.font;
 	clif->send(buf, packet_len(0x2ef), &sd->bl, AREA);
 #endif
 }
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index 0f46c1c01..2579d84ca 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -48,6 +48,15 @@ enum item_itemid {
 	ITEMID_TRAP_ALLOY = 7940,
 	ITEMID_ANCILLA = 12333,
 	ITEMID_REINS_OF_MOUNT = 12622,
+	ITEMID_LOVE_ANGEL = 12287,
+	ITEMID_SQUIRREL = 12288,
+	ITEMID_GOGO = 12289,
+	ITEMID_PICTURE_DIARY = 12304,
+	ITEMID_MINI_HEART = 12305,
+	ITEMID_NEWCOMER = 12306,
+	ITEMID_KID = 12307,
+	ITEMID_MAGIC_CASTLE = 12308,
+	ITEMID_BULGING_HEAD = 12309,
 };
 
 /**
diff --git a/src/map/pc.c b/src/map/pc.c
index 0244c6c84..35d883b6f 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -446,12 +446,66 @@ int pc_inventory_rental_clear(struct map_session_data *sd)
 /* assumes i is valid (from default areas where it is called, it is) */
 void pc_rental_expire(struct map_session_data *sd, int i) {
 	short nameid = sd->status.inventory[i].nameid;
-	
+
 	/* Soon to be dropped, we got plans to integrate it with item db */
 	switch( nameid ) {
 		case ITEMID_REINS_OF_MOUNT:
 			status_change_end(&sd->bl,SC_ALL_RIDING,INVALID_TIMER);
 			break;
+		case ITEMID_LOVE_ANGEL:
+			if( sd->status.font == 1 ) {
+				sd->status.font = 0;
+				clif->font(sd);
+			}
+			break;
+		case ITEMID_SQUIRREL:
+			if( sd->status.font == 2 ) {
+				sd->status.font = 0;
+				clif->font(sd);
+			}
+			break;
+		case ITEMID_GOGO:
+			if( sd->status.font == 3 ) {
+				sd->status.font = 0;
+				clif->font(sd);
+			}
+			break;
+		case ITEMID_PICTURE_DIARY:
+			if( sd->status.font == 4 ) {
+				sd->status.font = 0;
+				clif->font(sd);
+			}
+			break;
+		case ITEMID_MINI_HEART:
+			if( sd->status.font == 5 ) {
+				sd->status.font = 0;
+				clif->font(sd);
+			}
+			break;
+		case ITEMID_NEWCOMER:
+			if( sd->status.font == 6 ) {
+				sd->status.font = 0;
+				clif->font(sd);
+			}
+			break;
+		case ITEMID_KID:
+			if( sd->status.font == 7 ) {
+				sd->status.font = 0;
+				clif->font(sd);
+			}
+			break;
+		case ITEMID_MAGIC_CASTLE:
+			if( sd->status.font == 8 ) {
+				sd->status.font = 0;
+				clif->font(sd);
+			}
+			break;
+		case ITEMID_BULGING_HEAD:
+			if( sd->status.font == 9 ) {
+				sd->status.font = 0;
+				clif->font(sd);
+			}
+			break;
 	}
 	
 	clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
diff --git a/src/map/pc.h b/src/map/pc.h
index 14e1da5f4..ddd3de1b9 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -449,7 +449,6 @@ struct map_session_data {
 	const char* debug_func;
 
 	unsigned int bg_id;
-	unsigned short user_font;
 
 	/**
 	 * For the Secure NPC Timeout option (check config/Secure.h) [RR]
diff --git a/src/map/script.c b/src/map/script.c
index 2a83f3918..d51f27ce9 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -16229,10 +16229,10 @@ BUILDIN(setfont)
 	if( sd == NULL )
 		return true;
 	
-	if( sd->user_font != font )
-		sd->user_font = font;
+	if( sd->status.font != font )
+		sd->status.font = font;
 	else
-		sd->user_font = 0;
+		sd->status.font = 0;
 	
 	clif->font(sd);
 	return true;
-- 
cgit v1.2.3-70-g09d2


From c47d8e4b8f9d63ab6b4e7e286e91cd50a5bdd151 Mon Sep 17 00:00:00 2001
From: sevenzz23 <sevenzz23@yahoo.com>
Date: Thu, 31 Oct 2013 12:07:06 +0700
Subject: No error after compilation, but when logging in at map server it will
 crash.

Im pretty sure its on the clif.c

Signed-off-by: sevenzz23 <sevenzz23@yahoo.com>
---
 conf/messages.conf                       |  41 +++++-
 doc/atcommands.txt                       |  16 +++
 doc/permissions.txt                      |   3 +-
 doc/script_commands.txt                  |  46 +++++++
 sql-files/main.sql                       |   4 +
 sql-files/upgrades/2013-10-31--07-49.sql |   4 +
 src/char/char.c                          |  94 +++++++------
 src/char/int_mail.c                      |   2 +
 src/char/int_storage.c                   | 167 +++++++++++++++++++---
 src/char/inter.c                         |   4 +-
 src/common/mmo.h                         |   6 +-
 src/config/core.h                        |   4 +
 src/map/atcommand.c                      |  78 ++++++++---
 src/map/buyingstore.c                    |   4 +-
 src/map/clif.c                           |  26 ++--
 src/map/guild.c                          |  52 +++++++
 src/map/guild.h                          |   4 +
 src/map/intif.c                          |  63 +++++++--
 src/map/intif.h                          |   4 +
 src/map/mail.c                           |   5 +-
 src/map/packets_struct.h                 |   1 +
 src/map/party.c                          |   9 +-
 src/map/pc.c                             |  59 ++++++--
 src/map/pc.h                             |   7 +-
 src/map/pc_groups.c                      |   1 +
 src/map/pc_groups.h                      |   3 +-
 src/map/script.c                         | 229 ++++++++++++++++++++++++++++++-
 src/map/storage.c                        |  17 ++-
 src/map/trade.c                          |   6 +
 src/map/vending.c                        |   3 +-
 30 files changed, 825 insertions(+), 137 deletions(-)
 create mode 100644 sql-files/upgrades/2013-10-31--07-49.sql

(limited to 'sql-files/main.sql')

diff --git a/conf/messages.conf b/conf/messages.conf
index 7b7a99301..d2e57bb0e 100644
--- a/conf/messages.conf
+++ b/conf/messages.conf
@@ -316,6 +316,13 @@
 290: The player is no longer killable.
 291: Weather effects will dispell on warp/refresh
 292: Killer state reset.
+//Item Bound System
+293: This bounded item cannot be traded to that character.
+294: This bounded item cannot be stored there.
+295: Please enter an item name or ID (usage: @item <item name/ID> <quantity> <bound_type>).
+296: Please enter all parameters (usage: @item2 <item name/ID> <quantity>
+297:   <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>).
+298: Invalid bound type. Valid types are - 1:Account 2:Guild 3:Party 4:Character
 // Guild Castles Number
 // --------------------
 //299: ?? Castles
@@ -455,6 +462,13 @@
 // Messages of others (not for GM commands)
 // ----------------------------------------
 
+// Account-Bound Items
+497: You cannot distribute this item - it is an account bounded item!
+
+// @itembound / @itembound2
+498: Cannot create bounded pet eggs or pet armors.
+499: Cannot create bounded stackable items.
+
 //500: FREE
 501: Your account time limit is: %d-%m-%Y %H:%M:%S.
 502: Day Mode is activated
@@ -711,11 +725,13 @@
 981: Please enter color and message (usage: @kamic <color> <message>).
 982: Invalid color.
 
-// @item
-983: Please enter an item name or ID (usage: @item <item name/ID> <quantity>).
 
-// @item2
-984: Please enter all parameters (usage: @item2 <item name/ID> <quantity>
+// @item / @itembound
+983: Please enter an item name or ID (usage: @%s <item name/ID> <quantity>).
+ 
+
+// @item2 / @itembound2
+984: Please enter all parameters (usage: @%s <item name/ID> <quantity>).
 985:   <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4>).
 
 // @baselevelup
@@ -1360,7 +1376,8 @@
 1361: Already using this font.
 
 // @new_mount
-1362: NOTICE: If you crash with mount your LUA is outdated.
+//1362: NOTICE: If you crash with mount your LUA is outdated.
+1362: ..
 1363: You have mounted.
 1364: You have released your mount.
 
@@ -1534,5 +1551,19 @@
 
 //CashShop mapflag
 1489: Cash Shop is disabled in this map
+
+// @autoloottype
+1490: You're already autolooting this item type.
+1491: Your autoloottype list has all item types. You can remove some items with @autoloottype -<type name or ID>.
+1492: Autolooting item type: '%s' {%d}
+1493: You're currently not autolooting this item type.
+1494: Removed item type: '%s' {%d} from your autoloottype list.
+1495: To add an item type to the list, use "@aloottype +<type name or ID>". To remove an item type, use "@aloottype -<type name or ID>".
+1496: Type List: healing = 0, usable = 2, etc = 3, weapon = 4, armor = 5, card = 6, petegg = 7, petarmor = 8, ammo = 10
+1497: "@aloottype reset" will clear your autoloottype list.
+1498: Your autoloottype list is empty.
+1499: Item types on your autoloottype list:
+1500: Your autoloottype list has been reset.
+
 //Custom translations
 import: conf/import/msg_conf.txt
diff --git a/doc/atcommands.txt b/doc/atcommands.txt
index 42b085cd6..a7377b563 100644
--- a/doc/atcommands.txt
+++ b/doc/atcommands.txt
@@ -625,6 +625,22 @@ Creates an item with the given parameters (the 'cards' can be any item).
 identify_flag: 0 = unidentified, 1 = identified
 attribute: 0 = not broken, 1 = broken
 
+---------------------------------------
+ 
+@itembound <item name/ID> <amount> <bound_type>
+
+Creates the specified item and bounds it to the account.
+bound_type: 1 = Account, 2 = Guild, 3 = Party, 4 = Character
+
+---------------------------------------
+
+@itembound2 <item name/ID> <quantity> <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>
+
+Creates an item with the given parameters (the 'cards' can be any item) and bounds it to the account.
+identify_flag: 0 = unidentified, 1 = identified
+attribute: 0 = not broken, 1 = broken
+bound_type: 1 = Account, 2 = Guild, 3 = Party, 4 = Character
+
 ---------------------------------------
 
 @produce <equip name/ID> <element> <# of Very's>
diff --git a/doc/permissions.txt b/doc/permissions.txt
index 9760f716c..c2aeba081 100644
--- a/doc/permissions.txt
+++ b/doc/permissions.txt
@@ -3,7 +3,7 @@
 //===== By: ==================================================
 //= Hercules Dev Team
 //===== Current Version: =====================================
-//= 20130528
+//= 20131031
 //===== Description: =========================================
 //= Player group permissions, configured in /conf/groups.conf.
 //============================================================
@@ -31,4 +31,5 @@ show_bossmobs : Ability to see boss mobs with @showmobs.
 disable_pvm : Ability to disable Player vs. Monster.
 disable_pvp : Ability to disable Player vs. Player.
 disable_commands_when_dead : Ability to disable @command usage when dead.
+can_trade_bounded : Ability to trade or otherwise distribute bounded items (drop, storage, vending etc...).
 hchsys_admin : Hercules Chat System Admin (Ability to modify channel settings regardless of ownership and join password-protected channels without requiring a password.)
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index bd0b032f1..23bacec5f 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -2781,6 +2781,7 @@ recreate these items perfectly if they are destroyed. Here's what you get:
 @inventorylist_expire[]    - expire time (Unix time stamp). 0 means never 
                              expires.
 @inventorylist_count       - the number of items in these lists.
+@inventorylist_bound       - whether it is an account bounded item or not.
 
 This could be handy to save/restore a character's inventory, since no 
 other command returns such a complete set of data, and could also be the
@@ -4448,6 +4449,51 @@ command, creating a pet which is the same, but simultaneously exists in
 two eggs, and may hatch from either, although, I'm not sure what kind of a 
 mess will this really cause.
 
+---------------------------------------
+*getitembound <item id>,<amount>,<bound type>{,<account ID>};
+*getitembound "<item name>",<amount>,<bound type>{,<account ID>};
+
+This command behaves identically to 'getitem', but the items created will be
+bound to the target character as specified by the bound type. All items created
+in this manner cannot be dropped, sold, vended, auctioned, or mailed, and in
+some cases cannot be traded or stored.
+
+Valid bound types are:
+ 1 - Account Bound
+ 2 - Guild Bound
+ 3 - Party Bound
+ 4 - Character Bound
+
+---------------------------------------
+
+*getitembound2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,<bound type>;
+*getitembound2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,<bound type>;
+
+This command behaves identically to 'getitem2', but the items created will be
+bound to the target character as specified by the bound type. All items created
+in this manner cannot be dropped, sold, vended, auctioned, or mailed, and in
+some cases cannot be traded or stored.
+
+For a list of bound types see 'getitembound'.
+
+---------------------------------------
+
+*countbound({<bound type>})
+
+This function will return the number of bounded items in the character's
+inventory, and sets an array @bound_items[] containing all item IDs of the
+counted items. If a bound type is specified, only those items will be counted.
+
+For a list of bound types see 'getitembound'.
+
+Example:
+	mes "You currently have "+countbound()+" bounded items.";
+	next;
+	mes "The list of bounded items include:";
+	for(set .@i,0; .@i<getarraysize(@bound_items); set .@i,.@i+1)
+		mes getitemname(@bound_items[.@i]);
+	close;
+
 ---------------------------------------
 
 *getnameditem <item id>,<character name|character ID>;
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 2c91d58b1..3f425d411 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -43,6 +43,7 @@ CREATE TABLE IF NOT EXISTS `cart_inventory` (
   `card2` smallint(11) NOT NULL default '0',
   `card3` smallint(11) NOT NULL default '0',
   `expire_time` int(11) unsigned NOT NULL default '0',
+  `bound` tinyint(1) unsigned NOT NULL default '0',
   `unique_id` bigint(20) unsigned NOT NULL default '0',
   PRIMARY KEY  (`id`),
   KEY `char_id` (`char_id`)
@@ -342,6 +343,7 @@ CREATE TABLE IF NOT EXISTS `guild_storage` (
   `card2` smallint(11) NOT NULL default '0',
   `card3` smallint(11) NOT NULL default '0',
   `expire_time` int(11) unsigned NOT NULL default '0',
+  `bound` tinyint(1) unsigned NOT NULL default '0',
   `unique_id` bigint(20) unsigned NOT NULL default '0',
   PRIMARY KEY  (`id`),
   KEY `guild_id` (`guild_id`)
@@ -406,6 +408,7 @@ CREATE TABLE IF NOT EXISTS `inventory` (
   `card3` smallint(11) NOT NULL default '0',
   `expire_time` int(11) unsigned NOT NULL default '0',
   `favorite` tinyint(3) unsigned NOT NULL default '0',
+  `bound` tinyint(1) unsigned NOT NULL default '0',
   `unique_id` bigint(20) unsigned NOT NULL default '0',
   PRIMARY KEY  (`id`),
   KEY `char_id` (`char_id`)
@@ -691,6 +694,7 @@ CREATE TABLE IF NOT EXISTS `storage` (
   `card2` smallint(11) NOT NULL default '0',
   `card3` smallint(11) NOT NULL default '0',
   `expire_time` int(11) unsigned NOT NULL default '0',
+  `bound` tinyint(1) unsigned NOT NULL default '0',
   `unique_id` bigint(20) unsigned NOT NULL default '0',
   PRIMARY KEY  (`id`),
   KEY `account_id` (`account_id`)
diff --git a/sql-files/upgrades/2013-10-31--07-49.sql b/sql-files/upgrades/2013-10-31--07-49.sql
new file mode 100644
index 000000000..40e0421c8
--- /dev/null
+++ b/sql-files/upgrades/2013-10-31--07-49.sql
@@ -0,0 +1,4 @@
+ALTER TABLE `inventory` ADD COLUMN `bound` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `favorite`;
+ALTER TABLE `cart_inventory` ADD COLUMN `bound` tinyint(1) UNSIGNED NOT NULL default '0' AFTER `expire_time`;
+ALTER TABLE `storage` ADD COLUMN `bound` tinyint(1) UNSIGNED NOT NULL default '0' AFTER `expire_time`;
+ALTER TABLE `guild_storage` ADD COLUMN `bound` TINYINT(3) UNSIGNED NOT NULL default '0' AFTER `expire_time`;
\ No newline at end of file
diff --git a/src/char/char.c b/src/char/char.c
index 4a04c521d..61a1e24e0 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -724,8 +724,8 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 	// it significantly reduces cpu load on the database server.
 
 	StrBuf->Init(&buf);
-	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`");
-	for( j = 0; j < MAX_SLOTS; ++j )
+	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`");
+ 	for( j = 0; j < MAX_SLOTS; ++j )
 		StrBuf->Printf(&buf, ", `card%d`", j);
 	StrBuf->Printf(&buf, " FROM `%s` WHERE `%s`='%d'", tablename, selectoption, id);
 
@@ -747,8 +747,9 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 	SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,      &item.refine,      0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
-	for( j = 0; j < MAX_SLOTS; ++j )
-		SQL->StmtBindColumn(stmt, 8+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 8, SQLDT_UINT,      &item.bound,       0, NULL, NULL);
+ 	for( j = 0; j < MAX_SLOTS; ++j )
+		SQL->StmtBindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
 
 	// bit array indicating which inventory items have already been matched
 	flag = (bool*) aCalloc(max, sizeof(bool));
@@ -775,17 +776,18 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 				    items[i].identify == item.identify &&
 				    items[i].refine == item.refine &&
 				    items[i].attribute == item.attribute &&
-				    items[i].expire_time == item.expire_time )
+				    items[i].expire_time == item.expire_time &&
+				    items[i].bound == item.bound )
 				;	//Do nothing.
 				else
 				{
 					// update all fields.
 					StrBuf->Clear(&buf);
-					StrBuf->Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u'",
-						tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time);
-					for( j = 0; j < MAX_SLOTS; ++j )
-						StrBuf->Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);
-					StrBuf->Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
+					StrBuf->Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `bound`='%d'",
+						tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].bound);
+ 					for( j = 0; j < MAX_SLOTS; ++j )for( j = 0; j < MAX_SLOTS; ++j )
+						StrBuf->Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);	
+ 					StrBuf->Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
 
 					if( SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) )
 					{
@@ -810,8 +812,8 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 	SQL->StmtFree(stmt);
 
 	StrBuf->Clear(&buf);
-	StrBuf->Printf(&buf, "INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `unique_id`", tablename, selectoption);
-	for( j = 0; j < MAX_SLOTS; ++j )
+	StrBuf->Printf(&buf, "INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", tablename, selectoption);
+ 	for( j = 0; j < MAX_SLOTS; ++j )
 		StrBuf->Printf(&buf, ", `card%d`", j);
 	StrBuf->AppendStr(&buf, ") VALUES ");
 
@@ -828,9 +830,9 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 		else
 			found = true;
 
-		StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%"PRIu64"'",
-			id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].unique_id);
-		for( j = 0; j < MAX_SLOTS; ++j )
+		StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%d', '%"PRIu64"'",
+			id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].bound, items[i].unique_id);
+ 		for( j = 0; j < MAX_SLOTS; ++j )
 			StrBuf->Printf(&buf, ", '%d'", items[i].card[j]);
 		StrBuf->AppendStr(&buf, ")");
 		
@@ -868,8 +870,8 @@ int inventory_to_sql(const struct item items[], int max, int id) {
 	// it significantly reduces cpu load on the database server.
 
 	StrBuf->Init(&buf);
-	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`");
-	for( j = 0; j < MAX_SLOTS; ++j )
+	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`");
+ 	for( j = 0; j < MAX_SLOTS; ++j )
 		StrBuf->Printf(&buf, ", `card%d`", j);
 	StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", inventory_db, id);
 
@@ -892,8 +894,9 @@ int inventory_to_sql(const struct item items[], int max, int id) {
 	SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 8, SQLDT_CHAR,      &item.favorite,    0, NULL, NULL);
-	for( j = 0; j < MAX_SLOTS; ++j )
-		SQL->StmtBindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 9, SQLDT_CHAR,      &item.bound,       0, NULL, NULL);
+ 	for( j = 0; j < MAX_SLOTS; ++j )
+		SQL->StmtBindColumn(stmt, 10+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
 
 	// bit array indicating which inventory items have already been matched
 	flag = (bool*) aCalloc(max, sizeof(bool));
@@ -919,15 +922,16 @@ int inventory_to_sql(const struct item items[], int max, int id) {
 				   items[i].refine == item.refine &&
 				   items[i].attribute == item.attribute &&
 				   items[i].expire_time == item.expire_time &&
-				   items[i].favorite == item.favorite )
+				   items[i].favorite == item.favorite &&
+				   items[i].bound == item.bound )
 					;	//Do nothing.
 				else {
 					// update all fields.
 					StrBuf->Clear(&buf);
-					StrBuf->Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `favorite`='%d'",
-									 inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite);
-					for( j = 0; j < MAX_SLOTS; ++j )
-						StrBuf->Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);
+					StrBuf->Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `favorite`='%d', `bound`='%d'",
+									 inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].bound);
+ 					for( j = 0; j < MAX_SLOTS; ++j )
+ 						StrBuf->Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);
 					StrBuf->Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
 
 					if( SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) ) {
@@ -950,8 +954,8 @@ int inventory_to_sql(const struct item items[], int max, int id) {
 	SQL->StmtFree(stmt);
 
 	StrBuf->Clear(&buf);
-	StrBuf->Printf(&buf, "INSERT INTO `%s` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `unique_id`", inventory_db);
-	for( j = 0; j < MAX_SLOTS; ++j )
+	StrBuf->Printf(&buf, "INSERT INTO `%s` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`", inventory_db);
+ 	for( j = 0; j < MAX_SLOTS; ++j )
 		StrBuf->Printf(&buf, ", `card%d`", j);
 	StrBuf->AppendStr(&buf, ") VALUES ");
 
@@ -967,9 +971,9 @@ int inventory_to_sql(const struct item items[], int max, int id) {
 		else
 			found = true;
 
-		StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%d', '%"PRIu64"'",
-						 id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].unique_id);
-		for( j = 0; j < MAX_SLOTS; ++j )
+		StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%d', '%d', '%"PRIu64"'",
+						 id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].bound, items[i].unique_id);
+ 		for( j = 0; j < MAX_SLOTS; ++j )
 			StrBuf->Printf(&buf, ", '%d'", items[i].card[j]);
 		StrBuf->AppendStr(&buf, ")");
 
@@ -1229,10 +1233,10 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	strcat(t_msg, " memo");
 
 	//read inventory
-	//`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, `expire_time`, `favorite`, `unique_id`)
-	StrBuf->Init(&buf);
-	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `unique_id`");
-	for( i = 0; i < MAX_SLOTS; ++i )
+	//`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, `expire_time`, `favorite`, `bound`, `unique_id`)
+ 	StrBuf->Init(&buf);
+	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`");
+ 	for( i = 0; i < MAX_SLOTS; ++i )
 		StrBuf->Printf(&buf, ", `card%d`", i);
 	StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", inventory_db, MAX_INVENTORY);
 
@@ -1248,10 +1252,11 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &tmp_item.attribute, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 7, SQLDT_UINT,      &tmp_item.expire_time, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_CHAR,      &tmp_item.favorite, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_ULONGLONG, &tmp_item.unique_id, 0, NULL, NULL) )
-		SqlStmt_ShowDebug(stmt);
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_CHAR,      &tmp_item.bound, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 10, SQLDT_ULONGLONG, &tmp_item.unique_id, 0, NULL, NULL) )
+ 		SqlStmt_ShowDebug(stmt);
 	for( i = 0; i < MAX_SLOTS; ++i )
-		if( SQL_ERROR == SQL->StmtBindColumn(stmt, 10+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
+		if( SQL_ERROR == SQL->StmtBindColumn(stmt, 11+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
 			SqlStmt_ShowDebug(stmt);
 
 	for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SQL->StmtNextRow(stmt); ++i )
@@ -1260,10 +1265,10 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	strcat(t_msg, " inventory");
 
 	//read cart
-	//`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, expire_time`, `unique_id`)
-	StrBuf->Clear(&buf);
-	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `unique_id`");
-	for( j = 0; j < MAX_SLOTS; ++j )
+	//`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, expire_time`, `bound`, `unique_id`)
+ 	StrBuf->Clear(&buf);
+	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`");
+ 	for( j = 0; j < MAX_SLOTS; ++j )
 		StrBuf->Printf(&buf, ", `card%d`", j);
 	StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", cart_db, MAX_CART);
 
@@ -1278,10 +1283,11 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,        &tmp_item.refine, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,        &tmp_item.attribute, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 7, SQLDT_UINT,        &tmp_item.expire_time, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_ULONGLONG,   &tmp_item.unique_id, 0, NULL, NULL) )
-		SqlStmt_ShowDebug(stmt);
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_CHAR,        &tmp_item.bound, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_ULONGLONG,   &tmp_item.unique_id, 0, NULL, NULL) )
+ 		SqlStmt_ShowDebug(stmt);
 	for( i = 0; i < MAX_SLOTS; ++i )
-		if( SQL_ERROR == SQL->StmtBindColumn(stmt, 9+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
+		if( SQL_ERROR == SQL->StmtBindColumn(stmt, 10+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
 			SqlStmt_ShowDebug(stmt);
 
 	for( i = 0; i < MAX_CART && SQL_SUCCESS == SQL->StmtNextRow(stmt); ++i )
@@ -2947,7 +2953,7 @@ int parse_frommap(int fd)
 					break;
 				}
 				//Check account only if this ain't final save. Final-save goes through because of the char-map reconnect
-				if (RFIFOB(fd,12) || (
+				if (RFIFOB(fd,12) || RFIFOB(fd,13) || (
 					(character = (struct online_char_data*)idb_get(online_char_db, aid)) != NULL &&
 					character->char_id == cid))
 				{
diff --git a/src/char/int_mail.c b/src/char/int_mail.c
index e4b88b5bf..b69824d4b 100644
--- a/src/char/int_mail.c
+++ b/src/char/int_mail.c
@@ -64,6 +64,7 @@ static int mail_fromsql(int char_id, struct mail_data* md)
 		SQL->GetData(sql_handle,14, &data, NULL); item->identify = atoi(data);
 		SQL->GetData(sql_handle,15, &data, NULL); item->unique_id = strtoull(data, NULL, 10);
 		item->expire_time = 0;
+		item->bound = 0;
 
 		for (j = 0; j < MAX_SLOTS; j++)
 		{
@@ -184,6 +185,7 @@ static bool mail_loadmessage(int mail_id, struct mail_message* msg)
 		SQL->GetData(sql_handle,14, &data, NULL); msg->item.identify = atoi(data);
 		SQL->GetData(sql_handle,15, &data, NULL); msg->item.unique_id = strtoull(data, NULL, 10);
 		msg->item.expire_time = 0;
+		msg->item.bound = 0;
 
 		for( j = 0; j < MAX_SLOTS; j++ )
 		{
diff --git a/src/char/int_storage.c b/src/char/int_storage.c
index 429b80105..6443aa743 100644
--- a/src/char/int_storage.c
+++ b/src/char/int_storage.c
@@ -39,8 +39,8 @@ int storage_fromsql(int account_id, struct storage_data* p)
 
 	// storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
 	StrBuf->Init(&buf);
-	StrBuf->AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`expire_time`,`unique_id`");
-	for( j = 0; j < MAX_SLOTS; ++j )
+	StrBuf->AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`expire_time`,`bound`,`unique_id`");
+ 	for( j = 0; j < MAX_SLOTS; ++j )
 		StrBuf->Printf(&buf, ",`card%d`", j);
 	StrBuf->Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id);
 
@@ -60,10 +60,11 @@ int storage_fromsql(int account_id, struct storage_data* p)
 		SQL->GetData(sql_handle, 5, &data, NULL); item->refine = atoi(data);
 		SQL->GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data);
 		SQL->GetData(sql_handle, 7, &data, NULL); item->expire_time = (unsigned int)atoi(data);
-		SQL->GetData(sql_handle, 8, &data, NULL); item->unique_id = strtoull(data, NULL, 10);
-		for( j = 0; j < MAX_SLOTS; ++j )
+		SQL->GetData(sql_handle, 8, &data, NULL); item->bound = atoi(data);
+		SQL->GetData(sql_handle, 9, &data, NULL); item->unique_id = strtoull(data, NULL, 10);
+ 		for( j = 0; j < MAX_SLOTS; ++j )
 		{
-			SQL->GetData(sql_handle, 9+j, &data, NULL); item->card[j] = atoi(data);
+			SQL->GetData(sql_handle, 10+j, &data, NULL); item->card[j] = atoi(data);
 		}
 	}
 	p->storage_amount = i;
@@ -96,8 +97,8 @@ int guild_storage_fromsql(int guild_id, struct guild_storage* p)
 
 	// storage {`guild_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
 	StrBuf->Init(&buf);
-	StrBuf->AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`unique_id`");
-	for( j = 0; j < MAX_SLOTS; ++j )
+	StrBuf->AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`bound`,`unique_id`");
+ 	for( j = 0; j < MAX_SLOTS; ++j )
 		StrBuf->Printf(&buf, ",`card%d`", j);
 	StrBuf->Printf(&buf, " FROM `%s` WHERE `guild_id`='%d' ORDER BY `nameid`", guild_storage_db, guild_id);
 
@@ -116,11 +117,13 @@ int guild_storage_fromsql(int guild_id, struct guild_storage* p)
 		SQL->GetData(sql_handle, 4, &data, NULL); item->identify = atoi(data);
 		SQL->GetData(sql_handle, 5, &data, NULL); item->refine = atoi(data);
 		SQL->GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data);
-		SQL->GetData(sql_handle, 7, &data, NULL); item->unique_id = strtoull(data, NULL, 10);
-		item->expire_time = 0;
+		SQL->GetData(sql_handle, 7, &data, NULL); item->bound = atoi(data);
+		SQL->GetData(sql_handle, 8, &data, NULL); item->unique_id = strtoull(data, NULL, 10);
+ 		item->expire_time = 0;
+		item->bound = 0;
 		for( j = 0; j < MAX_SLOTS; ++j )
 		{
-			SQL->GetData(sql_handle, 8+j, &data, NULL); item->card[j] = atoi(data);
+			SQL->GetData(sql_handle, 9+j, &data, NULL); item->card[j] = atoi(data);
 		}
 	}
 	p->storage_amount = i;
@@ -159,19 +162,20 @@ int inter_guild_storage_delete(int guild_id)
 //---------------------------------------------------------
 // packet from map server
 
-int mapif_load_guild_storage(int fd,int account_id,int guild_id)
+int mapif_load_guild_storage(int fd,int account_id,int guild_id, char flag)
 {
 	if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id) )
 		Sql_ShowDebug(sql_handle);
 	else if( SQL->NumRows(sql_handle) > 0 )
 	{// guild exists
-		WFIFOHEAD(fd, sizeof(struct guild_storage)+12);
+		WFIFOHEAD(fd, sizeof(struct guild_storage)+13);
 		WFIFOW(fd,0) = 0x3818;
-		WFIFOW(fd,2) = sizeof(struct guild_storage)+12;
+		WFIFOW(fd,2) = sizeof(struct guild_storage)+13;
 		WFIFOL(fd,4) = account_id;
 		WFIFOL(fd,8) = guild_id;
-		guild_storage_fromsql(guild_id, (struct guild_storage*)WFIFOP(fd,12));
-		WFIFOSET(fd, WFIFOW(fd,2));
+		WFIFOB(fd,12) = flag; //1 open storage, 0 don't open
+		guild_storage_fromsql(guild_id, (struct guild_storage*)WFIFOP(fd,13));
+ 		WFIFOSET(fd, WFIFOW(fd,2));
 		return 0;
 	}
 	// guild does not exist
@@ -201,7 +205,7 @@ int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
 int mapif_parse_LoadGuildStorage(int fd)
 {
 	RFIFOHEAD(fd);
-	mapif_load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6));
+	mapif_load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6),1);
 	return 0;
 }
 
@@ -235,6 +239,134 @@ int mapif_parse_SaveGuildStorage(int fd)
 	return 0;
 }
 
+#ifdef BOUND_ITEMS
+int mapif_itembound_ack(int fd, int aid, int guild_id)
+{
+	WFIFOHEAD(fd,8);
+	WFIFOW(fd,0) = 0x3856;
+	WFIFOL(fd,2) = aid;
+	WFIFOW(fd,6) = guild_id;
+	WFIFOSET(fd,8);
+	return 0;
+}
+
+//------------------------------------------------
+//Guild bound items pull for offline characters [Akinari]
+//Revised by [Mhalicot]
+//------------------------------------------------
+int mapif_parse_itembound_retrieve(int fd)
+{
+	StringBuf buf;
+	SqlStmt* stmt;
+	struct item item;
+	int j, i=0, s;
+	bool found=false;
+	struct item items[MAX_INVENTORY];
+	int char_id = RFIFOL(fd,2);
+	int aid = RFIFOL(fd,6);
+	int guild_id = RFIFOW(fd,10);
+
+	StrBuf->Init(&buf);
+	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`");
+	for( j = 0; j < MAX_SLOTS; ++j )
+		StrBuf->Printf(&buf, ", `card%d`", j);
+	StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`='%d'",inventory_db,char_id);
+
+	stmt = SQL->StmtMalloc(sql_handle);
+	if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
+	||  SQL_ERROR == SQL->StmtExecute(stmt) )
+	{
+		Sql_ShowDebug(sql_handle);
+		SQL->StmtFree(stmt);
+		StrBuf->Destroy(&buf);
+		return 1;
+	}
+
+	SQL->StmtBindColumn(stmt, 0, SQLDT_INT,       &item.id,          0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT,     &item.nameid,      0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT,     &item.amount,      0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT,    &item.equip,       0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR,      &item.identify,    0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,      &item.refine,      0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 8, SQLDT_UINT,      &item.bound,       0, NULL, NULL);
+	for( j = 0; j < MAX_SLOTS; ++j )
+		SQL->StmtBindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
+
+	while( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) {
+		if(item.bound == 2) {
+			memcpy(&items[i],&item,sizeof(struct item));
+			i++;
+		}
+	}
+	SQL->FreeResult(sql_handle);
+	
+	if(!i) { //No items found - No need to continue
+		StrBuf->Destroy(&buf);
+		SQL->StmtFree(stmt);
+		return 0;
+	}
+
+	//First we delete the character's items
+	StrBuf->Clear(&buf);
+	StrBuf->Printf(&buf, "DELETE FROM `%s` WHERE",inventory_db);
+	for(j=0; j<i; j++) {
+		if( found )
+			StrBuf->AppendStr(&buf, " OR");
+		else
+			found = true;
+		StrBuf->Printf(&buf, " `id`=%d",items[j].id);
+	}
+
+	if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
+	||  SQL_ERROR == SQL->StmtExecute(stmt) )
+	{
+		Sql_ShowDebug(sql_handle);
+		SQL->StmtFree(stmt);
+		StrBuf->Destroy(&buf);
+		return 1;
+	}
+
+	//Now let's update the guild storage with those deleted items
+	found = false;
+	StrBuf->Clear(&buf);
+	StrBuf->Printf(&buf, "INSERT INTO `%s` (`guild_id`, `nameid`, `amount`, `identify`, `refine`, `attribute`, `expire_time`, `bound`", guild_storage_db);
+	for( j = 0; j < MAX_SLOTS; ++j )
+		StrBuf->Printf(&buf, ", `card%d`", j);
+	StrBuf->AppendStr(&buf, ") VALUES ");
+	
+	for( j = 0; j < i; ++j ) {
+		if( found )
+			StrBuf->AppendStr(&buf, ",");
+		else
+			found = true;
+
+		StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d'",
+			guild_id, items[j].nameid, items[j].amount, items[j].identify, items[j].refine, items[j].attribute, items[j].expire_time, items[j].bound);
+		for( s = 0; s < MAX_SLOTS; ++s )
+			StrBuf->Printf(&buf, ", '%d'", items[j].card[s]);
+		StrBuf->AppendStr(&buf, ")");
+	}
+
+	if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
+	||  SQL_ERROR == SQL->StmtExecute(stmt) )
+	{
+		Sql_ShowDebug(sql_handle);
+		SQL->StmtFree(stmt);
+		StrBuf->Destroy(&buf);
+		return 1;
+	}
+
+	StrBuf->Destroy(&buf);
+	SQL->StmtFree(stmt);
+
+	//Finally reload storage and tell map we're done
+	mapif_load_guild_storage(fd,aid,guild_id,0);
+	mapif_itembound_ack(fd,aid,guild_id);
+	return 0;
+}
+#endif
 
 int inter_storage_parse_frommap(int fd)
 {
@@ -242,6 +374,9 @@ int inter_storage_parse_frommap(int fd)
 	switch(RFIFOW(fd,0)){
 	case 0x3018: mapif_parse_LoadGuildStorage(fd); break;
 	case 0x3019: mapif_parse_SaveGuildStorage(fd); break;
+#ifdef BOUND_ITEMS
+	case 0x3056: mapif_parse_itembound_retrieve(fd); break;
+#endif
 	default:
 		return 0;
 	}
diff --git a/src/char/inter.c b/src/char/inter.c
index 040246c31..54672faee 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -52,8 +52,8 @@ int inter_recv_packet_length[] = {
 	-1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0,  0, 0,  0, 0,	// 3020- Party
 	-1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1,	// 3030-
 	-1, 9, 0, 0,  0, 0, 0, 0,  7, 6,10,10, 10,-1,  0, 0,	// 3040-
-	-1,-1,10,10,  0,-1, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,	// 3050-  Auction System [Zephyrus]
-	 6,-1, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,	// 3060-  Quest system [Kevin] [Inkfish]
+	-1,-1,10,10,  0,-1, 12, 0,  0, 0, 0, 0,  0, 0,  0, 0,	// 3050-  Auction System [Zephyrus] [Mhalicot]
+ 	 6,-1, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,	// 3060-  Quest system [Kevin] [Inkfish]
 	-1,10, 6,-1,  0, 0, 0, 0,  0, 0, 0, 0, -1,10,  6,-1,	// 3070-  Mercenary packets [Zephyrus], Elemental packets [pakpil]
 	48,14,-1, 6,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,	// 3080-
 	-1,10,-1, 6,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,	// 3090-  Homunculus packets [albator]
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 5f75f35da..d5bf45adf 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -48,11 +48,11 @@
 // 20120307 - 2012-03-07aRagexeRE+ - 0x970
 
 #ifndef PACKETVER
-	#define PACKETVER 20120418
+	#define PACKETVER 20130807
 #endif
 
 // Comment the following line if your client is NOT ragexeRE (required because of conflicting packets in ragexe vs ragexeRE).
-#define PACKETVER_RE
+//#define PACKETVER_RE
 
 // Client support for experimental RagexeRE UI present in 2012-04-10 and 2012-04-18
 #ifdef PACKETVER_RE
@@ -222,7 +222,7 @@ struct item {
 	char attribute;
 	short card[MAX_SLOTS];
 	unsigned int expire_time;
-	char favorite;
+	char favorite, bound;
 	uint64 unique_id;
 };
 
diff --git a/src/config/core.h b/src/config/core.h
index b5ad1b794..481c35af8 100644
--- a/src/config/core.h
+++ b/src/config/core.h
@@ -61,6 +61,10 @@
 /// By enabling it, the system will create an unique id for each new non stackable item created
 //#define NSI_UNIQUE_ID
 
+/// Comment to disable Guild/Party Bound item system
+/// By default, we recover/remove Guild/Party Bound items automatically
+#define BOUND_ITEMS
+
 /// Uncomment to enable real-time server stats (in and out data and ram usage). [Ai4rei]
 //#define SHOW_SERVER_STATS
 
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 146159c63..2900fde03 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -1081,22 +1081,29 @@ ACMD(heal)
 
 /*==========================================
  * @item command (usage: @item <name/id_of_item> <quantity>) (modified by [Yor] for pet_egg)
+ * @itembound command (usage: @itembound <name/id_of_item> <quantity> <bound type>) (revised by [Mhalicot])
  *------------------------------------------*/
 ACMD(item)
 {
 	char item_name[100];
-	int number = 0, item_id, flag = 0;
+	int number = 0, item_id, flag = 0, bound = 0;
 	struct item item_tmp;
 	struct item_data *item_data;
 	int get_count, i;
 	
 	memset(item_name, '\0', sizeof(item_name));
-	
-	if (!message || !*message || (
-								  sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 &&
-								  sscanf(message, "%99s %d", item_name, &number) < 1
-								  )) {
-		clif->message(fd, msg_txt(983)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity>).
+
+	if (!strcmpi(command+1,"itembound") && (!message || !*message || (
+		sscanf(message, "\"%99[^\"]\" %d %d", item_name, &number, &bound) < 2 && 
+		sscanf(message, "%99s %d %d", item_name, &number, &bound) < 2 
+	))) {
+		clif->message(fd, msg_txt(295)); // Please enter an item name or ID (usage: @itembound <item name/ID> <quantity> <bound_type>).
+		return -1;
+	} else if (!message || !*message || (
+		sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 && 
+		sscanf(message, "%99s %d", item_name, &number) < 1 )) 
+		{
+ 		clif->message(fd, msg_txt(983)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity>).
 		return false;
 	}
 	
@@ -1110,11 +1117,24 @@ ACMD(item)
 		return false;
 	}
 	
+	if( bound < 0 || bound > 4 ) {
+		clif->message(fd, msg_txt(298)); // Invalid bound type
+		return false;
+	}
+
 	item_id = item_data->nameid;
 	get_count = number;
 	//Check if it's stackable.
-	if (!itemdb->isstackable2(item_data))
-		get_count = 1;
+	if (!itemdb->isstackable2(item_data)) {
+		if( bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) ) {
+			clif->message(fd, msg_txt(498)); // Cannot create bounded pet eggs or pet armors.
+			return false;
+		}
+ 		get_count = 1;
+	} else if( bound ) {
+		clif->message(fd, msg_txt(499)); // Cannot create bounded stackable items.
+		return false;
+	}
 	
 	for (i = 0; i < number; i += get_count) {
 		// if not pet egg
@@ -1122,6 +1142,7 @@ ACMD(item)
 			memset(&item_tmp, 0, sizeof(item_tmp));
 			item_tmp.nameid = item_id;
 			item_tmp.identify = 1;
+			item_tmp.bound = bound;
 			
 			if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
 				clif->additem(sd, 0, 0, flag);
@@ -1134,21 +1155,27 @@ ACMD(item)
 }
 
 /*==========================================
- *
+ * @item2 and @itembound2 command (revised by [Mhalicot])
  *------------------------------------------*/
 ACMD(item2)
 {
 	struct item item_tmp;
 	struct item_data *item_data;
 	char item_name[100];
-	int item_id, number = 0;
+	int item_id, number = 0, bound = 0;
 	int identify = 0, refine = 0, attr = 0;
 	int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 	
 	memset(item_name, '\0', sizeof(item_name));
 	
-	if (!message || !*message || (
-								  sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 &&
+	if (!strcmpi(command+1,"itembound2") && (!message || !*message || (
+		sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 &&
+		sscanf(message, "%99s %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 ))) {
+		clif->message(fd, msg_txt(296)); // Please enter all parameters (usage: @itembound2 <item name/ID> <quantity>
+		clif->message(fd, msg_txt(297)); //   <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>).
+		return false;
+	} else if ( !message || !*message || (
+ 								  sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 &&
 								  sscanf(message, "%99s %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9
 								  )) {
 		clif->message(fd, msg_txt(984)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity>
@@ -1158,7 +1185,12 @@ ACMD(item2)
 	
 	if (number <= 0)
 		number = 1;
-	
+
+	if( bound < 0 || bound > 4 ) {
+		clif->message(fd, msg_txt(298)); // Invalid bound type
+		return -1;
+	}
+
 	item_id = 0;
 	if ((item_data = itemdb->search_name(item_name)) != NULL ||
 	    (item_data = itemdb->exists(atoi(item_name))) != NULL)
@@ -1169,9 +1201,14 @@ ACMD(item2)
 		int loop, get_count, i;
 		loop = 1;
 		get_count = number;
-		if (item_data->type == IT_WEAPON || item_data->type == IT_ARMOR ||
-			item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) {
-			loop = number;
+		if( !strcmpi(command+1,"itembound2") )
+			bound = 1;
+		if( !itemdb->isstackable2(item_data) ) {
+			if( bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) ) {
+				clif->message(fd, msg_txt(498)); // Cannot create bounded pet eggs or pet armors.
+				return false;
+			}
+ 			loop = number;
 			get_count = 1;
 			if (item_data->type == IT_PETEGG) {
 				identify = 1;
@@ -1182,6 +1219,10 @@ ACMD(item2)
 			if (refine > MAX_REFINE)
 				refine = MAX_REFINE;
 		} else {
+			if( bound ) {
+				clif->message(fd, msg_txt(499)); // Cannot create bounded stackable items.
+				return false;
+			}
 			identify = 1;
 			refine = attr = 0;
 		}
@@ -1195,6 +1236,7 @@ ACMD(item2)
 			item_tmp.card[1] = c2;
 			item_tmp.card[2] = c3;
 			item_tmp.card[3] = c4;
+			item_tmp.bound = bound;
 			if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
 				clif->additem(sd, 0, 0, flag);
 		}
@@ -9230,6 +9272,8 @@ void atcommand_basecommands(void) {
 		ACMD_DEF(heal),
 		ACMD_DEF(item),
 		ACMD_DEF(item2),
+		ACMD_DEF2("itembound", item),
+		ACMD_DEF2("itembound2", item2),
 		ACMD_DEF(itemreset),
 		ACMD_DEF(clearstorage),
 		ACMD_DEF(cleargstorage),
diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c
index 2a9e6a88e..44ece49c6 100644
--- a/src/map/buyingstore.c
+++ b/src/map/buyingstore.c
@@ -290,8 +290,8 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int
 			return;
 		}
 
-		if( sd->status.inventory[index].expire_time || !itemdb_cantrade(&sd->status.inventory[index], pc->get_group_level(sd), pc->get_group_level(pl_sd)) || memcmp(sd->status.inventory[index].card, buyingstore->blankslots, sizeof(buyingstore->blankslots)) )
-		{// non-tradable item
+		if( sd->status.inventory[index].expire_time || (sd->status.inventory[index].bound && !pc->can_give_bounded_items(sd)) || !itemdb_cantrade(&sd->status.inventory[index], pc->get_group_level(sd), pc->get_group_level(pl_sd)) || memcmp(sd->status.inventory[index].card, buyingstore->blankslots, sizeof(buyingstore->blankslots)) )
+ 		{// non-tradable item
 			clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
 			return;
 		}
diff --git a/src/map/clif.c b/src/map/clif.c
index c1e7cb1c9..99f7c87d7 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1802,10 +1802,13 @@ void clif_selllist(struct map_session_data *sd)
 			if( !itemdb_cansell(&sd->status.inventory[i], pc->get_group_level(sd)) )
 				continue;
 
-			if( sd->status.inventory[i].expire_time )
-				continue; // Cannot Sell Rental Items
+			if( sd->status.inventory[i].expire_time || (sd->status.inventory[i].bound && !pc->can_give_bounded_items(sd)) )
+				continue; // Cannot Sell Rental Items or Account Bounded Items
+ 
+			if( sd->status.inventory[i].bound && !pc->can_give_bounded_items(sd))
+				continue; // Don't allow sale of bound items
 
-			val=sd->inventory_data[i]->value_sell;
+ 			val=sd->inventory_data[i]->value_sell;
 			if( val < 0 )
 				continue;
 			WFIFOW(fd,4+c*10)=i+2;
@@ -2229,7 +2232,7 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
 		p.HireExpireDate = sd->status.inventory[n].expire_time;
 #endif
 #if PACKETVER >= 20071002
-		p.bindOnEquipType = 0; // unused
+		p.bindOnEquipType = sd->status.inventory[n].bound ? 2 : 0;
 #endif
 	}
 	p.result = (unsigned char)fail;
@@ -2341,7 +2344,7 @@ void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *i, struct
 #endif
 	
 #if PACKETVER >= 20080102
-	p->bindOnEquipType = 0;
+	p->bindOnEquipType = i->bound ? 2 : 0;
 #endif
 
 #if PACKETVER >= 20100629
@@ -2378,6 +2381,7 @@ void clif_item_normal(short idx, struct NORMALITEM_INFO *p, struct item *i, stru
 	
 #if PACKETVER >= 20080102
 	p->HireExpireDate = i->expire_time;
+	p->bindOnEquipType = i->bound ? 2 : 0;
 #endif
 
 #if PACKETVER >= 20120925
@@ -15061,8 +15065,9 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd)
 
 	if( !pc->can_give_items(sd) || sd->status.inventory[idx].expire_time ||
 			!sd->status.inventory[idx].identify ||
-				!itemdb_canauction(&sd->status.inventory[idx],pc->get_group_level(sd)) ) { // Quest Item or something else
-		clif->auction_setitem(sd->fd, idx, true);
+				!itemdb_canauction(&sd->status.inventory[idx],pc->get_group_level(sd)) ||
+					(sd->status.inventory[idx].bound && !pc->can_give_bounded_items(sd)) ) { // Quest Item or something else
+ 		clif->auction_setitem(sd->fd, idx, true);
 		return;
 	}
 
@@ -15139,9 +15144,10 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
 	}
 
 	// Auction checks...
-	if( sd->status.zeny < (auction.hours * battle_config.auction_feeperhour) ) {
-		clif->auction_message(fd, 5); // You do not have enough zeny to pay the Auction Fee.
-		return;
+	if( sd->status.inventory[sd->auction.index].bound && !pc->can_give_bounded_items(sd) ) {
+		clif->message(sd->fd, msg_txt(293));
+		clif->auction_message(fd, 2); // The auction has been canceled
+ 		return;
 	}
 
 	if( auction.buynow > battle_config.auction_maximumprice )
diff --git a/src/map/guild.c b/src/map/guild.c
index 0ae45bede..517a49cc4 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -865,6 +865,11 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c
 	online_member_sd = guild->getavailablesd(g);
 	if(online_member_sd == NULL)
 		return 0; // noone online to inform
+		
+#ifdef BOUND_ITEMS
+	//Guild bound item check
+	guild->retrieveitembound(char_id,account_id,guild_id);
+#endif
 
 	if(!flag)
 		clif->guild_leave(online_member_sd, name, mes);
@@ -899,6 +904,41 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c
 	return 0;
 }
 
+#ifdef BOUND_ITEMS
+void guild_retrieveitembound(int char_id,int aid,int guild_id)
+{
+	TBL_PC *sd = map->id2sd(aid);
+	if(sd){ //Character is online
+		int idxlist[MAX_INVENTORY];
+		int j,i;
+		j = pc->bound_chk(sd,2,idxlist);
+		if(j) {	
+			struct guild_storage *gstor = gstorage->id2storage(guild_id);
+			for(i=0;i<j;i++) { //Loop the matching items, guild_storage_additem takes care of opening storage
+				if(gstor)
+					gstorage->additem(sd,gstor,&sd->status.inventory[idxlist[i]],sd->status.inventory[idxlist[i]].amount);
+				pc->delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,4,LOG_TYPE_GSTORAGE);
+			}
+			gstorage->close(sd); //Close and save the storage
+		}
+	}
+	else { //Character is offline, ask char server to do the job
+		struct guild_storage *gstor = gstorage->id2storage2(guild_id);
+		if(gstor && gstor->storage_status == 1) { //Someone is in guild storage, close them
+			struct s_mapiterator* iter = mapit_getallusers();
+			for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) {
+				if(sd->status.guild_id == guild_id && sd->state.storage_flag == 2) {
+					gstorage->close(sd);
+					break;
+				}
+			}
+			mapit->free(iter);
+		}
+		intif->itembound_req(char_id,aid,guild_id);
+	}
+}
+#endif
+
 int guild_send_memberinfoshort(struct map_session_data *sd,int online)
 { // cleaned up [LuzZza]
 	struct guild *g;
@@ -1813,6 +1853,11 @@ int guild_break(struct map_session_data *sd,char *name) {
 	struct guild *g;
 	struct unit_data *ud;
 	int i;
+	
+#ifdef BOUND_ITEMS
+	int j;
+	int idxlist[MAX_INVENTORY];
+#endif
 
 	nullpo_ret(sd);
 
@@ -1855,6 +1900,13 @@ int guild_break(struct map_session_data *sd,char *name) {
 			skill->del_unitgroup(groups[i],ALC_MARK);
 		}
 	}
+
+#ifdef BOUND_ITEMS
+	//Guild bound item check - Removes the bound flag
+	j = pc->bound_chk(sd,2,idxlist);
+	for(i=0;i<j;i++)
+		sd->status.inventory[idxlist[i]].bound = 0;
+#endif
 	
 	intif->guild_break(g->guild_id);
 	return 1;
diff --git a/src/map/guild.h b/src/map/guild.h
index 348a6c7e4..57148867a 100644
--- a/src/map/guild.h
+++ b/src/map/guild.h
@@ -147,6 +147,10 @@ struct guild_interface {
 	void (*flags_clear) (void);
 	/* guild aura */
 	void (*aura_refresh) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
+	/* item bound [Mhalicot]*/
+#ifdef BOUND_ITEMS
+	void (*retrieveitembound) (int char_id,int aid,int guild_id);
+#endif
 	/* */
 	int (*payexp_timer) (int tid, int64 tick, int id, intptr_t data);
 	TBL_PC* (*sd_check) (int guild_id, int account_id, int char_id);
diff --git a/src/map/intif.c b/src/map/intif.c
index f31ab0f5a..b8b16a356 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -982,15 +982,19 @@ void intif_parse_LoadGuildStorage(int fd)
 {
 	struct guild_storage *gstor;
 	struct map_session_data *sd;
-	int guild_id;
+	int guild_id, flag;
 
 	guild_id = RFIFOL(fd,8);
+	flag = RFIFOL(fd,12);
 	if(guild_id <= 0)
 		return;
 	sd=map->id2sd( RFIFOL(fd,4) );
-	if(sd==NULL){
-		ShowError("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4));
-		return;
+	if( flag ){ //If flag != 0, we attach a player and open the storage
+		if(sd==NULL){
+			ShowError("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4));
+			return;
+		}
+ 	
 	}
 	gstor=gstorage->id2storage(guild_id);
 	if(!gstor) {
@@ -998,20 +1002,21 @@ void intif_parse_LoadGuildStorage(int fd)
 		return;
 	}
 	if (gstor->storage_status == 1) { // Already open.. lets ignore this update
-		ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
-		return;
+		ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", flag?sd->status.account_id:1, flag?sd->status.char_id:1);
+ 		return;
 	}
 	if (gstor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex]
-		ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
-		return;
+		ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", flag?sd->status.account_id:1, flag?sd->status.char_id:1);
+ 		return;
 	}
-	if( RFIFOW(fd,2)-12 != sizeof(struct guild_storage) ){
-		ShowError("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-12 , sizeof(struct guild_storage));
-		gstor->storage_status = 0;
+	if( RFIFOW(fd,2)-13 != sizeof(struct guild_storage) ){
+		ShowError("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-13 , sizeof(struct guild_storage));
+ 		gstor->storage_status = 0;
 		return;
 	}
 
-	memcpy(gstor,RFIFOP(fd,12),sizeof(struct guild_storage));
+	memcpy(gstor,RFIFOP(fd,13),sizeof(struct guild_storage));
+	if( flag )
 	gstorage->open(sd);
 }
 
@@ -2005,7 +2010,31 @@ void intif_parse_MessageToFD(int fd) {
 
 	return;
 }
+/*==========================================
+ * Item Bound System [Xantara][Mhalicot]
+ *------------------------------------------*/
+#ifdef BOUND_ITEMS
+void intif_itembound_req(int char_id,int aid,int guild_id) {
+	struct guild_storage *gstor = gstorage->id2storage2(guild_id);
+	WFIFOHEAD(inter_fd,12);
+	WFIFOW(inter_fd,0) = 0x3056;
+	WFIFOL(inter_fd,2) = char_id;
+	WFIFOL(inter_fd,6) = aid;
+	WFIFOW(inter_fd,10) = guild_id;
+	WFIFOSET(inter_fd,12);
+	if(gstor)
+		gstor->lock = 1; //Lock for retrieval process
+}
+ 
+//3856
+void intif_parse_Itembound_ack(int fd) {
+	struct guild_storage *gstor;
+	int guild_id = RFIFOW(fd,6);
 
+	gstor = gstorage->id2storage2(guild_id);
+	if(gstor) gstor->lock = 0; //Unlock now that operation is completed
+}
+#endif
 //-----------------------------------------------------------------
 // Communication from the inter server
 // Return a 0 (false) if there were any errors.
@@ -2088,7 +2117,10 @@ int intif_parse(int fd)
 		case 0x3853:	intif->pAuctionClose(fd); break;
 		case 0x3854:	intif->pAuctionMessage(fd); break;
 		case 0x3855:	intif->pAuctionBid(fd); break;
-			
+		//Bound items
+#ifdef BOUND_ITEMS
+		case 0x3856:	intif->pItembound_ack(fd); break;
+#endif	
 		// Mercenary System
 		case 0x3870:	intif->pMercenaryReceived(fd); break;
 		case 0x3871:	intif->pMercenaryDeleted(fd); break;
@@ -2127,8 +2159,8 @@ void intif_defaults(void) {
 		39,-1,15,15, 14,19, 7,-1,  0, 0, 0, 0,  0, 0,  0, 0, //0x3820
 		10,-1,15, 0, 79,19, 7,-1,  0,-1,-1,-1, 14,67,186,-1, //0x3830
 		-1, 0, 0,14,  0, 0, 0, 0, -1,74,-1,11, 11,-1,  0, 0, //0x3840
-		-1,-1, 7, 7,  7,11, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3850  Auctions [Zephyrus]
-		-1, 7, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3860  Quests [Kevin] [Inkfish]
+		-1,-1, 7, 7,  7,11, 8, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3850  Auctions [Zephyrus] itembound[Akinari]
+ 		-1, 7, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3860  Quests [Kevin] [Inkfish]
 		-1, 3, 3, 0,  0, 0, 0, 0,  0, 0, 0, 0, -1, 3,  3, 0, //0x3870  Mercenaries [Zephyrus] / Elemental [pakpil]
 		11,-1, 7, 3,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3880
 		-1,-1, 7, 3,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3890  Homunculus [albator]
@@ -2263,6 +2295,7 @@ void intif_defaults(void) {
 	intif->pAuctionClose = intif_parse_AuctionClose;
 	intif->pAuctionMessage = intif_parse_AuctionMessage;
 	intif->pAuctionBid = intif_parse_AuctionBid;
+	intif->pItembound_ack = intif_parse_Itembound_ack;
 	intif->pMercenaryReceived = intif_parse_MercenaryReceived;
 	intif->pMercenaryDeleted = intif_parse_MercenaryDeleted;
 	intif->pMercenarySaved = intif_parse_MercenarySaved;
diff --git a/src/map/intif.h b/src/map/intif.h
index 768e735de..577d58923 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -75,6 +75,9 @@ struct intif_interface {
 	int (*guild_emblem) (int guild_id, int len, const char *data);
 	int (*guild_castle_dataload) (int num, int *castle_ids);
 	int (*guild_castle_datasave) (int castle_id, int index, int value);
+#ifdef BOUND_ITEMS
+	void (*itembound_req) (int char_id, int aid, int guild_id);
+#endif
 	int (*request_petdata) (int account_id, int char_id, int pet_id);
 	int (*save_petdata) (int account_id, struct s_pet *p);
 	int (*delete_petdata) (int pet_id);
@@ -161,6 +164,7 @@ struct intif_interface {
 	void (*pAuctionClose) (int fd);
 	void (*pAuctionMessage) (int fd);
 	void (*pAuctionBid) (int fd);
+	void (*pItembound_ack) (int fd);
 	void (*pMercenaryReceived) (int fd);
 	void (*pMercenaryDeleted) (int fd);
 	void (*pMercenarySaved) (int fd);
diff --git a/src/map/mail.c b/src/map/mail.c
index 2378cbe2a..6b1537d87 100644
--- a/src/map/mail.c
+++ b/src/map/mail.c
@@ -82,8 +82,9 @@ unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) {
 		if( amount < 0 || amount > sd->status.inventory[idx].amount )
 			return 1;
 		if( !pc->can_give_items(sd) || sd->status.inventory[idx].expire_time ||
-				!itemdb_canmail(&sd->status.inventory[idx],pc->get_group_level(sd)) )
-			return 1;
+		   		!itemdb_canmail(&sd->status.inventory[idx],pc->get_group_level(sd)) ||
+					(sd->status.inventory[idx].bound && !pc->can_give_bounded_items(sd)) )
+ 			return 1;
 
 		sd->mail.index = idx;
 		sd->mail.nameid = sd->status.inventory[idx].nameid;
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 813aebee0..e6f68ea4f 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -212,6 +212,7 @@ struct NORMALITEM_INFO {
 #endif
 #if PACKETVER >= 20080102
 	int HireExpireDate;
+	unsigned short bindOnEquipType;
 #endif
 #if PACKETVER >= 20120925
 	struct {
diff --git a/src/map/party.c b/src/map/party.c
index ab05c23f7..69b343fb7 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -547,7 +547,14 @@ int party_member_withdraw(int party_id, int account_id, int char_id)
 	}
 
 	if( sd && sd->status.party_id == party_id && sd->status.char_id == char_id ) {
-		sd->status.party_id = 0;
+#ifdef BOUND_ITEMS
+		int idxlist[MAX_INVENTORY]; //or malloc to reduce consumtion
+		int j,i;
+		j = pc->bound_chk(sd,3,idxlist);
+		for(i=0;i<j;i++)
+			pc->delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,1,LOG_TYPE_OTHER);
+#endif
+	sd->status.party_id = 0;
 		clif->charnameupdate(sd); //Update name display [Skotlex]
 		//TODO: hp bars should be cleared too
 		if( p->instances )
diff --git a/src/map/pc.c b/src/map/pc.c
index 35d883b6f..ba445b4f4 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -568,6 +568,14 @@ bool pc_can_give_items(struct map_session_data *sd)
 	return pc->has_permission(sd, PC_PERM_TRADE);
 }
 
+/**
+ * Determines if player can give / drop / trade / vend bounded items
+ */
+bool pc_can_give_bounded_items(struct map_session_data *sd)
+{
+	return pc->has_permission(sd, PC_PERM_TRADE_BOUNDED);
+}
+
 /*==========================================
  * prepares character for saving.
  *------------------------------------------*/
@@ -991,6 +999,10 @@ int pc_isequip(struct map_session_data *sd,int n)
  *------------------------------------------*/
 bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers) {
 	int i;
+#ifdef BOUND_ITEMS
+	int j;
+	int idxlist[MAX_INVENTORY];
+#endif
 	int64 tick = timer->gettick();
 	uint32 ip = session[sd->fd]->client_addr;
 
@@ -1190,7 +1202,15 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
 	 * Check if player have any item cooldowns on
 	 **/
 	pc->itemcd_do(sd,true);
-	
+
+#ifdef BOUND_ITEMS
+	// Party bound item check
+	if(sd->status.party_id == 0 && (j = pc->bound_chk(sd,3,idxlist))) { // Party was deleted while character offline
+		for(i=0;i<j;i++)
+			pc->delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,1,LOG_TYPE_OTHER);
+	}
+#endif
+
 	/* [Ind/Hercules] */
 	sd->sc_display = NULL;
 	sd->sc_display_count = 0;
@@ -3948,8 +3968,8 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
 	{ // Stackable | Non Rental
 		for( i = 0; i < MAX_INVENTORY; i++ )
 		{
-			if( sd->status.inventory[i].nameid == item_data->nameid && memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 )
-			{
+			if( sd->status.inventory[i].nameid == item_data->nameid && sd->status.inventory[i].bound == item_data->bound && memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 )
+ 			{
 				if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) )
 					return 5;
 				sd->status.inventory[i].amount += amount;
@@ -4500,8 +4520,8 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
 		return 1;
 	}
 
-	if( !itemdb_cancartstore(item_data, pc->get_group_level(sd)) )
-	{ // Check item trade restrictions	[Skotlex]
+	if( !itemdb_cancartstore(item_data, pc->get_group_level(sd)) || (item_data->bound > 1 && !pc->can_give_bounded_items(sd)))
+ 	{ // Check item trade restrictions	[Skotlex]
 		clif->message (sd->fd, msg_txt(264));
 		return 1;/* TODO: there is no official response to this? */
 	}
@@ -4513,8 +4533,8 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
 	if( itemdb->isstackable2(data) && !item_data->expire_time )
 	{
 		ARR_FIND( 0, MAX_CART, i,
-			sd->status.cart[i].nameid == item_data->nameid &&
-			sd->status.cart[i].card[0] == item_data->card[0] && sd->status.cart[i].card[1] == item_data->card[1] &&
+			sd->status.cart[i].nameid == item_data->nameid && sd->status.cart[i].bound == item_data->bound &&
+ 			sd->status.cart[i].card[0] == item_data->card[0] && sd->status.cart[i].card[1] == item_data->card[1] &&
 			sd->status.cart[i].card[2] == item_data->card[2] && sd->status.cart[i].card[3] == item_data->card[3] );
 	};
 
@@ -4647,7 +4667,25 @@ int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
 
 	return flag;
 }
-
+ /*==========================================
+ * Bound Item Check
+ * Type:
+ * 1 Account Bound
+ * 2 Guild Bound
+ * 3 Party Bound
+ * 4 Character Bound
+ *------------------------------------------*/
+int pc_bound_chk(TBL_PC *sd,int type,int *idxlist)
+{
+	int i=0, j=0;
+	for(i=0;i<MAX_INVENTORY;i++){
+		if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0 && sd->status.inventory[i].bound == type) {
+			idxlist[j] = i;
+			j++;
+		}
+	}
+	return j;
+}
 /*==========================================
  *  Display item stolen msg to player sd
  *------------------------------------------*/
@@ -7965,8 +8003,8 @@ int pc_setmadogear(TBL_PC* sd, int flag)
  *------------------------------------------*/
 int pc_candrop(struct map_session_data *sd, struct item *item)
 {
-	if( item && item->expire_time )
-		return 0;
+	if( item && (item->expire_time || (item->bound && !pc->can_give_bounded_items(sd))) )
+ 		return 0;
 	if( !pc->can_give_items(sd) ) //check if this GM level can drop items
 		return 0;
 	return (itemdb_isdropable(item, pc->get_group_level(sd)));
@@ -10293,6 +10331,7 @@ void pc_defaults(void) {
 	pc->class2idx = pc_class2idx;
 	pc->get_group_level = pc_get_group_level;
 	pc->can_give_items = pc_can_give_items;
+	pc->can_give_bounded_items = pc_can_give_bounded_items;
 	
 	pc->can_use_command = pc_can_use_command;
 	pc->has_permission = pc_has_permission;
diff --git a/src/map/pc.h b/src/map/pc.h
index fc37d0ef2..d517d8fcf 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -749,7 +749,8 @@ struct pc_interface {
 	int (*get_group_level) (struct map_session_data *sd);
 	//int (*getrefinebonus) (int lv,int type); FIXME: This function does not exist, nor it is ever called
 	bool (*can_give_items) (struct map_session_data *sd);
-	
+	bool (*can_give_bounded_items) (struct map_session_data *sd);
+ 	
 	bool (*can_use_command) (struct map_session_data *sd, const char *command);
 	bool (*has_permission) (struct map_session_data *sd, enum e_pc_permission permission);
 	int (*set_group) (struct map_session_data *sd, int group_id);
@@ -788,6 +789,10 @@ struct pc_interface {
 	int (*additem) (struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type);
 	int (*getzeny) (struct map_session_data *sd,int zeny, enum e_log_pick_type type, struct map_session_data *tsd);
 	int (*delitem) (struct map_session_data *sd,int n,int amount,int type, short reason, e_log_pick_type log_type);
+
+	//Bound items
+	int (*bound_chk) (TBL_PC *sd,int type,int *idxlist);
+
 	// Special Shop System
 	int (*paycash) (struct map_session_data *sd, int price, int points);
 	int (*getcash) (struct map_session_data *sd, int cash, int points);
diff --git a/src/map/pc_groups.c b/src/map/pc_groups.c
index be02b5f15..41bc19cba 100644
--- a/src/map/pc_groups.c
+++ b/src/map/pc_groups.c
@@ -55,6 +55,7 @@ const struct pc_permission_name_table pc_g_permission_name[NUM_PC_PERM] = {
 	{ "disable_pvp", PC_PERM_DISABLE_PVP },
 	{ "disable_commands_when_dead", PC_PERM_DISABLE_CMD_DEAD },
 	{ "hchsys_admin", PC_PERM_HCHSYS_ADMIN },
+	{ "can_trade_bounded", PC_PERM_TRADE_BOUNDED },
 };
 
 static DBMap* pc_group_db; // id -> GroupSettings
diff --git a/src/map/pc_groups.h b/src/map/pc_groups.h
index 8f350c2b6..63e7acc51 100644
--- a/src/map/pc_groups.h
+++ b/src/map/pc_groups.h
@@ -30,6 +30,7 @@ enum e_pc_permission {
 	PC_PERM_DISABLE_PVP         = 0x080000, // #20
 	PC_PERM_DISABLE_CMD_DEAD    = 0x100000,
 	PC_PERM_HCHSYS_ADMIN        = 0x200000,
+	PC_PERM_TRADE_BOUNDED		= 0x400000,
 };
 
 /// Total number of PC permissions (without PC_PERM_NONE).
@@ -37,7 +38,7 @@ enum e_pc_permission {
 /// so it's possible to apply sizeof to it [C-FAQ 1.24]
 /// Whenever adding new permission: 1. add enum entry above, 2. add entry into
 /// pc_g_permission_name (in pc.c), 3. increase NUM_PC_PERM below by 1.
-#define NUM_PC_PERM 22
+#define NUM_PC_PERM 23
 
 struct pc_permission_name_table {
 	const char *name;
diff --git a/src/map/script.c b/src/map/script.c
index d51f27ce9..174d12316 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -5946,6 +5946,7 @@ BUILDIN(rentitem)
 	it.nameid = nameid;
 	it.identify = 1;
 	it.expire_time = (unsigned int)(time(NULL) + seconds);
+	it.bound = 0;
 	
 	if( (flag = pc->additem(sd, &it, 1, LOG_TYPE_SCRIPT)) )
 	{
@@ -10850,6 +10851,7 @@ BUILDIN(successremovecards) {
 		item_tmp.refine      = sd->status.inventory[i].refine;
 		item_tmp.attribute   = sd->status.inventory[i].attribute;
 		item_tmp.expire_time = sd->status.inventory[i].expire_time;
+		item_tmp.bound       = sd->status.inventory[i].bound;
 		
 		for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++)
 			item_tmp.card[j]=sd->status.inventory[i].card[j];
@@ -10923,7 +10925,8 @@ BUILDIN(failedremovecards) {
 			item_tmp.refine      = sd->status.inventory[i].refine;
 			item_tmp.attribute   = sd->status.inventory[i].attribute;
 			item_tmp.expire_time = sd->status.inventory[i].expire_time;
-			
+			item_tmp.bound       = sd->status.inventory[i].bound;
+ 			
 			for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++)
 				item_tmp.card[j]=sd->status.inventory[i].card[j];
 			
@@ -11573,7 +11576,8 @@ BUILDIN(getinventorylist)
 				pc->setreg(sd,reference_uid(script->add_str(card_var), j),sd->status.inventory[i].card[k]);
 			}
 			pc->setreg(sd,reference_uid(script->add_str("@inventorylist_expire"), j),sd->status.inventory[i].expire_time);
-			j++;
+			pc->setreg(sd,reference_uid(script->add_str("@inventorylist_bound"), j),sd->status.inventory[i].bound);
+ 			j++;
 		}
 	}
 	pc->setreg(sd,script->add_str("@inventorylist_count"),j);
@@ -17529,6 +17533,219 @@ BUILDIN(bg_join_team) {
 	
 	return true;
 }
+
+/*==============[Mhalicot]==================
+ * getitembound <item id>,<amount>,<type>{,<account ID>};
+ * getitembound "<item id>",<amount>,<type>{,<account ID>};
+ * Type:
+ *	1 - Account Bound
+ *	2 - Guild Bound
+ *	3 - Party Bound
+ *	4 - Character Bound
+ *------------------------------------------*/
+BUILDIN(getitembound)
+{
+	int nameid, amount, i, flag;
+	struct item it;
+	struct script_data *data;
+	char bound = script_getnum(st,4);
+	TBL_PC *sd;
+
+	data = script_getdata(st,2);
+	get_val(st,data);
+	if( data_isstring(data) ) { // "<item name>"
+		const char *name = script->conv_str(st,data);
+		struct item_data *item_data = itemdb->search_name(name);
+		if( item_data == NULL ) {
+			ShowError("buildin_getitembound: Nonexistant item %s requested.\n", name);
+			return 1; //No item created.
+		}
+		nameid = item_data->nameid;
+	} else if( data_isint(data) ) { // <item id>
+		nameid = script->conv_num(st,data);
+		if( nameid <= 0 || !itemdb->exists(nameid) ) {
+			ShowError("buildin_getitembound: Nonexistant item %d requested.\n", nameid);
+			return 1; //No item created.
+		}
+	} else {
+		ShowError("buildin_getitembound: invalid data type for argument #1 (%d).", data->type);
+		return 1;
+	}
+
+	if( itemdb->isstackable(nameid) || itemdb_type(nameid) == IT_PETEGG ) {
+		ShowError("buildin_getitembound: invalid item type. Bound only work for non stackeable items (Item %d).", nameid);
+		return 1;
+	}
+
+	if( (amount = script_getnum(st,3)) <= 0)
+		return 0; //return if amount <=0, skip the useless iteration
+
+	memset(&it,0,sizeof(it));
+	it.nameid = nameid;
+	it.identify = 1;
+	it.bound = bound;
+	
+	if( bound < 1 || bound > 4) { //Not a correct bound type
+		ShowError("script_getitembound: Not a correct bound type! Type=%d\n",bound);
+		return 1;
+	}
+	
+	if( script_hasdata(st,5) )
+			sd=map->id2sd(script_getnum(st,5)); // Account ID
+		else
+			sd=script->rid2sd(st); // Attached player
+
+	if( sd == NULL ) // no target
+		return 0;
+
+	for( i = 0; i < amount; i++ ) {
+		if( (flag = pc->additem(sd, &it, 1, LOG_TYPE_SCRIPT)) ) {
+			clif->additem(sd, 0, 0, flag);
+			if( pc->candrop(sd,&it) )
+				map->addflooritem(&it,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+		}
+	}
+
+	return 0;
+}
+
+/*==============[Mhalicot]==================
+ * getitembound2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,<bound type>; 
+ * getitembound2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,<bound type>;
+ *------------------------------------------*/
+BUILDIN(getitembound2)
+{
+	int nameid,amount,get_count,i,flag = 0;
+	int iden,ref,attr,c1,c2,c3,c4;
+	char bound=0;
+	struct item_data *item_data;
+	struct item item_tmp;
+	TBL_PC *sd;
+	struct script_data *data;
+	
+		bound = script_getnum(st,11);
+		if( bound < 1 || bound > 4) { //Not a correct bound type
+			ShowError("script_getitembound2: Not a correct bound type! Type=%d\n",bound);
+			return 1;
+		}
+		if( script_hasdata(st,12) )
+			sd=map->id2sd(script_getnum(st,12));
+		else
+			sd=script->rid2sd(st); // Attached player
+	
+	if( sd == NULL ) // no target
+		return true;
+	
+	data=script_getdata(st,2);
+	script->get_val(st,data);
+	if( data_isstring(data) ){
+		const char *name=script->conv_str(st,data);
+		struct item_data *item_data = itemdb->search_name(name);
+		if( item_data )
+			nameid=item_data->nameid;
+		else
+			nameid=UNKNOWN_ITEM_ID;
+	}else
+		nameid=script->conv_num(st,data);
+	
+	amount=script_getnum(st,3);
+	iden=script_getnum(st,4);
+	ref=script_getnum(st,5);
+	attr=script_getnum(st,6);
+	c1=(short)script_getnum(st,7);
+	c2=(short)script_getnum(st,8);
+	c3=(short)script_getnum(st,9);
+	c4=(short)script_getnum(st,10);
+	
+	if(nameid<0) { // Invalide nameid
+		nameid = -nameid;
+		flag = 1;
+	}
+	
+	if(nameid > 0) {
+		memset(&item_tmp,0,sizeof(item_tmp));
+		item_data=itemdb->exists(nameid);
+		if (item_data == NULL)
+			return -1;
+		if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR){
+			if(ref > MAX_REFINE) ref = MAX_REFINE;
+		}
+		else if(item_data->type==IT_PETEGG) {
+			iden = 1;
+			ref = 0;
+		}
+		else {
+			iden = 1;
+			ref = attr = 0;
+		}
+		
+		item_tmp.nameid=nameid;
+		if(!flag)
+			item_tmp.identify=iden;
+		else if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR)
+			item_tmp.identify=0;
+		item_tmp.refine=ref;
+		item_tmp.attribute=attr;
+		item_tmp.card[0]=(short)c1;
+		item_tmp.card[1]=(short)c2;
+		item_tmp.card[2]=(short)c3;
+		item_tmp.card[3]=(short)c4;
+		item_tmp.bound=bound;
+		
+		//Check if it's stackable.
+		if (!itemdb->isstackable(nameid))
+			get_count = 1;
+		else
+			get_count = amount;
+		
+		for (i = 0; i < amount; i += get_count) {
+			// if not pet egg
+			if (!pet->create_egg(sd, nameid)) {
+				if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT))) {
+					clif->additem(sd, 0, 0, flag);
+					if( pc->candrop(sd,&item_tmp) )
+						map->addflooritem(&item_tmp,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+				}
+			}
+		}
+	}
+	
+	return true;
+}
+/*==============[Mhalicot]==================
+ * countbound {<type>}; 
+ * Creates an array of bounded item IDs
+ * Returns amount of items found
+ * Type:
+ *	1 - Account Bound
+ *	2 - Guild Bound
+ *	3 - Party Bound
+ *------------------------------------------*/
+BUILDIN(countbound)
+{
+	int i, type, j=0, k=0;
+	TBL_PC *sd;
+
+	if( (sd = script->rid2sd(st)) == NULL )
+		return false;
+
+	type = script_hasdata(st,2)?script_getnum(st,2):0;
+
+	for(i=0;i<MAX_INVENTORY;i++){
+		if(sd->status.inventory[i].nameid > 0 && (
+			(!type && sd->status.inventory[i].bound > 0) ||
+			(type && sd->status.inventory[i].bound == type)
+		)) {
+			pc->setreg(sd,reference_uid(script->add_str("@bound_items"), k),sd->status.inventory[i].nameid);
+			k++;
+			j += sd->status.inventory[i].amount;
+		}
+	}
+	
+	script_pushint(st,j);
+	return 0;
+}
+
 /* bg_match_over( arena_name {, optional canceled } ) */
 /* returns 0 when successful, 1 otherwise */
 BUILDIN(bg_match_over) {
@@ -18109,7 +18326,13 @@ void script_parse_builtin(void) {
 		BUILDIN_DEF(bindatcmd, "ss???"),
 		BUILDIN_DEF(unbindatcmd, "s"),
 		BUILDIN_DEF(useatcmd, "s"),
-		
+		/**
+		 * Item bound [Mhalicot\Hercules]
+		 **/
+		BUILDIN_DEF(getitembound,"vii?"),
+		BUILDIN_DEF(getitembound2,"viiiiiiiii?"),
+		BUILDIN_DEF(countbound, "?"),
+ 		
 		//Quest Log System [Inkfish]
 		BUILDIN_DEF(questinfo, "ii??"),
 		BUILDIN_DEF(setquest, "i"),
diff --git a/src/map/storage.c b/src/map/storage.c
index cc1100d28..df406257d 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -107,7 +107,8 @@ int compare_item(struct item *a, struct item *b)
 		a->identify == b->identify &&
 		a->refine == b->refine &&
 		a->attribute == b->attribute &&
-		a->expire_time == b->expire_time )
+		a->expire_time == b->expire_time &&
+		a->bound == b->bound )
 	{
 		int i;
 		for (i = 0; i < MAX_SLOTS && (a->card[i] == b->card[i]); i++);
@@ -140,6 +141,11 @@ int storage_additem(struct map_session_data* sd, struct item* item_data, int amo
 		return 1;
 	}
 	
+	if( (item_data->bound > 1) && !pc->can_give_bounded_items(sd) ) {
+		clif->message(sd->fd, msg_txt(294));
+		return 1;
+	}
+
 	if( itemdb->isstackable2(data) )
 	{//Stackable
 		for( i = 0; i < MAX_STORAGE; i++ )
@@ -429,12 +435,17 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto
 		return 1;
 	}
 
-	if( !itemdb_canguildstore(item_data, pc->get_group_level(sd)) || item_data->expire_time )
-	{	//Check if item is storable. [Skotlex]
+	if( !itemdb_canguildstore(item_data, pc->get_group_level(sd)) || item_data->expire_time || (item_data->bound && !pc->can_give_bounded_items(sd)) )
+ 	{	//Check if item is storable. [Skotlex]
 		clif->message (sd->fd, msg_txt(264));
 		return 1;
 	}
 
+	if( (item_data->bound == 1 || item_data->bound > 2) && !pc->can_give_bounded_items(sd) ) {
+		clif->message(sd->fd, msg_txt(294));
+		return 1;
+	}
+	
 	if(itemdb->isstackable2(data)){ //Stackable
 		for(i=0;i<MAX_GUILD_STORAGE;i++){
 			if(compare_item(&stor->items[i], item_data)) {
diff --git a/src/map/trade.c b/src/map/trade.c
index 8dd30371b..7085fdda3 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -365,6 +365,12 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
 		return;
 	}
 
+	if( ((item->bound == 1 || item->bound > 2) || (item->bound == 2 && sd->status.guild_id != target_sd->status.guild_id)) && !pc->can_give_bounded_items(sd) ) { // Item Bound
+		clif->message(sd->fd, msg_txt(293));
+		clif->tradeitemok(sd, index+2, 1);
+		return;
+	}
+
 	//Locate a trade position
 	ARR_FIND( 0, 10, trade_i, sd->deal.item[trade_i].index == index || sd->deal.item[trade_i].amount == 0 );
 	if( trade_i == 10 ) //No space left
diff --git a/src/map/vending.c b/src/map/vending.c
index 7d6d02cfb..be3826754 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -257,7 +257,8 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
 		||  !sd->status.cart[index].identify // unidentified item
 		||  sd->status.cart[index].attribute == 1 // broken item
 		||  sd->status.cart[index].expire_time // It should not be in the cart but just in case
-		||  !itemdb_cantrade(&sd->status.cart[index], pc->get_group_level(sd), pc->get_group_level(sd)) ) // untradeable item
+		||  (sd->status.cart[index].bound && !pc->can_give_bounded_items(sd)) // can't trade account bound items and has no permission
+ 		||  !itemdb_cantrade(&sd->status.cart[index], pc->get_group_level(sd), pc->get_group_level(sd)) ) // untradeable item
 			continue;
 
 		sd->vending[i].index = index;
-- 
cgit v1.2.3-70-g09d2


From 5c94e76753c0cdb4ffb7dabbd6e135f1f7d42ef2 Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Sat, 2 Nov 2013 17:16:07 -0200
Subject: Updated to latest Hercules

Signed-off-by: shennetsind <ind@henn.et>
---
 sql-files/main.sql           | 4 ++++
 sql-files/upgrades/index.txt | 1 +
 src/common/mmo.h             | 3 +++
 3 files changed, 8 insertions(+)

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index 2c91d58b1..f8a225ee9 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -661,6 +661,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1366078541);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1381354728);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1381423003);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1382892428);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383162785);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383167577);
 
 --
@@ -715,6 +716,9 @@ INSERT INTO `interreg` (`varname`, `value`) VALUES
 CREATE TABLE IF NOT EXISTS `account_data` (
   `account_id` int(11) unsigned NOT NULL default '0',
   `bank_vault` int(11) unsigned NOT NULL default '0',
+  `base_exp` TINYINT( 4 ) UNSIGNED NOT NULL default '0',
+  `base_drop` TINYINT( 4 ) UNSIGNED NOT NULL default '0',
+  `base_death` TINYINT( 4 ) UNSIGNED NOT NULL default '0',
   PRIMARY KEY  (`account_id`)
 ) ENGINE=MyISAM; 
 
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index ca06e9c31..1fc0ebd77 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -7,4 +7,5 @@
 2013-10-09--21-38.sql
 2013-10-10--16-36.sql
 2013-10-27--16-47.sql
+2013-10-30--19-53.sql
 2013-10-30--21-12.sql
\ No newline at end of file
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 5f75f35da..603ec7573 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -415,6 +415,9 @@ struct mmo_charstatus {
 
 	time_t delete_date;
 
+	/* `account_data` modifiers */
+	unsigned short mod_exp,mod_drop,mod_death;
+	
 	unsigned char font;
 };
 
-- 
cgit v1.2.3-70-g09d2


From b9b32ac7609e33c21b488d722103cc0eea16b12c Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Thu, 7 Nov 2013 16:04:51 -0200
Subject: Item Bound Fixes/Adjustments/Improvements

Special Thanks to Haruna

Signed-off-by: shennetsind <ind@henn.et>
---
 conf/groups.conf                         |   2 +-
 conf/messages.conf                       |   4 +-
 doc/permissions.txt                      |   2 +-
 sql-files/main.sql                       |   1 +
 sql-files/upgrades/2013-10-31--07-49.sql |   4 +-
 sql-files/upgrades/index.txt             |   3 +-
 src/char/char.c                          |  32 ++--
 src/char/int_storage.c                   |  58 ++++---
 src/char/inter.c                         |  18 +--
 src/common/mmo.h                         |  12 +-
 src/config/core.h                        |   3 +-
 src/map/atcommand.c                      |  20 +--
 src/map/clif.c                           |  33 ++--
 src/map/clif.h                           |   8 +
 src/map/guild.c                          |  39 ++---
 src/map/guild.h                          |   2 -
 src/map/intif.c                          |  28 ++--
 src/map/intif.h                          |   2 -
 src/map/mail.c                           |   6 +-
 src/map/packets_struct.h                 |   1 -
 src/map/party.c                          |  10 +-
 src/map/pc.c                             |  92 +++++++----
 src/map/pc.h                             |   5 +-
 src/map/pc_groups.c                      |   2 +-
 src/map/pc_groups.h                      |   2 +-
 src/map/script.c                         | 252 ++++++++-----------------------
 src/map/script.h                         |   1 +
 src/map/storage.c                        |   8 +-
 src/map/trade.c                          |  23 +--
 src/map/vending.c                        |   2 +-
 30 files changed, 285 insertions(+), 390 deletions(-)

(limited to 'sql-files/main.sql')

diff --git a/conf/groups.conf b/conf/groups.conf
index c1a8d10e6..d31f46f24 100644
--- a/conf/groups.conf
+++ b/conf/groups.conf
@@ -261,7 +261,7 @@ groups: (
 	log_commands: true
 	permissions: {
 		can_trade: true
-		can_trade_bounded: false
+		can_trade_bound: false
 		can_party: true
 		all_skill: false
 		all_equipment: false
diff --git a/conf/messages.conf b/conf/messages.conf
index 3564de043..2d429d79e 100644
--- a/conf/messages.conf
+++ b/conf/messages.conf
@@ -317,8 +317,8 @@
 291: Weather effects will dispell on warp/refresh
 292: Killer state reset.
 //Item Bind System
-293: This bounded item cannot be traded to that character.
-294: This bounded item cannot be stored there.
+293: This bound item cannot be traded to that character.
+294: This bound item cannot be stored there.
 295: Please enter an item name or ID (usage: @itembound <item name/ID> <quantity> <bound_type>).
 296: Please enter all parameters (usage: @itembound2 <item name/ID> <quantity>
 297:   <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>).
diff --git a/doc/permissions.txt b/doc/permissions.txt
index c2aeba081..7280395dc 100644
--- a/doc/permissions.txt
+++ b/doc/permissions.txt
@@ -31,5 +31,5 @@ show_bossmobs : Ability to see boss mobs with @showmobs.
 disable_pvm : Ability to disable Player vs. Monster.
 disable_pvp : Ability to disable Player vs. Player.
 disable_commands_when_dead : Ability to disable @command usage when dead.
-can_trade_bounded : Ability to trade or otherwise distribute bounded items (drop, storage, vending etc...).
+can_trade_bound: Ability to trade or otherwise distribute bound items (drop, storage, vending etc...).
 hchsys_admin : Hercules Chat System Admin (Ability to modify channel settings regardless of ownership and join password-protected channels without requiring a password.)
diff --git a/sql-files/main.sql b/sql-files/main.sql
index ddf3b6712..387d01893 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -666,6 +666,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1381423003);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1382892428);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383162785);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383167577);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383205740);
 
 --
 -- Table structure for table `sstatus`
diff --git a/sql-files/upgrades/2013-10-31--07-49.sql b/sql-files/upgrades/2013-10-31--07-49.sql
index 40e0421c8..e18c7e20d 100644
--- a/sql-files/upgrades/2013-10-31--07-49.sql
+++ b/sql-files/upgrades/2013-10-31--07-49.sql
@@ -1,4 +1,6 @@
+#1383205740
 ALTER TABLE `inventory` ADD COLUMN `bound` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `favorite`;
 ALTER TABLE `cart_inventory` ADD COLUMN `bound` tinyint(1) UNSIGNED NOT NULL default '0' AFTER `expire_time`;
 ALTER TABLE `storage` ADD COLUMN `bound` tinyint(1) UNSIGNED NOT NULL default '0' AFTER `expire_time`;
-ALTER TABLE `guild_storage` ADD COLUMN `bound` TINYINT(3) UNSIGNED NOT NULL default '0' AFTER `expire_time`;
\ No newline at end of file
+ALTER TABLE `guild_storage` ADD COLUMN `bound` TINYINT(3) UNSIGNED NOT NULL default '0' AFTER `expire_time`;
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383205740);
\ No newline at end of file
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 1fc0ebd77..133366319 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -8,4 +8,5 @@
 2013-10-10--16-36.sql
 2013-10-27--16-47.sql
 2013-10-30--19-53.sql
-2013-10-30--21-12.sql
\ No newline at end of file
+2013-10-30--21-12.sql
+2013-10-31--07-49.sql
\ No newline at end of file
diff --git a/src/char/char.c b/src/char/char.c
index 9e84f0245..ce4fcbe53 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -747,7 +747,7 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 	SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,      &item.refine,      0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
-	SQL->StmtBindColumn(stmt, 8, SQLDT_UINT,      &item.bound,       0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 8, SQLDT_UCHAR,     &item.bound,       0, NULL, NULL);
  	for( j = 0; j < MAX_SLOTS; ++j )
 		SQL->StmtBindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
 
@@ -894,7 +894,7 @@ int inventory_to_sql(const struct item items[], int max, int id) {
 	SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 8, SQLDT_CHAR,      &item.favorite,    0, NULL, NULL);
-	SQL->StmtBindColumn(stmt, 9, SQLDT_CHAR,      &item.bound,       0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 9, SQLDT_UCHAR,     &item.bound,       0, NULL, NULL);
  	for( j = 0; j < MAX_SLOTS; ++j )
 		SQL->StmtBindColumn(stmt, 10+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
 
@@ -1243,17 +1243,17 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
 	||	SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0)
 	||	SQL_ERROR == SQL->StmtExecute(stmt)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT,       &tmp_item.id, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT,     &tmp_item.nameid, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT,     &tmp_item.amount, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_UINT,      &tmp_item.equip, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR,      &tmp_item.identify, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,      &tmp_item.refine, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &tmp_item.attribute, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 7, SQLDT_UINT,      &tmp_item.expire_time, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_CHAR,      &tmp_item.favorite, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_CHAR,      &tmp_item.bound, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 10, SQLDT_ULONGLONG, &tmp_item.unique_id, 0, NULL, NULL) )
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt,  0, SQLDT_INT,       &tmp_item.id, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt,  1, SQLDT_SHORT,     &tmp_item.nameid, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt,  2, SQLDT_SHORT,     &tmp_item.amount, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt,  3, SQLDT_UINT,      &tmp_item.equip, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt,  4, SQLDT_CHAR,      &tmp_item.identify, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt,  5, SQLDT_CHAR,      &tmp_item.refine, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt,  6, SQLDT_CHAR,      &tmp_item.attribute, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt,  7, SQLDT_UINT,      &tmp_item.expire_time, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt,  8, SQLDT_CHAR,      &tmp_item.favorite, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt,  9, SQLDT_UCHAR,     &tmp_item.bound, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 10, SQLDT_UINT64,    &tmp_item.unique_id, 0, NULL, NULL) )
  		SqlStmt_ShowDebug(stmt);
 	for( i = 0; i < MAX_SLOTS; ++i )
 		if( SQL_ERROR == SQL->StmtBindColumn(stmt, 11+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
@@ -1283,8 +1283,8 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,        &tmp_item.refine, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,        &tmp_item.attribute, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 7, SQLDT_UINT,        &tmp_item.expire_time, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_CHAR,        &tmp_item.bound, 0, NULL, NULL)
-	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_ULONGLONG,   &tmp_item.unique_id, 0, NULL, NULL) )
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_UCHAR,       &tmp_item.bound, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_UINT64,      &tmp_item.unique_id, 0, NULL, NULL) )
  		SqlStmt_ShowDebug(stmt);
 	for( i = 0; i < MAX_SLOTS; ++i )
 		if( SQL_ERROR == SQL->StmtBindColumn(stmt, 10+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
@@ -2959,7 +2959,7 @@ int parse_frommap(int fd)
 					break;
 				}
 				//Check account only if this ain't final save. Final-save goes through because of the char-map reconnect
-				if (RFIFOB(fd,12) || RFIFOB(fd,13) || (
+				if (RFIFOB(fd,12) || (
 					(character = (struct online_char_data*)idb_get(online_char_db, aid)) != NULL &&
 					character->char_id == cid))
 				{
diff --git a/src/char/int_storage.c b/src/char/int_storage.c
index 6443aa743..30671df5e 100644
--- a/src/char/int_storage.c
+++ b/src/char/int_storage.c
@@ -107,8 +107,7 @@ int guild_storage_fromsql(int guild_id, struct guild_storage* p)
 
 	StrBuf->Destroy(&buf);
 
-	for( i = 0; i < MAX_GUILD_STORAGE && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i )
-	{
+	for( i = 0; i < MAX_GUILD_STORAGE && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i ) {
 		item = &p->items[i];
 		SQL->GetData(sql_handle, 0, &data, NULL); item->id = atoi(data);
 		SQL->GetData(sql_handle, 1, &data, NULL); item->nameid = atoi(data);
@@ -120,9 +119,8 @@ int guild_storage_fromsql(int guild_id, struct guild_storage* p)
 		SQL->GetData(sql_handle, 7, &data, NULL); item->bound = atoi(data);
 		SQL->GetData(sql_handle, 8, &data, NULL); item->unique_id = strtoull(data, NULL, 10);
  		item->expire_time = 0;
-		item->bound = 0;
-		for( j = 0; j < MAX_SLOTS; ++j )
-		{
+
+		for( j = 0; j < MAX_SLOTS; ++j ) {
 			SQL->GetData(sql_handle, 9+j, &data, NULL); item->card[j] = atoi(data);
 		}
 	}
@@ -239,14 +237,15 @@ int mapif_parse_SaveGuildStorage(int fd)
 	return 0;
 }
 
-#ifdef BOUND_ITEMS
 int mapif_itembound_ack(int fd, int aid, int guild_id)
 {
+#ifdef GP_BOUND_ITEMS
 	WFIFOHEAD(fd,8);
 	WFIFOW(fd,0) = 0x3856;
 	WFIFOL(fd,2) = aid;
 	WFIFOW(fd,6) = guild_id;
 	WFIFOSET(fd,8);
+#endif
 	return 0;
 }
 
@@ -254,23 +253,23 @@ int mapif_itembound_ack(int fd, int aid, int guild_id)
 //Guild bound items pull for offline characters [Akinari]
 //Revised by [Mhalicot]
 //------------------------------------------------
-int mapif_parse_itembound_retrieve(int fd)
+int mapif_parse_ItemBoundRetrieve(int fd)
 {
+#ifdef GP_BOUND_ITEMS
 	StringBuf buf;
 	SqlStmt* stmt;
 	struct item item;
 	int j, i=0, s;
-	bool found=false;
 	struct item items[MAX_INVENTORY];
 	int char_id = RFIFOL(fd,2);
 	int aid = RFIFOL(fd,6);
 	int guild_id = RFIFOW(fd,10);
 
 	StrBuf->Init(&buf);
-	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`");
+	StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`");
 	for( j = 0; j < MAX_SLOTS; ++j )
 		StrBuf->Printf(&buf, ", `card%d`", j);
-	StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`='%d'",inventory_db,char_id);
+	StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`='%d' AND `bound` = '%d'",inventory_db,char_id,IBT_GUILD);
 
 	stmt = SQL->StmtMalloc(sql_handle);
 	if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
@@ -290,15 +289,14 @@ int mapif_parse_itembound_retrieve(int fd)
 	SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR,      &item.refine,      0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
-	SQL->StmtBindColumn(stmt, 8, SQLDT_UINT,      &item.bound,       0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 8, SQLDT_UCHAR,     &item.bound,       0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 9, SQLDT_UINT64,    &item.unique_id,   0, NULL, NULL);
 	for( j = 0; j < MAX_SLOTS; ++j )
-		SQL->StmtBindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
+		SQL->StmtBindColumn(stmt, 10+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
 
 	while( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) {
-		if(item.bound == 2) {
-			memcpy(&items[i],&item,sizeof(struct item));
-			i++;
-		}
+		memcpy(&items[i],&item,sizeof(struct item));
+		i++;
 	}
 	SQL->FreeResult(sql_handle);
 	
@@ -312,10 +310,9 @@ int mapif_parse_itembound_retrieve(int fd)
 	StrBuf->Clear(&buf);
 	StrBuf->Printf(&buf, "DELETE FROM `%s` WHERE",inventory_db);
 	for(j=0; j<i; j++) {
-		if( found )
+		if( j )
 			StrBuf->AppendStr(&buf, " OR");
-		else
-			found = true;
+
 		StrBuf->Printf(&buf, " `id`=%d",items[j].id);
 	}
 
@@ -329,21 +326,18 @@ int mapif_parse_itembound_retrieve(int fd)
 	}
 
 	//Now let's update the guild storage with those deleted items
-	found = false;
 	StrBuf->Clear(&buf);
-	StrBuf->Printf(&buf, "INSERT INTO `%s` (`guild_id`, `nameid`, `amount`, `identify`, `refine`, `attribute`, `expire_time`, `bound`", guild_storage_db);
+	StrBuf->Printf(&buf, "INSERT INTO `%s` (`guild_id`, `nameid`, `amount`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", guild_storage_db);
 	for( j = 0; j < MAX_SLOTS; ++j )
 		StrBuf->Printf(&buf, ", `card%d`", j);
 	StrBuf->AppendStr(&buf, ") VALUES ");
 	
 	for( j = 0; j < i; ++j ) {
-		if( found )
+		if( j )
 			StrBuf->AppendStr(&buf, ",");
-		else
-			found = true;
 
 		StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d'",
-			guild_id, items[j].nameid, items[j].amount, items[j].identify, items[j].refine, items[j].attribute, items[j].expire_time, items[j].bound);
+			guild_id, items[j].nameid, items[j].amount, items[j].identify, items[j].refine, items[j].attribute, items[j].expire_time, items[j].bound, items[j].unique_id);
 		for( s = 0; s < MAX_SLOTS; ++s )
 			StrBuf->Printf(&buf, ", '%d'", items[j].card[s]);
 		StrBuf->AppendStr(&buf, ")");
@@ -364,21 +358,21 @@ int mapif_parse_itembound_retrieve(int fd)
 	//Finally reload storage and tell map we're done
 	mapif_load_guild_storage(fd,aid,guild_id,0);
 	mapif_itembound_ack(fd,aid,guild_id);
+#endif
 	return 0;
 }
-#endif
 
 int inter_storage_parse_frommap(int fd)
 {
 	RFIFOHEAD(fd);
 	switch(RFIFOW(fd,0)){
-	case 0x3018: mapif_parse_LoadGuildStorage(fd); break;
-	case 0x3019: mapif_parse_SaveGuildStorage(fd); break;
-#ifdef BOUND_ITEMS
-	case 0x3056: mapif_parse_itembound_retrieve(fd); break;
+		case 0x3018: mapif_parse_LoadGuildStorage(fd); break;
+		case 0x3019: mapif_parse_SaveGuildStorage(fd); break;
+#ifdef GP_BOUND_ITEMS
+		case 0x3056: mapif_parse_ItemBoundRetrieve(fd); break;
 #endif
-	default:
-		return 0;
+		default:
+			return 0;
 	}
 	return 1;
 }
diff --git a/src/char/inter.c b/src/char/inter.c
index 54672faee..b213f1608 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -48,15 +48,15 @@ unsigned int party_share_level = 10;
 // recv. packet list
 int inter_recv_packet_length[] = {
 	-1,-1, 7,-1, -1,13,36, (2 + 4 + 4 + 4 + NAME_LENGTH),  0, 0, 0, 0,  0, 0,  0, 0,	// 3000-
-	 6,-1, 0, 0,  0, 0, 0, 0, 10,-1, 0, 0,  0, 0,  0, 0,	// 3010-
-	-1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0,  0, 0,  0, 0,	// 3020- Party
-	-1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1,	// 3030-
-	-1, 9, 0, 0,  0, 0, 0, 0,  7, 6,10,10, 10,-1,  0, 0,	// 3040-
-	-1,-1,10,10,  0,-1, 12, 0,  0, 0, 0, 0,  0, 0,  0, 0,	// 3050-  Auction System [Zephyrus] [Mhalicot]
- 	 6,-1, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,	// 3060-  Quest system [Kevin] [Inkfish]
-	-1,10, 6,-1,  0, 0, 0, 0,  0, 0, 0, 0, -1,10,  6,-1,	// 3070-  Mercenary packets [Zephyrus], Elemental packets [pakpil]
-	48,14,-1, 6,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,	// 3080-
-	-1,10,-1, 6,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,	// 3090-  Homunculus packets [albator]
+	 6,-1, 0, 0,  0, 0, 0, 0, 10,-1, 0, 0,  0, 0,  0, 0,    // 3010-
+	-1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0,  0, 0,  0, 0,    // 3020- Party
+	-1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1,    // 3030-
+	-1, 9, 0, 0,  0, 0, 0, 0,  7, 6,10,10, 10,-1,  0, 0,    // 3040-
+	-1,-1,10,10,  0,-1,12, 0,  0, 0, 0, 0,  0, 0,  0, 0,    // 3050-  Auction System [Zephyrus], Item Bound [Mhalicot]
+	 6,-1, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,    // 3060-  Quest system [Kevin] [Inkfish]
+	-1,10, 6,-1,  0, 0, 0, 0,  0, 0, 0, 0, -1,10,  6,-1,    // 3070-  Mercenary packets [Zephyrus], Elemental packets [pakpil]
+	48,14,-1, 6,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,    // 3080-
+	-1,10,-1, 6,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0,    // 3090-  Homunculus packets [albator]
 };
 
 struct WisData {
diff --git a/src/common/mmo.h b/src/common/mmo.h
index f676893ea..369f5c894 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -222,7 +222,8 @@ struct item {
 	char attribute;
 	short card[MAX_SLOTS];
 	unsigned int expire_time;
-	char favorite, bound;
+	char favorite;
+	unsigned char bound;
 	uint64 unique_id;
 };
 
@@ -249,6 +250,15 @@ enum e_mmo_charstatus_opt {
 	OPT_ALLOW_PARTY	= 0x2,
 };
 
+enum e_item_bound_type {
+	IBT_MIN       = 0x1,
+	IBT_ACCOUNT   = 0x1,
+	IBT_GUILD     = 0x2,
+	IBT_PARTY     = 0x3,
+	IBT_CHARACTER = 0x4,
+	IBT_MAX       = 0x4,
+};
+
 struct s_skill {
 	unsigned short id;
 	unsigned char lv;
diff --git a/src/config/core.h b/src/config/core.h
index 481c35af8..daadc6455 100644
--- a/src/config/core.h
+++ b/src/config/core.h
@@ -62,8 +62,7 @@
 //#define NSI_UNIQUE_ID
 
 /// Comment to disable Guild/Party Bound item system
-/// By default, we recover/remove Guild/Party Bound items automatically
-#define BOUND_ITEMS
+#define GP_BOUND_ITEMS
 
 /// Uncomment to enable real-time server stats (in and out data and ram usage). [Ai4rei]
 //#define SHOW_SERVER_STATS
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 3f3e9679e..e19428d36 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -1104,7 +1104,7 @@ ACMD(item)
 		sscanf(message, "%99s %d %d", item_name, &number, &bound) < 2 
 	))) {
 		clif->message(fd, msg_txt(295)); // Please enter an item name or ID (usage: @itembound <item name/ID> <quantity> <bound_type>).
-		return -1;
+		return false;
 	} else if (!message || !*message || (
 		sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 && 
 		sscanf(message, "%99s %d", item_name, &number) < 1 )) 
@@ -1123,7 +1123,7 @@ ACMD(item)
 		return false;
 	}
 	
-	if( bound < 0 || bound > 4 ) {
+	if( bound < IBT_MIN || bound > IBT_MAX ) {
 		clif->message(fd, msg_txt(298)); // Invalid bound type
 		return false;
 	}
@@ -1137,9 +1137,6 @@ ACMD(item)
 			return false;
 		}
  		get_count = 1;
-	} else if( bound ) {
-		clif->message(fd, msg_txt(499)); // Cannot create bounded stackable items.
-		return false;
 	}
 	
 	for (i = 0; i < number; i += get_count) {
@@ -1148,7 +1145,7 @@ ACMD(item)
 			memset(&item_tmp, 0, sizeof(item_tmp));
 			item_tmp.nameid = item_id;
 			item_tmp.identify = 1;
-			item_tmp.bound = bound;
+			item_tmp.bound = (unsigned char)bound;
 			
 			if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
 				clif->additem(sd, 0, 0, flag);
@@ -1192,9 +1189,9 @@ ACMD(item2)
 	if (number <= 0)
 		number = 1;
 
-	if( bound < 0 || bound > 4 ) {
+	if( bound < IBT_MIN || bound > IBT_MAX ) {
 		clif->message(fd, msg_txt(298)); // Invalid bound type
-		return -1;
+		return false;
 	}
 
 	item_id = 0;
@@ -1225,10 +1222,6 @@ ACMD(item2)
 			if (refine > MAX_REFINE)
 				refine = MAX_REFINE;
 		} else {
-			if( bound ) {
-				clif->message(fd, msg_txt(499)); // Cannot create bounded stackable items.
-				return false;
-			}
 			identify = 1;
 			refine = attr = 0;
 		}
@@ -1238,11 +1231,12 @@ ACMD(item2)
 			item_tmp.identify = identify;
 			item_tmp.refine = refine;
 			item_tmp.attribute = attr;
+			item_tmp.bound = (unsigned char)bound;
 			item_tmp.card[0] = c1;
 			item_tmp.card[1] = c2;
 			item_tmp.card[2] = c3;
 			item_tmp.card[3] = c4;
-			item_tmp.bound = bound;
+			
 			if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
 				clif->additem(sd, 0, 0, flag);
 		}
diff --git a/src/map/clif.c b/src/map/clif.c
index 04614158a..fecf0be0e 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1802,13 +1802,13 @@ void clif_selllist(struct map_session_data *sd)
 			if( !itemdb_cansell(&sd->status.inventory[i], pc->get_group_level(sd)) )
 				continue;
 
-			if( sd->status.inventory[i].expire_time || (sd->status.inventory[i].bound && !pc->can_give_bounded_items(sd)) )
-				continue; // Cannot Sell Rental Items or Account Bounded Items
+			if( sd->status.inventory[i].expire_time )
+				continue; // Cannot Sell Rental Items
  
 			if( sd->status.inventory[i].bound && !pc->can_give_bounded_items(sd))
 				continue; // Don't allow sale of bound items
 
- 			val=sd->inventory_data[i]->value_sell;
+			val=sd->inventory_data[i]->value_sell;
 			if( val < 0 )
 				continue;
 			WFIFOW(fd,4+c*10)=i+2;
@@ -2232,7 +2232,10 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
 		p.HireExpireDate = sd->status.inventory[n].expire_time;
 #endif
 #if PACKETVER >= 20071002
-		p.bindOnEquipType = sd->status.inventory[n].bound ? 2 : 0;
+		/* why restrict the flag to non-stackable? because this is the only packet allows stackable to,
+		 * show the color, and therefore it'd be inconsistent with the rest (aka it'd show yellow, you relog/refresh and boom its gone)
+		 */
+		p.bindOnEquipType = sd->status.inventory[n].bound && !itemdb->isstackable2(sd->inventory_data[n]) ? 2 : 0;
 #endif
 	}
 	p.result = (unsigned char)fail;
@@ -2381,7 +2384,6 @@ void clif_item_normal(short idx, struct NORMALITEM_INFO *p, struct item *i, stru
 	
 #if PACKETVER >= 20080102
 	p->HireExpireDate = i->expire_time;
-	p->bindOnEquipType = i->bound ? 2 : 0;
 #endif
 
 #if PACKETVER >= 20120925
@@ -15067,8 +15069,8 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd)
 
 	if( !pc->can_give_items(sd) || sd->status.inventory[idx].expire_time ||
 			!sd->status.inventory[idx].identify ||
-				!itemdb_canauction(&sd->status.inventory[idx],pc->get_group_level(sd)) ||
-					(sd->status.inventory[idx].bound && !pc->can_give_bounded_items(sd)) ) { // Quest Item or something else
+				!itemdb_canauction(&sd->status.inventory[idx],pc->get_group_level(sd)) || // Quest Item or something else
+					(sd->status.inventory[idx].bound && !pc->can_give_bounded_items(sd)) ) {
  		clif->auction_setitem(sd->fd, idx, true);
 		return;
 	}
@@ -15145,13 +15147,11 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
 		return;
 	}
 
-	// Auction checks...
-	if( sd->status.inventory[sd->auction.index].bound && !pc->can_give_bounded_items(sd) ) {
-		clif->message(sd->fd, msg_txt(293));
-		clif->auction_message(fd, 2); // The auction has been canceled
- 		return;
+	if( sd->status.zeny < (auction.hours * battle_config.auction_feeperhour) ) {
+		clif_Auction_message(fd, 5); // You do not have enough zeny to pay the Auction Fee.
+		return;
 	}
-
+	
 	if( auction.buynow > battle_config.auction_maximumprice )
 	{ // Zeny Limits
 		auction.buynow = battle_config.auction_maximumprice;
@@ -15177,6 +15177,13 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
 		return;
 	}
 
+	// Auction checks...
+	if( sd->status.inventory[sd->auction.index].bound && !pc->can_give_bounded_items(sd) ) {
+		clif->message(sd->fd, msg_txt(293));
+		clif->auction_message(fd, 2); // The auction has been canceled
+ 		return;
+	}
+	
 	safestrncpy(auction.item_name, item->jname, sizeof(auction.item_name));
 	auction.type = item->type;
 	memcpy(&auction.item, &sd->status.inventory[sd->auction.index], sizeof(struct item));
diff --git a/src/map/clif.h b/src/map/clif.h
index 710cb6590..cc222d8aa 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -450,6 +450,14 @@ enum e_UNEQUIP_ITEM_ACK {
 #endif
 };
 
+enum e_trade_item_ok {
+	TIO_SUCCESS    = 0x0,
+	TIO_OVERWEIGHT = 0x1,
+	TIO_CANCEL     = 0x2,
+	/* feedback-friendly code that causes the client not to display a error message */
+	TIO_INDROCKS   = 0x9,
+};
+
 /**
  * Structures
  **/
diff --git a/src/map/guild.c b/src/map/guild.c
index 719d6bf69..cba568bd8 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -866,7 +866,7 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c
 	if(online_member_sd == NULL)
 		return 0; // noone online to inform
 		
-#ifdef BOUND_ITEMS
+#ifdef GP_BOUND_ITEMS
 	//Guild bound item check
 	guild->retrieveitembound(char_id,account_id,guild_id);
 #endif
@@ -904,25 +904,12 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c
 	return 0;
 }
 
-#ifdef BOUND_ITEMS
-void guild_retrieveitembound(int char_id,int aid,int guild_id)
-{
+void guild_retrieveitembound(int char_id,int aid,int guild_id) {
+#ifdef GP_BOUND_ITEMS
 	TBL_PC *sd = map->id2sd(aid);
 	if(sd){ //Character is online
-		int idxlist[MAX_INVENTORY];
-		int j,i;
-		j = pc->bound_chk(sd,2,idxlist);
-		if(j) {	
-			struct guild_storage *gstor = gstorage->id2storage(guild_id);
-			for(i=0;i<j;i++) { //Loop the matching items, guild_storage_additem takes care of opening storage
-				if(gstor)
-					gstorage->additem(sd,gstor,&sd->status.inventory[idxlist[i]],sd->status.inventory[idxlist[i]].amount);
-				pc->delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,4,LOG_TYPE_GSTORAGE);
-			}
-			gstorage->close(sd); //Close and save the storage
-		}
-	}
-	else { //Character is offline, ask char server to do the job
+		pc->bound_clear(sd,IBT_GUILD);
+	} else { //Character is offline, ask char server to do the job
 		struct guild_storage *gstor = gstorage->id2storage2(guild_id);
 		if(gstor && gstor->storage_status == 1) { //Someone is in guild storage, close them
 			struct s_mapiterator* iter = mapit_getallusers();
@@ -936,8 +923,8 @@ void guild_retrieveitembound(int char_id,int aid,int guild_id)
 		}
 		intif->itembound_req(char_id,aid,guild_id);
 	}
-}
 #endif
+}
 
 int guild_send_memberinfoshort(struct map_session_data *sd,int online)
 { // cleaned up [LuzZza]
@@ -1854,11 +1841,6 @@ int guild_break(struct map_session_data *sd,char *name) {
 	struct unit_data *ud;
 	int i;
 	
-#ifdef BOUND_ITEMS
-	int j;
-	int idxlist[MAX_INVENTORY];
-#endif
-
 	nullpo_ret(sd);
 
 	if( (g=sd->guild)==NULL )
@@ -1901,11 +1883,8 @@ int guild_break(struct map_session_data *sd,char *name) {
 		}
 	}
 
-#ifdef BOUND_ITEMS
-	//Guild bound item check - Removes the bound flag
-	j = pc->bound_chk(sd,2,idxlist);
-	for(i=0;i<j;i++)
-		sd->status.inventory[idxlist[i]].bound = 0;
+#ifdef GP_BOUND_ITEMS
+	pc->bound_clear(sd,IBT_GUILD);
 #endif
 	
 	intif->guild_break(g->guild_id);
@@ -2380,4 +2359,6 @@ void guild_defaults(void) {
 	guild->check_member = guild_check_member;
 	guild->get_alliance_count = guild_get_alliance_count;
 	guild->castle_reconnect_sub = guild_castle_reconnect_sub;
+	/* */
+	guild->retrieveitembound = guild_retrieveitembound;
 }
diff --git a/src/map/guild.h b/src/map/guild.h
index 9326d8d5a..1a04a98ef 100644
--- a/src/map/guild.h
+++ b/src/map/guild.h
@@ -148,9 +148,7 @@ struct guild_interface {
 	/* guild aura */
 	void (*aura_refresh) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
 	/* item bound [Mhalicot]*/
-#ifdef BOUND_ITEMS
 	void (*retrieveitembound) (int char_id,int aid,int guild_id);
-#endif
 	/* */
 	int (*payexp_timer) (int tid, int64 tick, int id, intptr_t data);
 	TBL_PC* (*sd_check) (int guild_id, int account_id, int char_id);
diff --git a/src/map/intif.c b/src/map/intif.c
index b8b16a356..5cf385fe4 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -994,7 +994,6 @@ void intif_parse_LoadGuildStorage(int fd)
 			ShowError("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4));
 			return;
 		}
- 	
 	}
 	gstor=gstorage->id2storage(guild_id);
 	if(!gstor) {
@@ -1002,12 +1001,12 @@ void intif_parse_LoadGuildStorage(int fd)
 		return;
 	}
 	if (gstor->storage_status == 1) { // Already open.. lets ignore this update
-		ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", flag?sd->status.account_id:1, flag?sd->status.char_id:1);
- 		return;
+		ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", flag?sd->status.account_id:0, flag?sd->status.char_id:0);
+		return;
 	}
 	if (gstor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex]
-		ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", flag?sd->status.account_id:1, flag?sd->status.char_id:1);
- 		return;
+		ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", flag?sd->status.account_id:0, flag?sd->status.char_id:0);
+		return;
 	}
 	if( RFIFOW(fd,2)-13 != sizeof(struct guild_storage) ){
 		ShowError("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-13 , sizeof(struct guild_storage));
@@ -1017,7 +1016,7 @@ void intif_parse_LoadGuildStorage(int fd)
 
 	memcpy(gstor,RFIFOP(fd,13),sizeof(struct guild_storage));
 	if( flag )
-	gstorage->open(sd);
+		gstorage->open(sd);
 }
 
 // ACK guild_storage saved
@@ -2013,8 +2012,8 @@ void intif_parse_MessageToFD(int fd) {
 /*==========================================
  * Item Bound System [Xantara][Mhalicot]
  *------------------------------------------*/
-#ifdef BOUND_ITEMS
 void intif_itembound_req(int char_id,int aid,int guild_id) {
+#ifdef GP_BOUND_ITEMS
 	struct guild_storage *gstor = gstorage->id2storage2(guild_id);
 	WFIFOHEAD(inter_fd,12);
 	WFIFOW(inter_fd,0) = 0x3056;
@@ -2024,17 +2023,20 @@ void intif_itembound_req(int char_id,int aid,int guild_id) {
 	WFIFOSET(inter_fd,12);
 	if(gstor)
 		gstor->lock = 1; //Lock for retrieval process
+#endif
 }
  
 //3856
 void intif_parse_Itembound_ack(int fd) {
+#ifdef GP_BOUND_ITEMS
 	struct guild_storage *gstor;
 	int guild_id = RFIFOW(fd,6);
 
 	gstor = gstorage->id2storage2(guild_id);
-	if(gstor) gstor->lock = 0; //Unlock now that operation is completed
-}
+	if(gstor)
+		gstor->lock = 0; //Unlock now that operation is completed
 #endif
+}
 //-----------------------------------------------------------------
 // Communication from the inter server
 // Return a 0 (false) if there were any errors.
@@ -2118,9 +2120,9 @@ int intif_parse(int fd)
 		case 0x3854:	intif->pAuctionMessage(fd); break;
 		case 0x3855:	intif->pAuctionBid(fd); break;
 		//Bound items
-#ifdef BOUND_ITEMS
+#ifdef GP_BOUND_ITEMS
 		case 0x3856:	intif->pItembound_ack(fd); break;
-#endif	
+#endif
 		// Mercenary System
 		case 0x3870:	intif->pMercenaryReceived(fd); break;
 		case 0x3871:	intif->pMercenaryDeleted(fd); break;
@@ -2160,7 +2162,7 @@ void intif_defaults(void) {
 		10,-1,15, 0, 79,19, 7,-1,  0,-1,-1,-1, 14,67,186,-1, //0x3830
 		-1, 0, 0,14,  0, 0, 0, 0, -1,74,-1,11, 11,-1,  0, 0, //0x3840
 		-1,-1, 7, 7,  7,11, 8, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3850  Auctions [Zephyrus] itembound[Akinari]
- 		-1, 7, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3860  Quests [Kevin] [Inkfish]
+		-1, 7, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3860  Quests [Kevin] [Inkfish]
 		-1, 3, 3, 0,  0, 0, 0, 0,  0, 0, 0, 0, -1, 3,  3, 0, //0x3870  Mercenaries [Zephyrus] / Elemental [pakpil]
 		11,-1, 7, 3,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3880
 		-1,-1, 7, 3,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3890  Homunculus [albator]
@@ -2248,6 +2250,8 @@ void intif_defaults(void) {
 	/* */
 	intif->CheckForCharServer = CheckForCharServer;
 	/* */
+	intif->itembound_req = intif_itembound_req;
+	/* parse functions */
 	intif->pWisMessage = intif_parse_WisMessage;
 	intif->pWisEnd = intif_parse_WisEnd;
 	intif->pWisToGM_sub = mapif_parse_WisToGM_sub;
diff --git a/src/map/intif.h b/src/map/intif.h
index 577d58923..5e996b6fe 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -75,9 +75,7 @@ struct intif_interface {
 	int (*guild_emblem) (int guild_id, int len, const char *data);
 	int (*guild_castle_dataload) (int num, int *castle_ids);
 	int (*guild_castle_datasave) (int castle_id, int index, int value);
-#ifdef BOUND_ITEMS
 	void (*itembound_req) (int char_id, int aid, int guild_id);
-#endif
 	int (*request_petdata) (int account_id, int char_id, int pet_id);
 	int (*save_petdata) (int account_id, struct s_pet *p);
 	int (*delete_petdata) (int pet_id);
diff --git a/src/map/mail.c b/src/map/mail.c
index 6b1537d87..76c94879b 100644
--- a/src/map/mail.c
+++ b/src/map/mail.c
@@ -82,9 +82,9 @@ unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) {
 		if( amount < 0 || amount > sd->status.inventory[idx].amount )
 			return 1;
 		if( !pc->can_give_items(sd) || sd->status.inventory[idx].expire_time ||
-		   		!itemdb_canmail(&sd->status.inventory[idx],pc->get_group_level(sd)) ||
-					(sd->status.inventory[idx].bound && !pc->can_give_bounded_items(sd)) )
- 			return 1;
+			!itemdb_canmail(&sd->status.inventory[idx],pc->get_group_level(sd)) ||
+			(sd->status.inventory[idx].bound && !pc->can_give_bounded_items(sd)) )
+			return 1;
 
 		sd->mail.index = idx;
 		sd->mail.nameid = sd->status.inventory[idx].nameid;
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index e6f68ea4f..813aebee0 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -212,7 +212,6 @@ struct NORMALITEM_INFO {
 #endif
 #if PACKETVER >= 20080102
 	int HireExpireDate;
-	unsigned short bindOnEquipType;
 #endif
 #if PACKETVER >= 20120925
 	struct {
diff --git a/src/map/party.c b/src/map/party.c
index 16b9d99f9..0a7467162 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -547,14 +547,10 @@ int party_member_withdraw(int party_id, int account_id, int char_id)
 	}
 
 	if( sd && sd->status.party_id == party_id && sd->status.char_id == char_id ) {
-#ifdef BOUND_ITEMS
-		int idxlist[MAX_INVENTORY]; //or malloc to reduce consumtion
-		int j,i;
-		j = pc->bound_chk(sd,3,idxlist);
-		for(i=0;i<j;i++)
-			pc->delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,1,LOG_TYPE_OTHER);
+#ifdef GP_BOUND_ITEMS
+		pc->bound_clear(sd,IBT_PARTY);
 #endif
-	sd->status.party_id = 0;
+		sd->status.party_id = 0;
 		clif->charnameupdate(sd); //Update name display [Skotlex]
 		//TODO: hp bars should be cleared too
 		if( p->instances )
diff --git a/src/map/pc.c b/src/map/pc.c
index 31a38372a..752151888 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -573,7 +573,7 @@ bool pc_can_give_items(struct map_session_data *sd)
  */
 bool pc_can_give_bounded_items(struct map_session_data *sd)
 {
-	return pc->has_permission(sd, PC_PERM_TRADE_BOUNDED);
+	return pc->has_permission(sd, PC_PERM_TRADE_BOUND);
 }
 
 /*==========================================
@@ -999,10 +999,6 @@ int pc_isequip(struct map_session_data *sd,int n)
  *------------------------------------------*/
 bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers) {
 	int i;
-#ifdef BOUND_ITEMS
-	int j;
-	int idxlist[MAX_INVENTORY];
-#endif
 	int64 tick = timer->gettick();
 	uint32 ip = session[sd->fd]->client_addr;
 
@@ -1203,12 +1199,9 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
 	 **/
 	pc->itemcd_do(sd,true);
 
-#ifdef BOUND_ITEMS
-	// Party bound item check
-	if(sd->status.party_id == 0 && (j = pc->bound_chk(sd,3,idxlist))) { // Party was deleted while character offline
-		for(i=0;i<j;i++)
-			pc->delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,1,LOG_TYPE_OTHER);
-	}
+#ifdef GP_BOUND_ITEMS
+	if( sd->status.party_id == 0 )
+		pc->bound_clear(sd,IBT_PARTY);
 #endif
 
 	/* [Ind/Hercules] */
@@ -3962,6 +3955,28 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
 	if(sd->weight + w > sd->max_weight)
 		return 2;
 
+	if( item_data->bound ) {
+		switch( (enum e_item_bound_type)item_data->bound ) {
+			case IBT_CHARACTER:
+			case IBT_ACCOUNT:
+				break; /* no restrictions */
+			case IBT_PARTY:
+				if( !sd->status.party_id ) {
+					ShowError("pc_additem: can't add party_bound item to character without party!\n");
+					ShowError("pc_additem: %s - x%d %s (%d)\n",sd->status.name,amount,data->jname,data->nameid);
+					return 7;/* need proper code? */
+				}
+				break;
+			case IBT_GUILD:
+				if( !sd->status.guild_id ) {
+					ShowError("pc_additem: can't add guild_bound item to character without guild!\n");
+					ShowError("pc_additem: %s - x%d %s (%d)\n",sd->status.name,amount,data->jname,data->nameid);
+					return 7;/* need proper code? */
+				}
+				break;
+		}
+	}
+	
 	i = MAX_INVENTORY;
 
 	if( itemdb->isstackable2(data) && item_data->expire_time == 0 )
@@ -3969,7 +3984,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
 		for( i = 0; i < MAX_INVENTORY; i++ )
 		{
 			if( sd->status.inventory[i].nameid == item_data->nameid && sd->status.inventory[i].bound == item_data->bound && memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 )
- 			{
+			{
 				if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) )
 					return 5;
 				sd->status.inventory[i].amount += amount;
@@ -4520,7 +4535,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
 		return 1;
 	}
 
-	if( !itemdb_cancartstore(item_data, pc->get_group_level(sd)) || (item_data->bound > 1 && !pc->can_give_bounded_items(sd)))
+	if( !itemdb_cancartstore(item_data, pc->get_group_level(sd)) || (item_data->bound > IBT_ACCOUNT && !pc->can_give_bounded_items(sd)))
  	{ // Check item trade restrictions	[Skotlex]
 		clif->message (sd->fd, msg_txt(264));
 		return 1;/* TODO: there is no official response to this? */
@@ -4667,24 +4682,38 @@ int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
 
 	return flag;
 }
- /*==========================================
- * Bound Item Check
- * Type:
- * 1 Account Bound
- * 2 Guild Bound
- * 3 Party Bound
- * 4 Character Bound
- *------------------------------------------*/
-int pc_bound_chk(TBL_PC *sd,int type,int *idxlist)
-{
-	int i=0, j=0;
-	for(i=0;i<MAX_INVENTORY;i++){
-		if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0 && sd->status.inventory[i].bound == type) {
-			idxlist[j] = i;
-			j++;
-		}
+void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type) {
+	int i;
+	
+	switch( type ) {
+		/* both restricted to inventory */
+		case IBT_PARTY:
+		case IBT_CHARACTER:
+			for( i = 0; i < MAX_INVENTORY; i++ ){
+				if( sd->status.inventory[i].bound == type ) {
+					pc->delitem(sd,i,sd->status.inventory[i].amount,0,1,LOG_TYPE_OTHER);
+				}
+			}
+			break;
+		case IBT_ACCOUNT:
+			ShowError("Helllo! You reached pc_bound_clear for IBT_ACCOUNT, unfortunately no scenario was expected for this!\n");
+			break;
+		case IBT_GUILD: {
+				struct guild_storage *gstor = gstorage->id2storage(sd->status.guild_id);
+				
+				for( i = 0; i < MAX_INVENTORY; i++ ){
+					if(sd->status.inventory[i].bound == type) {
+						if( gstor )
+							gstorage->additem(sd,gstor,&sd->status.inventory[i],sd->status.inventory[i].amount);
+						pc->delitem(sd,i,sd->status.inventory[i].amount,0,1,gstor?LOG_TYPE_GSTORAGE:LOG_TYPE_OTHER);
+					}
+				}
+				if( gstor )
+					gstorage->close(sd);
+			}
+			break;
 	}
-	return j;
+	
 }
 /*==========================================
  *  Display item stolen msg to player sd
@@ -10366,7 +10395,6 @@ void pc_defaults(void) {
 	pc->class2idx = pc_class2idx;
 	pc->get_group_level = pc_get_group_level;
 	pc->can_give_items = pc_can_give_items;
-	pc->bound_chk = pc_bound_chk;
 	pc->can_give_bounded_items = pc_can_give_bounded_items;
 	
 	pc->can_use_command = pc_can_use_command;
@@ -10600,4 +10628,6 @@ void pc_defaults(void) {
 	
 	pc->rental_expire = pc_rental_expire;
 	pc->scdata_received = pc_scdata_received;
+	
+	pc->bound_clear = pc_bound_clear;
 }
diff --git a/src/map/pc.h b/src/map/pc.h
index 3645fc599..93463d19b 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -791,9 +791,6 @@ struct pc_interface {
 	int (*getzeny) (struct map_session_data *sd,int zeny, enum e_log_pick_type type, struct map_session_data *tsd);
 	int (*delitem) (struct map_session_data *sd,int n,int amount,int type, short reason, e_log_pick_type log_type);
 
-	//Bound items
-	int (*bound_chk) (TBL_PC *sd,int type,int *idxlist);
-
 	// Special Shop System
 	int (*paycash) (struct map_session_data *sd, int price, int points);
 	int (*getcash) (struct map_session_data *sd, int cash, int points);
@@ -986,6 +983,8 @@ struct pc_interface {
 	
 	void (*rental_expire) (struct map_session_data *sd, int i);
 	void (*scdata_received) (struct map_session_data *sd);
+	
+	void (*bound_clear) (struct map_session_data *sd, enum e_item_bound_type type);
 };
 
 struct pc_interface *pc;
diff --git a/src/map/pc_groups.c b/src/map/pc_groups.c
index c44e2634a..f95878e97 100644
--- a/src/map/pc_groups.c
+++ b/src/map/pc_groups.c
@@ -417,7 +417,7 @@ void do_init_pc_groups(void) {
 		{ "disable_pvp", PC_PERM_DISABLE_PVP },
 		{ "disable_commands_when_dead", PC_PERM_DISABLE_CMD_DEAD },
 		{ "hchsys_admin", PC_PERM_HCHSYS_ADMIN },
-		{ "can_trade_bounded", PC_PERM_TRADE_BOUNDED },
+		{ "can_trade_bound", PC_PERM_TRADE_BOUND },
 	};
 	unsigned char i, len = ARRAYLENGTH(pc_g_defaults);
 	
diff --git a/src/map/pc_groups.h b/src/map/pc_groups.h
index df99b19df..943fb7fa5 100644
--- a/src/map/pc_groups.h
+++ b/src/map/pc_groups.h
@@ -30,7 +30,7 @@ enum e_pc_permission {
 	PC_PERM_DISABLE_PVP         = 0x080000, // #20
 	PC_PERM_DISABLE_CMD_DEAD    = 0x100000,
 	PC_PERM_HCHSYS_ADMIN        = 0x200000,
-	PC_PERM_TRADE_BOUNDED       = 0x400000,
+	PC_PERM_TRADE_BOUND         = 0x400000,
 };
 
 // Cached config settings for quick lookup
diff --git a/src/map/script.c b/src/map/script.c
index 6dce018ef..cf3c3fb50 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -3779,6 +3779,17 @@ int script_reload(void) {
 	
 	return 0;
 }
+/* returns name of current function being run, from within the stack [Ind/Hercules] */
+const char *script_getfuncname(struct script_state *st) {
+	struct script_data *data;
+	
+	data = &st->stack->stack_data[st->start];
+	
+	if( data->type == C_NAME && script->str_data[data->u.num].type == C_FUNC )
+		return script->get_str(data->u.num);
+	
+	return NULL;
+}
 
 //-----------------------------------------------------------------------------
 // buildin functions
@@ -5763,10 +5774,13 @@ BUILDIN(checkweight2)
 /*==========================================
  * getitem <item id>,<amount>{,<account ID>};
  * getitem "<item name>",<amount>{,<account ID>};
+ *
+ * getitembound <item id>,<amount>,<type>{,<account ID>};
+ * getitembound "<item id>",<amount>,<type>{,<account ID>};
  *------------------------------------------*/
 BUILDIN(getitem)
 {
-	int nameid,amount,get_count,i,flag = 0;
+	int nameid,amount,get_count,i,flag = 0, offset = 0;
 	struct item it;
 	TBL_PC *sd;
 	struct script_data *data;
@@ -5778,7 +5792,7 @@ BUILDIN(getitem)
 	{// "<item name>"
 		const char *name=script->conv_str(st,data);
 		if( (item_data = itemdb->search_name(name)) == NULL ){
-			ShowError("buildin_getitem: Nonexistant item %s requested.\n", name);
+			ShowError("buildin_%s: Nonexistant item %s requested.\n", script->getfuncname(st), name);
 			return false; //No item created.
 		}
 		nameid=item_data->nameid;
@@ -5790,11 +5804,11 @@ BUILDIN(getitem)
 			flag = 1;
 		}
 		if( nameid <= 0 || !(item_data = itemdb->exists(nameid)) ){
-			ShowError("buildin_getitem: Nonexistant item %d requested.\n", nameid);
+			ShowError("buildin_%s: Nonexistant item %d requested.\n", script->getfuncname(st), nameid);
 			return false; //No item created.
 		}
 	} else {
-		ShowError("buildin_getitem: invalid data type for argument #1 (%d).", data->type);
+		ShowError("buildin_%s: invalid data type for argument #1 (%d).", script->getfuncname(st), data->type);
 		return false;
 	}
 	
@@ -5804,13 +5818,28 @@ BUILDIN(getitem)
 	
 	memset(&it,0,sizeof(it));
 	it.nameid=nameid;
+	
 	if(!flag)
 		it.identify=1;
 	else
 		it.identify=itemdb->isidentified2(item_data);
 	
-	if( script_hasdata(st,4) )
-		sd=map->id2sd(script_getnum(st,4)); // <Account ID>
+	if( !strcmp(script->getfuncname(st),"getitembound") ) {
+		int bound = script_getnum(st,4);
+		if( bound < IBT_MIN || bound > IBT_MAX ) { //Not a correct bound type
+			ShowError("script_getitembound: Not a correct bound type! Type=%d\n",bound);
+			return false;
+		}
+		if( item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR ) {
+			ShowError("script_getitembound: can't bind a pet egg/armor!\n",bound);
+			return false;
+		}
+		it.bound = (unsigned char)bound;
+		offset += 1;
+	}
+	
+	if( script_hasdata(st,4+offset) )
+		sd=map->id2sd(script_getnum(st,4+offset)); // <Account ID>
 	else
 		sd=script->rid2sd(st); // Attached player
 	
@@ -5842,15 +5871,24 @@ BUILDIN(getitem)
  *------------------------------------------*/
 BUILDIN(getitem2)
 {
-	int nameid,amount,get_count,i,flag = 0;
-	int iden,ref,attr,c1,c2,c3,c4;
+	int nameid,amount,get_count,i,flag = 0, offset = 0;
+	int iden,ref,attr,c1,c2,c3,c4, bound = 0;
 	struct item_data *item_data;
 	struct item item_tmp;
 	TBL_PC *sd;
 	struct script_data *data;
 	
-	if( script_hasdata(st,11) )
-		sd=map->id2sd(script_getnum(st,11)); // <Account ID>
+	if( !strcmp(script->getfuncname(st),"getitembound2") ) {
+		bound = script_getnum(st,11);
+		if( bound < IBT_MIN || bound > IBT_MAX ) { //Not a correct bound type
+			ShowError("script_getitembound2: Not a correct bound type! Type=%d\n",bound);
+			return false;
+		}
+		offset += 1;
+	}
+	
+	if( script_hasdata(st,11+offset) )
+		sd=map->id2sd(script_getnum(st,11+offset)); // <Account ID>
 	else
 		sd=script->rid2sd(st); // Attached player
 	
@@ -5878,6 +5916,11 @@ BUILDIN(getitem2)
 	c3=(short)script_getnum(st,9);
 	c4=(short)script_getnum(st,10);
 	
+	if( bound && (itemdb_type(nameid) == IT_PETEGG || itemdb_type(nameid) == IT_PETARMOR) ) {
+		ShowError("script_getitembound2: can't bind a pet egg/armor!\n",bound);
+		return false;
+	}
+	
 	if(nameid<0) { // Invalide nameid
 		nameid = -nameid;
 		flag = 1;
@@ -5907,6 +5950,7 @@ BUILDIN(getitem2)
 			item_tmp.identify=0;
 		item_tmp.refine=ref;
 		item_tmp.attribute=attr;
+		item_tmp.bound=(unsigned char)bound;
 		item_tmp.card[0]=(short)c1;
 		item_tmp.card[1]=(short)c2;
 		item_tmp.card[2]=(short)c3;
@@ -17562,185 +17606,6 @@ BUILDIN(bg_join_team) {
 	
 	return true;
 }
-
-/*==============[Mhalicot]==================
- * getitembound <item id>,<amount>,<type>{,<account ID>};
- * getitembound "<item id>",<amount>,<type>{,<account ID>};
- * Type:
- *	1 - Account Bound
- *	2 - Guild Bound
- *	3 - Party Bound
- *	4 - Character Bound
- *------------------------------------------*/
-BUILDIN(getitembound)
-{
-	int nameid, amount, i, flag;
-	struct item it;
-	struct script_data *data;
-	char bound = script_getnum(st,4);
-	TBL_PC *sd;
-
-	data = script_getdata(st,2);
-	get_val(st,data);
-	if( data_isstring(data) ) { // "<item name>"
-		const char *name = script->conv_str(st,data);
-		struct item_data *item_data = itemdb->search_name(name);
-		if( item_data == NULL ) {
-			ShowError("buildin_getitembound: Nonexistant item %s requested.\n", name);
-			return 1; //No item created.
-		}
-		nameid = item_data->nameid;
-	} else if( data_isint(data) ) { // <item id>
-		nameid = script->conv_num(st,data);
-		if( nameid <= 0 || !itemdb->exists(nameid) ) {
-			ShowError("buildin_getitembound: Nonexistant item %d requested.\n", nameid);
-			return 1; //No item created.
-		}
-	} else {
-		ShowError("buildin_getitembound: invalid data type for argument #1 (%d).", data->type);
-		return 1;
-	}
-
-	if( itemdb->isstackable(nameid) || itemdb_type(nameid) == IT_PETEGG ) {
-		ShowError("buildin_getitembound: invalid item type. Bound only work for non stackeable items (Item %d).", nameid);
-		return 1;
-	}
-
-	if( (amount = script_getnum(st,3)) <= 0)
-		return 0; //return if amount <=0, skip the useless iteration
-
-	memset(&it,0,sizeof(it));
-	it.nameid = nameid;
-	it.identify = 1;
-	it.bound = bound;
-	
-	if( bound < 1 || bound > 4) { //Not a correct bound type
-		ShowError("script_getitembound: Not a correct bound type! Type=%d\n",bound);
-		return 1;
-	}
-	
-	if( script_hasdata(st,5) )
-			sd=map->id2sd(script_getnum(st,5)); // Account ID
-		else
-			sd=script->rid2sd(st); // Attached player
-
-	if( sd == NULL ) // no target
-		return 0;
-
-	for( i = 0; i < amount; i++ ) {
-		if( (flag = pc->additem(sd, &it, 1, LOG_TYPE_SCRIPT)) ) {
-			clif->additem(sd, 0, 0, flag);
-			if( pc->candrop(sd,&it) )
-				map->addflooritem(&it,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
-		}
-	}
-
-	return 0;
-}
-
-/*==============[Mhalicot]==================
- * getitembound2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,<bound type>; 
- * getitembound2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,<bound type>;
- *------------------------------------------*/
-BUILDIN(getitembound2)
-{
-	int nameid,amount,get_count,i,flag = 0;
-	int iden,ref,attr,c1,c2,c3,c4;
-	char bound=0;
-	struct item_data *item_data;
-	struct item item_tmp;
-	TBL_PC *sd;
-	struct script_data *data;
-	
-		bound = script_getnum(st,11);
-		if( bound < 1 || bound > 4) { //Not a correct bound type
-			ShowError("script_getitembound2: Not a correct bound type! Type=%d\n",bound);
-			return 1;
-		}
-		if( script_hasdata(st,12) )
-			sd=map->id2sd(script_getnum(st,12));
-		else
-			sd=script->rid2sd(st); // Attached player
-	
-	if( sd == NULL ) // no target
-		return true;
-	
-	data=script_getdata(st,2);
-	script->get_val(st,data);
-	if( data_isstring(data) ){
-		const char *name=script->conv_str(st,data);
-		struct item_data *item_data = itemdb->search_name(name);
-		if( item_data )
-			nameid=item_data->nameid;
-		else
-			nameid=UNKNOWN_ITEM_ID;
-	}else
-		nameid=script->conv_num(st,data);
-	
-	amount=script_getnum(st,3);
-	iden=script_getnum(st,4);
-	ref=script_getnum(st,5);
-	attr=script_getnum(st,6);
-	c1=(short)script_getnum(st,7);
-	c2=(short)script_getnum(st,8);
-	c3=(short)script_getnum(st,9);
-	c4=(short)script_getnum(st,10);
-	
-	if(nameid<0) { // Invalide nameid
-		nameid = -nameid;
-		flag = 1;
-	}
-	
-	if(nameid > 0) {
-		memset(&item_tmp,0,sizeof(item_tmp));
-		item_data=itemdb->exists(nameid);
-		if (item_data == NULL)
-			return -1;
-		if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR){
-			if(ref > MAX_REFINE) ref = MAX_REFINE;
-		}
-		else if(item_data->type==IT_PETEGG) {
-			iden = 1;
-			ref = 0;
-		}
-		else {
-			iden = 1;
-			ref = attr = 0;
-		}
-		
-		item_tmp.nameid=nameid;
-		if(!flag)
-			item_tmp.identify=iden;
-		else if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR)
-			item_tmp.identify=0;
-		item_tmp.refine=ref;
-		item_tmp.attribute=attr;
-		item_tmp.card[0]=(short)c1;
-		item_tmp.card[1]=(short)c2;
-		item_tmp.card[2]=(short)c3;
-		item_tmp.card[3]=(short)c4;
-		item_tmp.bound=bound;
-		
-		//Check if it's stackable.
-		if (!itemdb->isstackable(nameid))
-			get_count = 1;
-		else
-			get_count = amount;
-		
-		for (i = 0; i < amount; i += get_count) {
-			// if not pet egg
-			if (!pet->create_egg(sd, nameid)) {
-				if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT))) {
-					clif->additem(sd, 0, 0, flag);
-					if( pc->candrop(sd,&item_tmp) )
-						map->addflooritem(&item_tmp,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
-				}
-			}
-		}
-	}
-	
-	return true;
-}
 /*==============[Mhalicot]==================
  * countbound {<type>}; 
  * Creates an array of bounded item IDs
@@ -17749,6 +17614,7 @@ BUILDIN(getitembound2)
  *	1 - Account Bound
  *	2 - Guild Bound
  *	3 - Party Bound
+ *  4 - Character Bound
  *------------------------------------------*/
 BUILDIN(countbound)
 {
@@ -18355,11 +18221,12 @@ void script_parse_builtin(void) {
 		BUILDIN_DEF(bindatcmd, "ss???"),
 		BUILDIN_DEF(unbindatcmd, "s"),
 		BUILDIN_DEF(useatcmd, "s"),
+		
 		/**
-		 * Item bound [Mhalicot\Hercules]
+		 * Item bound [Xantara] [Akinari] [Mhalicot/Hercules]
 		 **/
-		BUILDIN_DEF(getitembound,"vii?"),
-		BUILDIN_DEF(getitembound2,"viiiiiiiii?"),
+		BUILDIN_DEF2(getitem,"getitembound","vii?"),
+		BUILDIN_DEF2(getitem2,"getitembound2","viiiiiiiii?"),
 		BUILDIN_DEF(countbound, "?"),
  		
 		//Quest Log System [Inkfish]
@@ -18652,6 +18519,7 @@ void script_defaults(void) {
 	script->buildin_mobuseskill_sub = buildin_mobuseskill_sub;
 	script->cleanfloor_sub = script_cleanfloor_sub;
 	script->run_func = run_func;
+	script->getfuncname = script_getfuncname;
 	
 	/* script_config base */
 	script->config.warn_func_mismatch_argtypes = 1;
diff --git a/src/map/script.h b/src/map/script.h
index 6aebc8a30..a846365dd 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -630,6 +630,7 @@ struct script_interface {
 	int (*buildin_mobuseskill_sub) (struct block_list *bl, va_list ap);
 	int (*cleanfloor_sub) (struct block_list *bl, va_list ap);
 	int (*run_func) (struct script_state *st);
+	const char *(*getfuncname) (struct script_state *st);
 };
 
 struct script_interface *script;
diff --git a/src/map/storage.c b/src/map/storage.c
index cffbf23ec..0a2e6d118 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -141,7 +141,7 @@ int storage_additem(struct map_session_data* sd, struct item* item_data, int amo
 		return 1;
 	}
 	
-	if( (item_data->bound > 1) && !pc->can_give_bounded_items(sd) ) {
+	if( item_data->bound > IBT_ACCOUNT && !pc->can_give_bounded_items(sd) ) {
 		clif->message(sd->fd, msg_txt(294));
 		return 1;
 	}
@@ -435,13 +435,13 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto
 		return 1;
 	}
 
-	if( !itemdb_canguildstore(item_data, pc->get_group_level(sd)) || item_data->expire_time || (item_data->bound && !pc->can_give_bounded_items(sd)) )
+	if( !itemdb_canguildstore(item_data, pc->get_group_level(sd)) || item_data->expire_time )
  	{	//Check if item is storable. [Skotlex]
 		clif->message (sd->fd, msg_txt(264));
 		return 1;
 	}
 
-	if( (item_data->bound == 1 || item_data->bound > 2) && !pc->can_give_bounded_items(sd) ) {
+	if( item_data->bound && item_data->bound != IBT_GUILD && !pc->can_give_bounded_items(sd) ) {
 		clif->message(sd->fd, msg_txt(294));
 		return 1;
 	}
@@ -531,6 +531,8 @@ int storage_guild_storageadd(struct map_session_data* sd, int index, int amount)
 
 	if(gstorage->additem(sd,stor,&sd->status.inventory[index],amount)==0)
 		pc->delitem(sd,index,amount,0,4,LOG_TYPE_GSTORAGE);
+	else
+		clif->dropitem(sd, index,0);
 
 	return 1;
 }
diff --git a/src/map/trade.c b/src/map/trade.c
index 7085fdda3..327d19880 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -335,7 +335,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
 
 	if( amount == 0 )
 	{	//Why do this.. ~.~ just send an ack, the item won't display on the trade window.
-		clif->tradeitemok(sd, index, 0);
+		clif->tradeitemok(sd, index, TIO_SUCCESS);
 		return;
 	}
 
@@ -354,35 +354,38 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
 		(pc->get_partner(sd) != target_sd || !itemdb_canpartnertrade(item, src_lv, dst_lv)) ) //Can't partner-trade
 	{
 		clif->message (sd->fd, msg_txt(260));
-		clif->tradeitemok(sd, index+2, 1);
+		clif->tradeitemok(sd, index+2, TIO_INDROCKS);
 		return;
 	}
 
 	if( item->expire_time )
 	{ // Rental System
 		clif->message (sd->fd, msg_txt(260));
-		clif->tradeitemok(sd, index+2, 1);
+		clif->tradeitemok(sd, index+2, TIO_INDROCKS);
 		return;
 	}
 
-	if( ((item->bound == 1 || item->bound > 2) || (item->bound == 2 && sd->status.guild_id != target_sd->status.guild_id)) && !pc->can_give_bounded_items(sd) ) { // Item Bound
+	if( item->bound &&
+			!( item->bound == IBT_GUILD && sd->status.guild_id == target_sd->status.guild_id ) &&
+			!( item->bound == IBT_PARTY && sd->status.party_id == target_sd->status.party_id )
+					&& !pc->can_give_bounded_items(sd) ) {
 		clif->message(sd->fd, msg_txt(293));
-		clif->tradeitemok(sd, index+2, 1);
+		clif->tradeitemok(sd, index+2, TIO_INDROCKS);
 		return;
 	}
-
+	
 	//Locate a trade position
 	ARR_FIND( 0, 10, trade_i, sd->deal.item[trade_i].index == index || sd->deal.item[trade_i].amount == 0 );
 	if( trade_i == 10 ) //No space left
 	{
-		clif->tradeitemok(sd, index+2, 1);
+		clif->tradeitemok(sd, index+2, TIO_OVERWEIGHT);
 		return;
 	}
 
 	trade_weight = sd->inventory_data[index]->weight * amount;
 	if( target_sd->weight + sd->deal.weight + trade_weight > target_sd->max_weight )
 	{	//fail to add item -- the player was over weighted.
-		clif->tradeitemok(sd, index+2, 1);
+		clif->tradeitemok(sd, index+2, TIO_OVERWEIGHT);
 		return;
 	}
 
@@ -402,7 +405,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
 	}
 	sd->deal.weight += trade_weight;
 
-	clif->tradeitemok(sd, index+2, 0); // Return the index as it was received
+	clif->tradeitemok(sd, index+2, TIO_SUCCESS); // Return the index as it was received
 	clif->tradeadditem(sd, target_sd, index+2, amount);
 }
 
@@ -446,7 +449,7 @@ void trade_tradeok(struct map_session_data *sd) {
 		return;
 	}
 	sd->state.deal_locked = 1;
-	clif->tradeitemok(sd, 0, 0);
+	clif->tradeitemok(sd, 0, TIO_SUCCESS);
 	clif->tradedeal_lock(sd, 0);
 	clif->tradedeal_lock(target_sd, 1);
 }
diff --git a/src/map/vending.c b/src/map/vending.c
index 14a5e64d1..d5e5d1804 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -257,7 +257,7 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
 		||  !sd->status.cart[index].identify // unidentified item
 		||  sd->status.cart[index].attribute == 1 // broken item
 		||  sd->status.cart[index].expire_time // It should not be in the cart but just in case
-		||  (sd->status.cart[index].bound && !pc->can_give_bounded_items(sd)) // can't trade account bound items and has no permission
+		||  (sd->status.cart[index].bound && !pc->can_give_bounded_items(sd)) // can't trade bound items w/o permission
  		||  !itemdb_cantrade(&sd->status.cart[index], pc->get_group_level(sd), pc->get_group_level(sd)) ) // untradeable item
 			continue;
 
-- 
cgit v1.2.3-70-g09d2


From 8ed38f98894fb04b4403b44dc0f36281cfd36326 Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Fri, 8 Nov 2013 22:09:40 -0200
Subject: Adjusted account-modifiers default values to 100.

Special Thanks to Haruna, ossi0110.

Signed-off-by: shennetsind <ind@henn.et>
---
 sql-files/main.sql                       | 7 ++++---
 sql-files/upgrades/2013-11-09--00-03.sql | 5 +++++
 sql-files/upgrades/index.txt             | 3 ++-
 3 files changed, 11 insertions(+), 4 deletions(-)
 create mode 100644 sql-files/upgrades/2013-11-09--00-03.sql

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index 387d01893..23170096f 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -667,6 +667,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1382892428);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383162785);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383167577);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383205740);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383955424);
 
 --
 -- Table structure for table `sstatus`
@@ -721,9 +722,9 @@ INSERT INTO `interreg` (`varname`, `value`) VALUES
 CREATE TABLE IF NOT EXISTS `account_data` (
   `account_id` int(11) unsigned NOT NULL default '0',
   `bank_vault` int(11) unsigned NOT NULL default '0',
-  `base_exp` TINYINT( 4 ) UNSIGNED NOT NULL default '0',
-  `base_drop` TINYINT( 4 ) UNSIGNED NOT NULL default '0',
-  `base_death` TINYINT( 4 ) UNSIGNED NOT NULL default '0',
+  `base_exp` TINYINT( 4 ) UNSIGNED NOT NULL default '100',
+  `base_drop` TINYINT( 4 ) UNSIGNED NOT NULL default '100',
+  `base_death` TINYINT( 4 ) UNSIGNED NOT NULL default '100',
   PRIMARY KEY  (`account_id`)
 ) ENGINE=MyISAM; 
 
diff --git a/sql-files/upgrades/2013-11-09--00-03.sql b/sql-files/upgrades/2013-11-09--00-03.sql
new file mode 100644
index 000000000..09c63307f
--- /dev/null
+++ b/sql-files/upgrades/2013-11-09--00-03.sql
@@ -0,0 +1,5 @@
+#1383955424
+ALTER TABLE `account_data` MODIFY `base_exp` TINYINT( 4 ) UNSIGNED NOT NULL default '100';
+ALTER TABLE `account_data` MODIFY `base_drop` TINYINT( 4 ) UNSIGNED NOT NULL default '100';
+ALTER TABLE `account_data` MODIFY `base_death` TINYINT( 4 ) UNSIGNED NOT NULL default '100';
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383955424);
\ No newline at end of file
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 133366319..9074f5c62 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -9,4 +9,5 @@
 2013-10-27--16-47.sql
 2013-10-30--19-53.sql
 2013-10-30--21-12.sql
-2013-10-31--07-49.sql
\ No newline at end of file
+2013-10-31--07-49.sql
+2013-11-09--00-03.sql
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 40262e063a7d503104667a4135c564d996bc49c6 Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Fri, 15 Nov 2013 18:02:59 -0200
Subject: Updated `account_data` upgrade files

to avoid issues as demonstrated by report 7824 http://hercules.ws/board/tracker/issue-7824-exp-and-drop-rates-in-lat/
Special Thanks to Yommy!

Signed-off-by: shennetsind <ind@henn.et>
---
 sql-files/main.sql                       | 1 +
 sql-files/upgrades/2013-10-30--19-53.sql | 6 +++---
 sql-files/upgrades/2013-11-15--19-57.sql | 5 +++++
 sql-files/upgrades/index.txt             | 1 +
 4 files changed, 10 insertions(+), 3 deletions(-)
 create mode 100644 sql-files/upgrades/2013-11-15--19-57.sql

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index 23170096f..cd50c10fa 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -668,6 +668,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1383162785);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383167577);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383205740);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383955424);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1384545461);
 
 --
 -- Table structure for table `sstatus`
diff --git a/sql-files/upgrades/2013-10-30--19-53.sql b/sql-files/upgrades/2013-10-30--19-53.sql
index 05481cff4..8bc63b1f1 100644
--- a/sql-files/upgrades/2013-10-30--19-53.sql
+++ b/sql-files/upgrades/2013-10-30--19-53.sql
@@ -1,5 +1,5 @@
 #1383162785
-ALTER TABLE  `account_data` ADD  `base_exp` TINYINT( 4 ) UNSIGNED NOT NULL default '0';
-ALTER TABLE  `account_data` ADD  `base_drop` TINYINT( 4 ) UNSIGNED NOT NULL default '0';
-ALTER TABLE  `account_data` ADD  `base_death` TINYINT( 4 ) UNSIGNED NOT NULL default '0';
+ALTER TABLE  `account_data` ADD  `base_exp` TINYINT( 4 ) UNSIGNED NOT NULL default '100';
+ALTER TABLE  `account_data` ADD  `base_drop` TINYINT( 4 ) UNSIGNED NOT NULL default '100';
+ALTER TABLE  `account_data` ADD  `base_death` TINYINT( 4 ) UNSIGNED NOT NULL default '100';
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383162785);
\ No newline at end of file
diff --git a/sql-files/upgrades/2013-11-15--19-57.sql b/sql-files/upgrades/2013-11-15--19-57.sql
new file mode 100644
index 000000000..0644c47c9
--- /dev/null
+++ b/sql-files/upgrades/2013-11-15--19-57.sql
@@ -0,0 +1,5 @@
+#1384545461
+UPDATE `account_data` SET `base_exp` = '100' WHERE `base_exp` = '0';
+UPDATE `account_data` SET `base_drop` = '100' WHERE `base_drop` = '0';
+UPDATE `account_data` SET `base_death` = '100' WHERE `base_death` = '0';
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1384545461);
\ No newline at end of file
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 734c0868a..4fed9ff9b 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -12,3 +12,4 @@
 2013-10-31--07-49.sql
 2013-11-09--00-03.sql
 2013-11-15--00-06.sql
+2013-11-15--19-57.sql
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From aee2f6317e1c927847993801b5973d7e2e27a418 Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Sat, 16 Nov 2013 16:30:11 -0200
Subject: Introducing Character Ban Support.

@charban/@charunban, can temporarily block any accounts as opposed to the usual account-wide block.
Special Thanks to Haruna, Yommy!

Signed-off-by: shennetsind <ind@henn.et>
---
 conf/messages.conf                       |   3 +-
 sql-files/main.sql                       |   2 +
 sql-files/upgrades/2013-11-16--07-49.sql |   3 +
 sql-files/upgrades/index.txt             |   3 +-
 src/char/char.c                          | 215 +++++++++++++++++++++++--------
 src/char/char.h                          |   1 +
 src/common/showmsg.h                     |   1 +
 src/common/utils.c                       |  11 ++
 src/common/utils.h                       |   2 +
 src/login/login.c                        |  13 +-
 src/map/atcommand.c                      |   8 +-
 src/map/chrif.c                          |  24 +++-
 src/map/clif.c                           |  32 +++++
 src/map/clif.h                           |   2 +
 14 files changed, 241 insertions(+), 79 deletions(-)
 create mode 100644 sql-files/upgrades/2013-11-16--07-49.sql

(limited to 'sql-files/main.sql')

diff --git a/conf/messages.conf b/conf/messages.conf
index 2d429d79e..f98a91083 100644
--- a/conf/messages.conf
+++ b/conf/messages.conf
@@ -452,7 +452,8 @@
 430: unblock
 431: unban
 432: change the sex of
-
+433: This character has been banned until 
+434: Char-server has been asked to %s the character '%.*s'.
 // Homunculus messages
 450: You already have a homunculus
 
diff --git a/sql-files/main.sql b/sql-files/main.sql
index cd50c10fa..60b21285d 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -110,6 +110,7 @@ CREATE TABLE IF NOT EXISTS `char` (
   `slotchange` SMALLINT(3) unsigned NOT NULL default '0',
   `char_opt` INT( 11 ) unsigned NOT NULL default '0',
   `font` TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT  '0',
+  `unban_time` int(11) unsigned NOT NULL default '0',
   PRIMARY KEY  (`char_id`),
   UNIQUE KEY `name_key` (`name`),
   KEY `account_id` (`account_id`),
@@ -669,6 +670,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1383167577);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383205740);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383955424);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1384545461);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1384588175);
 
 --
 -- Table structure for table `sstatus`
diff --git a/sql-files/upgrades/2013-11-16--07-49.sql b/sql-files/upgrades/2013-11-16--07-49.sql
new file mode 100644
index 000000000..9f4b80452
--- /dev/null
+++ b/sql-files/upgrades/2013-11-16--07-49.sql
@@ -0,0 +1,3 @@
+#1384588175
+ALTER TABLE `char` ADD COLUMN `unban_time` int(11) unsigned NOT NULL default '0';
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1384588175);
\ No newline at end of file
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 4fed9ff9b..1e76ee41b 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -12,4 +12,5 @@
 2013-10-31--07-49.sql
 2013-11-09--00-03.sql
 2013-11-15--00-06.sql
-2013-11-15--19-57.sql
\ No newline at end of file
+2013-11-15--19-57.sql
+2013-11-16--07-49.sql
\ No newline at end of file
diff --git a/src/char/char.c b/src/char/char.c
index 112bbe0ae..ce05f32f4 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -1004,6 +1004,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
 	struct mmo_charstatus p;
 	int j = 0, i;
 	char last_map[MAP_NAME_LENGTH_EXT];
+	size_t unban_time;
 
 	stmt = SQL->StmtMalloc(sql_handle);
 	if( stmt == NULL ) {
@@ -1012,8 +1013,10 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
 	}
 	memset(&p, 0, sizeof(p));
 
-	for(i = 0 ; i < MAX_CHARS; i++ )
+	for(i = 0 ; i < MAX_CHARS; i++ ) {
 		sd->found_char[i] = -1;
+		sd->unban_time[i] = 0;
+	}
 	
 	// read char data
 	if( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT "
@@ -1021,7 +1024,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
 		"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,"
 		"`status_point`,`skill_point`,`option`,`karma`,`manner`,`hair`,`hair_color`,"
 		"`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`,"
-		"`robe`,`slotchange`"
+		"`robe`,`slotchange`,`unban_time`"
 		" FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", char_db, sd->account_id, MAX_CHARS)
 	||	SQL_ERROR == SQL->StmtExecute(stmt)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 0,  SQLDT_INT,    &p.char_id, 0, NULL, NULL)
@@ -1061,6 +1064,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 34, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 35, SQLDT_SHORT,  &p.robe, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 36, SQLDT_USHORT, &p.slotchange, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 37, SQLDT_LONG,   &unban_time, 0, NULL, NULL)
 	)
 	{
 		SqlStmt_ShowDebug(stmt);
@@ -1071,6 +1075,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
 	for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SQL->StmtNextRow(stmt); i++ ) {
 		p.last_point.map = mapindex_name2id(last_map);
 		sd->found_char[p.slot] = p.char_id;
+		sd->unban_time[p.slot] = unban_time;
 		j += mmo_char_tobuf(WBUFP(buf, j), &p);
 	}
 	
@@ -1931,6 +1936,7 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) {
 
 	return 106+offset;
 }
+	
 /* Made Possible by Yommy~! <3 */
 void mmo_char_send099d(int fd, struct char_session_data *sd) {
 	WFIFOHEAD(fd,4 + (MAX_CHARS*MAX_CHAR_BUF));
@@ -1938,6 +1944,34 @@ void mmo_char_send099d(int fd, struct char_session_data *sd) {
 	WFIFOW(fd,2) = mmo_chars_fromsql(sd, WFIFOP(fd,4)) + 4;
 	WFIFOSET(fd,WFIFOW(fd,2));
 }
+/* Sends character ban list */
+/* Made Possible by Yommy~! <3 */
+void mmo_char_send020d(int fd, struct char_session_data *sd) {
+	int i;
+	time_t now = time(NULL);
+	
+	ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now);
+	
+	if( i != MAX_CHARS ) {
+		int c;
+		
+		WFIFOHEAD(fd, 4 + (MAX_CHARS*24));
+
+		WFIFOW(fd, 0) = 0x20d;
+		
+		for(i = 0, c = 0; i < MAX_CHARS; i++) {
+			if( sd->unban_time[i] > now ) {
+				WFIFOL(fd, 4 + (24*c)) = sd->found_char[i];
+				timestamp2string((char*)WFIFOP(fd,8 + (28*c)), 20, sd->unban_time[i], "%Y-%m-%d %H:%M:%S");
+				c++;
+			}
+		}
+		
+		WFIFOW(fd, 2) = 4 + (24*c);
+		
+		WFIFOSET(fd, WFIFOW(fd, 2));
+	}
+}
 int mmo_char_send006b(int fd, struct char_session_data* sd);
 //----------------------------------------
 // [Ind/Hercules] notify client about charselect window data
@@ -2304,6 +2338,9 @@ int parse_fromlogin(int fd) {
 	#else
 						mmo_char_send006b(i, sd);
 	#endif
+	#if PACKETVER >= 20080000
+						mmo_char_send020d(i, sd);
+	#endif
 	#if PACKETVER >= 20110309
 						pincode->handle(i, sd);
 	#endif
@@ -3141,7 +3178,7 @@ int parse_frommap(int fd)
 				RFIFOSKIP(fd, 86);
 			break;
 
-			case 0x2b0e: // Request from map-server to change an account's status (will just be forwarded to login server)
+			case 0x2b0e: // Request from map-server to change an account's or character's status (accounts will just be forwarded to login server)
 				if (RFIFOREST(fd) < 44)
 					return 0;
 			{
@@ -3150,7 +3187,7 @@ int parse_frommap(int fd)
 
 				int acc = RFIFOL(fd,2); // account_id of who ask (-1 if server itself made this request)
 				const char* name = (char*)RFIFOP(fd,6); // name of the target character
-				int type = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban
+				int type = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban, 5 changesex, 6 charban, 7 charunban
 				short year = RFIFOW(fd,32);
 				short month = RFIFOW(fd,34);
 				short day = RFIFOW(fd,36);
@@ -3160,25 +3197,24 @@ int parse_frommap(int fd)
 				RFIFOSKIP(fd,44);
 
 				SQL->EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
-				if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id`,`name` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) )
+				
+				if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id`,`name`,`char_id`,`unban_time` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) )
 					Sql_ShowDebug(sql_handle);
-				else
-				if( SQL->NumRows(sql_handle) == 0 )
-				{
+				else if( SQL->NumRows(sql_handle) == 0 ) {
 					result = 1; // 1-player not found
-				}
-				else
-				if( SQL_SUCCESS != SQL->NextRow(sql_handle) )
+				} else if( SQL_SUCCESS != SQL->NextRow(sql_handle) ) {
 					Sql_ShowDebug(sql_handle);
-					//FIXME: set proper result value?
-				else
-				{
+					result = 1; // 1-player not found
+				} else {
 					char name[NAME_LENGTH];
-					int account_id;
+					int account_id, char_id;
 					char* data;
+					time_t unban_time;
 
 					SQL->GetData(sql_handle, 0, &data, NULL); account_id = atoi(data);
 					SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
+					SQL->GetData(sql_handle, 2, &data, NULL); char_id = atoi(data);
+					SQL->GetData(sql_handle, 3, &data, NULL); unban_time = atol(data);
 
 					if( login_fd <= 0 )
 						result = 3; // 3-login-server offline
@@ -3186,53 +3222,111 @@ int parse_frommap(int fd)
 	//				else
 	//				if( acc != -1 && isGM(acc) < isGM(account_id) )
 	//					result = 2; // 2-gm level too low
-					else
-					switch( type ) {
-					case 1: // block
-							WFIFOHEAD(login_fd,10);
-							WFIFOW(login_fd,0) = 0x2724;
-							WFIFOL(login_fd,2) = account_id;
-							WFIFOL(login_fd,6) = 5; // new account status
-							WFIFOSET(login_fd,10);
-					break;
-					case 2: // ban
-							WFIFOHEAD(login_fd,18);
-							WFIFOW(login_fd, 0) = 0x2725;
-							WFIFOL(login_fd, 2) = account_id;
-							WFIFOW(login_fd, 6) = year;
-							WFIFOW(login_fd, 8) = month;
-							WFIFOW(login_fd,10) = day;
-							WFIFOW(login_fd,12) = hour;
-							WFIFOW(login_fd,14) = minute;
-							WFIFOW(login_fd,16) = second;
-							WFIFOSET(login_fd,18);
-					break;
-					case 3: // unblock
-							WFIFOHEAD(login_fd,10);
-							WFIFOW(login_fd,0) = 0x2724;
-							WFIFOL(login_fd,2) = account_id;
-							WFIFOL(login_fd,6) = 0; // new account status
-							WFIFOSET(login_fd,10);
-					break;
-					case 4: // unban
-							WFIFOHEAD(login_fd,6);
-							WFIFOW(login_fd,0) = 0x272a;
-							WFIFOL(login_fd,2) = account_id;
-							WFIFOSET(login_fd,6);
-					break;
-					case 5: // changesex
-							WFIFOHEAD(login_fd,6);
-							WFIFOW(login_fd,0) = 0x2727;
-							WFIFOL(login_fd,2) = account_id;
-							WFIFOSET(login_fd,6);
-					break;
+					else {
+						switch( type ) {
+							case 1: // block
+									WFIFOHEAD(login_fd,10);
+									WFIFOW(login_fd,0) = 0x2724;
+									WFIFOL(login_fd,2) = account_id;
+									WFIFOL(login_fd,6) = 5; // new account status
+									WFIFOSET(login_fd,10);
+							break;
+							case 2: // ban
+									WFIFOHEAD(login_fd,18);
+									WFIFOW(login_fd, 0) = 0x2725;
+									WFIFOL(login_fd, 2) = account_id;
+									WFIFOW(login_fd, 6) = year;
+									WFIFOW(login_fd, 8) = month;
+									WFIFOW(login_fd,10) = day;
+									WFIFOW(login_fd,12) = hour;
+									WFIFOW(login_fd,14) = minute;
+									WFIFOW(login_fd,16) = second;
+									WFIFOSET(login_fd,18);
+							break;
+							case 3: // unblock
+									WFIFOHEAD(login_fd,10);
+									WFIFOW(login_fd,0) = 0x2724;
+									WFIFOL(login_fd,2) = account_id;
+									WFIFOL(login_fd,6) = 0; // new account status
+									WFIFOSET(login_fd,10);
+							break;
+							case 4: // unban
+									WFIFOHEAD(login_fd,6);
+									WFIFOW(login_fd,0) = 0x272a;
+									WFIFOL(login_fd,2) = account_id;
+									WFIFOSET(login_fd,6);
+							break;
+							case 5: // changesex
+									WFIFOHEAD(login_fd,6);
+									WFIFOW(login_fd,0) = 0x2727;
+									WFIFOL(login_fd,2) = account_id;
+									WFIFOSET(login_fd,6);
+							break;
+							case 6: //char ban
+							/* handled by char server, so no redirection */
+							{
+								time_t timestamp;
+								struct tm *tmtime;
+								SqlStmt* stmt = SQL->StmtMalloc(sql_handle);
+
+								if (unban_time == 0 || unban_time < time(NULL))
+									timestamp = time(NULL); // new ban
+								else
+									timestamp = unban_time; // add to existing ban
+								
+								tmtime = localtime(&timestamp);
+								tmtime->tm_year = tmtime->tm_year + year;
+								tmtime->tm_mon  = tmtime->tm_mon + month;
+								tmtime->tm_mday = tmtime->tm_mday + day;
+								tmtime->tm_hour = tmtime->tm_hour + hour;
+								tmtime->tm_min  = tmtime->tm_min + minute;
+								tmtime->tm_sec  = tmtime->tm_sec + second;
+								timestamp = mktime(tmtime);
+																
+								if( SQL_SUCCESS != SQL->StmtPrepare(stmt,
+																	"UPDATE `%s` SET `unban_time` = ? WHERE `char_id` = ? LIMIT 1",
+																	char_db)
+								   || SQL_SUCCESS != SQL->StmtBindParam(stmt,  0, SQLDT_LONG,   (void*)&timestamp,   sizeof(timestamp))
+								   || SQL_SUCCESS != SQL->StmtBindParam(stmt,  1, SQLDT_INT,    (void*)&char_id,     sizeof(char_id))
+								   || SQL_SUCCESS != SQL->StmtExecute(stmt)
+
+								   ) {
+									SqlStmt_ShowDebug(stmt);
+								}
+								
+								SQL->StmtFree(stmt);
+								
+								// condition applies; send to all map-servers to disconnect the player
+								if( timestamp > time(NULL) ) {
+									unsigned char buf[11];
+									
+									WBUFW(buf,0) = 0x2b14;
+									WBUFL(buf,2) = account_id;
+									WBUFB(buf,6) = 2;
+									WBUFL(buf,7) = (unsigned int)timestamp;
+									mapif_sendall(buf, 11);
+									
+									// disconnect player if online on char-server
+									disconnect_player(account_id);
+								}
+							}
+							break;
+						case 7: //char unban
+							/* handled by char server, so no redirection */
+							if( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `unban_time` = '0' WHERE `char_id` = '%d' LIMIT 1", char_db, char_id) ) {
+								Sql_ShowDebug(sql_handle);
+								result = 1;
+							}
+							break;
+
+						}
 					}
 				}
 
 				SQL->FreeResult(sql_handle);
 
 				// send answer if a player ask, not if the server ask
-				if( acc != -1 && type != 5) { // Don't send answer for changesex
+				if( acc != -1 && type != 5 ) { // Don't send answer for changesex
 					WFIFOHEAD(fd,34);
 					WFIFOW(fd, 0) = 0x2b0f;
 					WFIFOL(fd, 2) = acc;
@@ -3984,6 +4078,15 @@ int parse_char(int fd)
 				char_id = atoi(data);
 				SQL->FreeResult(sql_handle);
 				
+				/* client doesn't let it get to this point if you're banned, so its a forged packet */
+				if( sd->found_char[slot] == char_id && sd->unban_time[slot] > time(NULL) ) {
+					WFIFOHEAD(fd,3);
+					WFIFOW(fd,0) = 0x6c;
+					WFIFOB(fd,2) = 0; // rejected from server
+					WFIFOSET(fd,3);
+					break;
+				}
+				
 				/* set char as online prior to loading its data so 3rd party applications will realise the sql data is not reliable */
 				set_char_online(-2,char_id,sd->account_id);
 				if( !mmo_char_fromsql(char_id, &char_dat, true) ) { /* failed? set it back offline */
diff --git a/src/char/char.h b/src/char/char.h
index a3bbdd904..c7a387645 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -20,6 +20,7 @@ struct char_session_data {
 	bool auth; // whether the session is authed or not
 	int account_id, login_id1, login_id2, sex;
 	int found_char[MAX_CHARS]; // ids of chars on this account
+	time_t unban_time[MAX_CHARS]; // char unban time array
 	char email[40]; // e-mail (default: a@a.com) by [Yor]
 	time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
 	int group_id; // permission
diff --git a/src/common/showmsg.h b/src/common/showmsg.h
index 59a0d9538..43d38973f 100644
--- a/src/common/showmsg.h
+++ b/src/common/showmsg.h
@@ -99,5 +99,6 @@ extern void ClearScreen(void);
 	extern void ShowFatalError(const char *, ...);
 	extern void ShowConfigWarning(config_setting_t *config, const char *string, ...);
 #endif
+extern int _vShowMessage(enum msg_type flag, const char *string, va_list ap);
 
 #endif /* _SHOWMSG_H_ */
diff --git a/src/common/utils.c b/src/common/utils.c
index 9e3dbac47..9a7d4971b 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -287,6 +287,17 @@ unsigned int get_percentage(const unsigned int A, const unsigned int B)
 	return (unsigned int)floor(result);
 }
 
+//-----------------------------------------------------
+// custom timestamp formatting (from eApp)
+//-----------------------------------------------------
+const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format)
+{
+	size_t len = strftime(str, size, format, localtime(&timestamp));
+	memset(str + len, '\0', size - len);
+	return str;
+}
+
+
 /* [Ind/Hercules] Caching */
 bool HCache_check(const char *file) {
 	struct stat bufa, bufb;
diff --git a/src/common/utils.h b/src/common/utils.h
index 32087d78f..3e1463d6b 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -25,6 +25,8 @@ bool exists(const char* filename);
 /// calculates the value of A / B, in percent (rounded down)
 unsigned int get_percentage(const unsigned int A, const unsigned int B);
 
+const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format);
+
 //////////////////////////////////////////////////////////////////////////
 // byte word dword access [Shinomori]
 //////////////////////////////////////////////////////////////////////////
diff --git a/src/login/login.c b/src/login/login.c
index 3da592ebc..75247845d 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -11,6 +11,7 @@
 #include "../common/socket.h"
 #include "../common/strlib.h"
 #include "../common/timer.h"
+#include "../common/utils.h"
 #include "../common/HPM.h"
 #include "account.h"
 #include "ipban.h"
@@ -271,18 +272,6 @@ bool check_password(const char* md5key, int passwdenc, const char* passwd, const
 	}
 }
 
-
-//-----------------------------------------------------
-// custom timestamp formatting (from eApp)
-//-----------------------------------------------------
-const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format)
-{
-	size_t len = strftime(str, size, format, localtime(&timestamp));
-	memset(str + len, '\0', size - len);
-	return str;
-}
-
-
 //--------------------------------------------
 // Test to know if an IP come from LAN or WAN.
 //--------------------------------------------
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 902d179db..a2bea32a8 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -2798,7 +2798,7 @@ ACMD(char_ban)
 		return false;
 	}
 	
-	chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 2, year, month, day, hour, minute, second); // type: 2 - ban
+	chrif->char_ask_name(sd->status.account_id, atcmd_player_name, !strcmpi(info->command,"charban") ? 6 : 2, year, month, day, hour, minute, second); // type: 2 - ban; 6 - charban
 	clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it.
 	
 	return true;
@@ -2838,7 +2838,7 @@ ACMD(char_unban)
 	}
 	
 	// send answer to login server via char-server
-	chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban
+	chrif->char_ask_name(sd->status.account_id, atcmd_player_name, !strcmpi(info->command,"charunban") ? 7 : 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban account; type 7 - unban character
 	clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it.
 	
 	return true;
@@ -3138,7 +3138,7 @@ ACMD(spiritball)
 	if( !message || !*message || (number = atoi(message)) < 0 || number > max_spiritballs )
 	{
 		char msg[CHAT_SIZE_MAX];
-		safesnprintf(msg, sizeof(msg), msg_txt(1028), max_spiritballs); // Please enter a party name (usage: @party <party_name>).
+		safesnprintf(msg, sizeof(msg), msg_txt(1028), max_spiritballs); // Please enter an amount (usage: @spiritball <number: 0-%d>).
 		clif->message(fd, msg);
 		return false;
 	}
@@ -9448,7 +9448,9 @@ void atcommand_basecommands(void) {
 		ACMD_DEF2("allstats", stat_all),
 		ACMD_DEF2("block", char_block),
 		ACMD_DEF2("ban", char_ban),
+		ACMD_DEF2("charban", char_ban),/* char-specific ban time */
 		ACMD_DEF2("unblock", char_unblock),
+		ACMD_DEF2("charunban", char_unban),/* char-specific ban time */
 		ACMD_DEF2("unban", char_unban),
 		ACMD_DEF2("mount", mount_peco),
 		ACMD_DEF(guildspy),
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 87ec71ec5..56572d492 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -752,7 +752,7 @@ int chrif_changeemail(int id, const char *actual_email, const char *new_email) {
  * S 2b0e <accid>.l <name>.24B <type>.w { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w }
  * Send an account modification request to the login server (via char server).
  * type of operation:
- *   1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5)
+ *   1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5), 6: charban
  *------------------------------------------*/
 int chrif_char_ask_name(int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second) {
 	
@@ -764,7 +764,7 @@ int chrif_char_ask_name(int acc, const char* character_name, unsigned short oper
 	safestrncpy((char*)WFIFOP(chrif->fd,6), character_name, NAME_LENGTH);
 	WFIFOW(chrif->fd,30) = operation_type;
 	
-	if ( operation_type == 2 ) {
+	if ( operation_type == 2 || operation_type == 6 ) {
 		WFIFOW(chrif->fd,32) = year;
 		WFIFOW(chrif->fd,34) = month;
 		WFIFOW(chrif->fd,36) = day;
@@ -800,7 +800,7 @@ int chrif_changesex(struct map_session_data *sd) {
  * R 2b0f <accid>.l <name>.24B <type>.w <answer>.w
  * Processing a reply to chrif->char_ask_name() (request to modify an account).
  * type of operation:
- *   1: block, 2: ban, 3: unblock, 4: unban, 5: changesex
+ *   1: block, 2: ban, 3: unblock, 4: unban, 5: changesex, 6: charban, 7: charunban
  * type of answer:
  *   0: login-server request done
  *   1: player not found
@@ -811,6 +811,7 @@ void chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, u
 	struct map_session_data* sd;
 	char action[25];
 	char output[256];
+	bool charsrv = ( type == 6 || type == 7 ) ? true : false;
 	
 	sd = map->id2sd(acc);
 	
@@ -819,13 +820,17 @@ void chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, u
 		return;
 	}
 
+	/* re-use previous msg_txt */
+	if( type == 6 ) type = 2;
+	if( type == 7 ) type = 4;
+	
 	if( type > 0 && type <= 5 )
 		snprintf(action,25,"%s",msg_txt(427+type)); //block|ban|unblock|unban|change the sex of
 	else
 		snprintf(action,25,"???");
 
 	switch( answer ) {
-		case 0 : sprintf(output, msg_txt(424), action, NAME_LENGTH, player_name); break;
+		case 0 : sprintf(output, msg_txt(charsrv?434:424), action, NAME_LENGTH, player_name); break;
 		case 1 : sprintf(output, msg_txt(425), NAME_LENGTH, player_name); break;
 		case 2 : sprintf(output, msg_txt(426), action, NAME_LENGTH, player_name); break;
 		case 3 : sprintf(output, msg_txt(427), action, NAME_LENGTH, player_name); break;
@@ -980,7 +985,7 @@ int chrif_accountban(int fd) {
 	}
 
 	sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
-	if (RFIFOB(fd,6) == 0) { // 0: change of statut, 1: ban
+	if (RFIFOB(fd,6) == 0) { // 0: change of statut
 		int ret_status = RFIFOL(fd,7); // status or final date of a banishment
 		if(0<ret_status && ret_status<=9)
 			clif->message(sd->fd, msg_txt(411+ret_status));
@@ -988,13 +993,20 @@ int chrif_accountban(int fd) {
 			clif->message(sd->fd, msg_txt(421));
 		else
 			clif->message(sd->fd, msg_txt(420)); //"Your account has not more authorised."
-	} else if (RFIFOB(fd,6) == 1) { // 0: change of statut, 1: ban
+	} else if (RFIFOB(fd,6) == 1) { // 1: ban
 		time_t timestamp;
 		char tmpstr[2048];
 		timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment
 		strcpy(tmpstr, msg_txt(423)); //"Your account has been banished until "
 		strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(&timestamp));
 		clif->message(sd->fd, tmpstr);
+	} else if (RFIFOB(fd,6) == 2) { // 2: change of status for character
+		time_t timestamp;
+		char tmpstr[2048];
+		timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment
+		strcpy(tmpstr, msg_txt(433)); //"This character has been banned until  "
+		strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(&timestamp));
+		clif->message(sd->fd, tmpstr);
 	}
 
 	set_eof(sd->fd); // forced to disconnect for the change
diff --git a/src/map/clif.c b/src/map/clif.c
index d84a0dea8..6740c7a74 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -5634,7 +5634,38 @@ void clif_displaymessage2(const int fd, const char* mes) {
 		aFree(message);		
 	}
 }
+/* oh noo! another version of 0x8e! */
+void clif_displaymessage_sprintf(const int fd, const char* mes, ...) {
+	va_list ap;
 
+	if( fd == -2 ) {
+		ShowInfo("HCP: ");
+		va_start(ap,mes);
+		_vShowMessage(MSG_NONE,mes,ap);
+		va_end(ap);
+		ShowMessage("\n");
+	} else if ( fd > 0 ) {
+		int len = 1;
+		char *ptr;
+		
+		WFIFOHEAD(fd, 5 + 255);/* ensure the maximum */
+
+		/* process */
+		va_start(ap,mes);
+		len += vsnprintf((char *)WFIFOP(fd,4), 255, mes, ap);
+		va_end(ap);
+
+		/* adjusting */
+		ptr = (char *)WFIFOP(fd,4);
+		ptr[len - 1] = '\0';
+		
+		/* */
+		WFIFOW(fd,0) = 0x8e;
+		WFIFOW(fd,2) = 5 + len; // 4 + len + NULL teminate
+		
+		WFIFOSET(fd, 5 + len);
+	}
+}
 /// Send broadcast message in yellow or blue without font formatting (ZC_BROADCAST).
 /// 009a <packet len>.W <message>.?B
 void clif_broadcast(struct block_list* bl, const char* mes, int len, int type, enum send_target target)
@@ -18407,6 +18438,7 @@ void clif_defaults(void) {
 	clif->msgtable_num = clif_msgtable_num;
 	clif->message = clif_displaymessage;
 	clif->messageln = clif_displaymessage2;
+	clif->messages = clif_displaymessage_sprintf;
 	clif->colormes = clif_colormes;
 	clif->process_message = clif_process_message;
 	clif->wisexin = clif_wisexin;
diff --git a/src/map/clif.h b/src/map/clif.h
index e50af7432..043f7dd3a 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -787,6 +787,8 @@ struct clif_interface {
 	void (*msgtable_num) (int fd, int line, int num);
 	void (*message) (const int fd, const char* mes);
 	void (*messageln) (const int fd, const char* mes);
+	/* message+s(printf) */
+	void (*messages) (const int fd, const char* mes, ...);
 	int (*colormes) (int fd, enum clif_colors color, const char* msg);
 	bool (*process_message) (struct map_session_data* sd, int format, char** name_, int* namelen_, char** message_, int* messagelen_);
 	void (*wisexin) (struct map_session_data *sd,int type,int flag);
-- 
cgit v1.2.3-70-g09d2


From cf19b26d50ac96111e44c33a80afd1f1ea935cec Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Tue, 24 Dec 2013 02:03:04 -0200
Subject: Christmas Patch - 2013-12-23 Support

Info:
http://hercules.ws/board/topic/3614-christmas-patch-gifto/
Signed-off-by: shennetsind <ind@henn.et>
---
 db/const.txt                             |    6 +
 doc/sample/npc_trader_sample.txt         |   58 +
 doc/script_commands.txt                  |   64 +
 npc/merchants/shops.txt                  | 2240 +++++++++++++++++++++++++++---
 sql-files/main.sql                       |   12 +
 sql-files/upgrades/2013-12-24--00-15.sql |    8 +
 sql-files/upgrades/index.txt             |    1 +
 src/common/mmo.h                         |    2 +-
 src/map/atcommand.c                      |   27 +-
 src/map/clif.c                           |  224 ++-
 src/map/clif.h                           |    8 +
 src/map/map.c                            |    3 +-
 src/map/npc.c                            |  566 ++++++--
 src/map/npc.h                            |   46 +-
 src/map/packets.h                        |   43 +
 src/map/packets_struct.h                 |   44 +
 src/map/script.c                         |  277 +++-
 src/map/status.c                         |  324 ++---
 src/map/status.h                         |   51 +-
 19 files changed, 3500 insertions(+), 504 deletions(-)
 create mode 100644 doc/sample/npc_trader_sample.txt
 create mode 100644 sql-files/upgrades/2013-12-24--00-15.sql

(limited to 'sql-files/main.sql')

diff --git a/db/const.txt b/db/const.txt
index 8e7807695..ab14afca2 100644
--- a/db/const.txt
+++ b/db/const.txt
@@ -1257,6 +1257,7 @@ SC_MTF_MLEATKED 569
 SC_MTF_CRIDAMAGE 570
 SC_MOONSTAR	571
 SC_SUPER_STAR	572
+SC_OKTOBERFEST	573
 
 e_gasp	0
 e_what	1
@@ -3348,3 +3349,8 @@ IOT_GUILD	3
 
 false	0
 true	1
+
+NST_ZENY	0
+NST_CASH	1
+NST_MARKET	2
+NST_CUSTOM	3
diff --git a/doc/sample/npc_trader_sample.txt b/doc/sample/npc_trader_sample.txt
new file mode 100644
index 000000000..abc87f6b4
--- /dev/null
+++ b/doc/sample/npc_trader_sample.txt
@@ -0,0 +1,58 @@
+//===== Hercules Script =======================================
+//= Sample: NPC Trader
+//===== By: ==================================================
+//= Hercules Dev Team
+//===== Current Version: =====================================
+//= 20131223
+//===== Description: ========================================= 
+//= Demonstrates NPC Trader.
+//============================================================
+
+/* ordinary zeny trader */
+prontera,152,151,1	trader	TestTrader	952,{
+	OnInit:
+	sellitem 2115;
+	end;
+}
+/* ordinary cash trader */
+prontera,152,152,1	trader	TestTraderCash	952,{
+	OnInit:
+	tradertype(NST_CASH);
+	sellitem 2115;
+	end;
+}
+/* custom npc trader */
+prontera,153,152,1	trader	TestCustom2	952,{
+	OnInit:
+	tradertype(NST_CUSTOM);
+	sellitem 501,2;
+	end;
+	
+/* allows currency to be item 501 and 502 */
+OnCountFunds:
+	setcurrency(countitem(501),countitem(502));
+	end;
+
+/* receives @price (total cost) and @points (the secondary input field for cash windows) */
+OnPayFunds:
+	dispbottom "Hi: price="+@price+" and points="+@points;
+	if( countitem(502) < @points || countitem(501) < @price-@points )
+		end;
+	delitem 502,@points;
+	delitem 501,@price-@points;
+	purchaseok();
+	end;
+}
+/* demonstrates Market Trader */
+prontera,150,160,6	trader	HaiMarket	952,{
+OnInit:
+	tradertype(NST_MARKET);
+	sellitem 501,-1,49;
+	end;
+	
+OnClock0000://resupplies red potions on midnight
+OnMyResupply:
+	if( shopcount(501) < 20 )
+		sellitem 501,-1,49;
+	end;
+}
\ No newline at end of file
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 9186ba714..f5f2d7d9c 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -1120,6 +1120,7 @@ From here on, we will have the commands sorted as follow:
 9.- Battleground commands.
 10.- Mercenary commands.
 11.- Queue commands.
+12.- NPC Trader commands
 
 
 =====================
@@ -8471,3 +8472,66 @@ Deletes a queue iterator from memory and returns 1 when it fails,
 otherwise 0 is returned.
 
 ---------------------------------------
+
+======================
+|12.- NPC Trader Commands.|
+======================
+---------------------------------------
+Commands that control NPC Trader Shops
+See /doc/sample/npc_trader_sample.txt
+
+---------------------------------------
+
+*openshop({NPC_Name});
+
+opens the trader shop from the currently-attached npc unless,
+when the optional NPC_Name param is used.
+
+---------------------------------------
+
+*sellitem <Item_ID>{,<price>{,<qty>}};
+
+adds (or modifies) <Item_ID> data to the shop,
+when <price> is not provided (or when it is -1) itemdb default is used.
+qty is only necessary for NST_MARKET trader types.
+
+when <Item_ID> is already in the shop,
+the previous data (price/qty), is overwritten with the new.
+
+---------------------------------------
+
+*stopselling <Item_ID>;
+
+attempts to remove <Item_ID> from the current shop list.
+
+---------------------------------------
+
+*setcurrency <Val1>{,<Val2>};
+
+updates the currently attached player shop funds.
+
+---------------------------------------
+
+*tradertype(<Type>);
+
+Modifies the npc trader type, item list is cleared upon modifiying the value.
+By default, all npcs staart with tradertype(NST_ZENY);
+
+- NST_ZENY (0) Normal Zeny Shop
+- NST_CASH (1) Normal Cash Shop
+- NST_MARKET (2) Normal NPC Market Shop (where items have limited availability and need to be refurbished)
+- NST_CUSTOM (3) Custom Shop (any currency, item/var/etca, check sample)
+
+---------------------------------------
+
+*purchaseok();
+
+Signs that the transaction (on a NST_CUSTOM trader) has been successful.
+
+---------------------------------------
+
+*shopcount(<Item_ID>);
+
+Returns the amount of still-available <Item_ID> in the shop (on a NST_MARKET trader).
+
+---------------------------------------
diff --git a/npc/merchants/shops.txt b/npc/merchants/shops.txt
index b20874ffb..a1ab894d0 100644
--- a/npc/merchants/shops.txt
+++ b/npc/merchants/shops.txt
@@ -1,9 +1,7 @@
 //===== Hercules Script ======================================
 //= Shops
-//===== By: ==================================================
-//= rAthena Dev Team
 //===== Current Version: =====================================
-//= 3.4
+//= 3.5
 //===== Description: =========================================
 //= Town shop NPCs.
 //===== Additional Comments: =================================
@@ -36,291 +34,2169 @@
 //= 3.2 Added Missing Items to the pet Groomers in prontera, payon, and yuno. BugReport:6680[Spre]
 //= 3.3 Moved more shops to Renewal file. [Euphy]
 //= 3.4 Moved Izlude shops to pre-re/re paths. [Streusel]
+//= 3.5 Converted to trader format [Yommy]
 //============================================================
 
 //=======================================================
 // Alberta
 //=======================================================
-alb2trea,87,65,5	shop	Tool Dealer#alb	4_M_01,1750:-1,1751:-1,1752:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1
-alberta_in,165,96,0	shop	Item Collector#alb	1_F_MERCHANT_02,911:-1,528:-1
-alberta_in,182,97,0	shop	Tool Dealer#alb2	1_F_MERCHANT_01,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,2243:-1
-alberta_in,180,15,0	shop	Armor Dealer#alb	4W_F_01,2101:-1,2103:-1,2401:-1,2403:-1,2405:-1,2501:-1,2503:-1,2505:-1,2203:-1,2201:-1,2205:-1,2226:-1,2301:-1,2303:-1,2305:-1,2321:-1,2328:-1,2332:-1,2307:-1,2309:-1,2312:-1,2314:-1,2628:-1
-alberta_in,188,21,0	shop	Weapon Dealer#alb	1_M_03,1750:-1,1751:-1,1101:-1,1104:-1,1107:-1,1201:-1,1204:-1,1207:-1,1601:-1,1701:-1,1301:-1,1351:-1,1354:-1,1357:-1,1360:-1
-alberta_in,175,97,4	shop	Weapon Dealer#alb2	4_KID01,1146:-1,1245:-1
-alberta_in,176,81,3	shop	Trading Merchant#alb	4_M_HUMERCHANT,13200:-1,13201:-1,13202:-1,13150:-1,13102:-1,13151:-1,13154:-1,13155:-1,13163:-1,13165:-1,13168:-1
+alb2trea,87,65,5	trader	Tool Dealer#alb	4_M_01,{
+OnInit:
+	sellitem Arrow;
+	sellitem Silver_Arrow;
+	sellitem Fire_Arrow;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+}
+
+alberta_in,165,96,0	trader	Item Collector#alb	1_F_MERCHANT_02,{
+OnInit:
+	sellitem Scell;
+	sellitem Monster's_Feed;
+}
+
+alberta_in,182,97,0	trader	Tool Dealer#alb2	1_F_MERCHANT_01,{
+OnInit:
+	sellitem Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Spinning_Eyes;
+}
+
+alberta_in,180,15,0	trader	Armor Dealer#alb	4W_F_01,{
+OnInit:
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Sandals;
+	sellitem Shoes;
+	sellitem Boots;
+	sellitem Hood;
+	sellitem Muffler;
+	sellitem Manteau;
+	sellitem Glasses;
+	sellitem Sunglasses;
+	sellitem Diver's_Goggles;
+	sellitem Cap;
+	sellitem Cotton_Shirt;
+	sellitem Leather_Jacket;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Wooden_Mail;
+	sellitem Silver_Robe;
+	sellitem Mantle;
+	sellitem Coat;
+	sellitem Padded_Armor;
+	sellitem Chain_Mail;
+	sellitem Novice_Armlet;
+}
+
+alberta_in,188,21,0	trader	Weapon Dealer#alb	1_M_03,{
+OnInit:
+	sellitem Arrow;
+	sellitem Silver_Arrow;
+	sellitem Sword;
+	sellitem Falchion;
+	sellitem Blade;
+	sellitem Knife;
+	sellitem Cutter;
+	sellitem Main_Gauche;
+	sellitem Rod;
+	sellitem Bow;
+	sellitem Axe;
+	sellitem Battle_Axe;
+	sellitem Hammer;
+	sellitem Buster;
+	sellitem Two_Handed_Axe;
+}
+
+alberta_in,175,97,4	trader	Weapon Dealer#alb2	4_KID01,{
+OnInit:
+	sellitem Town_Sword;
+	sellitem Cinquedea;
+}
+
+alberta_in,176,81,3	trader	Trading Merchant#alb	4_M_HUMERCHANT,{
+OnInit:
+	sellitem Bullet;
+	sellitem Silver_Bullet;
+	sellitem Shell_Of_Blood;
+	sellitem Branch;
+	sellitem Crimson_Bolt;
+	sellitem The_Cyclone;
+	sellitem Rolling_Stone;
+	sellitem Black_Rose;
+	sellitem Long_Barrel;
+	sellitem Jungle_Carbine;
+	sellitem Thunder_P;
+}
+
 
 //=======================================================
 // Al De Baran
 //=======================================================
-aldeba_in,20,60,0	shop	Armor Dealer#alde	4W_F_01,2228:-1,2103:-1,2105:-1,2307:-1,2309:-1,2312:-1,2314:-1,2316:-1,2505:-1,2405:-1,2628:-1,2627:-1
-aldeba_in,28,54,0	shop	Weapon Dealer#alde	1_M_03,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1219:-1,1222:-1
-aldeba_in,22,47,4	shop	Weapon Dealer#alde2	4_M_06,1146:-1,1245:-1
-aldeba_in,94,56,5	shop	Tool Dealer#alde	4_M_01,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,611:-1,610:-1
-alde_alche,38,184,3	shop	Material Seller#alche	4_M_SAGE_C,7143:-1,7141:-1,7140:-1,6248:-1,6250:-1,6251:-1,6255:-1,6261:-1,6262:-1,6297:-1
+aldeba_in,20,60,0	trader	Armor Dealer#alde	4W_F_01,{
+OnInit:
+	sellitem Helm;
+	sellitem Buckler;
+	sellitem Shield;
+	sellitem Mantle;
+	sellitem Coat;
+	sellitem Padded_Armor;
+	sellitem Chain_Mail;
+	sellitem Plate_Armor;
+	sellitem Manteau;
+	sellitem Boots;
+	sellitem Novice_Armlet;
+	sellitem Belt;
+}
+
+aldeba_in,28,54,0	trader	Weapon Dealer#alde	1_M_03,{
+OnInit:
+	sellitem Knife;
+	sellitem Cutter;
+	sellitem Main_Gauche;
+	sellitem Dirk;
+	sellitem Dagger;
+	sellitem Stiletto;
+	sellitem Gladius;
+	sellitem Damascus;
+}
+
+aldeba_in,22,47,4	trader	Weapon Dealer#alde2	4_M_06,{
+OnInit:
+	sellitem Town_Sword;
+	sellitem Cinquedea;
+}
+
+aldeba_in,94,56,5	trader	Tool Dealer#alde	4_M_01,{
+OnInit:
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Spectacles;
+	sellitem Leaf_Of_Yggdrasil;
+}
+
+alde_alche,38,184,3	trader	Material Seller#alche	4_M_SAGE_C,{
+OnInit:
+	sellitem Life_Force_Pot;
+	sellitem Yggdrasilberry_Dew;
+	sellitem Seed_Of_Life;
+	sellitem Melange_Pot;
+	sellitem Cooking_Skewer;
+	sellitem Black_Charcoal;
+	sellitem Large_Cookpot;
+	sellitem Fine_Noodle;
+	sellitem Cool_Gravy;
+	sellitem Bottle_To_Throw;
+}
+
 
 //=======================================================
 // Amatsu
 //=======================================================
-ama_in01,89,28,5	shop	Armor Dealer#ama	4_F_JPN2,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2101:-1,2103:-1,2305:-1,2321:-1,2332:-1,2328:-1,2627:-1
-ama_in01,102,28,3	shop	Weapon Dealer#ama	4_M_JPNOJI,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1
-ama_in01,24,30,5	shop	Tool Dealer#ama	4_M_JPN,1750:-1,1770:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
+ama_in01,89,28,5	trader	Armor Dealer#ama	4_F_JPN2,{
+OnInit:
+	sellitem Bandana;
+	sellitem Sandals;
+	sellitem Shoes;
+	sellitem Hood;
+	sellitem Muffler;
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Silver_Robe;
+	sellitem Wooden_Mail;
+	sellitem Belt;
+}
+
+ama_in01,102,28,3	trader	Weapon Dealer#ama	4_M_JPNOJI,{
+OnInit:
+	sellitem Main_Gauche;
+	sellitem Stiletto;
+	sellitem Blade;
+	sellitem Ring_Pommel_Saber;
+	sellitem Katana;
+	sellitem Bastard_Sword;
+	sellitem Pike;
+	sellitem Partizan;
+	sellitem Hammer;
+	sellitem Chain;
+}
+
+ama_in01,24,30,5	trader	Tool Dealer#ama	4_M_JPN,{
+OnInit:
+	sellitem Arrow;
+	sellitem Iron_Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+}
+
 // Ninja Shops
-que_ng,72,31,2	shop	Boonji#nin	4_M_01,13250:-1,13251:-1,13252:-1,13253:-1,13254:-1
-que_ng,73,26,5	shop	Boonray#nin	4_M_01,2117:-1,7521:-1,7522:-1,7523:-1,7524:-1
+que_ng,72,31,2	trader	Boonji#nin	4_M_01,{
+OnInit:
+	sellitem Shuriken;
+	sellitem Nimbus_Shuriken;
+	sellitem Flash_Shuriken;
+	sellitem Sharp_Leaf_Shuriken;
+	sellitem Thorn_Needle_Shuriken;
+}
+
+que_ng,73,26,5	trader	Boonray#nin	4_M_01,{
+OnInit:
+	sellitem Arm_Guard;
+	sellitem Flame_Stone;
+	sellitem Ice_Stone;
+	sellitem Wind_Stone;
+	sellitem Shadow_Orb;
+}
+
 
 //=======================================================
 // Ayothaya
 //=======================================================
-ayo_in01,18,182,1	shop	Tool Dealer#ayo	4_F_THAISHAMAN,1750:-1,1770:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-ayo_in01,90,192,3	shop	Weapon Dealer#ayo	4_M_THAIONGBAK,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1
-ayo_in01,90,160,1	shop	Armor Dealer#ayo	4_M_THAIOLD,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2101:-1,2103:-1,2305:-1,2321:-1,2332:-1,2328:-1,2627:-1
+ayo_in01,18,182,1	trader	Tool Dealer#ayo	4_F_THAISHAMAN,{
+OnInit:
+	sellitem Arrow;
+	sellitem Iron_Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+}
+
+ayo_in01,90,192,3	trader	Weapon Dealer#ayo	4_M_THAIONGBAK,{
+OnInit:
+	sellitem Main_Gauche;
+	sellitem Stiletto;
+	sellitem Blade;
+	sellitem Ring_Pommel_Saber;
+	sellitem Katana;
+	sellitem Bastard_Sword;
+	sellitem Pike;
+	sellitem Partizan;
+	sellitem Hammer;
+	sellitem Chain;
+}
+
+ayo_in01,90,160,1	trader	Armor Dealer#ayo	4_M_THAIOLD,{
+OnInit:
+	sellitem Bandana;
+	sellitem Sandals;
+	sellitem Shoes;
+	sellitem Hood;
+	sellitem Muffler;
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Silver_Robe;
+	sellitem Wooden_Mail;
+	sellitem Belt;
+}
+
 
 //=======================================================
 // Brasilis
 //=======================================================
-brasilis,252,257,3	shop	Tool Dealer#bra	4_F_BRZ_WOMAN,645:-1,656:-1,601:-1,602:-1,611:-1,1065:-1,610:-1
-brasilis,244,243,3	shop	Weapon Dealer#bra	4_M_BRZ_MAN2,1407:-1,1457:-1,1354:-1,1519:-1,13003:-1
-brasilis,201,309,3	shop	Pet Groomer#bra	4_M_BRZ_MAN1,537:-1,643:-1
-brasilis,221,128,3	shop	Fruit Gardener#bra	4_M_BRZ_MAN2,11515:-1,513:-1,11516:-1
+brasilis,252,257,3	trader	Tool Dealer#bra	4_F_BRZ_WOMAN,{
+OnInit:
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Spectacles;
+	sellitem Booby_Trap;
+	sellitem Leaf_Of_Yggdrasil;
+}
+
+brasilis,244,243,3	trader	Weapon Dealer#bra	4_M_BRZ_MAN2,{
+OnInit:
+	sellitem Pike;
+	sellitem Partizan;
+	sellitem Hammer;
+	sellitem Chain;
+	sellitem Coward;
+}
+
+brasilis,201,309,3	trader	Pet Groomer#bra	4_M_BRZ_MAN1,{
+OnInit:
+	sellitem Pet_Food;
+	sellitem Pet_Incubator;
+}
+
+brasilis,221,128,3	trader	Fruit Gardener#bra	4_M_BRZ_MAN2,{
+OnInit:
+	sellitem Coconut;
+	sellitem Banana;
+	sellitem Asai_Fruit;
+}
+
 
 //=======================================================
 // Comodo
 //=======================================================
-cmd_in01,117,165,4	shop	Armor Dealer#cmd	4W_F_01,2226:-1,2228:-1,2103:-1,2105:-1,2405:-1,2503:-1,2505:-1,2305:-1,2321:-1,2307:-1,2309:-1,2335:-1,2312:-1,2314:-1,2316:-1
-cmd_in01,128,165,2	shop	Weapon Dealer#cmd	1_M_03,1901:-1,1903:-1,1905:-1,1909:-1,1911:-1,1907:-1,1950:-1,1952:-1,1954:-1,1958:-1,1960:-1,1956:-1
-cmd_in01,79,182,5	shop	Tool Dealer#cmd	4_M_01,1770:-1,501:-1,502:-1,503:-1,504:-1,645:-1,656:-1,657:-1,601:-1,602:-1,611:-1,1065:-1
-comodo,296,125,4	shop	Souvenir Vendor#cmd	4W_F_01,965:-1,964:-1
-cmd_fild07,257,126,5	shop	Tool Dealer#cmd2	4_M_01,1770:-1,501:-1,502:-1,503:-1,504:-1,645:-1,656:-1,601:-1,602:-1,611:-1,1065:-1
-cmd_fild07,250,98,2	shop	Weapon Dealer#cmd2	1_M_03,1401:-1,1404:-1,1407:-1,1451:-1,1454:-1,1457:-1,1460:-1,1463:-1,1410:-1
-cmd_fild07,277,85,4	shop	Armor Dealer#cmd2	4W_F_01,2226:-1,2228:-1,2103:-1,2105:-1,2405:-1,2503:-1,2505:-1,2305:-1,2321:-1,2307:-1,2309:-1,2335:-1,2312:-1,2314:-1,2316:-1
+cmd_in01,117,165,4	trader	Armor Dealer#cmd	4W_F_01,{
+OnInit:
+	sellitem Cap;
+	sellitem Helm;
+	sellitem Buckler;
+	sellitem Shield;
+	sellitem Boots;
+	sellitem Muffler;
+	sellitem Manteau;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Mantle;
+	sellitem Coat;
+	sellitem Thief_Clothes;
+	sellitem Padded_Armor;
+	sellitem Chain_Mail;
+	sellitem Plate_Armor;
+}
+
+cmd_in01,128,165,2	trader	Weapon Dealer#cmd	1_M_03,{
+OnInit:
+	sellitem Violin;
+	sellitem Mandolin;
+	sellitem Lute;
+	sellitem Harp;
+	sellitem Guh_Moon_Goh;
+	sellitem Guitar;
+	sellitem Rope;
+	sellitem Line;
+	sellitem Wire;
+	sellitem Tail;
+	sellitem Whip;
+	sellitem Rante;
+}
+
+cmd_in01,79,182,5	trader	Tool Dealer#cmd	4_M_01,{
+OnInit:
+	sellitem Iron_Arrow;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Berserk_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Spectacles;
+	sellitem Booby_Trap;
+}
+
+comodo,296,125,4	trader	Souvenir Vendor#cmd	4W_F_01,{
+OnInit:
+	sellitem Clam_Shell;
+	sellitem Crap_Shell;
+}
+
+cmd_fild07,257,126,5	trader	Tool Dealer#cmd2	4_M_01,{
+OnInit:
+	sellitem Iron_Arrow;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Spectacles;
+	sellitem Booby_Trap;
+}
+
+cmd_fild07,250,98,2	trader	Weapon Dealer#cmd2	1_M_03,{
+OnInit:
+	sellitem Javelin;
+	sellitem Spear;
+	sellitem Pike;
+	sellitem Guisarme;
+	sellitem Glaive;
+	sellitem Partizan;
+	sellitem Trident;
+	sellitem Halberd;
+	sellitem Lance;
+}
+
+cmd_fild07,277,85,4	trader	Armor Dealer#cmd2	4W_F_01,{
+OnInit:
+	sellitem Cap;
+	sellitem Helm;
+	sellitem Buckler;
+	sellitem Shield;
+	sellitem Boots;
+	sellitem Muffler;
+	sellitem Manteau;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Mantle;
+	sellitem Coat;
+	sellitem Thief_Clothes;
+	sellitem Padded_Armor;
+	sellitem Chain_Mail;
+	sellitem Plate_Armor;
+}
+
 
 //=======================================================
 // Einbroch
 //=======================================================
-ein_in01,106,27,4	shop	One Hand Weapon Dealer	4_F_EINWOMAN,1101:-1,1104:-1,1107:-1,1110:-1,1113:-1,1119:-1,1122:-1,1123:-1,1126:-1,1129:-1,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1219:-1,1222:-1,1301:-1,1401:-1,1404:-1,1407:-1,1501:-1,1504:-1,1507:-1,1510:-1,1513:-1,1516:-1,1519:-1,1522:-1,1801:-1,1803:-1,1805:-1,1807:-1,1809:-1,1811:-1
-ein_in01,109,27,4	shop	Two Hand Weapon Dealer	4_F_EINWOMAN,1116:-1,1151:-1,1154:-1,1157:-1,1160:-1,1351:-1,1354:-1,1357:-1,1360:-1,1410:-1,1451:-1,1454:-1,1457:-1,1460:-1,1463:-1,1250:-1,1252:-1,1254:-1
-ein_in01,119,26,4	shop	Weapon Dealer#ein	4_M_EINMAN,1247:-1,1248:-1,1249:-1,13000:-1
-ein_in01,189,15,1	shop	Tool Dealer#ein	4_F_EINWOMAN,1750:-1,1752:-1,1751:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-einbroch,138,66,4	shop	Flu Mask Dealer#ein	4_F_EINWOMAN,5114:-1,2218:-1
-einbroch,82,199,4	shop	Paddler#ein	4_M_EINMAN,512:-1,645:-1,1750:-1,501:-1
+ein_in01,106,27,4	trader	One Hand Weapon Dealer	4_F_EINWOMAN,{
+OnInit:
+	sellitem Sword;
+	sellitem Falchion;
+	sellitem Blade;
+	sellitem Lapier;
+	sellitem Scimiter;
+	sellitem Tsurugi;
+	sellitem Ring_Pommel_Saber;
+	sellitem Haedonggum;
+	sellitem Saber;
+	sellitem Flamberge;
+	sellitem Knife;
+	sellitem Cutter;
+	sellitem Main_Gauche;
+	sellitem Dirk;
+	sellitem Dagger;
+	sellitem Stiletto;
+	sellitem Gladius;
+	sellitem Damascus;
+	sellitem Axe;
+	sellitem Javelin;
+	sellitem Spear;
+	sellitem Pike;
+	sellitem Club;
+	sellitem Mace;
+	sellitem Smasher;
+	sellitem Flail;
+	sellitem Morning_Star;
+	sellitem Sword_Mace;
+	sellitem Chain;
+	sellitem Stunner;
+	sellitem Waghnakh;
+	sellitem Knuckle_Duster;
+	sellitem Hora;
+	sellitem Fist;
+	sellitem Claw;
+	sellitem Finger;
+}
+
+ein_in01,109,27,4	trader	Two Hand Weapon Dealer	4_F_EINWOMAN,{
+OnInit:
+	sellitem Katana;
+	sellitem Slayer;
+	sellitem Bastard_Sword;
+	sellitem Two_Hand_Sword;
+	sellitem Broad_Sword;
+	sellitem Battle_Axe;
+	sellitem Hammer;
+	sellitem Buster;
+	sellitem Two_Handed_Axe;
+	sellitem Lance;
+	sellitem Guisarme;
+	sellitem Glaive;
+	sellitem Partizan;
+	sellitem Trident;
+	sellitem Halberd;
+	sellitem Jur;
+	sellitem Katar;
+	sellitem Jamadhar;
+}
+
+ein_in01,119,26,4	trader	Weapon Dealer#ein	4_M_EINMAN,{
+OnInit:
+	sellitem Kindling_Dagger;
+	sellitem Obsidian_Dagger;
+	sellitem Fisherman's_Dagger;
+	sellitem Jujube_Dagger;
+}
+
+ein_in01,189,15,1	trader	Tool Dealer#ein	4_F_EINWOMAN,{
+OnInit:
+	sellitem Arrow;
+	sellitem Fire_Arrow;
+	sellitem Silver_Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+}
+
+einbroch,138,66,4	trader	Flu Mask Dealer#ein	4_F_EINWOMAN,{
+OnInit:
+	sellitem Fedora;
+	sellitem Flu_Mask;
+}
+
+einbroch,82,199,4	trader	Paddler#ein	4_M_EINMAN,{
+OnInit:
+	sellitem Apple;
+	sellitem Center_Potion;
+	sellitem Arrow;
+	sellitem Red_Potion;
+}
+
 //Official Gunslingers shops.
-que_ng,179,91,3	shop	Chivas Lugal	4_M_HUMERCHANT,13150:-1,13102:-1,13151:-1,13154:-1,13155:-1,13163:-1,13165:-1,13168:-1
-que_ng,180,79,3	shop	Johnny Waiker	4_M_HUMERCHANT,13200:-1,13201:-1,13202:-1
+que_ng,179,91,3	trader	Chivas Lugal	4_M_HUMERCHANT,{
+OnInit:
+	sellitem Branch;
+	sellitem Crimson_Bolt;
+	sellitem The_Cyclone;
+	sellitem Rolling_Stone;
+	sellitem Black_Rose;
+	sellitem Long_Barrel;
+	sellitem Jungle_Carbine;
+	sellitem Thunder_P;
+}
+
+que_ng,180,79,3	trader	Johnny Waiker	4_M_HUMERCHANT,{
+OnInit:
+	sellitem Bullet;
+	sellitem Silver_Bullet;
+	sellitem Shell_Of_Blood;
+}
+
 
 //=======================================================
 // Geffen
 //=======================================================
-geffen_in,26,178,4	shop	Armor Dealer#gef	1_F_01,2628:-1,2101:-1,2107:-1,2401:-1,2501:-1,2230:-1,2301:-1,2303:-1,2305:-1,2321:-1,2332:-1
-geffen_in,30,178,4	shop	Weapon Dealer#gef2	1_M_01,1750:-1,1751:-1,1101:-1,1701:-1,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1601:-1,1604:-1,1607:-1,1610:-1
-geffen_in,22,171,7	shop	Weapon Dealer#gef	4_M_02,1146:-1,1245:-1
-geffen_in,74,144,0	shop	Trader#gef	1_F_01,911:-1,910:-1,912:-1
-geffen_in,77,167,0	shop	Tool Dealer#gef	1_F_03,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,2241:-1
-geffen_in,77,173,0	shop	Magical Item Seller#gef	1_M_WIZARD,717:-1,1601:-1,1604:-1,1607:-1,1610:-1,2232:-1,2321:-1,2332:-1
-geffen_in,171,123,4	shop	Tool Dealer#gef2	1_M_WIZARD,1092:-1,1093:-1
-geffen,193,152,4	shop	Pet Groomer#gef	4_F_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,554:-1,6113:-1,6114:-1,6115:-1
+geffen_in,26,178,4	trader	Armor Dealer#gef	1_F_01,{
+OnInit:
+	sellitem Novice_Armlet;
+	sellitem Guard;
+	sellitem Mirror_Shield;
+	sellitem Sandals;
+	sellitem Hood;
+	sellitem Gemmed_Sallet;
+	sellitem Cotton_Shirt;
+	sellitem Leather_Jacket;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Silver_Robe;
+}
+
+geffen_in,30,178,4	trader	Weapon Dealer#gef2	1_M_01,{
+OnInit:
+	sellitem Arrow;
+	sellitem Silver_Arrow;
+	sellitem Sword;
+	sellitem Bow;
+	sellitem Knife;
+	sellitem Cutter;
+	sellitem Main_Gauche;
+	sellitem Dirk;
+	sellitem Dagger;
+	sellitem Stiletto;
+	sellitem Rod;
+	sellitem Wand;
+	sellitem Staff;
+	sellitem Arc_Wand;
+}
+
+geffen_in,22,171,7	trader	Weapon Dealer#gef	4_M_02,{
+OnInit:
+	sellitem Town_Sword;
+	sellitem Cinquedea;
+}
+
+geffen_in,74,144,0	trader	Trader#gef	1_F_01,{
+OnInit:
+	sellitem Scell;
+	sellitem Garlet;
+	sellitem Zargon;
+}
+
+geffen_in,77,167,0	trader	Tool Dealer#gef	1_F_03,{
+OnInit:
+	sellitem Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Granpa_Beard;
+}
+
+geffen_in,77,173,0	trader	Magical Item Seller#gef	1_M_WIZARD,{
+OnInit:
+	sellitem Blue_Gemstone;
+	sellitem Rod;
+	sellitem Wand;
+	sellitem Staff;
+	sellitem Arc_Wand;
+	sellitem Circlet;
+	sellitem Silk_Robe;
+	sellitem Silver_Robe;
+}
+
+geffen_in,171,123,4	trader	Tool Dealer#gef2	1_M_WIZARD,{
+OnInit:
+	sellitem Empty_Cylinder;
+	sellitem Empty_Potion;
+}
+
+geffen,193,152,4	trader	Pet Groomer#gef	4_F_TELEPORTER,{
+OnInit:
+	sellitem Pet_Food;
+	sellitem Pet_Incubator;
+	sellitem Backpack;
+	sellitem Rocker_Glasses;
+	sellitem Mojji;
+	sellitem Vital_Flower_;
+	sellitem Flame_Gemstone;
+	sellitem Bun_;
+}
+
 
 //=======================================================
 // Gonryun
 //=======================================================
-gonryun,147,84,5	shop	Tool Dealer#gon	4_M_TWOLDMAN,1750:-1,1770:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-gonryun,174,101,3	shop	Weapon Dealer#gon	4_M_TWBOY,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1
-gonryun,173,84,3	shop	Armor Dealer#gon	4_F_TWGIRL,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2101:-1,2103:-1,2305:-1,2321:-1,2332:-1,2328:-1,2627:-1
+gonryun,147,84,5	trader	Tool Dealer#gon	4_M_TWOLDMAN,{
+OnInit:
+	sellitem Arrow;
+	sellitem Iron_Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+}
+
+gonryun,174,101,3	trader	Weapon Dealer#gon	4_M_TWBOY,{
+OnInit:
+	sellitem Main_Gauche;
+	sellitem Stiletto;
+	sellitem Blade;
+	sellitem Ring_Pommel_Saber;
+	sellitem Katana;
+	sellitem Bastard_Sword;
+	sellitem Pike;
+	sellitem Partizan;
+	sellitem Hammer;
+	sellitem Chain;
+}
+
+gonryun,173,84,3	trader	Armor Dealer#gon	4_F_TWGIRL,{
+OnInit:
+	sellitem Bandana;
+	sellitem Sandals;
+	sellitem Shoes;
+	sellitem Hood;
+	sellitem Muffler;
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Silver_Robe;
+	sellitem Wooden_Mail;
+	sellitem Belt;
+}
+
 
 //=======================================================
 // Hugel
 //=======================================================
-hugel,105,169,5	shop	Vendor from Milk Ranch#h	4_F_01,519:-1
-hugel,77,167,3	shop	Vegetable Gardener#hu	4_F_HUGRANMA,522:-1,512:-1,513:-1,515:-1,516:-1,535:-1
-hu_in01,241,368,2	shop	Tool Dealer#hu	1_M_INNKEEPER,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-hu_in01,252,368,3	shop	Tool Dealer#hu2	4_F_01,717:-1,2201:-1,910:-1,528:-1
-hu_in01,100,390,3	shop	Bow Dealer#hu	4_M_04,1701:-1,1707:-1,1718:-1,1714:-1
-hu_in01,94,390,3	shop	Weapon Dealer#hu	4_M_HUMAN_01,1116:-1,1154:-1,1354:-1,1201:-1
-hu_in01,94,313,3	shop	Armor Dealer#hu	4_M_04,2224:-1,2232:-1,2226:-1,2101:-1,2103:-1,2401:-1,2501:-1,2307:-1,2105:-1
+hugel,105,169,5	trader	Vendor from Milk Ranch#h	4_F_01,{
+OnInit:
+	sellitem Milk;
+}
+
+hugel,77,167,3	trader	Vegetable Gardener#hu	4_F_HUGRANMA,{
+OnInit:
+	sellitem Fruit_Of_Mastela;
+	sellitem Apple;
+	sellitem Banana;
+	sellitem Carrot;
+	sellitem Sweet_Potato;
+	sellitem Pumpkin;
+}
+
+hu_in01,241,368,2	trader	Tool Dealer#hu	1_M_INNKEEPER,{
+OnInit:
+	sellitem Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+}
+
+hu_in01,252,368,3	trader	Tool Dealer#hu2	4_F_01,{
+OnInit:
+	sellitem Blue_Gemstone;
+	sellitem Sunglasses;
+	sellitem Garlet;
+	sellitem Monster's_Feed;
+}
+
+hu_in01,100,390,3	trader	Bow Dealer#hu	4_M_04,{
+OnInit:
+	sellitem Bow;
+	sellitem Great_Bow;
+	sellitem Hunter_Bow;
+	sellitem Kakkung;
+}
+
+hu_in01,94,390,3	trader	Weapon Dealer#hu	4_M_HUMAN_01,{
+OnInit:
+	sellitem Katana;
+	sellitem Bastard_Sword;
+	sellitem Hammer;
+	sellitem Knife;
+}
+
+hu_in01,94,313,3	trader	Armor Dealer#hu	4_M_04,{
+OnInit:
+	sellitem Goggle;
+	sellitem Circlet;
+	sellitem Cap;
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Sandals;
+	sellitem Hood;
+	sellitem Mantle;
+	sellitem Shield;
+}
+
 
 //=======================================================
 // Izlude
 //=======================================================
-izlude_in,60,127,4	shop	Weapon Dealer#iz	1_F_MARIA,1750:-1,1751:-1,1701:-1,1601:-1,1201:-1,1204:-1,1207:-1,1101:-1,1104:-1,1107:-1,1116:-1,1151:-1,1154:-1,1157:-1,1160:-1,1301:-1
-izlude_in,70,127,4	shop	Armor Dealer#iz	1_M_SIZ,2103:-1,2105:-1,2403:-1,2405:-1,2503:-1,2505:-1,2226:-1,2228:-1,2303:-1,2305:-1,2328:-1,2307:-1,2309:-1,2312:-1,2314:-1,2316:-1,2628:-1
+izlude_in,60,127,4	trader	Weapon Dealer#iz	1_F_MARIA,{
+OnInit:
+	sellitem Arrow;
+	sellitem Silver_Arrow;
+	sellitem Bow;
+	sellitem Rod;
+	sellitem Knife;
+	sellitem Cutter;
+	sellitem Main_Gauche;
+	sellitem Sword;
+	sellitem Falchion;
+	sellitem Blade;
+	sellitem Katana;
+	sellitem Slayer;
+	sellitem Bastard_Sword;
+	sellitem Two_Hand_Sword;
+	sellitem Broad_Sword;
+	sellitem Axe;
+}
+
+izlude_in,70,127,4	trader	Armor Dealer#iz	1_M_SIZ,{
+OnInit:
+	sellitem Buckler;
+	sellitem Shield;
+	sellitem Shoes;
+	sellitem Boots;
+	sellitem Muffler;
+	sellitem Manteau;
+	sellitem Cap;
+	sellitem Helm;
+	sellitem Leather_Jacket;
+	sellitem Adventure_Suit;
+	sellitem Wooden_Mail;
+	sellitem Mantle;
+	sellitem Coat;
+	sellitem Padded_Armor;
+	sellitem Chain_Mail;
+	sellitem Plate_Armor;
+	sellitem Novice_Armlet;
+}
+
 
 //=======================================================
 // Jawaii
 //=======================================================
-jawaii,186,174,3	shop	Ice Cream Guy#ja	4_M_03,536:-1,536:-1,536:-1,536:-1,536:-1,536:-1,536:-1
+jawaii,186,174,3	trader	Ice Cream Guy#ja	4_M_03,{
+OnInit:
+	sellitem Ice_Cream;
+	sellitem Ice_Cream;
+	sellitem Ice_Cream;
+	sellitem Ice_Cream;
+	sellitem Ice_Cream;
+	sellitem Ice_Cream;
+	sellitem Ice_Cream;
+}
+
 
 //=======================================================
 // Juno
 //=======================================================
-yuno,218,97,5	shop	Tool Dealer#yuno	4_M_02,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1
-yuno,226,107,5	shop	Tool Dealer#yuno1	4_M_01,911:-1,910:-1,912:-1
-yuno,197,114,4	shop	Pet Groomer#yuno	4_F_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,6115:-1,554:-1,6114:-1,6113:-1,6110:-1,6115:-1,6100:-1,6098:-1,6112:-1,6104:-1,6108:-1,6111:-1,6095:-1,6099:-1,6096:-1,6097:-1
-yuno,205,103,4	shop	Mr. King's Shop#yuno	4_M_TELEPORTER,2340:-1,2341:-1,2411:-1,2222:-1,2230:-1,1721:-1
-yuno,163,187,5	shop	Magical Item Seller#yuno	4_F_01,717:-1,1601:-1,1604:-1,1607:-1,1610:-1,2232:-1,2321:-1,2332:-1
-yuno_in01,25,34,5	shop	Tool Dealer#yuno2	4_M_01,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1
-yuno_in01,103,35,2	shop	Weapon Dealer#yuno	1_M_03,1750:-1,1751:-1,1101:-1,1701:-1,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1601:-1,1604:-1,1607:-1,1610:-1
-yuno_in01,112,26,4	shop	Armor Dealer#yuno	4W_F_01,2628:-1,2101:-1,2107:-1,2401:-1,2501:-1,2230:-1,2301:-1,2303:-1,2305:-1,2321:-1,2332:-1
-yuno_in03,176,22,3	shop	Scroll Merchant#yuno03	4_M_ORIENT02,7433:-1	//Temp shop in Yuno that sells Blank Scrolls
+yuno,218,97,5	trader	Tool Dealer#yuno	4_M_02,{
+OnInit:
+	sellitem Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+}
+
+yuno,226,107,5	trader	Tool Dealer#yuno1	4_M_01,{
+OnInit:
+	sellitem Scell;
+	sellitem Garlet;
+	sellitem Zargon;
+}
+
+yuno,197,114,4	trader	Pet Groomer#yuno	4_F_TELEPORTER,{
+OnInit:
+	sellitem Pet_Food;
+	sellitem Pet_Incubator;
+	sellitem Backpack;
+	sellitem Rocker_Glasses;
+	sellitem Bun_;
+	sellitem Mojji;
+	sellitem Flame_Gemstone;
+	sellitem Vital_Flower_;
+	sellitem Vital_Flower;
+	sellitem Bun_;
+	sellitem Damp_Darkness;
+	sellitem Small_Snow_Flower;
+	sellitem Fresh_Plant;
+	sellitem Big_Cell;
+	sellitem Apple_Pudding;
+	sellitem Mystic_Stone;
+	sellitem Flavored_Alcohol;
+	sellitem Grilled_Rice_Cake;
+	sellitem Fish_With_Blue_Back;
+	sellitem Pumpkin_Pie_;
+}
+
+yuno,205,103,4	trader	Mr. King's Shop#yuno	4_M_TELEPORTER,{
+OnInit:
+	sellitem Novice_Breast;
+	sellitem Full_Plate_Armor;
+	sellitem Grave;
+	sellitem Turban;
+	sellitem Gemmed_Sallet;
+	sellitem Repeting_CrossBow;
+}
+
+yuno,163,187,5	trader	Magical Item Seller#yuno	4_F_01,{
+OnInit:
+	sellitem Blue_Gemstone;
+	sellitem Rod;
+	sellitem Wand;
+	sellitem Staff;
+	sellitem Arc_Wand;
+	sellitem Circlet;
+	sellitem Silk_Robe;
+	sellitem Silver_Robe;
+}
+
+yuno_in01,25,34,5	trader	Tool Dealer#yuno2	4_M_01,{
+OnInit:
+	sellitem Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+}
+
+yuno_in01,103,35,2	trader	Weapon Dealer#yuno	1_M_03,{
+OnInit:
+	sellitem Arrow;
+	sellitem Silver_Arrow;
+	sellitem Sword;
+	sellitem Bow;
+	sellitem Knife;
+	sellitem Cutter;
+	sellitem Main_Gauche;
+	sellitem Dirk;
+	sellitem Dagger;
+	sellitem Stiletto;
+	sellitem Rod;
+	sellitem Wand;
+	sellitem Staff;
+	sellitem Arc_Wand;
+}
+
+yuno_in01,112,26,4	trader	Armor Dealer#yuno	4W_F_01,{
+OnInit:
+	sellitem Novice_Armlet;
+	sellitem Guard;
+	sellitem Mirror_Shield;
+	sellitem Sandals;
+	sellitem Hood;
+	sellitem Gemmed_Sallet;
+	sellitem Cotton_Shirt;
+	sellitem Leather_Jacket;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Silver_Robe;
+}
+
+yuno_in03,176,22,3	trader	Scroll Merchant#yuno03	4_M_ORIENT02,{
+OnInit:
+	sellitem Scroll; //Temp shop in Yuno that sells Blank Scrolls
+}
+
 
 //=======================================================
 // Lighthalzen
 //=======================================================
-lighthalzen,69,75,5	shop	Fruit Gardener#lhz	8_F,512:-1,513:-1
-lighthalzen,112,44,0	shop	Flower Girl#lhz	4_F_01,712:-1,744:-1,748:-1
-lighthalzen,124,129,0	shop	Vegetable Gardener#lhz	4_F_02,515:-1,516:-1,535:-1
-lighthalzen,220,122,3	shop	Vendor from Milk Ranch#l	4_F_01,519:-1
-lighthalzen,222,191,4	shop	Pet Groomer#lhz	4_M_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,554:-1,6113:-1,6114:-1,6115:-1
-lhz_in02,286,95,4	shop	Beginner's Merchant#lhz	1_M_SIZ,5112:-1,2416:-1,2113:-1,2512:-1
-lhz_in02,271,99,5	shop	Armor Dealer#lhz	4_M_REPAIR,2101:-1,2103:-1,2403:-1,2405:-1,2503:-1,2321:-1,2314:-1,2309:-1,2335:-1,2628:-1
-lhz_in02,276,99,4	shop	Weapon Dealer#lhz	4_M_REPAIR,1201:-1,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1,13003:-1
-lhz_in02,273,35,4	shop	Wand Dealer#lhz	4_M_EINMAN2,1601:-1,1604:-1,1607:-1,1617:-1,1619:-1
-lhz_in02,105,21,3	shop	Jeweler#lhz	4_F_02,721:-1,723:-1,726:-1,728:-1,729:-1,730:-1,2613:-1
-lhz_in02,17,220,5	shop	Vegetable Gardener#lhz2	4_F_02,515:-1,516:-1,535:-1
-lhz_in02,21,220,5	shop	Fruit Gardener#lhz2	8_F,512:-1,513:-1
-lhz_in02,32,219,5	shop	Butcher#lhz	1_M_JOBGUIDER,517:-1
-lhz_in02,38,145,5	shop	Gift Merchant#lhz	4_F_02,734:-1,735:-1,736:-1,737:-1,746:-1
-lhz_in02,47,148,3	shop	Wedding Shop Dealer#lhz	1_F_LIBRARYGIRL,744:-1,745:-1,2338:-1,2206:-1,7170:-1
-lhz_in02,31,145,4	shop	Tool Dealer#lhz	4_F_01,611:-1,503:-1,504:-1,506:-1,657:-1,656:-1,601:-1,602:-1,1065:-1,610:-1,1770:-1
-lhz_in02,85,216,5	shop	Doll Supplier#lhz	4_F_LGTGIRL,740:-1,741:-1,742:-1
-lhz_in02,87,208,3	shop	Toy Supplier#lhz	4_M_PIERROT,2243:-1,2212:-1,2242:-1,2241:-1
-lhz_in03,239,106,5	shop	Tool Dealer#lhz2	4_F_EINWOMAN,501:-1,502:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1,611:-1
-lhz_in03,258,101,3	shop	Arrow Merchant#lhz	4_M_EINMAN,1750:-1,1770:-1,1752:-1,1751:-1
-lhz_in03,249,24,4	shop	Merchant#lhz	4_M_EINMAN,911:-1,910:-1,912:-1,528:-1
+lighthalzen,69,75,5	trader	Fruit Gardener#lhz	8_F,{
+OnInit:
+	sellitem Apple;
+	sellitem Banana;
+}
+
+lighthalzen,112,44,0	trader	Flower Girl#lhz	4_F_01,{
+OnInit:
+	sellitem Flower;
+	sellitem Bunch_Of_Flowers;
+	sellitem Witherless_Rose;
+}
+
+lighthalzen,124,129,0	trader	Vegetable Gardener#lhz	4_F_02,{
+OnInit:
+	sellitem Carrot;
+	sellitem Sweet_Potato;
+	sellitem Pumpkin;
+}
+
+lighthalzen,220,122,3	trader	Vendor from Milk Ranch#l	4_F_01,{
+OnInit:
+	sellitem Milk;
+}
+
+lighthalzen,222,191,4	trader	Pet Groomer#lhz	4_M_TELEPORTER,{
+OnInit:
+	sellitem Pet_Food;
+	sellitem Pet_Incubator;
+	sellitem Backpack;
+	sellitem Rocker_Glasses;
+	sellitem Mojji;
+	sellitem Vital_Flower_;
+	sellitem Flame_Gemstone;
+	sellitem Bun_;
+}
+
+lhz_in02,286,95,4	trader	Beginner's Merchant#lhz	1_M_SIZ,{
+OnInit:
+	sellitem Super_Novice_Hat;
+	sellitem Novice_Shoes;
+	sellitem Novice_Shield;
+	sellitem Novice_Manteau;
+}
+
+lhz_in02,271,99,5	trader	Armor Dealer#lhz	4_M_REPAIR,{
+OnInit:
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Shoes;
+	sellitem Boots;
+	sellitem Muffler;
+	sellitem Silk_Robe;
+	sellitem Chain_Mail;
+	sellitem Coat;
+	sellitem Thief_Clothes;
+	sellitem Novice_Armlet;
+}
+
+lhz_in02,276,99,4	trader	Weapon Dealer#lhz	4_M_REPAIR,{
+OnInit:
+	sellitem Knife;
+	sellitem Main_Gauche;
+	sellitem Stiletto;
+	sellitem Blade;
+	sellitem Ring_Pommel_Saber;
+	sellitem Katana;
+	sellitem Bastard_Sword;
+	sellitem Pike;
+	sellitem Partizan;
+	sellitem Hammer;
+	sellitem Chain;
+	sellitem Coward;
+}
+
+lhz_in02,273,35,4	trader	Wand Dealer#lhz	4_M_EINMAN2,{
+OnInit:
+	sellitem Rod;
+	sellitem Wand;
+	sellitem Staff;
+	sellitem Survival_Rod;
+	sellitem Survival_Rod2;
+}
+
+lhz_in02,105,21,3	trader	Jeweler#lhz	4_F_02,{
+OnInit:
+	sellitem Azure_Jewel;
+	sellitem Cardinal_Jewel;
+	sellitem Blue_Jewel;
+	sellitem Golden_Jewel;
+	sellitem Bluish_Green_Jewel;
+	sellitem Crystal_Jewel;
+	sellitem Diamond_Ring;
+}
+
+lhz_in02,17,220,5	trader	Vegetable Gardener#lhz2	4_F_02,{
+OnInit:
+	sellitem Carrot;
+	sellitem Sweet_Potato;
+	sellitem Pumpkin;
+}
+
+lhz_in02,21,220,5	trader	Fruit Gardener#lhz2	8_F,{
+OnInit:
+	sellitem Apple;
+	sellitem Banana;
+}
+
+lhz_in02,32,219,5	trader	Butcher#lhz	1_M_JOBGUIDER,{
+OnInit:
+	sellitem Meat;
+}
+
+lhz_in02,38,145,5	trader	Gift Merchant#lhz	4_F_02,{
+OnInit:
+	sellitem Red_Frame;
+	sellitem Blue_Porcelain;
+	sellitem White_Platter;
+	sellitem Black_Ladle;
+	sellitem Glass_Bead;
+}
+
+lhz_in02,47,148,3	trader	Wedding Shop Dealer#lhz	1_F_LIBRARYGIRL,{
+OnInit:
+	sellitem Bunch_Of_Flowers;
+	sellitem Wedding_Bouquet;
+	sellitem Wedding_Dress;
+	sellitem Wedding_Veil;
+	sellitem Tuxedo;
+}
+
+lhz_in02,31,145,4	trader	Tool Dealer#lhz	4_F_01,{
+OnInit:
+	sellitem Spectacles;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Berserk_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+	sellitem Leaf_Of_Yggdrasil;
+	sellitem Iron_Arrow;
+}
+
+lhz_in02,85,216,5	trader	Doll Supplier#lhz	4_F_LGTGIRL,{
+OnInit:
+	sellitem Stuffed_Doll;
+	sellitem Poring_Doll;
+	sellitem Chonchon_Doll;
+}
+
+lhz_in02,87,208,3	trader	Toy Supplier#lhz	4_M_PIERROT,{
+OnInit:
+	sellitem Spinning_Eyes;
+	sellitem Eye_Bandage;
+	sellitem Luxury_Sunglasses;
+	sellitem Granpa_Beard;
+}
+
+lhz_in03,239,106,5	trader	Tool Dealer#lhz2	4_F_EINWOMAN,{
+OnInit:
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+	sellitem Spectacles;
+}
+
+lhz_in03,258,101,3	trader	Arrow Merchant#lhz	4_M_EINMAN,{
+OnInit:
+	sellitem Arrow;
+	sellitem Iron_Arrow;
+	sellitem Fire_Arrow;
+	sellitem Silver_Arrow;
+}
+
+lhz_in03,249,24,4	trader	Merchant#lhz	4_M_EINMAN,{
+OnInit:
+	sellitem Scell;
+	sellitem Garlet;
+	sellitem Zargon;
+	sellitem Monster's_Feed;
+}
+
 
 //=======================================================
 // Louyang
 //=======================================================
-lou_in02,121,182,5	shop	Armor Dealer#lou	4_F_CHNWOMAN,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2101:-1,2103:-1,2305:-1,2321:-1,2332:-1,2328:-1,2627:-1
-lou_in02,130,182,5	shop	Weapon Dealer#lou	4_M_CHNMAN,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1
-lou_in02,239,176,5	shop	Tool Dealer#lou	4_F_CHNWOMAN,1750:-1,1770:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
+lou_in02,121,182,5	trader	Armor Dealer#lou	4_F_CHNWOMAN,{
+OnInit:
+	sellitem Bandana;
+	sellitem Sandals;
+	sellitem Shoes;
+	sellitem Hood;
+	sellitem Muffler;
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Silver_Robe;
+	sellitem Wooden_Mail;
+	sellitem Belt;
+}
+
+lou_in02,130,182,5	trader	Weapon Dealer#lou	4_M_CHNMAN,{
+OnInit:
+	sellitem Main_Gauche;
+	sellitem Stiletto;
+	sellitem Blade;
+	sellitem Ring_Pommel_Saber;
+	sellitem Katana;
+	sellitem Bastard_Sword;
+	sellitem Pike;
+	sellitem Partizan;
+	sellitem Hammer;
+	sellitem Chain;
+}
+
+lou_in02,239,176,5	trader	Tool Dealer#lou	4_F_CHNWOMAN,{
+OnInit:
+	sellitem Arrow;
+	sellitem Iron_Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+}
+
 
 //=======================================================
 // Lutie
 //=======================================================
-xmas_in,40,38,5	shop	Tool Dealer#xmas	4_M_01,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,611:-1,610:-1
-xmas_in,168,104,4	shop	Armor Dealer#xmas	4W_F_01,2228:-1,2103:-1,2105:-1,2307:-1,2309:-1,2312:-1,2314:-1,2316:-1,2505:-1,2405:-1
-xmas_in,169,34,2	shop	Gift Seller#xmas	4_F_GON,2612:-1,744:-1,748:-1,736:-1,746:-1,740:-1,2613:-1
-xmas_in,174,98,2	shop	Weapon Dealer#xmas	1_M_03,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1219:-1,1222:-1
+xmas_in,40,38,5	trader	Tool Dealer#xmas	4_M_01,{
+OnInit:
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Spectacles;
+	sellitem Leaf_Of_Yggdrasil;
+}
+
+xmas_in,168,104,4	trader	Armor Dealer#xmas	4W_F_01,{
+OnInit:
+	sellitem Helm;
+	sellitem Buckler;
+	sellitem Shield;
+	sellitem Mantle;
+	sellitem Coat;
+	sellitem Padded_Armor;
+	sellitem Chain_Mail;
+	sellitem Plate_Armor;
+	sellitem Manteau;
+	sellitem Boots;
+}
+
+xmas_in,169,34,2	trader	Gift Seller#xmas	4_F_GON,{
+OnInit:
+	sellitem Flower_Ring;
+	sellitem Bunch_Of_Flowers;
+	sellitem Witherless_Rose;
+	sellitem White_Platter;
+	sellitem Glass_Bead;
+	sellitem Stuffed_Doll;
+	sellitem Diamond_Ring;
+}
+
+xmas_in,174,98,2	trader	Weapon Dealer#xmas	1_M_03,{
+OnInit:
+	sellitem Knife;
+	sellitem Cutter;
+	sellitem Main_Gauche;
+	sellitem Dirk;
+	sellitem Dagger;
+	sellitem Stiletto;
+	sellitem Gladius;
+	sellitem Damascus;
+}
+
 
 //=======================================================
 // Morroc - Post Ep. 12.1
 //=======================================================
-in_moc_16,22,20,7	shop	Sepulchral Merchant#moc	4_M_MASKMAN,1771:-1
-moc_ruins,91,128,4	shop	Tool Dealer#moc1	4_F_04,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-moc_ruins,114,63,6	shop	Tool Dealer#moc2	4W_M_03,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1,2242:-1
-moc_ruins,93,53,2	shop	Item Collector#moc1	4_M_03,911:-1,528:-1,919:-1,925:-1
-moc_ruins,81,113,0	shop	Item Collector#moc2	4_M_03,911:-1,528:-1,919:-1,925:-1
-moc_ruins,110,105,2	shop	Jeweler#moc1	8_F,721:-1,723:-1,726:-1,728:-1,729:-1
-moc_ruins,52,85,6	shop	Jeweler#moc2	4W_M_03,730:-1,2613:-1
-moc_ruins,113,126,4	shop	Trader#moc1	4W_M_03,747:-1
-moc_ruins,131,138,0	shop	Trader#moc2	4_F_04,748:-1
-moc_ruins,71,139,5	shop	Trader#moc3	4_F_04,2612:-1
-moc_ruins,125,135,6	shop	Trader#moc4	4_M_ORIENT02,2609:-1,1516:-1,1522:-1
-moc_ruins,87,109,0	shop	Butcher#moc	1_M_MERCHANT,517:-1
-moc_ruins,90,149,6	shop	Trader#moc5	4W_M_03,513:-1,513:-1,513:-1,513:-1,513:-1,513:-1
-moc_ruins,118,170,4	shop	Pet Groomer#moc	4_M_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,554:-1,6113:-1,6114:-1,6115:-1
-morocc_in,141,67,0	shop	Weapon Dealer#moc1	1_M_MERCHANT,1750:-1,1751:-1,1701:-1,1601:-1,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1219:-1,1222:-1,1250:-1,1252:-1,1254:-1
-morocc_in,141,60,0	shop	Armor Dealer#moc	1_M_MERCHANT,2101:-1,2103:-1,2401:-1,2403:-1,2405:-1,2501:-1,2503:-1,2218:-1,2301:-1,2303:-1,2305:-1,2321:-1,2328:-1,2332:-1,2307:-1,2309:-1,2335:-1,2628:-1
-morocc_in,132,57,0	shop	Weapon Dealer#moc2	4W_M_03,1146:-1,1245:-1
+in_moc_16,22,20,7	trader	Sepulchral Merchant#moc	4_M_MASKMAN,{
+OnInit:
+	sellitem Venom_Knife;
+}
+
+moc_ruins,91,128,4	trader	Tool Dealer#moc1	4_F_04,{
+OnInit:
+	sellitem Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+}
+
+moc_ruins,114,63,6	trader	Tool Dealer#moc2	4W_M_03,{
+OnInit:
+	sellitem Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+	sellitem Luxury_Sunglasses;
+}
+
+moc_ruins,93,53,2	trader	Item Collector#moc1	4_M_03,{
+OnInit:
+	sellitem Scell;
+	sellitem Monster's_Feed;
+	sellitem Animal's_Skin;
+	sellitem Bill_Of_Birds;
+}
+
+moc_ruins,81,113,0	trader	Item Collector#moc2	4_M_03,{
+OnInit:
+	sellitem Scell;
+	sellitem Monster's_Feed;
+	sellitem Animal's_Skin;
+	sellitem Bill_Of_Birds;
+}
+
+moc_ruins,110,105,2	trader	Jeweler#moc1	8_F,{
+OnInit:
+	sellitem Azure_Jewel;
+	sellitem Cardinal_Jewel;
+	sellitem Blue_Jewel;
+	sellitem Golden_Jewel;
+	sellitem Bluish_Green_Jewel;
+}
+
+moc_ruins,52,85,6	trader	Jeweler#moc2	4W_M_03,{
+OnInit:
+	sellitem Crystal_Jewel;
+	sellitem Diamond_Ring;
+}
+
+moc_ruins,113,126,4	trader	Trader#moc1	4W_M_03,{
+OnInit:
+	sellitem Crystal_Mirror;
+}
+
+moc_ruins,131,138,0	trader	Trader#moc2	4_F_04,{
+OnInit:
+	sellitem Witherless_Rose;
+}
+
+moc_ruins,71,139,5	trader	Trader#moc3	4_F_04,{
+OnInit:
+	sellitem Flower_Ring;
+}
+
+moc_ruins,125,135,6	trader	Trader#moc4	4_M_ORIENT02,{
+OnInit:
+	sellitem Skul_Ring;
+	sellitem Sword_Mace;
+	sellitem Stunner;
+}
+
+moc_ruins,87,109,0	trader	Butcher#moc	1_M_MERCHANT,{
+OnInit:
+	sellitem Meat;
+}
+
+moc_ruins,90,149,6	trader	Trader#moc5	4W_M_03,{
+OnInit:
+	sellitem Banana;
+	sellitem Banana;
+	sellitem Banana;
+	sellitem Banana;
+	sellitem Banana;
+	sellitem Banana;
+}
+
+moc_ruins,118,170,4	trader	Pet Groomer#moc	4_M_TELEPORTER,{
+OnInit:
+	sellitem Pet_Food;
+	sellitem Pet_Incubator;
+	sellitem Backpack;
+	sellitem Rocker_Glasses;
+	sellitem Mojji;
+	sellitem Vital_Flower_;
+	sellitem Flame_Gemstone;
+	sellitem Bun_;
+}
+
+morocc_in,141,67,0	trader	Weapon Dealer#moc1	1_M_MERCHANT,{
+OnInit:
+	sellitem Arrow;
+	sellitem Silver_Arrow;
+	sellitem Bow;
+	sellitem Rod;
+	sellitem Knife;
+	sellitem Cutter;
+	sellitem Main_Gauche;
+	sellitem Dirk;
+	sellitem Dagger;
+	sellitem Stiletto;
+	sellitem Gladius;
+	sellitem Damascus;
+	sellitem Jur;
+	sellitem Katar;
+	sellitem Jamadhar;
+}
+
+morocc_in,141,60,0	trader	Armor Dealer#moc	1_M_MERCHANT,{
+OnInit:
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Sandals;
+	sellitem Shoes;
+	sellitem Boots;
+	sellitem Hood;
+	sellitem Muffler;
+	sellitem Flu_Mask;
+	sellitem Cotton_Shirt;
+	sellitem Leather_Jacket;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Wooden_Mail;
+	sellitem Silver_Robe;
+	sellitem Mantle;
+	sellitem Coat;
+	sellitem Thief_Clothes;
+	sellitem Novice_Armlet;
+}
+
+morocc_in,132,57,0	trader	Weapon Dealer#moc2	4W_M_03,{
+OnInit:
+	sellitem Town_Sword;
+	sellitem Cinquedea;
+}
+
 
 //=======================================================
 // Moscovia
 //=======================================================
-mosk_in,21,254,5	shop	Tool Dealer#mosk	4_M_RUSMAN2,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1,1750:-1
-mosk_in,31,180,3	shop	Weapon Dealer#mosk	4_M_RUSMAN2,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1
-mosk_in,79,178,1	shop	Armor Dealer#mosk	4_F_RUSWOMAN3,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2101:-1,2103:-1,2305:-1,2321:-1,2332:-1,2328:-1,2627:-1
-moscovia,152,71,4	shop	Fruit Gardener#mosk	4_M_RUSMAN2,512:-1,513:-1,515:-1,516:-1
-moscovia,199,110,3	shop	Vendor from Milk Ranch#m	4_F_RUSWOMAN1,519:-1
+mosk_in,21,254,5	trader	Tool Dealer#mosk	4_M_RUSMAN2,{
+OnInit:
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+	sellitem Arrow;
+}
+
+mosk_in,31,180,3	trader	Weapon Dealer#mosk	4_M_RUSMAN2,{
+OnInit:
+	sellitem Main_Gauche;
+	sellitem Stiletto;
+	sellitem Blade;
+	sellitem Ring_Pommel_Saber;
+	sellitem Katana;
+	sellitem Bastard_Sword;
+	sellitem Pike;
+	sellitem Partizan;
+	sellitem Hammer;
+	sellitem Chain;
+}
+
+mosk_in,79,178,1	trader	Armor Dealer#mosk	4_F_RUSWOMAN3,{
+OnInit:
+	sellitem Bandana;
+	sellitem Sandals;
+	sellitem Shoes;
+	sellitem Hood;
+	sellitem Muffler;
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Silver_Robe;
+	sellitem Wooden_Mail;
+	sellitem Belt;
+}
+
+moscovia,152,71,4	trader	Fruit Gardener#mosk	4_M_RUSMAN2,{
+OnInit:
+	sellitem Apple;
+	sellitem Banana;
+	sellitem Carrot;
+	sellitem Sweet_Potato;
+}
+
+moscovia,199,110,3	trader	Vendor from Milk Ranch#m	4_F_RUSWOMAN1,{
+OnInit:
+	sellitem Milk;
+}
+
 
 //=======================================================
 // Niflheim
 //=======================================================
-nif_in,37,93,1	shop	Axe Dealer#nif	4_NFCOFFIN,1301:-1,1351:-1,1354:-1,1357:-1,1360:-1
-nif_in,37,84,1	shop	Armor Dealer#nif	4_NFCOFFIN,2501:-1,2501:-1,2503:-1,2503:-1,2505:-1,2505:-1
-nif_in,145,23,1	shop	Tool Dealer#nif	4_NFCOFFIN,535:-1,1062:-1,902:-1,7106:-1,537:-1,7154:-1,1052:-1,934:-1
+nif_in,37,93,1	trader	Axe Dealer#nif	4_NFCOFFIN,{
+OnInit:
+	sellitem Axe;
+	sellitem Battle_Axe;
+	sellitem Hammer;
+	sellitem Buster;
+	sellitem Two_Handed_Axe;
+}
+
+nif_in,37,84,1	trader	Armor Dealer#nif	4_NFCOFFIN,{
+OnInit:
+	sellitem Hood;
+	sellitem Hood;
+	sellitem Muffler;
+	sellitem Muffler;
+	sellitem Manteau;
+	sellitem Manteau;
+}
+
+nif_in,145,23,1	trader	Tool Dealer#nif	4_NFCOFFIN,{
+OnInit:
+	sellitem Pumpkin;
+	sellitem Pumpkin_Head;
+	sellitem Tree_Root;
+	sellitem Goat's_Horn;
+	sellitem Pet_Food;
+	sellitem Poison_Powder;
+	sellitem Single_Cell;
+	sellitem Mementos;
+}
+
 
 //=======================================================
 // Payon
 //=======================================================
-payon_in01,15,119,0	shop	Weapon Dealer#pay	1_F_ORIENT_03,1750:-1,1751:-1,1101:-1,1104:-1,1107:-1,1201:-1,1204:-1,1207:-1,1601:-1,1701:-1,1704:-1,1707:-1,1710:-1,1713:-1,1714:-1,1718:-1
-payon_in01,5,129,7	shop	Weapon Dealer#pay2	4_F_KID2,1146:-1,1245:-1
-payon_in01,7,119,2	shop	Armor Dealer#pay	1_F_ORIENT_02,2401:-1,2403:-1,2405:-1,2501:-1,2503:-1,2505:-1,2208:-1,2211:-1,2212:-1,2301:-1,2303:-1,2305:-1,2321:-1,2328:-1,2332:-1,2307:-1,2309:-1,2330:-1,2628:-1
-payon_in01,5,49,7	shop	Tool Dealer#pay	4_M_ORIENT01,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-payon_in02,87,34,0	shop	Tool Dealer#pay2	1_F_ORIENT_01,1750:-1,1751:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-payon,159,96,4	shop	Tool Dealer#pay3	4_M_ORIENT01,1750:-1,501:-1,645:-1,601:-1,602:-1
-payon,177,131,4	shop	Pet Groomer#pay	4_F_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,554:-1,6114:-1,6113:-1,6110:-1,6115:-1,6100:-1,6098:-1,6112:-1,6104:-1,6108:-1,6111:-1,6095:-1,6099:-1,6096:-1,6097:-1,6094:-1
+payon_in01,15,119,0	trader	Weapon Dealer#pay	1_F_ORIENT_03,{
+OnInit:
+	sellitem Arrow;
+	sellitem Silver_Arrow;
+	sellitem Sword;
+	sellitem Falchion;
+	sellitem Blade;
+	sellitem Knife;
+	sellitem Cutter;
+	sellitem Main_Gauche;
+	sellitem Rod;
+	sellitem Bow;
+	sellitem Composite_Bow;
+	sellitem Great_Bow;
+	sellitem CrossBow;
+	sellitem Arbalest;
+	sellitem Kakkung;
+	sellitem Hunter_Bow;
+}
+
+payon_in01,5,129,7	trader	Weapon Dealer#pay2	4_F_KID2,{
+OnInit:
+	sellitem Town_Sword;
+	sellitem Cinquedea;
+}
+
+payon_in01,7,119,2	trader	Armor Dealer#pay	1_F_ORIENT_02,{
+OnInit:
+	sellitem Sandals;
+	sellitem Shoes;
+	sellitem Boots;
+	sellitem Hood;
+	sellitem Muffler;
+	sellitem Manteau;
+	sellitem Ribbon;
+	sellitem Bandana;
+	sellitem Eye_Bandage;
+	sellitem Cotton_Shirt;
+	sellitem Leather_Jacket;
+	sellitem Adventure_Suit;
+	sellitem Silk_Robe;
+	sellitem Wooden_Mail;
+	sellitem Silver_Robe;
+	sellitem Mantle;
+	sellitem Coat;
+	sellitem Tights;
+	sellitem Novice_Armlet;
+}
+
+payon_in01,5,49,7	trader	Tool Dealer#pay	4_M_ORIENT01,{
+OnInit:
+	sellitem Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+}
+
+payon_in02,87,34,0	trader	Tool Dealer#pay2	1_F_ORIENT_01,{
+OnInit:
+	sellitem Arrow;
+	sellitem Silver_Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+}
+
+payon,159,96,4	trader	Tool Dealer#pay3	4_M_ORIENT01,{
+OnInit:
+	sellitem Arrow;
+	sellitem Red_Potion;
+	sellitem Center_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+}
+
+payon,177,131,4	trader	Pet Groomer#pay	4_F_TELEPORTER,{
+OnInit:
+	sellitem Pet_Food;
+	sellitem Pet_Incubator;
+	sellitem Backpack;
+	sellitem Rocker_Glasses;
+	sellitem Mojji;
+	sellitem Flame_Gemstone;
+	sellitem Vital_Flower_;
+	sellitem Vital_Flower;
+	sellitem Bun_;
+	sellitem Damp_Darkness;
+	sellitem Small_Snow_Flower;
+	sellitem Fresh_Plant;
+	sellitem Big_Cell;
+	sellitem Apple_Pudding;
+	sellitem Mystic_Stone;
+	sellitem Flavored_Alcohol;
+	sellitem Grilled_Rice_Cake;
+	sellitem Fish_With_Blue_Back;
+	sellitem Pumpkin_Pie_;
+	sellitem Traditional_Cookie;
+}
+
 
 //=======================================================
 // Prontera
 //=======================================================
-prontera,73,134,0	shop	Vendor from Milk Ranch#p	4_F_01,519:-1
-prontera,104,49,0	shop	Fruit Gardener#prt	8_F,512:-1,513:-1
-prontera,64,125,0	shop	Butcher#prt	4_M_BARBER,517:-1,528:-1
-prontera,58,182,0	shop	Flower Girl#prt	4W_KID,712:-1,744:-1
-prontera,113,42,0	shop	Flower Lady#prt	4_F_01,712:-1,744:-1
-prontera,105,87,0	shop	Gift Merchant#prt	4_F_02,734:-1,735:-1,736:-1,737:-1,746:-1
-prontera,218,211,4	shop	Pet Groomer#prt	4_M_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,554:-1,6114:-1,6113:-1,6110:-1,6115:-1,6100:-1,6098:-1,6112:-1,6104:-1,6108:-1,6111:-1,6095:-1,6099:-1,6096:-1,6097:-1,6094:-1
-prontera,248,153,0	shop	Doll Supplier#prt	4_M_03,740:-1,741:-1,742:-1
-prontera,48,58,0	shop	Vegetable Gardener#prt	4_F_02,515:-1,516:-1,535:-1
-prt_church,108,124,4	shop	Nun#prt	1_F_PRIEST,2608:-1,2216:-1,5092:-1,2323:-1,2325:-1,1501:-1,1504:-1,1507:-1,1510:-1,1513:-1,1519:-1
-prt_fild05,290,221,2	shop	Tool Dealer#prt	4_M_01,1750:-1,611:-1,501:-1,502:-1,506:-1,645:-1,601:-1,602:-1
-prt_in,211,169,0	shop	Wedding Shop Dealer#prt	1_F_LIBRARYGIRL,744:-1,745:-1,2338:-1,2206:-1,7170:-1
-prt_in,126,76,0	shop	Tool Dealer#prt1	1_M_INNKEEPER,611:-1,1750:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1,2239:-1
-prt_in,172,130,0	shop	Weapon Dealer#prt	1_M_JOBGUIDER,1750:-1,1751:-1,1701:-1,1201:-1,1204:-1,1207:-1,1601:-1,1101:-1,1104:-1,1107:-1,1110:-1,1113:-1,1122:-1,1119:-1,1123:-1,1126:-1,1129:-1,1116:-1,1301:-1
-prt_in,172,132,0	shop	Armor Dealer#prt	1_M_02,2101:-1,2103:-1,2401:-1,2403:-1,2501:-1,2503:-1,2220:-1,2226:-1,2301:-1,2303:-1,2305:-1,2328:-1,2307:-1,2309:-1,2312:-1,2314:-1,2628:-1,2627:-1
-prt_in,171,140,0	shop	Weapon Dealer#prt2	1_M_01,1401:-1,1404:-1,1407:-1,1451:-1,1454:-1,1457:-1,1460:-1,1463:-1,1410:-1
-prt_in,165,140,4	shop	Weapon Dealer#prt3	1_F_01,1146:-1,1245:-1
-prt_monk,135,263,5	shop	Weapon Dealer#prt4	4_F_JOB_BLACKSMITH,1801:-1,1803:-1,1805:-1
+prontera,73,134,0	trader	Vendor from Milk Ranch#p	4_F_01,{
+OnInit:
+	sellitem Milk;
+}
+
+prontera,104,49,0	trader	Fruit Gardener#prt	8_F,{
+OnInit:
+	sellitem Apple;
+	sellitem Banana;
+}
+
+prontera,64,125,0	trader	Butcher#prt	4_M_BARBER,{
+OnInit:
+	sellitem Meat;
+	sellitem Monster's_Feed;
+}
+
+prontera,58,182,0	trader	Flower Girl#prt	4W_KID,{
+OnInit:
+	sellitem Flower;
+	sellitem Bunch_Of_Flowers;
+}
+
+prontera,113,42,0	trader	Flower Lady#prt	4_F_01,{
+OnInit:
+	sellitem Flower;
+	sellitem Bunch_Of_Flowers;
+}
+
+prontera,105,87,0	trader	Gift Merchant#prt	4_F_02,{
+OnInit:
+	sellitem Red_Frame;
+	sellitem Blue_Porcelain;
+	sellitem White_Platter;
+	sellitem Black_Ladle;
+	sellitem Glass_Bead;
+}
+
+prontera,218,211,4	trader	Pet Groomer#prt	4_M_TELEPORTER,{
+OnInit:
+	sellitem Pet_Food;
+	sellitem Pet_Incubator;
+	sellitem Backpack;
+	sellitem Rocker_Glasses;
+	sellitem Mojji;
+	sellitem Flame_Gemstone;
+	sellitem Vital_Flower_;
+	sellitem Vital_Flower;
+	sellitem Bun_;
+	sellitem Damp_Darkness;
+	sellitem Small_Snow_Flower;
+	sellitem Fresh_Plant;
+	sellitem Big_Cell;
+	sellitem Apple_Pudding;
+	sellitem Mystic_Stone;
+	sellitem Flavored_Alcohol;
+	sellitem Grilled_Rice_Cake;
+	sellitem Fish_With_Blue_Back;
+	sellitem Pumpkin_Pie_;
+	sellitem Traditional_Cookie;
+}
+
+prontera,248,153,0	trader	Doll Supplier#prt	4_M_03,{
+OnInit:
+	sellitem Stuffed_Doll;
+	sellitem Poring_Doll;
+	sellitem Chonchon_Doll;
+}
+
+prontera,48,58,0	trader	Vegetable Gardener#prt	4_F_02,{
+OnInit:
+	sellitem Carrot;
+	sellitem Sweet_Potato;
+	sellitem Pumpkin;
+}
+
+prt_church,108,124,4	trader	Nun#prt	1_F_PRIEST,{
+OnInit:
+	sellitem Rosary;
+	sellitem Biretta;
+	sellitem Blue_Coif;
+	sellitem Scapulare;
+	sellitem Saint_Robe;
+	sellitem Club;
+	sellitem Mace;
+	sellitem Smasher;
+	sellitem Flail;
+	sellitem Morning_Star;
+	sellitem Chain;
+}
+
+prt_fild05,290,221,2	trader	Tool Dealer#prt	4_M_01,{
+OnInit:
+	sellitem Arrow;
+	sellitem Spectacles;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+}
+
+prt_in,211,169,0	trader	Wedding Shop Dealer#prt	1_F_LIBRARYGIRL,{
+OnInit:
+	sellitem Bunch_Of_Flowers;
+	sellitem Wedding_Bouquet;
+	sellitem Wedding_Dress;
+	sellitem Wedding_Veil;
+	sellitem Tuxedo;
+}
+
+prt_in,126,76,0	trader	Tool Dealer#prt1	1_M_INNKEEPER,{
+OnInit:
+	sellitem Spectacles;
+	sellitem Arrow;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Booby_Trap;
+	sellitem One_Eyed_Glass;
+}
+
+prt_in,172,130,0	trader	Weapon Dealer#prt	1_M_JOBGUIDER,{
+OnInit:
+	sellitem Arrow;
+	sellitem Silver_Arrow;
+	sellitem Bow;
+	sellitem Knife;
+	sellitem Cutter;
+	sellitem Main_Gauche;
+	sellitem Rod;
+	sellitem Sword;
+	sellitem Falchion;
+	sellitem Blade;
+	sellitem Lapier;
+	sellitem Scimiter;
+	sellitem Ring_Pommel_Saber;
+	sellitem Tsurugi;
+	sellitem Haedonggum;
+	sellitem Saber;
+	sellitem Flamberge;
+	sellitem Katana;
+	sellitem Axe;
+}
+
+prt_in,172,132,0	trader	Armor Dealer#prt	1_M_02,{
+OnInit:
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Sandals;
+	sellitem Shoes;
+	sellitem Hood;
+	sellitem Muffler;
+	sellitem Hat;
+	sellitem Cap;
+	sellitem Cotton_Shirt;
+	sellitem Leather_Jacket;
+	sellitem Adventure_Suit;
+	sellitem Wooden_Mail;
+	sellitem Mantle;
+	sellitem Coat;
+	sellitem Padded_Armor;
+	sellitem Chain_Mail;
+	sellitem Novice_Armlet;
+	sellitem Belt;
+}
+
+prt_in,171,140,0	trader	Weapon Dealer#prt2	1_M_01,{
+OnInit:
+	sellitem Javelin;
+	sellitem Spear;
+	sellitem Pike;
+	sellitem Guisarme;
+	sellitem Glaive;
+	sellitem Partizan;
+	sellitem Trident;
+	sellitem Halberd;
+	sellitem Lance;
+}
+
+prt_in,165,140,4	trader	Weapon Dealer#prt3	1_F_01,{
+OnInit:
+	sellitem Town_Sword;
+	sellitem Cinquedea;
+}
+
+prt_monk,135,263,5	trader	Weapon Dealer#prt4	4_F_JOB_BLACKSMITH,{
+OnInit:
+	sellitem Waghnakh;
+	sellitem Knuckle_Duster;
+	sellitem Hora;
+}
+
 
 //=======================================================
 // Rachel
 //=======================================================
-ra_in01,175,364,3	shop	Armor Dealer#ra	4_F_SHABBY,2101:-1,2103:-1,2403:-1,2405:-1,2503:-1,2321:-1,2314:-1,2309:-1,2335:-1,2628:-1
-ra_in01,257,269,3	shop	Tool Dealer#ra	4_F_SHABBY,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,611:-1,1065:-1,610:-1
-ra_in01,176,389,3	shop	Weapon Dealer#ra	4_M_RACHMAN1,1201:-1,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1,13003:-1,1601:-1,1604:-1,1607:-1
-ra_in01,254,300,3	shop	Fruit Gardener#ra	4_M_RACHMAN1,512:-1,513:-1
-rachel,65,80,1	shop	Vegetable Gardener#ra	4_F_SHABBY,515:-1,535:-1,516:-1
+ra_in01,175,364,3	trader	Armor Dealer#ra	4_F_SHABBY,{
+OnInit:
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Shoes;
+	sellitem Boots;
+	sellitem Muffler;
+	sellitem Silk_Robe;
+	sellitem Chain_Mail;
+	sellitem Coat;
+	sellitem Thief_Clothes;
+	sellitem Novice_Armlet;
+}
+
+ra_in01,257,269,3	trader	Tool Dealer#ra	4_F_SHABBY,{
+OnInit:
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Spectacles;
+	sellitem Booby_Trap;
+	sellitem Leaf_Of_Yggdrasil;
+}
+
+ra_in01,176,389,3	trader	Weapon Dealer#ra	4_M_RACHMAN1,{
+OnInit:
+	sellitem Knife;
+	sellitem Main_Gauche;
+	sellitem Stiletto;
+	sellitem Blade;
+	sellitem Ring_Pommel_Saber;
+	sellitem Katana;
+	sellitem Bastard_Sword;
+	sellitem Pike;
+	sellitem Partizan;
+	sellitem Hammer;
+	sellitem Chain;
+	sellitem Coward;
+	sellitem Rod;
+	sellitem Wand;
+	sellitem Staff;
+}
+
+ra_in01,254,300,3	trader	Fruit Gardener#ra	4_M_RACHMAN1,{
+OnInit:
+	sellitem Apple;
+	sellitem Banana;
+}
+
+rachel,65,80,1	trader	Vegetable Gardener#ra	4_F_SHABBY,{
+OnInit:
+	sellitem Carrot;
+	sellitem Pumpkin;
+	sellitem Sweet_Potato;
+}
+
 
 //=======================================================
 // Turtle Island
 //=======================================================
-tur_dun01,158,54,6	shop	Tool Dealer#tu	4W_M_03,1750:-1,501:-1,502:-1,503:-1,504:-1,506:-1,601:-1,602:-1,645:-1,656:-1,2242:-1
+tur_dun01,158,54,6	trader	Tool Dealer#tu	4W_M_03,{
+OnInit:
+	sellitem Arrow;
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Luxury_Sunglasses;
+}
+
 
 //=======================================================
 // Umbala
 //=======================================================
-um_in,104,124,3	shop	Tool Dealer#um	4_M_UMOLDMAN,512:-1,515:-1,535:-1,516:-1,513:-1,517:-1,528:-1,537:-1,601:-1,602:-1,645:-1,656:-1,610:-1
-um_in,160,125,3	shop	Weapon Dealer#um	4_M_UMSOLDIER,1501:-1,1504:-1,1507:-1,1510:-1,1513:-1,1519:-1,1807:-1,1811:-1,1809:-1
+um_in,104,124,3	trader	Tool Dealer#um	4_M_UMOLDMAN,{
+OnInit:
+	sellitem Apple;
+	sellitem Carrot;
+	sellitem Pumpkin;
+	sellitem Sweet_Potato;
+	sellitem Banana;
+	sellitem Meat;
+	sellitem Monster's_Feed;
+	sellitem Pet_Food;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Leaf_Of_Yggdrasil;
+}
+
+um_in,160,125,3	trader	Weapon Dealer#um	4_M_UMSOLDIER,{
+OnInit:
+	sellitem Club;
+	sellitem Mace;
+	sellitem Smasher;
+	sellitem Flail;
+	sellitem Morning_Star;
+	sellitem Chain;
+	sellitem Fist;
+	sellitem Finger;
+	sellitem Claw;
+}
+
 
 //=======================================================
 // Veins
 //=======================================================
-ve_in,386,245,3	shop	Weapon Dealer#ve	4_M_RACHMAN1,1201:-1,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1
-ve_in,336,243,3	shop	Weapon Dealer#ve2	4_M_RACHMAN1,1407:-1,1457:-1,1354:-1,1519:-1,13003:-1
-ve_in,374,230,3	shop	Armor Dealer#ve	4_F_SHABBY,2101:-1,2103:-1,2403:-1,2405:-1,2503:-1,2321:-1,2314:-1,2309:-1,2335:-1,2628:-1
-ve_in,243,303,5	shop	Tool Dealer#ve	4_M_DESERT,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,611:-1,1065:-1,610:-1
-ve_in,253,304,5	shop	Fruit Gardener#ve	4_F_DST_CHILD,512:-1,513:-1
-ve_in,252,313,0	shop	Magical Item Seller#ve	4_F_DST_GRAND,717:-1,1601:-1,1604:-1,1607:-1,1610:-1,2232:-1,2321:-1,2332:-1
+ve_in,386,245,3	trader	Weapon Dealer#ve	4_M_RACHMAN1,{
+OnInit:
+	sellitem Knife;
+	sellitem Main_Gauche;
+	sellitem Stiletto;
+	sellitem Blade;
+	sellitem Ring_Pommel_Saber;
+	sellitem Katana;
+	sellitem Bastard_Sword;
+}
+
+ve_in,336,243,3	trader	Weapon Dealer#ve2	4_M_RACHMAN1,{
+OnInit:
+	sellitem Pike;
+	sellitem Partizan;
+	sellitem Hammer;
+	sellitem Chain;
+	sellitem Coward;
+}
+
+ve_in,374,230,3	trader	Armor Dealer#ve	4_F_SHABBY,{
+OnInit:
+	sellitem Guard;
+	sellitem Buckler;
+	sellitem Shoes;
+	sellitem Boots;
+	sellitem Muffler;
+	sellitem Silk_Robe;
+	sellitem Chain_Mail;
+	sellitem Coat;
+	sellitem Thief_Clothes;
+	sellitem Novice_Armlet;
+}
+
+ve_in,243,303,5	trader	Tool Dealer#ve	4_M_DESERT,{
+OnInit:
+	sellitem Red_Potion;
+	sellitem Orange_Potion;
+	sellitem Yellow_Potion;
+	sellitem White_Potion;
+	sellitem Green_Potion;
+	sellitem Center_Potion;
+	sellitem Awakening_Potion;
+	sellitem Wing_Of_Fly;
+	sellitem Wing_Of_Butterfly;
+	sellitem Spectacles;
+	sellitem Booby_Trap;
+	sellitem Leaf_Of_Yggdrasil;
+}
+
+ve_in,253,304,5	trader	Fruit Gardener#ve	4_F_DST_CHILD,{
+OnInit:
+	sellitem Apple;
+	sellitem Banana;
+}
+
+ve_in,252,313,0	trader	Magical Item Seller#ve	4_F_DST_GRAND,{
+OnInit:
+	sellitem Blue_Gemstone;
+	sellitem Rod;
+	sellitem Wand;
+	sellitem Staff;
+	sellitem Arc_Wand;
+	sellitem Circlet;
+	sellitem Silk_Robe;
+	sellitem Silver_Robe;
+}
+
 
 //=======================================================
 // Cooking Addition
 //=======================================================
-prontera,156,212,1	shop	Chef Assistant#prt	8_F_GIRL,7454:-1,7456:-1,7482:-1,580:-1
-payon,206,119,5	shop	Chef Assistant#pay	4_M_ORIENT02,7455:-1
-moc_ruins,115,123,5	shop	Chef Assistant#moc	4_M_04,7455:-1,7453:-1,7454:-1,7456:-1,7452:-1
-geffen,196,111,3	shop	Chef Assistant#gef	4_M_03,7482:-1
-alberta,167,135,5	shop	Chef Assistant#alb	4_M_05,579:-1
-aldebaran,165,107,2	shop	Chef Assistant#alde	4W_M_01,7456:-1,7452:-1,580:-1
-comodo,225,164,3	shop	Chef Assistant#cmd	4_M_01,7455:-1,7453:-1,7454:-1,579:-1
-umbala,102,154,3	shop	Chef Assistant#um	4_M_01,7456:-1,577:-1
-yuno,130,173,3	shop	Chef Assistant#yuno	4_M_01,7457:-1,7482:-1
-einbroch,224,207,5	shop	Chef Assistant#ein	4_M_01,7457:-1
-lighthalzen,126,126,3	shop	Chef Assistant#lhz	4_M_01,7456:-1,7452:-1
-amatsu,206,150,3	shop	Chef Assistant#ama	4_M_01,7453:-1,579:-1
-louyang,256,123,5	shop	Chef Assistant#lou	4_M_CHNCOOK,7454:-1,577:-1
-gonryun,147,101,5	shop	Chef Assistant#gon	4_M_01,7452:-1,580:-1
-ayothaya,203,178,3	shop	Chef Assistant#ayo	4_M_01,7455:-1,577:-1
-xmas,152,137,5	shop	Chef Assistant#xmas	4_M_01,7457:-1,577:-1
-niflheim,209,180,5	shop	Chef Assistant#nif	4_M_01,581:-1
+prontera,156,212,1	trader	Chef Assistant#prt	8_F_GIRL,{
+OnInit:
+	sellitem Plain_Sauce;
+	sellitem Red_Spice;
+	sellitem Pot;
+	sellitem Bread;
+}
+
+payon,206,119,5	trader	Chef Assistant#pay	4_M_ORIENT02,{
+OnInit:
+	sellitem Hot_Sauce;
+}
+
+moc_ruins,115,123,5	trader	Chef Assistant#moc	4_M_04,{
+OnInit:
+	sellitem Hot_Sauce;
+	sellitem Sweet_Sauce;
+	sellitem Plain_Sauce;
+	sellitem Red_Spice;
+	sellitem Yellow_Spice;
+}
+
+geffen,196,111,3	trader	Chef Assistant#gef	4_M_03,{
+OnInit:
+	sellitem Pot;
+}
+
+alberta,167,135,5	trader	Chef Assistant#alb	4_M_05,{
+OnInit:
+	sellitem Delicious_Fish;
+}
+
+aldebaran,165,107,2	trader	Chef Assistant#alde	4W_M_01,{
+OnInit:
+	sellitem Red_Spice;
+	sellitem Yellow_Spice;
+	sellitem Bread;
+}
+
+comodo,225,164,3	trader	Chef Assistant#cmd	4_M_01,{
+OnInit:
+	sellitem Hot_Sauce;
+	sellitem Sweet_Sauce;
+	sellitem Plain_Sauce;
+	sellitem Delicious_Fish;
+}
+
+umbala,102,154,3	trader	Chef Assistant#um	4_M_01,{
+OnInit:
+	sellitem Red_Spice;
+	sellitem Grain;
+}
+
+yuno,130,173,3	trader	Chef Assistant#yuno	4_M_01,{
+OnInit:
+	sellitem Cooking_Oil;
+	sellitem Pot;
+}
+
+einbroch,224,207,5	trader	Chef Assistant#ein	4_M_01,{
+OnInit:
+	sellitem Cooking_Oil;
+}
+
+lighthalzen,126,126,3	trader	Chef Assistant#lhz	4_M_01,{
+OnInit:
+	sellitem Red_Spice;
+	sellitem Yellow_Spice;
+}
+
+amatsu,206,150,3	trader	Chef Assistant#ama	4_M_01,{
+OnInit:
+	sellitem Sweet_Sauce;
+	sellitem Delicious_Fish;
+}
+
+louyang,256,123,5	trader	Chef Assistant#lou	4_M_CHNCOOK,{
+OnInit:
+	sellitem Plain_Sauce;
+	sellitem Grain;
+}
+
+gonryun,147,101,5	trader	Chef Assistant#gon	4_M_01,{
+OnInit:
+	sellitem Yellow_Spice;
+	sellitem Bread;
+}
+
+ayothaya,203,178,3	trader	Chef Assistant#ayo	4_M_01,{
+OnInit:
+	sellitem Hot_Sauce;
+	sellitem Grain;
+}
+
+xmas,152,137,5	trader	Chef Assistant#xmas	4_M_01,{
+OnInit:
+	sellitem Cooking_Oil;
+	sellitem Grain;
+}
+
+niflheim,209,180,5	trader	Chef Assistant#nif	4_M_01,{
+OnInit:
+	sellitem Mushroom;
+}
+
 
 //===== Additional Comments(old): =================================
 //= swapped shop titles in GONRYUN, thanks to Kashy
@@ -364,4 +2240,4 @@ niflheim,209,180,5	shop	Chef Assistant#nif	4_M_01,581:-1
 //= 1.9a Pet Merchant -> Lighthalzen [erKURITA]
 //= 1.9b Added items to Chivas Regal
 //= 1.9c Slight update for Rachel shop: Tool Dealer -> Fruit Gardener [L0ne_W0lf]
-//============================================================
+//============================================================
\ No newline at end of file
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 60b21285d..906c329fa 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -671,6 +671,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1383205740);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1383955424);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1384545461);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1384588175);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1387844126);
 
 --
 -- Table structure for table `sstatus`
@@ -731,3 +732,14 @@ CREATE TABLE IF NOT EXISTS `account_data` (
   PRIMARY KEY  (`account_id`)
 ) ENGINE=MyISAM; 
 
+--
+-- Table structure for table `npc_market_data`
+--
+
+CREATE TABLE IF NOT EXISTS `npc_market_data` (
+  `name` varchar(24) NOT NULL default '',
+  `itemid` int(11) unsigned NOT NULL default '0',
+  `amount` int(11) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`name`,`itemid`)
+) ENGINE=MyISAM;
+
diff --git a/sql-files/upgrades/2013-12-24--00-15.sql b/sql-files/upgrades/2013-12-24--00-15.sql
new file mode 100644
index 000000000..b1f8d019d
--- /dev/null
+++ b/sql-files/upgrades/2013-12-24--00-15.sql
@@ -0,0 +1,8 @@
+#1387844126
+CREATE TABLE IF NOT EXISTS `npc_market_data` (
+  `name` varchar(24) NOT NULL default '',
+  `itemid` int(11) unsigned NOT NULL default '0',
+  `amount` int(11) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`name`,`itemid`)
+) ENGINE=MyISAM;
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1387844126);
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 9b7ad20d8..0c4ac87e5 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -15,3 +15,4 @@
 2013-11-15--19-57.sql
 2013-11-16--07-49.sql
 2013-11-18--08-23.sql
+2013-12-24--00-15.sql
\ No newline at end of file
diff --git a/src/common/mmo.h b/src/common/mmo.h
index b33b01fa7..bd5da6a9f 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -48,7 +48,7 @@
 // 20120307 - 2012-03-07aRagexeRE+ - 0x970
 
 #ifndef PACKETVER
-#define PACKETVER 20120418
+	#define PACKETVER 20131223
 #endif // PACKETVER
 
 #ifndef DISABLE_PACKETVER_RE
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 953f1a0dc..ce73319e2 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -9273,17 +9273,28 @@ ACMD(searchstore){
 	return true;
 }
 ACMD(costume){
-	const char* names[4] = {
+	const char* names[] = {
 		"Wedding",
 		"Xmas",
 		"Summer",
 		"Hanbok",
+#if PACKETVER >= 20131218
+		"Oktoberfest",
+#endif
+	};
+	const int name2id[] = {
+		SC_WEDDING,
+		SC_XMAS,
+		SC_SUMMER,
+		SC_HANBOK,
+#if PACKETVER >= 20131218
+		SC_OKTOBERFEST,
+#endif
 	};
-	const int name2id[4] = { SC_WEDDING, SC_XMAS, SC_SUMMER, SC_HANBOK };
-	unsigned short k = 0;
+	unsigned short k = 0, len = ARRAYLENGTH(names);
 	
 	if( !message || !*message ) {
-		for( k = 0; k < 4; k++ ) {
+		for( k = 0; k < len; k++ ) {
 			if( sd->sc.data[name2id[k]] ) {
 				sprintf(atcmd_output,msg_txt(1473),names[k]);//Costume '%s' removed.
 				clif->message(sd->fd,atcmd_output);
@@ -9293,14 +9304,14 @@ ACMD(costume){
 		}
 		
 		clif->message(sd->fd,msg_txt(1472));
-		for( k = 0; k < 4; k++ ) {
+		for( k = 0; k < len; k++ ) {
 			sprintf(atcmd_output,msg_txt(1471),names[k]);//-- %s
 			clif->message(sd->fd,atcmd_output);
 		}
 		return false;
 	}
 	
-	for( k = 0; k < 4; k++ ) {
+	for( k = 0; k < len; k++ ) {
 		if( sd->sc.data[name2id[k]] ) {
 			sprintf(atcmd_output,msg_txt(1470),names[k]);// You're already with a '%s' costume, type '@costume' to remove it.
 			clif->message(sd->fd,atcmd_output);
@@ -9308,11 +9319,11 @@ ACMD(costume){
 		}
 	}
 	
-	for( k = 0; k < 4; k++ ) {
+	for( k = 0; k < len; k++ ) {
 		if( strcmpi(message,names[k]) == 0 )
 			break;
 	}
-	if( k == 4 ) {
+	if( k == len ) {
 		sprintf(atcmd_output,msg_txt(1469),message);// '%s' is not a known costume
 		clif->message(sd->fd,atcmd_output);
 		return false;
diff --git a/src/map/clif.c b/src/map/clif.c
index 6a55ad344..b442d6279 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -61,7 +61,8 @@ static struct packet_itemlist_equip itemlist_equip;
 static struct packet_storelist_normal storelist_normal;
 static struct packet_storelist_equip storelist_equip;
 static struct packet_viewequip_ack viewequip_list;
-
+static struct packet_npc_market_result_ack npcmarket_result;
+static struct packet_npc_market_open npcmarket_open;
 //#define DUMP_UNKNOWN_PACKET
 //#define DUMP_INVALID_PACKET
 
@@ -811,7 +812,7 @@ void clif_clearunit_delayed(struct block_list* bl, clr_type type, int64 tick) {
 
 void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, unsigned short *lhand)
 {
-	if(sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK)) {
+	if(sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST)) {
 		*rhand = *lhand = 0;
 		return;
 	}
@@ -1743,29 +1744,40 @@ void clif_npcbuysell(struct map_session_data* sd, int id)
 
 /// Presents list of items, that can be bought in an NPC shop (ZC_PC_PURCHASE_ITEMLIST).
 /// 00c6 <packet len>.W { <price>.L <discount price>.L <item type>.B <name id>.W }*
-void clif_buylist(struct map_session_data *sd, struct npc_data *nd)
-{
+void clif_buylist(struct map_session_data *sd, struct npc_data *nd) {
+	struct npc_item_list *shop = NULL;
+	unsigned short shop_size = 0;
 	int fd,i,c;
-
+	
 	nullpo_retv(sd);
 	nullpo_retv(nd);
 
+	if( nd->subtype == SCRIPT ) {
+		shop = nd->u.scr.shop->item;
+		shop_size = nd->u.scr.shop->items;
+	} else {
+		shop = nd->u.shop.shop_item;
+		shop_size = nd->u.shop.count;
+	}
+	
 	fd = sd->fd;
-	WFIFOHEAD(fd, 4 + nd->u.shop.count * 11);
+	
+	WFIFOHEAD(fd, 4 + shop_size * 11);
 	WFIFOW(fd,0) = 0xc6;
 
 	c = 0;
-	for( i = 0; i < nd->u.shop.count; i++ )
-	{
-		struct item_data* id = itemdb->exists(nd->u.shop.shop_item[i].nameid);
-		int val = nd->u.shop.shop_item[i].value;
-		if( id == NULL )
-			continue;
-		WFIFOL(fd, 4+c*11) = val;
-		WFIFOL(fd, 8+c*11) = pc->modifybuyvalue(sd,val);
-		WFIFOB(fd,12+c*11) = itemtype(id->type);
-		WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
-		c++;
+	for( i = 0; i < shop_size; i++ ) {
+		if( shop[i].nameid ) {
+			struct item_data* id = itemdb->exists(shop[i].nameid);
+			int val = shop[i].value;
+			if( id == NULL )
+				continue;
+			WFIFOL(fd, 4+c*11) = val;
+			WFIFOL(fd, 8+c*11) = pc->modifybuyvalue(sd,val);
+			WFIFOB(fd,12+c*11) = itemtype(id->type);
+			WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+			c++;
+		}
 	}
 
 	WFIFOW(fd,2) = 4 + c*11;
@@ -3170,7 +3182,7 @@ void clif_changelook(struct block_list *bl,int type,int val)
 			case LOOK_BASE:
 				if( !sd ) break;
 				
-				if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) )
+				if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) )
 					vd->weapon = vd->shield = 0;
 				
 				if( !vd->cloth_color )
@@ -3185,6 +3197,8 @@ void clif_changelook(struct block_list *bl,int type,int val)
 						vd->cloth_color = 0;
 					if( sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette )
 						vd->cloth_color = 0;
+					if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ )
+						vd->cloth_color = 0;
 				}
 			break;
 			case LOOK_HAIR:
@@ -3212,6 +3226,8 @@ void clif_changelook(struct block_list *bl,int type,int val)
 						val = 0;
 					if( sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette )
 						val = 0;
+					if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ )
+						val = 0;
 				}
 				vd->cloth_color = val;
 			break;
@@ -9616,6 +9632,7 @@ void clif_parse_Hotkey(int fd, struct map_session_data *sd) {
 
 /// Displays cast-like progress bar (ZC_PROGRESS).
 /// 02f0 <color>.L <time>.L
+/* TODO ZC_PROGRESS_ACTOR <account_id>.L */
 void clif_progressbar(struct map_session_data * sd, unsigned int color, unsigned int second)
 {
 	int fd = sd->fd;
@@ -9901,6 +9918,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
 		WFIFOW(fd,0) = 0x8e;
 	}
 	WFIFOSET(fd, WFIFOW(fd,2));
+	
 #ifdef PCRE_SUPPORT
 	// trigger listening npcs
 	map->foreachinrange(npc_chat->sub, &sd->bl, AREA_SIZE, BL_NPC, text, textlen, &sd->bl);
@@ -10058,7 +10076,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
 			if( pc_cant_act(sd) || sd->sc.option&OPTION_HIDE )
 				return;
 
-			if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) )
+			if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) )
 				return;
 
 			if( sd->sc.data[SC_BASILICA] || sd->sc.data[SC__SHADOWFORM] )
@@ -11303,7 +11321,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
 		}
 	}
 
-	if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) )
+	if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) )
 		return;
 
 	if( sd->sc.data[SC_BASILICA] && (skill_id != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) )
@@ -11395,7 +11413,7 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 ski
 		}
 	}
 
-	if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) )
+	if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) )
 		return;
 
 	if( sd->sc.data[SC_BASILICA] && (skill_id != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) )
@@ -13524,19 +13542,20 @@ void clif_parse_GMRecall2(int fd, struct map_session_data* sd) {
 /// /item cap_n - capture n monster as pet.(not yet implemented)
 /// /item agitinvest - reset current global agit investments.(not yet implemented)
 /// 013f <item/mob name>.24B
-void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
-{
+/// 09ce <item/mob name>.100B [Ind/Yommy<3]
+void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) {
+	struct packet_gm_monster_item *p = P2PTR(fd);
 	int i, count;
 	char *item_monster_name;
 	struct item_data *item_array[10];
 	struct mob_db *mob_array[10];
-	char command[NAME_LENGTH+10];
+	char command[256];
 
-	item_monster_name = (char*)RFIFOP(fd,2);
-	item_monster_name[NAME_LENGTH-1] = '\0';
+	item_monster_name = p->str;
+	item_monster_name[(sizeof(struct packet_gm_monster_item)-2)-1] = '\0';
 
-	if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, 1)) > 0 ){
-		for(i = 0; i < count; i++){
+	if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, 1)) > 0 ) {
+		for(i = 0; i < count; i++) {
 			if( !item_array[i] )
 				continue;
 			// It only accepts aegis name
@@ -13546,7 +13565,7 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
 				break;
 		}
 
-		if( i < count ){
+		if( i < count ) {
 			if( item_array[i]->type == IT_WEAPON || item_array[i]->type == IT_ARMOR ) // nonstackable
 				snprintf(command, sizeof(command)-1, "%citem2 %d 1 0 0 0 0 0 0 0", atcommand->at_symbol, item_array[i]->nameid);
 			else
@@ -13562,8 +13581,8 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
 		return;
 	}
 
-	if( (count=mob->db_searchname_array(mob_array, 10, item_monster_name, 1)) > 0){
-		for(i = 0; i < count; i++){
+	if( (count=mob->db_searchname_array(mob_array, 10, item_monster_name, 1)) > 0) {
+		for(i = 0; i < count; i++) {
 			if( !mob_array[i] )
 				continue;
 			// It only accepts sprite name
@@ -15402,9 +15421,11 @@ void clif_parse_Auction_buysell(int fd, struct map_session_data* sd)
 /// List of items offered in a cash shop (ZC_PC_CASH_POINT_ITEMLIST).
 /// 0287 <packet len>.W <cash point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }*
 /// 0287 <packet len>.W <cash point>.L <kafra point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }* (PACKETVER >= 20070711)
-void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
-{
-	int fd,i;
+void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd) {
+	struct npc_item_list *shop = NULL;
+	unsigned short shop_size = 0;
+	int fd,i, c = 0;
+	int currency[2] = { 0,0 };
 #if PACKETVER < 20070711
 	const int offset = 8;
 #else
@@ -15414,23 +15435,43 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
 	nullpo_retv(sd);
 	nullpo_retv(nd);
 
+	if( nd->subtype == SCRIPT ) {
+		shop = nd->u.scr.shop->item;
+		shop_size = nd->u.scr.shop->items;
+		
+		npc->trader_count_funds(nd, sd);
+		
+		currency[0] = npc->trader_funds[0];
+		currency[1] = npc->trader_funds[1];
+	} else {
+		shop = nd->u.shop.shop_item;
+		shop_size = nd->u.shop.count;
+		
+		currency[0] = sd->cashPoints;
+		currency[1] = sd->kafraPoints;
+	}
+	
 	fd = sd->fd;
 	sd->npc_shopid = nd->bl.id;
-	WFIFOHEAD(fd,offset+nd->u.shop.count*11);
+	WFIFOHEAD(fd,offset+shop_size*11);
 	WFIFOW(fd,0) = 0x287;
-	WFIFOW(fd,2) = offset+nd->u.shop.count*11;
-	WFIFOL(fd,4) = sd->cashPoints; // Cash Points
+	/* 0x2 = length, set after parsing */
+	WFIFOL(fd,4) = currency[0]; // Cash Points
 #if PACKETVER >= 20070711
-	WFIFOL(fd,8) = sd->kafraPoints; // Kafra Points
+	WFIFOL(fd,8) = currency[1]; // Kafra Points
 #endif
 
-	for( i = 0; i < nd->u.shop.count; i++ ) {
-		struct item_data* id = itemdb->search(nd->u.shop.shop_item[i].nameid);
-		WFIFOL(fd,offset+0+i*11) = nd->u.shop.shop_item[i].value;
-		WFIFOL(fd,offset+4+i*11) = nd->u.shop.shop_item[i].value; // Discount Price
-		WFIFOB(fd,offset+8+i*11) = itemtype(id->type);
-		WFIFOW(fd,offset+9+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+	for( i = 0; i < shop_size; i++ ) {
+		if( shop[i].nameid ) {
+			struct item_data* id = itemdb->search(shop[i].nameid);
+			WFIFOL(fd,offset+0+i*11) = shop[i].value;
+			WFIFOL(fd,offset+4+i*11) = shop[i].value; // Discount Price
+			WFIFOB(fd,offset+8+i*11) = itemtype(id->type);
+			WFIFOW(fd,offset+9+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+			c++;
+		}
 	}
+	WFIFOW(fd,2) = offset+c*11;
 	WFIFOSET(fd,WFIFOW(fd,2));
 }
 
@@ -15449,15 +15490,26 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
 ///     7 = You can purchase up to 10 items.
 ///     8 = Some items could not be purchased.
 void clif_cashshop_ack(struct map_session_data* sd, int error) {
-	int fd = sd->fd;
+	struct npc_data *nd;
+    int fd = sd->fd;
+	int currency[2] = { 0,0 };
+	
+	if( (nd = map->id2nd(sd->npc_shopid)) && nd->subtype == SCRIPT ) {
+		npc->trader_count_funds(nd,sd);
+		currency[0] = npc->trader_funds[0];
+		currency[1] = npc->trader_funds[1];
+	} else {
+		currency[0] = sd->cashPoints;
+		currency[1] = sd->kafraPoints;
+	}
 
 	WFIFOHEAD(fd, packet_len(0x289));
 	WFIFOW(fd,0) = 0x289;
-	WFIFOL(fd,2) = sd->cashPoints;
+	WFIFOL(fd,2) = currency[0];
 #if PACKETVER < 20070711
 	WFIFOW(fd,6) = TOW(error);
 #else
-	WFIFOL(fd,6) = sd->kafraPoints;
+	WFIFOL(fd,6) = currency[1];
 	WFIFOW(fd,10) = TOW(error);
 #endif
 	WFIFOSET(fd, packet_len(0x289));
@@ -18048,7 +18100,77 @@ int clif_delay_damage(int64 tick, struct block_list *src, struct block_list *dst
 	
 	return clif->calc_walkdelay(dst,ddelay,type,damage,div);
 }
+/* Thanks to Yommy */
+void clif_parse_NPCShopClosed(int fd, struct map_session_data *sd) {
+	/* TODO track the state <3~ */
+	sd->npc_shopid = 0;
+}
+/* NPC Market (by Ind after an extensive debugging of the packet, only possible thanks to Yommy <3) */
+void clif_npc_market_open(struct map_session_data *sd, struct npc_data *nd) {
+	struct npc_item_list *shop = nd->u.scr.shop->item;
+	unsigned short shop_size = nd->u.scr.shop->items, i, c;
+	struct item_data *id = NULL;
+	
+	npcmarket_open.PacketType = npcmarketopenType;
+	
+	for(i = 0, c = 0; i < shop_size; i++) {
+		if( shop[i].nameid && (id = itemdb->exists(shop[i].nameid)) ) {
+			npcmarket_open.list[c].nameid = shop[i].nameid;
+			npcmarket_open.list[c].price  = shop[i].value;
+			npcmarket_open.list[c].qty    = shop[i].qty;
+			npcmarket_open.list[c].type   = itemtype(id->type);
+			npcmarket_open.list[c].view   = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+			c++;
+		}
+	}
+
+	npcmarket_open.PacketLength = 4 + ( sizeof(npcmarket_open.list[0]) * c );
+	
+	clif->send(&npcmarket_open,npcmarket_open.PacketLength,&sd->bl,SELF);
+}
+void clif_parse_NPCMarketClosed(int fd, struct map_session_data *sd) {
+	/* TODO track the state <3~ */
+	sd->npc_shopid = 0;
+}
+void clif_npc_market_purchase_ack(struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char response) {
+	unsigned short c = 0;
+	
+	npcmarket_result.PacketType = npcmarketresultackType;
+	npcmarket_result.result = response == 0 ? 1 : 0;/* find other values */
+		
+	if( npcmarket_result.result ) {
+		unsigned short i, list_size = (req->PacketLength - 4) / sizeof(req->list[0]), j;
+		struct npc_data* nd;
+		struct npc_item_list *shop = NULL;
+		unsigned short shop_size = 0;
+		
+		nd = map->id2nd(sd->npc_shopid);
 
+		shop = nd->u.scr.shop->item;
+		shop_size = nd->u.scr.shop->items;
+		
+		for(i = 0; i < list_size; i++) {
+			
+			npcmarket_result.list[i].ITID  = req->list[i].ITID;
+			npcmarket_result.list[i].qty   = req->list[i].qty;
+			
+			ARR_FIND( 0, shop_size, j, req->list[i].ITID == shop[j].nameid );
+			
+			npcmarket_result.list[i].price = (j != shop_size) ? shop[j].value : 0;
+			
+			c++;
+		}
+	}
+	
+	npcmarket_result.PacketLength = 5 + ( sizeof(npcmarket_result.list[0]) * c );;
+	
+	clif->send(&npcmarket_result,npcmarket_result.PacketLength,&sd->bl,SELF);
+}
+void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) {
+	struct packet_npc_market_purchase *p = P2PTR(fd);
+
+	clif->npc_market_purchase_ack(sd,p,npc->market_buylist(sd,(p->PacketLength - 4) / sizeof(p->list[0]),p));
+}
 /* */
 unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
 	if( sd ) {
@@ -18863,6 +18985,9 @@ void clif_defaults(void) {
 	/* */
 	clif->delay_damage = clif_delay_damage;
 	clif->delay_damage_sub = clif_delay_damage_sub;
+	/* NPC Market */
+	clif->npc_market_open = clif_npc_market_open;
+	clif->npc_market_purchase_ack = clif_npc_market_purchase_ack;
 	/*------------------------
 	 *- Parse Incoming Packet
 	 *------------------------*/ 
@@ -19092,4 +19217,9 @@ void clif_defaults(void) {
 	clif->pBankCheck = clif_parse_BankCheck;
 	clif->pBankOpen = clif_parse_BankOpen;
 	clif->pBankClose = clif_parse_BankClose;
+	/* */
+	clif->pNPCShopClosed = clif_parse_NPCShopClosed;
+	/* NPC Market */
+	clif->pNPCMarketClosed = clif_parse_NPCMarketClosed;
+	clif->pNPCMarketPurchase = clif_parse_NPCMarketPurchase;
 }
diff --git a/src/map/clif.h b/src/map/clif.h
index c4088893a..6405bbd3e 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -1034,6 +1034,9 @@ struct clif_interface {
 	/* */
 	int (*delay_damage) (int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type);
 	int (*delay_damage_sub) (int tid, int64 tick, int id, intptr_t data);
+	/* NPC Market */
+	void (*npc_market_open) (struct map_session_data *sd, struct npc_data *nd);
+	void (*npc_market_purchase_ack) (struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char response);
 	/*------------------------
 	 *- Parse Incoming Packet
 	 *------------------------*/
@@ -1261,6 +1264,11 @@ struct clif_interface {
 	void (*pBankCheck) (int fd, struct map_session_data *sd);
 	void (*pBankOpen) (int fd, struct map_session_data *sd);
 	void (*pBankClose) (int fd, struct map_session_data *sd);
+	/* */
+	void (*pNPCShopClosed) (int fd, struct map_session_data *sd);
+	/* NPC Market (by Ind after an extensive debugging of the packet, only possible thanks to Yommy <3) */
+	void (*pNPCMarketClosed) (int fd, struct map_session_data *sd);
+	void (*pNPCMarketPurchase) (int fd, struct map_session_data *sd);
 };
 
 struct clif_interface *clif;
diff --git a/src/map/map.c b/src/map/map.c
index 7ff4ebcc5..aef34ef00 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -5630,7 +5630,8 @@ int do_init(int argc, char *argv[])
 	}
 	
 	npc->event_do_oninit();	// Init npcs (OnInit)
-
+	npc->market_fromsql(); /* after OnInit */
+	
 	if (battle_config.pk_mode)
 		ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n");
 
diff --git a/src/map/npc.c b/src/map/npc.c
index 84a2446ad..44df2fe7a 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -56,6 +56,9 @@ struct npc_path_data *npc_last_npd;
 static struct view_data npc_viewdb[MAX_NPC_CLASS];
 static struct view_data npc_viewdb2[MAX_NPC_CLASS2_END-MAX_NPC_CLASS2_START];
 
+/* for speedup */
+unsigned int npc_market_qty[MAX_INVENTORY];
+
 static struct script_event_s
 {	//Holds pointers to the commonly executed scripts for speedup. [Skotlex]
 	struct event_data *event[UCHAR_MAX];
@@ -1150,8 +1153,10 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd)
 	}
 
 	if(!nd) return 1;
+	
 	if ((nd = npc->checknear(sd,&nd->bl)) == NULL)
 		return 1;
+	
 	//Hidden/Disabled npc.
 	if (nd->class_ < 0 || nd->option&(OPTION_INVISIBLE|OPTION_HIDE))
 		return 1;
@@ -1164,7 +1169,11 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd)
 			clif->cashshop_show(sd,nd);
 			break;
 		case SCRIPT:
-			script->run(nd->u.scr.script,0,sd->bl.id,nd->bl.id);
+			if( nd->u.scr.shop && nd->u.scr.shop->items && nd->u.scr.trader ) {
+				if( !npc->trader_open(sd,nd) )
+					return 1;
+			} else
+				script->run(nd->u.scr.script,0,sd->bl.id,nd->bl.id);
 			break;
 		case TOMB:
 			npc->run_tomb(sd,nd);
@@ -1231,16 +1240,22 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) {
 	if ((nd = npc->checknear(sd,map->id2bl(id))) == NULL)
 		return 1;
 
-	if (nd->subtype!=SHOP) {
-		ShowError("no such shop npc : %d\n",id);
+	if ( nd->subtype != SHOP && !(nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->items) ) {
+		
+		if( nd->subtype == SCRIPT )
+			ShowError("npc_buysellsel: trader '%s' has no shop list!\n",nd->exname);
+		else
+			ShowError("npc_buysellsel: no such shop npc %d (%s)\n",id,nd->exname);
+		 
 		if (sd->npc_id == id)
-			sd->npc_id=0;
+			sd->npc_id = 0;
 		return 1;
 	}
-    if (nd->option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
+    
+	if (nd->option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
 		return 1;
-	if( nd->class_ < 0 && !sd->state.callshop )
-	{// not called through a script and is not a visible NPC so an invalid call
+	
+	if( nd->class_ < 0 && !sd->state.callshop ) {// not called through a script and is not a visible NPC so an invalid call
 		return 1;
 	}
 
@@ -1253,6 +1268,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) {
 	} else {
 		clif->selllist(sd);
 	}
+	
 	return 0;
 }
 
@@ -1261,14 +1277,33 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) {
 *------------------------------------------*/
 int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list) {
 	int i, j, nameid, amount, new_, w, vt;
-	struct npc_data *nd = (struct npc_data *)map->id2bl(sd->npc_shopid);
-
-	if( !nd || nd->subtype != CASHSHOP )
-		return 1;
+	struct npc_data *nd = NULL;
+	struct npc_item_list *shop = NULL;
+	unsigned short shop_size = 0;
 
 	if( sd->state.trading )
 		return 4;
 
+	if( count <= 0 )
+		return 5;
+	
+	if( points < 0 )
+		return 6;
+	
+	if( !(nd = (struct npc_data *)map->id2bl(sd->npc_shopid)) )
+		return 1;
+	
+	if( nd->subtype != CASHSHOP ) {
+		if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET ) {
+			shop = nd->u.scr.shop->item;
+			shop_size = nd->u.scr.shop->items;
+		} else
+			return 1;
+	} else {
+		shop = nd->u.shop.shop_item;
+		shop_size = nd->u.shop.count;
+	}
+	
 	new_ = 0;
 	w = 0;
 	vt = 0; // Global Value
@@ -1281,12 +1316,13 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
 		if( !itemdb->exists(nameid) || amount <= 0 )
 			return 5;
 
-		ARR_FIND(0,nd->u.shop.count,j,nd->u.shop.shop_item[j].nameid == nameid);
-		if( j == nd->u.shop.count || nd->u.shop.shop_item[j].value <= 0 )
+		ARR_FIND(0,shop_size,j,shop[j].nameid == nameid);
+		if( j == shop_size || shop[j].value <= 0 )
 			return 5;
 
 		if( !itemdb->isstackable(nameid) && amount > 1 ) {
-			ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
+			ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
+						sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
 			amount = item_list[i*2+0] = 1;
 		}
 
@@ -1298,21 +1334,27 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
 				return 3;
 		}
 
-		vt += nd->u.shop.shop_item[j].value * amount;
+		vt += shop[j].value * amount;
 		w += itemdb_weight(nameid) * amount;
 	}
 
 	if( w + sd->weight > sd->max_weight )
 		return 3;
+	
 	if( pc->inventoryblank(sd) < new_ )
 		return 3;
+	
 	if( points > vt ) points = vt;
 
 	// Payment Process ----------------------------------------------------
-	if( sd->kafraPoints < points || sd->cashPoints < (vt - points) )
-		return 6;
-	pc->paycash(sd,vt,points);
-
+	if( nd->subtype == SCRIPT && nd->u.scr.shop->type == NST_CUSTOM ) {
+		if( !npc->trader_pay(nd,sd,vt,points) )
+			return 6;
+	} else {
+		if( sd->kafraPoints < points || sd->cashPoints < (vt - points) )
+			return 6;
+		pc->paycash(sd,vt,points);
+	}
 	// Delivery Process ----------------------------------------------------
 	for( i = 0; i < count; i++ ) {
 		struct item item_tmp;
@@ -1356,45 +1398,257 @@ int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* item_lis
 
 	return 0;
 }
+/**
+ * Loads persistent NPC Market Data from SQL
+ **/
+void npc_market_fromsql(void) {
+	SqlStmt* stmt = SQL->StmtMalloc(map->mysql_handle);
+	char name[NAME_LENGTH+1];
+	int itemid;
+	int amount;
+	
+	/* TODO inter-server.conf npc_market_data */
+	if ( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `name`, `itemid`, `amount` FROM `npc_market_data`")
+		|| SQL_ERROR == SQL->StmtExecute(stmt)
+		) {
+		SqlStmt_ShowDebug(stmt);
+		SQL->StmtFree(stmt);
+		return;
+	}
+	
+	SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &name[0], sizeof(name), NULL, NULL);
+	SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &itemid, 0, NULL, NULL);
+	SQL->StmtBindColumn(stmt, 2, SQLDT_INT, &amount, 0, NULL, NULL);
+	
+	while ( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) {
+		struct npc_data *nd = NULL;
+		unsigned short i;
+		
+		if( !(nd = npc->name2id(name)) ) {
+			ShowError("npc_market_fromsql: NPC '%s' not found! skipping...\n",name);
+			continue;
+		} else if ( nd->subtype != SCRIPT || !nd->u.scr.shop || !nd->u.scr.shop->items || nd->u.scr.shop->type != NST_MARKET ) {
+			ShowError("npc_market_fromsql: NPC '%s' is not proper for market, skipping...\n",name);
+			continue;
+		}
+		
+		for(i = 0; i < nd->u.scr.shop->items; i++) {
+			if( nd->u.scr.shop->item[i].nameid == itemid ) {
+				nd->u.scr.shop->item[i].qty = amount;
+				break;
+			}
+		}
+		
+		if( i == nd->u.scr.shop->items ) {
+			ShowError("npc_market_fromsql: NPC '%s' does not sell item %d (qty %d), deleting...\n",name,itemid,amount);
+			/* TODO inter-server.conf npc_market_data */
+			if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `npc_market_data` WHERE `name`='%s' AND `itemid`='%d' LIMIT 1", name,itemid) )
+				Sql_ShowDebug(map->mysql_handle);
+			continue;
+		}
+		
+	}
+	
+	SQL->StmtFree(stmt);
+}
+/**
+ * Saves persistent NPC Market Data into SQL
+ **/
+void npc_market_tosql(struct npc_data *nd, unsigned short index) {
+	/* TODO inter-server.conf npc_market_data */
+	if( SQL_ERROR == SQL->Query(map->mysql_handle, "REPLACE INTO `npc_market_data` VALUES ('%s','%d','%d')", nd->exname, nd->u.scr.shop->item[index].nameid, nd->u.scr.shop->item[index].qty) )
+		Sql_ShowDebug(map->mysql_handle);
+}
+/**
+ * Removes persistent NPC Market Data from SQL
+ **/
+void npc_market_delfromsql(struct npc_data *nd, unsigned short index) {
+	/* TODO inter-server.conf npc_market_data */
+	if( index == USHRT_MAX ) {
+		if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `npc_market_data` WHERE `name`='%s'", nd->exname) )
+			Sql_ShowDebug(map->mysql_handle);
+	} else {
+		if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `npc_market_data` WHERE `name`='%s' AND `itemid`='%d' LIMIT 1", nd->exname, nd->u.scr.shop->item[index].nameid) )
+			Sql_ShowDebug(map->mysql_handle);
+	}
+}
+/**
+ * Judges whether to allow and spawn a trader's window.
+ **/
+bool npc_trader_open(struct map_session_data *sd, struct npc_data *nd) {
+	
+	if( !nd->u.scr.shop || !nd->u.scr.shop->items )
+		return false;
+		
+	switch( nd->u.scr.shop->type ) {
+		case NST_ZENY:
+			sd->state.callshop = 1;
+			npc->buysellsel(sd,nd->bl.id,0);
+			break;
+		case NST_MARKET: {
+				unsigned short i;
+				
+				for(i = 0; i < nd->u.scr.shop->items; i++) {
+					if( nd->u.scr.shop->item[i].qty )
+						break;
+				}
+			
+				/* nothing to display, no items available */
+				if( i == nd->u.scr.shop->items ) {
+					clif->colormes(sd->fd,COLOR_RED,"Shop is out of stock! Come again later!");/* TODO messages.conf-it */
+					return false;
+				}
 
+				clif->npc_market_open(sd,nd);
+			}
+			break;
+		default:
+			clif->cashshop_show(sd,nd);
+			break;
+	}
+	
+	sd->npc_shopid = nd->bl.id;
+	
+	return true;
+}
+/**
+ * Creates (npc_data)->u.scr.shop and updates all duplicates across the server to match the created pointer
+ *
+ * @param master id of the original npc
+ **/
+void npc_trader_update(int master) {
+	DBIterator* iter;
+	struct block_list* bl;
+	struct npc_data *master_nd = map->id2nd(master);
+	
+	CREATE(master_nd->u.scr.shop,struct npc_shop_data,1);
+	
+	iter = db_iterator(map->id_db);
+	
+	for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) {
+		if( bl->type == BL_NPC ) {
+			struct npc_data* nd = (struct npc_data*)bl;
+			
+			if( nd->src_id == master ) {
+				nd->u.scr.shop = master_nd->u.scr.shop;
+			}
+		}
+	}
+	
+	dbi_destroy(iter);
+}
+/**
+ * Tries to issue a CountFunds event to the shop.
+ *
+ * @param nd shop
+ * @param sd player
+ **/
+void npc_trader_count_funds(struct npc_data *nd, struct map_session_data *sd) {
+	char evname[EVENT_NAME_LENGTH];
+	struct event_data *ev = NULL;
+	
+	npc->trader_funds[0] = npc->trader_funds[1] = 0;/* clear */
+	
+	switch( nd->u.scr.shop->type ) {
+		case NST_CASH:
+			npc->trader_funds[0] = sd->cashPoints;
+			npc->trader_funds[1] = sd->kafraPoints;
+			return;
+		case NST_CUSTOM:
+			break;
+		default:
+			ShowError("npc_trader_count_funds: unsupported shop type %d\n",nd->u.scr.shop->type);
+			return;
+	}
+	
+	snprintf(evname, EVENT_NAME_LENGTH, "%s::OnCountFunds",nd->exname);
+	
+	if ( (ev = strdb_get(npc->ev_db, evname)) )
+		script->run(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id);
+	else
+		ShowError("npc_trader_count_funds: '%s' event '%s' not found, operation failed\n",nd->exname,evname);
+	
+	/* the callee will rely on npc->trader_funds, upon success script->run updates them */
+}
+/**
+ * Tries to issue a payment to the NPC Event capable of handling it
+ *
+ * @param nd shop
+ * @param sd player
+ * @param price total cost
+ * @param points the amount input in the shop by the user to use from the secondary currency (if any is being employed)
+ *
+ * @return bool whether it was successful (if the script does not respond it will fail)
+ **/
+bool npc_trader_pay(struct npc_data *nd, struct map_session_data *sd, int price, int points) {
+	char evname[EVENT_NAME_LENGTH];
+	struct event_data *ev = NULL;
+	
+	npc->trader_ok = false;/* clear */
+	
+	snprintf(evname, EVENT_NAME_LENGTH, "%s::OnPayFunds",nd->exname);
+	
+	if ( (ev = strdb_get(npc->ev_db, evname)) ) {
+		pc->setreg(sd,script->add_str("@price"),price);
+		pc->setreg(sd,script->add_str("@points"),points);
+		
+		script->run(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id);
+	} else
+		ShowError("npc_trader_pay: '%s' event '%s' not found, operation failed\n",nd->exname,evname);
+	
+	return npc->trader_ok;/* run script will deal with it */
+}
 /*==========================================
  * Cash Shop Buy
  *------------------------------------------*/
 int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int points) {
-	struct npc_data *nd = (struct npc_data *)map->id2bl(sd->npc_shopid);
+	struct npc_data *nd = NULL;
 	struct item_data *item;
+	struct npc_item_list *shop = NULL;
 	int i, price, w;
-
+	unsigned short shop_size = 0;
+	
 	if( amount <= 0 )
 		return 5;
 
 	if( points < 0 )
 		return 6;
 
-	if( !nd || nd->subtype != CASHSHOP )
-		return 1;
-
 	if( sd->state.trading )
 		return 4;
+	
+	if( !(nd = (struct npc_data *)map->id2bl(sd->npc_shopid)) )
+		return 1;
 
 	if( (item = itemdb->exists(nameid)) == NULL )
 		return 5; // Invalid Item
 
-	ARR_FIND(0, nd->u.shop.count, i, nd->u.shop.shop_item[i].nameid == nameid);
-	if( i == nd->u.shop.count )
+	if( nd->subtype != CASHSHOP ) {
+		if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET ) {
+			shop = nd->u.scr.shop->item;
+			shop_size = nd->u.scr.shop->items;
+		} else
+			return 1;
+	} else {
+		shop = nd->u.shop.shop_item;
+		shop_size = nd->u.shop.count;
+	}
+	
+	ARR_FIND(0, shop_size, i, shop[i].nameid == nameid);
+	
+	if( i == shop_size )
 		return 5;
-	if( nd->u.shop.shop_item[i].value <= 0 )
+	
+	if( shop[i].value <= 0 )
 		return 5;
 
-	if(!itemdb->isstackable(nameid) && amount > 1)
-	{
+	if(!itemdb->isstackable(nameid) && amount > 1) {
 		ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
 			sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
 		amount = 1;
 	}
 
-	switch( pc->checkadditem(sd, nameid, amount) )
-	{
+	switch( pc->checkadditem(sd, nameid, amount) ) {
 		case ADDITEM_NEW:
 			if( pc->inventoryblank(sd) == 0 )
 				return 3;
@@ -1407,26 +1661,31 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
 	if( w + sd->weight > sd->max_weight )
 		return 3;
 
-	if( (double)nd->u.shop.shop_item[i].value * amount > INT_MAX ) {
+	if( (double)shop[i].value * amount > INT_MAX ) {
 		ShowWarning("npc_cashshop_buy: Item '%s' (%d) price overflow attempt!\n", item->name, nameid);
 		ShowDebug("(NPC:'%s' (%s,%d,%d), player:'%s' (%d/%d), value:%d, amount:%d)\n",
 				nd->exname, map->list[nd->bl.m].name, nd->bl.x, nd->bl.y,
 				sd->status.name, sd->status.account_id, sd->status.char_id,
-				nd->u.shop.shop_item[i].value, amount);
+				shop[i].value, amount);
 		return 5;
 	}
 
-	price = nd->u.shop.shop_item[i].value * amount;
+	price = shop[i].value * amount;
+	
 	if( points > price )
 		points = price;
 
-	if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) )
-		return 6;
-
-	pc->paycash(sd, price, points);
+	if( nd->subtype == SCRIPT && nd->u.scr.shop->type == NST_CUSTOM ) {
+		if( !npc->trader_pay(nd,sd,price,points) )
+			return 6;
+	} else {
+		if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) )
+			return 6;
+			
+		pc->paycash(sd, price, points);
+	}
 
-	if( !pet->create_egg(sd, nameid) )
-	{
+	if( !pet->create_egg(sd, nameid) ) {
 		struct item item_tmp;
 		memset(&item_tmp, 0, sizeof(struct item));
 		item_tmp.nameid = nameid;
@@ -1444,104 +1703,115 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
 /// @return result code for clif->parse_NpcBuyListSend
 int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) {
 	struct npc_data* nd;
+	struct npc_item_list *shop = NULL;
 	double z;
 	int i,j,w,skill_t,new_, idx = skill->get_index(MC_DISCOUNT);
-
+	unsigned short shop_size = 0;
+	
 	nullpo_retr(3, sd);
 	nullpo_retr(3, item_list);
-
+	
 	nd = npc->checknear(sd,map->id2bl(sd->npc_shopid));
 	if( nd == NULL )
 		return 3;
-	if( nd->subtype != SHOP )
-		return 3;
-
+	
+	if( nd->subtype != SHOP ) {
+		if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type == NST_ZENY ) {
+			shop = nd->u.scr.shop->item;
+			shop_size = nd->u.scr.shop->items;
+		} else
+			return 3;
+	} else {
+		shop = nd->u.shop.shop_item;
+		shop_size = nd->u.shop.count;
+	}
+	
 	z = 0;
 	w = 0;
 	new_ = 0;
 	// process entries in buy list, one by one
 	for( i = 0; i < n; ++i ) {
 		int nameid, amount, value;
-
+		
 		// find this entry in the shop's sell list
-		ARR_FIND( 0, nd->u.shop.count, j,
-			item_list[i*2+1] == nd->u.shop.shop_item[j].nameid || //Normal items
-			item_list[i*2+1] == itemdb_viewid(nd->u.shop.shop_item[j].nameid) //item_avail replacement
-		);
-
-		if( j == nd->u.shop.count )
+		ARR_FIND( 0, shop_size, j,
+				 item_list[i*2+1] == shop[j].nameid || //Normal items
+				 item_list[i*2+1] == itemdb_viewid(shop[j].nameid) //item_avail replacement
+				 );
+		
+		if( j == shop_size )
 			return 3; // no such item in shop
-
+		
 		amount = item_list[i*2+0];
-		nameid = item_list[i*2+1] = nd->u.shop.shop_item[j].nameid; //item_avail replacement
-		value = nd->u.shop.shop_item[j].value;
-
+		nameid = item_list[i*2+1] = shop[j].nameid; //item_avail replacement
+		value = shop[j].value;
+		
 		if( !itemdb->exists(nameid) )
 			return 3; // item no longer in itemdb
-
+		
 		if( !itemdb->isstackable(nameid) && amount > 1 ) {
 			//Exploit? You can't buy more than 1 of equipment types o.O
 			ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
-				sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
+						sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
 			amount = item_list[i*2+0] = 1;
 		}
-
+		
 		if( nd->master_nd ) {
 			// Script-controlled shops decide by themselves, what can be bought and for what price.
 			continue;
 		}
-
+		
 		switch( pc->checkadditem(sd,nameid,amount) ) {
 			case ADDITEM_EXIST:
 				break;
-
+				
 			case ADDITEM_NEW:
 				new_++;
 				break;
-
+				
 			case ADDITEM_OVERAMOUNT:
 				return 2;
 		}
-
+		
 		value = pc->modifybuyvalue(sd,value);
-
+		
 		z += (double)value * amount;
 		w += itemdb_weight(nameid) * amount;
 	}
-
+	
 	if( nd->master_nd != NULL ) //Script-based shops.
 		return npc->buylist_sub(sd,n,item_list,nd->master_nd);
-
+	
 	if( z > (double)sd->status.zeny )
 		return 1;	// Not enough Zeny
 	if( w + sd->weight > sd->max_weight )
 		return 2;	// Too heavy
 	if( pc->inventoryblank(sd) < new_ )
 		return 3;	// Not enough space to store items
-
+	
 	pc->payzeny(sd,(int)z,LOG_TYPE_NPC, NULL);
-
+	
 	for( i = 0; i < n; ++i ) {
 		int nameid = item_list[i*2+1];
 		int amount = item_list[i*2+0];
 		struct item item_tmp;
-
+		
 		if (itemdb_type(nameid) == IT_PETEGG)
 			pet->create_egg(sd, nameid);
 		else {
 			memset(&item_tmp,0,sizeof(item_tmp));
 			item_tmp.nameid = nameid;
 			item_tmp.identify = 1;
-
+			
 			pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC);
 		}
 	}
-
+	
 	// custom merchant shop exp bonus
 	if( battle_config.shop_exp > 0 && z > 0 && (skill_t = pc->checkskill2(sd,idx)) > 0 ) {
 		if( sd->status.skill[idx].flag >= SKILL_FLAG_REPLACED_LV_0 )
 			skill_t = sd->status.skill[idx].flag - SKILL_FLAG_REPLACED_LV_0;
-
+		
 		if( skill_t > 0 ) {
 			z = z * (double)skill_t * (double)battle_config.shop_exp/10000.;
 			if( z < 1 )
@@ -1549,10 +1819,120 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) {
 			pc->gainexp(sd,NULL,0,(int)z, false);
 		}
 	}
-
+	
 	return 0;
 }
 
+/**
+ * parses incoming npc market purchase list
+ **/
+int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, struct packet_npc_market_purchase *p) {
+	struct npc_data* nd;
+	struct npc_item_list *shop = NULL;
+	double z;
+	int i,j,w,new_;
+	unsigned short shop_size = 0;
+	
+	nullpo_retr(1, sd);
+	nullpo_retr(1, p);
+
+	nd = npc->checknear(sd,map->id2bl(sd->npc_shopid));
+
+	if( nd == NULL || nd->subtype != SCRIPT || !list_size || !nd->u.scr.shop || nd->u.scr.shop->type != NST_MARKET )
+		return 1;
+
+	shop = nd->u.scr.shop->item;
+	shop_size = nd->u.scr.shop->items;
+	
+	z = 0;
+	w = 0;
+	new_ = 0;
+	
+	// process entries in buy list, one by one
+	for( i = 0; i < list_size; ++i ) {
+		int nameid, amount, value;
+		
+		// find this entry in the shop's sell list
+		ARR_FIND( 0, shop_size, j,
+				 p->list[i].ITID == shop[j].nameid || //Normal items
+				 p->list[i].ITID == itemdb_viewid(shop[j].nameid) //item_avail replacement
+				 );
+		
+		if( j == shop_size ) /* TODO find official response for this */
+			return 1; // no such item in shop
+
+		if( p->list[i].qty > shop[j].qty )
+			return 1;
+
+		amount = p->list[i].qty;
+		nameid = p->list[i].ITID = shop[j].nameid; //item_avail replacement
+		value = shop[j].value;
+		npc_market_qty[i] = j;
+
+		if( !itemdb->exists(nameid) ) /* TODO find official response for this */
+			return 1; // item no longer in itemdb
+		
+		if( !itemdb->isstackable(nameid) && amount > 1 ) {
+			//Exploit? You can't buy more than 1 of equipment types o.O
+			ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
+						sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
+			amount = p->list[i].qty = 1;
+		}
+				
+		switch( pc->checkadditem(sd,nameid,amount) ) {
+			case ADDITEM_EXIST:
+				break;
+				
+			case ADDITEM_NEW:
+				new_++;
+				break;
+				
+			case ADDITEM_OVERAMOUNT: /* TODO find official response for this */
+				return 1;
+		}
+				
+		z += (double)value * amount;
+		w += itemdb_weight(nameid) * amount;
+	}
+
+	if( z > (double)sd->status.zeny ) /* TODO find official response for this */
+		return 1;	// Not enough Zeny
+
+	if( w + sd->weight > sd->max_weight ) /* TODO find official response for this */
+		return 1;	// Too heavy
+
+	if( pc->inventoryblank(sd) < new_ ) /* TODO find official response for this */
+		return 1;	// Not enough space to store items
+
+	pc->payzeny(sd,(int)z,LOG_TYPE_NPC, NULL);
+	
+	for( i = 0; i < list_size; ++i ) {
+		int nameid = p->list[i].ITID;
+		int amount = p->list[i].qty;
+		struct item item_tmp;
+		
+		j = npc_market_qty[i];
+		
+		if( p->list[i].qty > shop[j].qty ) /* wohoo someone tampered with the packet. */
+			return 1;
+		
+		shop[j].qty -= amount;
+		
+		npc->market_tosql(nd,j);
+		
+		if (itemdb_type(nameid) == IT_PETEGG)
+			pet->create_egg(sd, nameid);
+		else {
+			memset(&item_tmp,0,sizeof(item_tmp));
+			item_tmp.nameid = nameid;
+			item_tmp.identify = 1;
+			
+			pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC);
+		}
+	}
+
+	return 0;
+}
 
 /// npc_selllist for script-controlled shops
 int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd)
@@ -1844,6 +2224,11 @@ int npc_unload(struct npc_data* nd, bool single) {
 				nd->u.scr.label_list = NULL;
 				nd->u.scr.label_list_num = 0;
 			}
+			if(nd->u.scr.shop) {
+				if(nd->u.scr.shop->item)
+					aFree(nd->u.scr.shop->item);
+				aFree(nd->u.scr.shop);
+			}
 		}
 		if( nd->u.scr.guild_id )
 			guild->flag_remove(nd);
@@ -2395,7 +2780,7 @@ const char* npc_skip_script(const char* start, const char* buffer, const char* f
 /// -%TAB%script%TAB%<NPC Name>%TAB%-1,{<code>}
 /// <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,{<code>}
 /// <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>,{<code>}
-const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath, bool runOnInit) {
+const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath, int options) {
 	int x, y, dir = 0, m, xs = 0, ys = 0;	// [Valaris] thanks to fov
 	char mapname[32];
 	struct script_code *scriptroot;
@@ -2466,7 +2851,10 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char*
 	nd->u.scr.script = scriptroot;
 	nd->u.scr.label_list = label_list;
 	nd->u.scr.label_list_num = label_list_num;
-
+	if( options&NPO_TRADER )
+		nd->u.scr.trader = true;
+	nd->u.scr.shop = NULL;
+	
 	++npc_script;
 	nd->bl.type = BL_NPC;
 	nd->subtype = SCRIPT;
@@ -2500,7 +2888,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char*
 
 	nd->u.scr.timerid = INVALID_TIMER;
 
-	if( runOnInit ) {
+	if( options&NPO_ONINIT ) {
 		char evname[EVENT_NAME_LENGTH];
 		struct event_data *ev;
 
@@ -2604,6 +2992,8 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
 			nd->u.scr.script = dnd->u.scr.script;
 			nd->u.scr.label_list = dnd->u.scr.label_list;
 			nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
+			nd->u.scr.shop = dnd->u.scr.shop;
+			nd->u.scr.trader = dnd->u.scr.trader;
 			break;
 
 		case SHOP:
@@ -3656,9 +4046,12 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit) {
 #ifdef ENABLE_CASE_CHECK
 				if( strcasecmp(w1, "function") == 0 ) DeprecationWarning("npc_parsesrcfile", w1, "function", filepath, strline(buffer, p-buffer)); // TODO
 #endif // ENABLE_CASE_CHECK
-				p = npc->parse_script(w1,w2,w3,w4, p, buffer, filepath,runOnInit);
+				p = npc->parse_script(w1,w2,w3,w4, p, buffer, filepath,runOnInit?NPO_ONINIT:NPO_NONE);
 			}
 		}
+		else if( strcmp(w2,"trader") == 0 && count > 3 ) {
+			p = npc->parse_script(w1,w2,w3,w4, p, buffer, filepath,(runOnInit?NPO_ONINIT:NPO_NONE)|NPO_TRADER);
+		}
 		else if( (i=0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3 )
 		{
 			p = npc->parse_duplicate(w1,w2,w3,w4, p, buffer, filepath);
@@ -3678,6 +4071,7 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit) {
 			else if( strcasecmp(w2,"shop") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "shop", filepath, strline(buffer, p-buffer)); } // TODO
 			else if( strcasecmp(w2,"cashshop") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "cashshop", filepath, strline(buffer, p-buffer)); } // TODO
 			else if( strcasecmp(w2, "script") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "script", filepath, strline(buffer, p-buffer)); } // TODO
+			else if( strcasecmp(w2,"trader") == 0 ) DeprecationWarning("npc_parsesrcfile", w2, "trader", filepath, strline(buffer, p-buffer)) // TODO
 			else if( strncasecmp(w2, "duplicate", 9) == 0 ) {
 				char temp[10];
 				safestrncpy(temp, w2, 10);
@@ -3871,7 +4265,7 @@ int npc_reload(void) {
 		"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
 		"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
 		npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
-	
+		
 	itemdb->name_constants();
 	
 	instance->reload();
@@ -3890,6 +4284,8 @@ int npc_reload(void) {
 	//Execute the OnInit event for freshly loaded npcs. [Skotlex]
 	ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n",npc->event_doall("OnInit"));
 
+	npc->market_fromsql();/* after OnInit */
+	
 	// Execute rest of the startup events if connected to char-server. [Lance]
 	if(!intif->CheckForCharServer()){
 		ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc->event_doall("OnInterIfInit"));
@@ -4024,7 +4420,7 @@ int do_init_npc(bool minimal) {
 			"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
 			npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
 	}
-
+	
 	itemdb->name_constants();
 
 	if (!minimal) {
@@ -4076,6 +4472,9 @@ void npc_defaults(void) {
 	npc->fake_nd = NULL;
 	npc->src_files = NULL;
 	/* */
+	npc->trader_ok = false;
+	npc->trader_funds[0] = npc->trader_funds[1] = 0;
+	/* */
 	npc->init = do_init_npc;
 	npc->final = do_final_npc;
 	/* */
@@ -4165,4 +4564,13 @@ void npc_defaults(void) {
 	npc->debug_warps_sub = npc_debug_warps_sub;
 	npc->debug_warps = npc_debug_warps;
 	npc->secure_timeout_timer = npc_rr_secure_timeout_timer;
+	/* */
+	npc->trader_count_funds = npc_trader_count_funds;
+	npc->trader_pay = npc_trader_pay;
+	npc->trader_update = npc_trader_update;
+	npc->market_buylist = npc_market_buylist;
+	npc->trader_open = npc_trader_open;
+	npc->market_fromsql = npc_market_fromsql;
+	npc->market_tosql = npc_market_tosql;
+	npc->market_delfromsql = npc_market_delfromsql;
 }
diff --git a/src/map/npc.h b/src/map/npc.h
index feee8f203..792d85d59 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -14,6 +14,21 @@ struct block_list;
 struct npc_data;
 struct view_data;
 
+enum npc_parse_options {
+	NPO_NONE  = 0x0,
+	NPO_ONINIT  = 0x1,
+	NPO_TRADER  = 0x2,
+};
+
+enum npc_shop_types {
+	NST_ZENY,/* default */
+	NST_CASH,/* official npc cash shop */
+	NST_MARKET,/* official npc market type */
+	NST_CUSTOM,
+	/* */
+	NST_MAX,
+};
+
 struct npc_timerevent_list {
 	int timer,pos;
 };
@@ -22,9 +37,15 @@ struct npc_label_list {
 	int pos;
 };
 struct npc_item_list {
-	unsigned int nameid,value;
+	unsigned short nameid;
+	unsigned int value;
+	unsigned int qty;
+};
+struct npc_shop_data {
+	unsigned char type;/* what am i */
+	struct npc_item_list *item;/* list */
+	unsigned short items;/* total */
 };
-
 struct npc_data {
 	struct block_list bl;
 	struct unit_data *ud;
@@ -60,10 +81,13 @@ struct npc_data {
 			struct npc_timerevent_list *timer_event;
 			int label_list_num;
 			struct npc_label_list *label_list;
+			/* */
+			struct npc_shop_data *shop;
+			bool trader;
 		} scr;
-		struct {
+		struct { /* TODO duck this as soon as the new shop formatting is deemed stable */
 			struct npc_item_list* shop_item;
-			int count;
+			unsigned short count;
 		} shop;
 		struct {
 			short xs,ys; // OnTouch area radius
@@ -143,6 +167,9 @@ struct npc_interface {
 	struct npc_data *fake_nd;
 	struct npc_src_list *src_files;
 	struct unit_data base_ud;
+	/* npc trader global data, for ease of transition between the script, cleared on every usage */
+	bool trader_ok;
+	int trader_funds[2];
 	/* */
 	int (*init) (bool minimal);
 	int (*final) (void);
@@ -208,7 +235,7 @@ struct npc_interface {
 	const char* (*parse_shop) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
 	void (*convertlabel_db) (struct npc_label_list *label_list, const char *filepath);
 	const char* (*skip_script) (const char *start, const char *buffer, const char *filepath);
-	const char* (*parse_script) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, bool runOnInit);
+	const char* (*parse_script) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int options);
 	const char* (*parse_duplicate) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
 	int (*duplicate4instance) (struct npc_data *snd, int16 m);
 	void (*setcells) (struct npc_data *nd);
@@ -232,6 +259,15 @@ struct npc_interface {
 	void (*do_clear_npc) (void);
 	void (*debug_warps_sub) (struct npc_data *nd);
 	void (*debug_warps) (void);
+	/* */
+	void (*trader_count_funds) (struct npc_data *nd, struct map_session_data *sd);
+	bool (*trader_pay) (struct npc_data *nd, struct map_session_data *sd, int price, int points);
+	void (*trader_update) (int master);
+	int (*market_buylist) (struct map_session_data* sd, unsigned short list_size, struct packet_npc_market_purchase *p);
+	bool (*trader_open) (struct map_session_data *sd, struct npc_data *nd);
+	void (*market_fromsql) (void);
+	void (*market_tosql) (struct npc_data *nd, unsigned short index);
+	void (*market_delfromsql) (struct npc_data *nd, unsigned short index);
 	/**
 	 * For the Secure NPC Timeout option (check config/Secure.h) [RR]
 	 **/
diff --git a/src/map/packets.h b/src/map/packets.h
index 08c73fdb0..cea916f6d 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -2453,6 +2453,45 @@ packet(0x020d,-1);
 	packet(0x0887,36,clif->pStoragePassword,0);
 #endif
 
+// 2013-12-23cRagexe - Yommy
+#if PACKETVER >= 20131223
+	packet(0x0369,7,clif->pActionRequest,2,6);
+	packet(0x083C,10,clif->pUseSkillToId,2,4,6);
+	packet(0x0437,5,clif->pWalkToXY,2);
+	packet(0x035F,6,clif->pTickSend,2);
+	packet(0x0202,5,clif->pChangeDir,2,4);
+	packet(0x07E4,6,clif->pTakeItem,2);
+	packet(0x0362,6,clif->pDropItem,2,4);
+	packet(0x07EC,8,clif->pMoveToKafra,2,4);
+	packet(0x0364,8,clif->pMoveFromKafra,2,4);
+	packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8);
+	packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10);
+	packet(0x096A,6,clif->pGetCharNameRequest,2);
+	packet(0x0368,6,clif->pSolveCharName,2);
+	packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10);
+	packet(0x0835,2,clif->pSearchStoreInfoNextPage,0);
+	packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15);
+	packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12);
+	packet(0x0360,6,clif->pReqClickBuyingStore,2);
+	packet(0x0817,2,clif->pReqCloseBuyingStore,0);
+	packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89);
+	packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4);
+	// packet(0x0363,8); // CZ_JOIN_BATTLE_FIELD
+	packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8);
+	packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18);
+	packet(0x0802,26,clif->pPartyInvite2,2);
+	// packet(0x0436,4); // CZ_GANGSI_RANK
+	packet(0x023B,26,clif->pFriendsListAdd,2);
+	packet(0x0361,5,clif->pHomMenu,2,4);
+	packet(0x08A4,36,clif->pStoragePassword,0);
+	/* New */
+	packet(0x09d4,2,clif->pNPCShopClosed);
+	packet(0x09ce,102,clif->pGM_Monster_Item,2);
+	/* NPC Market */
+	packet(0x09d8,2,clif->pNPCMarketClosed);
+	packet(0x09d6,-1,clif->pNPCMarketPurchase);
+#endif
+
 /* PacketKeys: http://hercules.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */
 #if PACKETVER >= 20110817
 	packetKeys(0x053D5CED,0x3DED6DED,0x6DED6DED); /* Thanks to Shakto */
@@ -2646,6 +2685,10 @@ packet(0x020d,-1);
 	packetKeys(0x7E241DE0,0x5E805580,0x3D807D80); /* Thanks to Shakto */
 #endif
 
+#if PACKETVER >= 20131223
+	packetKeys(0x631C511C, 0x111C111C,0x111C111C);
+#endif
+
 #if defined(OBFUSCATIONKEY1) && defined(OBFUSCATIONKEY2) && defined(OBFUSCATIONKEY3)
 	packetKeys(OBFUSCATIONKEY1,OBFUSCATIONKEY2,OBFUSCATIONKEY3);
 #endif
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index df90b35a4..8f0989f3d 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -201,6 +201,8 @@ enum packet_headers {
 	notifybindonequip = 0x2d3,
 	monsterhpType = 0x977,
 	maptypeproperty2Type = 0x99b,
+	npcmarketresultackType = 0x9d7,
+	npcmarketopenType = 0x9d5,
 };
 
 #pragma pack(push, 1)
@@ -895,6 +897,48 @@ struct packet_damage {
 #endif
 } __attribute__((packed));
 
+struct packet_gm_monster_item {
+	short PacketType;
+#if PACKETVER >= 20131218
+	char str[100];
+#else
+	char str[24];
+#endif
+} __attribute__((packed));
+
+struct packet_npc_market_purchase {
+	short PacketType;
+	short PacketLength;
+	struct {
+		unsigned short ITID;
+		int qty;
+	} list[MAX_INVENTORY];/* assuming MAX_INVENTORY is max since you can't hold more than MAX_INVENTORY items thus cant buy that many at once. */
+} __attribute__((packed));
+
+struct packet_npc_market_result_ack {
+	short PacketType;
+	short PacketLength;
+	unsigned char result;
+	struct {
+		unsigned short ITID;
+		unsigned short qty;
+		unsigned int price;
+	} list[MAX_INVENTORY];/* assuming MAX_INVENTORY is max since you can't hold more than MAX_INVENTORY items thus cant buy that many at once. */
+} __attribute__((packed));
+
+struct packet_npc_market_open {
+	short PacketType;
+	short PacketLength;
+	/* inner struct figured by Ind after some annoying hour of debugging (data Thanks to Yommy) */
+	struct {
+		unsigned short nameid;
+		unsigned char type;
+		unsigned int price;
+		unsigned int qty;
+		unsigned short view;
+	} list[1000];/* TODO: whats the actual max of this? */
+} __attribute__((packed));
+
 #pragma pack(pop)
 
 #endif /* _PACKETS_STRUCT_H_ */
diff --git a/src/map/script.c b/src/map/script.c
index 074348ef0..a9ad69954 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -2072,7 +2072,7 @@ void script_set_constant2(const char *name, int value, bool isparameter) {
 	int n = script->add_str(name);
 
 	if( ( script->str_data[n].type == C_NAME || script->str_data[n].type == C_PARAM ) && ( script->str_data[n].val != 0 || script->str_data[n].backpatch != -1 ) ) { // existing parameter or constant
-		ShowNotice("Conflicting item/script var '%s', prioritising the script var\n",name);
+		ShowNotice("Conflicting var name '%s', prioritising the script var\n",name);
 		return;
 	}
 
@@ -18012,6 +18012,272 @@ BUILDIN(instance_set_respawn) {
 	
 	return true;
 }
+/**
+ * @call openshop({NPC Name});
+ *
+ * @return 1 on success, 0 otherwise.
+ **/
+BUILDIN(openshop) {
+	struct npc_data *nd;
+	struct map_session_data *sd;
+	const char *name = NULL;
+	
+	if( script_hasdata(st, 2) ) {
+		name = script_getstr(st, 2);
+		if( !(nd = npc->name2id(name)) || nd->subtype != SCRIPT ) {
+			ShowWarning("buildin_openshop(\"%s\"): trying to run without a proper NPC!\n",name);
+			return false;
+		}
+	} else if( !(nd = map->id2nd(st->oid)) ) {
+		ShowWarning("buildin_openshop: trying to run without a proper NPC!\n");
+		return false;
+	}
+	if( !( sd = script->rid2sd(st) ) ) {
+		ShowWarning("buildin_openshop: trying to run without a player attached!\n");
+		return false;
+	} else if ( !nd->u.scr.shop || !nd->u.scr.shop->items ) {
+		ShowWarning("buildin_openshop: trying to open without any items!\n");
+		return false;
+	}
+	
+	if( !npc->trader_open(sd,nd) )
+		script_pushint(st, 0);
+	else
+		script_pushint(st, 1);
+
+	return true;
+}
+/**
+ * @call sellitem <Item_ID>,{,price{,qty}};
+ *
+ * adds <Item_ID> (or modifies if present) to shop
+ * if price not provided (or -1) uses the item's value_sell
+ **/
+BUILDIN(sellitem) {
+	struct npc_data *nd;
+	struct item_data *it;
+	int i = 0, id = script_getnum(st,2);
+	int value = 0;
+	int qty = 0;
+	
+	if( !(nd = map->id2nd(st->oid)) ) {
+		ShowWarning("buildin_sellitem: trying to run without a proper NPC!\n");
+		return false;
+	} else if ( !(it = itemdb->exists(id)) ) {
+		ShowWarning("buildin_sellitem: unknown item id '%d'!\n",id);
+		return false;
+	}
+	
+	value = script_hasdata(st,3) ? script_getnum(st, 3) : it->value_buy;
+	if( value == -1 )
+		value = it->value_buy;
+		
+	if( !nd->u.scr.shop )
+		npc->trader_update(nd->src_id?nd->src_id:nd->bl.id);
+	else {/* no need to run this if its empty */
+		for( i = 0; i < nd->u.scr.shop->items; i++ ) {
+			if( nd->u.scr.shop->item[i].nameid == id )
+				break;
+		}
+	}
+	
+	if( nd->u.scr.shop->type == NST_MARKET ) {
+		if( !script_hasdata(st,4) || ( qty = script_getnum(st, 4) ) <= 0 ) {
+			ShowError("buildin_sellitem: invalid 'qty' for market-type shop!\n");
+			return false;
+		}
+	}
+	
+	if( ( nd->u.scr.shop->type == NST_ZENY || nd->u.scr.shop->type == NST_MARKET )  && value*0.75 < it->value_sell*1.24 ) {
+		ShowWarning("buildin_sellitem: Item %s [%d] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) in NPC %s (%s)\n",
+					it->name, id, value, (int)(value*0.75), it->value_sell, (int)(it->value_sell*1.24), nd->exname, nd->path);
+	}
+	
+	if( i != nd->u.scr.shop->items ) {
+		nd->u.scr.shop->item[i].value = value;
+		nd->u.scr.shop->item[i].qty   = qty;
+		if( nd->u.scr.shop->type == NST_MARKET ) /* has been manually updated, make it reflect on sql */
+			npc->market_tosql(nd,i);
+	} else {
+		for( i = 0; i < nd->u.scr.shop->items; i++ ) {
+			if( nd->u.scr.shop->item[i].nameid == 0 )
+				break;
+		}
+		
+		if( i == nd->u.scr.shop->items ) {
+			if( nd->u.scr.shop->items == USHRT_MAX ) {
+				ShowWarning("buildin_sellitem: Can't add %s (%s/%s), shop list is full!\n", it->name, nd->exname, nd->path);
+				return false;
+			}
+			i = nd->u.scr.shop->items;
+			RECREATE(nd->u.scr.shop->item, struct npc_item_list, ++nd->u.scr.shop->items);
+		}
+		
+		nd->u.scr.shop->item[i].nameid	= it->nameid;
+		nd->u.scr.shop->item[i].value	= value;
+		nd->u.scr.shop->item[i].qty	    = qty;
+	}
+	
+	return true;
+}
+/**
+ * @call stopselling <Item_ID>;
+ *
+ * removes <Item_ID> from the current npc shop
+ *
+ * @return 1 on success, 0 otherwise
+ **/
+BUILDIN(stopselling) {
+	struct npc_data *nd;
+	int i, id = script_getnum(st,2);
+	
+	if( !(nd = map->id2nd(st->oid)) || !nd->u.scr.shop ) {
+		ShowWarning("buildin_stopselling: trying to run without a proper NPC!\n");
+		return false;
+	}
+	
+	for( i = 0; i < nd->u.scr.shop->items; i++ ) {
+		if( nd->u.scr.shop->item[i].nameid == id )
+			break;
+	}
+	
+	if( i != nd->u.scr.shop->items ) {
+		int cursor;
+		
+		if( nd->u.scr.shop->type == NST_MARKET )
+			npc->market_delfromsql(nd,i);
+		
+		nd->u.scr.shop->item[i].nameid = 0;
+		nd->u.scr.shop->item[i].value  = 0;
+		nd->u.scr.shop->item[i].qty    = 0;
+		
+		for( i = 0, cursor = 0; i < nd->u.scr.shop->items; i++ ) {
+			if( nd->u.scr.shop->item[i].nameid == 0 )
+				continue;
+			
+			if( cursor != i ) {
+				nd->u.scr.shop->item[cursor].nameid = nd->u.scr.shop->item[i].nameid;
+				nd->u.scr.shop->item[cursor].value  = nd->u.scr.shop->item[i].value;
+				nd->u.scr.shop->item[cursor].qty    = nd->u.scr.shop->item[i].qty;
+			}
+			
+			cursor++;
+		}
+
+		script_pushint(st, 1);
+	} else
+		script_pushint(st, 0);
+	
+	return true;
+}
+/**
+ * @call setcurrency <Val1>{,<Val2>};
+ *
+ * updates currently-attached player shop currency
+ **/
+/* setcurrency(<Val1>,{<Val2>}) */
+BUILDIN(setcurrency) {
+	int val1 = script_getnum(st,2),
+	val2 = script_hasdata(st, 3) ? script_getnum(st,3) : 0;
+	struct npc_data *nd;
+	
+	if( !(nd = map->id2nd(st->oid)) ) {
+		ShowWarning("buildin_setcurrency: trying to run without a proper NPC!\n");
+		return false;
+	}
+	
+	npc->trader_funds[0] = val1;
+	npc->trader_funds[1] = val2;
+	
+	return true;
+}
+/**
+ * @call tradertype(<type>);
+ *
+ * defaults to 0, so no need to call when you're doing zeny
+ * check enum npc_shop_types for list
+ * cleans shop list on use
+ **/
+BUILDIN(tradertype) {
+	int type = script_getnum(st, 2);
+	struct npc_data *nd;
+	
+	if( !(nd = map->id2nd(st->oid)) ) {
+		ShowWarning("buildin_tradertype: trying to run without a proper NPC!\n");
+		return false;
+	} else if ( type < 0 || type > NST_MAX ) {
+		ShowWarning("buildin_tradertype: invalid type param %d!\n",type);
+		return false;
+	}
+	
+	if( !nd->u.scr.shop )
+		npc->trader_update(nd->src_id?nd->src_id:nd->bl.id);
+	else {/* clear list */
+		int i;
+		for( i = 0; i < nd->u.scr.shop->items; i++ ) {
+			nd->u.scr.shop->item[i].nameid = 0;
+			nd->u.scr.shop->item[i].value  = 0;
+			nd->u.scr.shop->item[i].qty    = 0;
+		}
+		npc->market_delfromsql(nd,USHRT_MAX);
+	}
+	
+	nd->u.scr.shop->type = type;
+	
+	return true;
+}
+/**
+ * @call purchaseok();
+ *
+ * signs the transaction can proceed
+ **/
+BUILDIN(purchaseok) {
+	struct npc_data *nd;
+	
+	if( !(nd = map->id2nd(st->oid)) || !nd->u.scr.shop ) {
+		ShowWarning("buildin_purchaseok: trying to run without a proper NPC!\n");
+		return false;
+	}
+	
+	npc->trader_ok = true;
+	
+	return true;
+}
+/**
+ * @call shopcount(<Item_ID>);
+ *
+ * @return number of available items in the script's attached shop
+ **/
+BUILDIN(shopcount) {
+	struct npc_data *nd;
+	int id = script_getnum(st, 2);
+	unsigned short i;
+	
+	if( !(nd = map->id2nd(st->oid)) ) {
+		ShowWarning("buildin_shopcount(%d): trying to run without a proper NPC!\n",id);
+		return false;
+	} else if ( !nd->u.scr.shop || !nd->u.scr.shop->items ) {
+		ShowWarning("buildin_shopcount(%d): trying to use without any items!\n",id);
+		return false;
+	} else if ( nd->u.scr.shop->type != NST_MARKET ) {
+		ShowWarning("buildin_shopcount(%d): trying to use on a non-NST_MARKET shop!\n",id);
+		return false;
+	}
+
+	/* lookup */
+	for(i = 0; i < nd->u.scr.shop->items; i++) {
+		if( nd->u.scr.shop->item[i].nameid == id ) {
+			script_pushint(st, nd->u.scr.shop->item[i].qty);
+			break;
+		}
+	}
+	
+	/* didn't find it */
+	if( i == nd->u.scr.shop->items )
+		script_pushint(st, 0);
+	
+	return true;
+}
 
 // declarations that were supposed to be exported from npc_chat.c
 #ifdef PCRE_SUPPORT
@@ -18609,6 +18875,15 @@ void script_parse_builtin(void) {
 		BUILDIN_DEF(bg_create_team,"sii"),
 		BUILDIN_DEF(bg_join_team,"i?"),
 		BUILDIN_DEF(bg_match_over,"s?"),
+		
+		/* New Shop Support */
+		BUILDIN_DEF(openshop,"?"),
+		BUILDIN_DEF(sellitem,"i??"),
+		BUILDIN_DEF(stopselling,"i"),
+		BUILDIN_DEF(setcurrency,"i?"),
+		BUILDIN_DEF(tradertype,"i"),
+		BUILDIN_DEF(purchaseok,""),
+		BUILDIN_DEF(shopcount, "i"),
 	};
 	int i, len = ARRAYLENGTH(BUILDIN);
 	RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up
diff --git a/src/map/status.c b/src/map/status.c
index f6ca1ff00..7d354718d 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -6060,6 +6060,8 @@ void status_set_viewdata(struct block_list *bl, int class_)
 						sd->vd.cloth_color = 0;
 					if( sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette )
 						sd->vd.cloth_color = 0;
+					if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ )
+						sd->vd.cloth_color = 0;
 				}
 			} else if (vd)
 				memcpy(&sd->vd, vd, sizeof(struct view_data));
@@ -7463,6 +7465,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			case SC_XMAS:
 			case SC_SUMMER:
 			case SC_HANBOK:
+			case SC_OKTOBERFEST:
 				if (!vd) return 0;
 				//Store previous values as they could be removed.
 				unit->stop_attack(bl);
@@ -8680,6 +8683,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			case SC_XMAS:
 			case SC_SUMMER:
 			case SC_HANBOK:
+			case SC_OKTOBERFEST:
 				if( !vd ) break;
 				clif->changelook(bl,LOOK_BASE,vd->class_);
 				clif->changelook(bl,LOOK_WEAPON,0);
@@ -9067,6 +9071,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 		case SC_FUSION:
 			sc->option |= OPTION_FLYING;
 			break;
+		case SC_OKTOBERFEST:
+			sc->option |= OPTION_OKTOBERFEST;
+			opt_flag |= 0x4;
+			break;
 		default:
 			opt_flag = 0;
 	}
@@ -9768,167 +9776,171 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 
 	opt_flag = 1;
 	switch(type){
-	case SC_STONE:
-	case SC_FREEZE:
-	case SC_STUN:
-	case SC_SLEEP:
-	case SC_DEEP_SLEEP:
-	case SC_BURNING:
-	case SC_WHITEIMPRISON:
-	case SC_COLD:
-		sc->opt1 = 0;
-		break;
+		case SC_STONE:
+		case SC_FREEZE:
+		case SC_STUN:
+		case SC_SLEEP:
+		case SC_DEEP_SLEEP:
+		case SC_BURNING:
+		case SC_WHITEIMPRISON:
+		case SC_COLD:
+			sc->opt1 = 0;
+			break;
 
-	case SC_POISON:
-	case SC_CURSE:
-	case SC_SILENCE:
-	case SC_BLIND:
-		sc->opt2 &= ~(1<<(type-SC_POISON));
-		break;
-	case SC_DPOISON:
-		sc->opt2 &= ~OPT2_DPOISON;
-		break;
-	case SC_CRUCIS:
-		sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
-		break;
+		case SC_POISON:
+		case SC_CURSE:
+		case SC_SILENCE:
+		case SC_BLIND:
+			sc->opt2 &= ~(1<<(type-SC_POISON));
+			break;
+		case SC_DPOISON:
+			sc->opt2 &= ~OPT2_DPOISON;
+			break;
+		case SC_CRUCIS:
+			sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
+			break;
 
-	case SC_HIDING:
-		sc->option &= ~OPTION_HIDE;
-		opt_flag|= 2|4; //Check for warp trigger + AoE trigger
-		break;
-	case SC_CLOAKING:
-	case SC_CLOAKINGEXCEED:
-	case SC__INVISIBILITY:
-		sc->option &= ~OPTION_CLOAK;
-	case SC_CAMOUFLAGE:
-		opt_flag|= 2;
-		break;
-	case SC_CHASEWALK:
-		sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
-		opt_flag|= 2;
-		break;
-	case SC_SIGHT:
-		sc->option &= ~OPTION_SIGHT;
-		break;
-	case SC_WEDDING:
-		sc->option &= ~OPTION_WEDDING;
-		opt_flag |= 0x4;
-		break;
-	case SC_XMAS:
-		sc->option &= ~OPTION_XMAS;
-		opt_flag |= 0x4;
-		break;
-	case SC_SUMMER:
-		sc->option &= ~OPTION_SUMMER;
-		opt_flag |= 0x4;
-		break;
-	case SC_HANBOK:
-		sc->option &= ~OPTION_HANBOK;
-		opt_flag |= 0x4;
-		break;
-	case SC_ORCISH:
-		sc->option &= ~OPTION_ORCISH;
-		break;
-	case SC_RUWACH:
-		sc->option &= ~OPTION_RUWACH;
-		break;
-	case SC_FUSION:
-		sc->option &= ~OPTION_FLYING;
-		break;
-		//opt3
-	case SC_TWOHANDQUICKEN:
-	case SC_ONEHANDQUICKEN:
-	case SC_SPEARQUICKEN:
-	case SC_CONCENTRATION:
-	case SC_MER_QUICKEN:
-		sc->opt3 &= ~OPT3_QUICKEN;
-		opt_flag = 0;
-		break;
-	case SC_OVERTHRUST:
-	case SC_OVERTHRUSTMAX:
-	case SC_SWOO:
-		sc->opt3 &= ~OPT3_OVERTHRUST;
-		if( type == SC_SWOO )
-			opt_flag = 8;
-		else
+		case SC_HIDING:
+			sc->option &= ~OPTION_HIDE;
+			opt_flag|= 2|4; //Check for warp trigger + AoE trigger
+			break;
+		case SC_CLOAKING:
+		case SC_CLOAKINGEXCEED:
+		case SC__INVISIBILITY:
+			sc->option &= ~OPTION_CLOAK;
+		case SC_CAMOUFLAGE:
+			opt_flag|= 2;
+			break;
+		case SC_CHASEWALK:
+			sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
+			opt_flag|= 2;
+			break;
+		case SC_SIGHT:
+			sc->option &= ~OPTION_SIGHT;
+			break;
+		case SC_WEDDING:
+			sc->option &= ~OPTION_WEDDING;
+			opt_flag |= 0x4;
+			break;
+		case SC_XMAS:
+			sc->option &= ~OPTION_XMAS;
+			opt_flag |= 0x4;
+			break;
+		case SC_SUMMER:
+			sc->option &= ~OPTION_SUMMER;
+			opt_flag |= 0x4;
+			break;
+		case SC_HANBOK:
+			sc->option &= ~OPTION_HANBOK;
+			opt_flag |= 0x4;
+			break;
+		case SC_OKTOBERFEST:
+			sc->option &= ~OPTION_OKTOBERFEST;
+			opt_flag |= 0x4;
+			break;
+		case SC_ORCISH:
+			sc->option &= ~OPTION_ORCISH;
+			break;
+		case SC_RUWACH:
+			sc->option &= ~OPTION_RUWACH;
+			break;
+		case SC_FUSION:
+			sc->option &= ~OPTION_FLYING;
+			break;
+			//opt3
+		case SC_TWOHANDQUICKEN:
+		case SC_ONEHANDQUICKEN:
+		case SC_SPEARQUICKEN:
+		case SC_CONCENTRATION:
+		case SC_MER_QUICKEN:
+			sc->opt3 &= ~OPT3_QUICKEN;
 			opt_flag = 0;
-		break;
-	case SC_ENERGYCOAT:
-	case SC_SKE:
-		sc->opt3 &= ~OPT3_ENERGYCOAT;
-		opt_flag = 0;
-		break;
-	case SC_INCATKRATE: //Simulated Explosion spirits effect.
-		if (bl->type != BL_MOB)
-		{
+			break;
+		case SC_OVERTHRUST:
+		case SC_OVERTHRUSTMAX:
+		case SC_SWOO:
+			sc->opt3 &= ~OPT3_OVERTHRUST;
+			if( type == SC_SWOO )
+				opt_flag = 8;
+			else
+				opt_flag = 0;
+			break;
+		case SC_ENERGYCOAT:
+		case SC_SKE:
+			sc->opt3 &= ~OPT3_ENERGYCOAT;
 			opt_flag = 0;
 			break;
-		}
-	case SC_EXPLOSIONSPIRITS:
-		sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS;
-		opt_flag = 0;
-		break;
-	case SC_STEELBODY:
-	case SC_SKA:
-		sc->opt3 &= ~OPT3_STEELBODY;
-		opt_flag = 0;
-		break;
-	case SC_BLADESTOP:
-		sc->opt3 &= ~OPT3_BLADESTOP;
-		opt_flag = 0;
-		break;
-	case SC_AURABLADE:
-		sc->opt3 &= ~OPT3_AURABLADE;
-		opt_flag = 0;
-		break;
-	case SC_BERSERK:
-		opt_flag = 0;
-		sc->opt3 &= ~OPT3_BERSERK;
-		break;
-		//	case ???: // doesn't seem to do anything
-		//		sc->opt3 &= ~OPT3_LIGHTBLADE;
-		//		opt_flag = 0;
-		//		break;
-	case SC_DANCING:
-		if ((sce->val1&0xFFFF) == CG_MOONLIT)
-			sc->opt3 &= ~OPT3_MOONLIT;
-		opt_flag = 0;
-		break;
-	case SC_MARIONETTE:
-	case SC_MARIONETTE_MASTER:
-		sc->opt3 &= ~OPT3_MARIONETTE;
-		opt_flag = 0;
-		break;
-	case SC_ASSUMPTIO:
-		sc->opt3 &= ~OPT3_ASSUMPTIO;
-		opt_flag = 0;
-		break;
-	case SC_WARM: //SG skills [Komurka]
-		sc->opt3 &= ~OPT3_WARM;
-		opt_flag = 0;
-		break;
-	case SC_KAITE:
-		sc->opt3 &= ~OPT3_KAITE;
-		opt_flag = 0;
-		break;
-	case SC_NJ_BUNSINJYUTSU:
-		sc->opt3 &= ~OPT3_BUNSIN;
-		opt_flag = 0;
-		break;
-	case SC_SOULLINK:
-		sc->opt3 &= ~OPT3_SOULLINK;
-		opt_flag = 0;
-		break;
-	case SC_PROPERTYUNDEAD:
-		sc->opt3 &= ~OPT3_UNDEAD;
-		opt_flag = 0;
-		break;
-		//	case ???: // from DA_CONTRACT (looks like biolab mobs aura)
-		//		sc->opt3 &= ~OPT3_CONTRACT;
-		//		opt_flag = 0;
-		//		break;
-	default:
-		opt_flag = 0;
+		case SC_INCATKRATE: //Simulated Explosion spirits effect.
+			if (bl->type != BL_MOB)
+			{
+				opt_flag = 0;
+				break;
+			}
+		case SC_EXPLOSIONSPIRITS:
+			sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS;
+			opt_flag = 0;
+			break;
+		case SC_STEELBODY:
+		case SC_SKA:
+			sc->opt3 &= ~OPT3_STEELBODY;
+			opt_flag = 0;
+			break;
+		case SC_BLADESTOP:
+			sc->opt3 &= ~OPT3_BLADESTOP;
+			opt_flag = 0;
+			break;
+		case SC_AURABLADE:
+			sc->opt3 &= ~OPT3_AURABLADE;
+			opt_flag = 0;
+			break;
+		case SC_BERSERK:
+			opt_flag = 0;
+			sc->opt3 &= ~OPT3_BERSERK;
+			break;
+			//	case ???: // doesn't seem to do anything
+			//		sc->opt3 &= ~OPT3_LIGHTBLADE;
+			//		opt_flag = 0;
+			//		break;
+		case SC_DANCING:
+			if ((sce->val1&0xFFFF) == CG_MOONLIT)
+				sc->opt3 &= ~OPT3_MOONLIT;
+			opt_flag = 0;
+			break;
+		case SC_MARIONETTE:
+		case SC_MARIONETTE_MASTER:
+			sc->opt3 &= ~OPT3_MARIONETTE;
+			opt_flag = 0;
+			break;
+		case SC_ASSUMPTIO:
+			sc->opt3 &= ~OPT3_ASSUMPTIO;
+			opt_flag = 0;
+			break;
+		case SC_WARM: //SG skills [Komurka]
+			sc->opt3 &= ~OPT3_WARM;
+			opt_flag = 0;
+			break;
+		case SC_KAITE:
+			sc->opt3 &= ~OPT3_KAITE;
+			opt_flag = 0;
+			break;
+		case SC_NJ_BUNSINJYUTSU:
+			sc->opt3 &= ~OPT3_BUNSIN;
+			opt_flag = 0;
+			break;
+		case SC_SOULLINK:
+			sc->opt3 &= ~OPT3_SOULLINK;
+			opt_flag = 0;
+			break;
+		case SC_PROPERTYUNDEAD:
+			sc->opt3 &= ~OPT3_UNDEAD;
+			opt_flag = 0;
+			break;
+			//	case ???: // from DA_CONTRACT (looks like biolab mobs aura)
+			//		sc->opt3 &= ~OPT3_CONTRACT;
+			//		opt_flag = 0;
+			//		break;
+		default:
+			opt_flag = 0;
 	}
 
 	if (calc_flag&SCB_DYE) { //Restore DYE color
diff --git a/src/map/status.h b/src/map/status.h
index cdf3e03d6..1fd354c79 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -696,6 +696,8 @@ typedef enum sc_type {
 	SC_MOONSTAR,
 	SC_SUPER_STAR,
 
+	SC_OKTOBERFEST,
+	
 	SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
 } sc_type;
 // Official status change ids, used to display status icons on the client.
@@ -1545,30 +1547,31 @@ enum {
 };
 
 enum {
-	OPTION_NOTHING		= 0x00000000,
-	OPTION_SIGHT		= 0x00000001,
-	OPTION_HIDE			= 0x00000002,
-	OPTION_CLOAK		= 0x00000004,
-	OPTION_FALCON		= 0x00000010,
-	OPTION_RIDING		= 0x00000020,
-	OPTION_INVISIBLE	= 0x00000040,
-	OPTION_ORCISH		= 0x00000800,
-	OPTION_WEDDING		= 0x00001000,
-	OPTION_RUWACH		= 0x00002000,
-	OPTION_CHASEWALK	= 0x00004000,
-	OPTION_FLYING		= 0x00008000, //Note that clientside Flying and Xmas are 0x8000 for clients prior to 2007.
-	OPTION_XMAS			= 0x00010000,
-	OPTION_TRANSFORM	= 0x00020000,
-	OPTION_SUMMER		= 0x00040000,
-	OPTION_DRAGON1		= 0x00080000,
-	OPTION_WUG			= 0x00100000,
-	OPTION_WUGRIDER		= 0x00200000,
-	OPTION_MADOGEAR		= 0x00400000,
-	OPTION_DRAGON2		= 0x00800000,
-	OPTION_DRAGON3		= 0x01000000,
-	OPTION_DRAGON4		= 0x02000000,
-	OPTION_DRAGON5		= 0x04000000,
-	OPTION_HANBOK		= 0x08000000,
+	OPTION_NOTHING      = 0x00000000,
+	OPTION_SIGHT        = 0x00000001,
+	OPTION_HIDE         = 0x00000002,
+	OPTION_CLOAK        = 0x00000004,
+	OPTION_FALCON       = 0x00000010,
+	OPTION_RIDING       = 0x00000020,
+	OPTION_INVISIBLE    = 0x00000040,
+	OPTION_ORCISH       = 0x00000800,
+	OPTION_WEDDING      = 0x00001000,
+	OPTION_RUWACH       = 0x00002000,
+	OPTION_CHASEWALK    = 0x00004000,
+	OPTION_FLYING       = 0x00008000, //Note that clientside Flying and Xmas are 0x8000 for clients prior to 2007.
+	OPTION_XMAS         = 0x00010000,
+	OPTION_TRANSFORM    = 0x00020000,
+	OPTION_SUMMER       = 0x00040000,
+	OPTION_DRAGON1      = 0x00080000,
+	OPTION_WUG          = 0x00100000,
+	OPTION_WUGRIDER     = 0x00200000,
+	OPTION_MADOGEAR     = 0x00400000,
+	OPTION_DRAGON2      = 0x00800000,
+	OPTION_DRAGON3      = 0x01000000,
+	OPTION_DRAGON4      = 0x02000000,
+	OPTION_DRAGON5      = 0x04000000,
+	OPTION_HANBOK       = 0x08000000,
+	OPTION_OKTOBERFEST  = 0x10000000,
 	
 #ifndef NEW_CARTS
 	OPTION_CART1     = 0x00000008,
-- 
cgit v1.2.3-70-g09d2


From b79a9d7efa9213e3c791ec356bf21b712878d1aa Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Mon, 6 Jan 2014 15:26:00 -0200
Subject: Introducing Hercules Autotrade Persistency

Aka autotrading merchants survive server restarts.
Originally sekai's (aka me).
Special Thanks to Haruna, Michieru.

Signed-off-by: shennetsind <ind@henn.et>
---
 conf/inter-server.conf                   |   2 +
 sql-files/main.sql                       |  25 ++++
 sql-files/upgrades/2014-01-06--17-22.sql |  16 ++
 sql-files/upgrades/index.txt             |   3 +-
 src/char/char.c                          |  31 +++-
 src/config/core.h                        |   4 +
 src/map/atcommand.c                      |   9 +-
 src/map/chrif.c                          |  21 ++-
 src/map/chrif.h                          |   2 +-
 src/map/clif.c                           |   2 +-
 src/map/map.c                            |   7 +
 src/map/map.h                            |   2 +
 src/map/pc.c                             | 243 +++++++++++++++++++++++++++++--
 src/map/pc.h                             |  27 ++++
 src/map/vending.c                        |   3 +-
 15 files changed, 366 insertions(+), 31 deletions(-)
 create mode 100644 sql-files/upgrades/2014-01-06--17-22.sql

(limited to 'sql-files/main.sql')

diff --git a/conf/inter-server.conf b/conf/inter-server.conf
index db94494f1..d4a75ee51 100644
--- a/conf/inter-server.conf
+++ b/conf/inter-server.conf
@@ -120,6 +120,8 @@ mob_db2_db: mob_db2
 mob_skill_db_db: mob_skill_db
 mob_skill_db2_db: mob_skill_db2
 mapreg_db: mapreg
+autotrade_merchants_db: autotrade_merchants
+autotrade_data_db: autotrade_data
 
 // Use SQL for item_db?
 use_sql_item_db: no
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 906c329fa..30882546e 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -672,6 +672,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1383955424);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1384545461);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1384588175);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1387844126);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1389028967);
 
 --
 -- Table structure for table `sstatus`
@@ -743,3 +744,27 @@ CREATE TABLE IF NOT EXISTS `npc_market_data` (
   PRIMARY KEY  (`name`,`itemid`)
 ) ENGINE=MyISAM;
 
+--
+-- Table structure for table `autotrade_merchants`
+--
+
+CREATE TABLE IF NOT EXISTS `autotrade_merchants` (
+  `account_id` int(11) NOT NULL default '0',
+  `char_id` int(11) NOT NULL default '0',
+  `sex` tinyint(2) NOT NULL default '0',
+  `title` varchar(80) NOT NULL default 'Buy From Me!',
+  PRIMARY KEY  (`account_id`,`char_id`)
+) ENGINE=MyISAM; 
+
+--
+-- Table structure for table `autotrade_data`
+--
+
+CREATE TABLE IF NOT EXISTS `autotrade_data` (
+  `char_id` int(11) NOT NULL default '0',
+  `itemkey` int(11) NOT NULL default '0',
+  `amount` int(11) NOT NULL default '0',
+  `price` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`char_id`,`itemkey`)
+) ENGINE=MyISAM; 
+
diff --git a/sql-files/upgrades/2014-01-06--17-22.sql b/sql-files/upgrades/2014-01-06--17-22.sql
new file mode 100644
index 000000000..0ba9cb69f
--- /dev/null
+++ b/sql-files/upgrades/2014-01-06--17-22.sql
@@ -0,0 +1,16 @@
+#1389028967
+CREATE TABLE IF NOT EXISTS `autotrade_merchants` (
+  `account_id` int(11) NOT NULL default '0',
+  `char_id` int(11) NOT NULL default '0',
+  `sex` tinyint(2) NOT NULL default '0',
+  `title` varchar(80) NOT NULL default 'Buy From Me!',
+  PRIMARY KEY  (`account_id`,`char_id`)
+) ENGINE=MyISAM; 
+CREATE TABLE IF NOT EXISTS `autotrade_data` (
+  `char_id` int(11) NOT NULL default '0',
+  `itemkey` int(11) NOT NULL default '0',
+  `amount` int(11) NOT NULL default '0',
+  `price` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`char_id`,`itemkey`)
+) ENGINE=MyISAM; 
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1389028967);
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 0c4ac87e5..ce75fa882 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -15,4 +15,5 @@
 2013-11-15--19-57.sql
 2013-11-16--07-49.sql
 2013-11-18--08-23.sql
-2013-12-24--00-15.sql
\ No newline at end of file
+2013-12-24--00-15.sql
+2014-01-06--17-22.sql
\ No newline at end of file
diff --git a/src/char/char.c b/src/char/char.c
index 292973449..9b3f1443d 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -3503,14 +3503,14 @@ int parse_frommap(int fd)
 			break;
 
 			case 0x2b26: // auth request from map-server
-				if (RFIFOREST(fd) < 19)
+				if (RFIFOREST(fd) < 20)
 					return 0;
 
 			{
 				int account_id;
 				int char_id;
 				int login_id1;
-				char sex;
+				char sex, standalone;
 				uint32 ip;
 				struct auth_node* node;
 				struct mmo_charstatus* cd;
@@ -3521,15 +3521,36 @@ int parse_frommap(int fd)
 				login_id1  = RFIFOL(fd,10);
 				sex        = RFIFOB(fd,14);
 				ip         = ntohl(RFIFOL(fd,15));
-				RFIFOSKIP(fd,19);
+				standalone = RFIFOB(fd, 19);
+				RFIFOSKIP(fd,20);
 
 				node = (struct auth_node*)idb_get(auth_db, account_id);
 				cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id);
-				if( cd == NULL )
-				{	//Really shouldn't happen.
+				
+				if( cd == NULL ) { //Really shouldn't happen.
 					mmo_char_fromsql(char_id, &char_dat, true);
 					cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id);
 				}
+
+				if( runflag == CHARSERVER_ST_RUNNING && cd && standalone ) {
+					cd->sex = sex;
+					
+					WFIFOHEAD(fd,25 + sizeof(struct mmo_charstatus));
+					WFIFOW(fd,0) = 0x2afd;
+					WFIFOW(fd,2) = 25 + sizeof(struct mmo_charstatus);
+					WFIFOL(fd,4) = account_id;
+					WFIFOL(fd,8) = 0;
+					WFIFOL(fd,12) = 0;
+					WFIFOL(fd,16) = 0;
+					WFIFOL(fd,20) = 0;
+					WFIFOB(fd,24) = 0;
+					memcpy(WFIFOP(fd,25), cd, sizeof(struct mmo_charstatus));
+					WFIFOSET(fd, WFIFOW(fd,2));
+					
+					set_char_online(id, char_id, account_id);
+					break;
+				}
+				
 				if( runflag == CHARSERVER_ST_RUNNING &&
 					cd != NULL &&
 					node != NULL &&
diff --git a/src/config/core.h b/src/config/core.h
index daadc6455..edd5c2b2a 100644
--- a/src/config/core.h
+++ b/src/config/core.h
@@ -67,6 +67,10 @@
 /// Uncomment to enable real-time server stats (in and out data and ram usage). [Ai4rei]
 //#define SHOW_SERVER_STATS
 
+
+/// Comment to disable autotrade persistency (where autotrading merchants survive server restarts)
+#define AUTOTRADE_PERSISTENCY
+
 /**
  * No settings past this point
  **/
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index ce73319e2..ffd6da9d5 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -5479,12 +5479,19 @@ ACMD(autotrade) {
 		int timeout = atoi(message);
 		status->change_start(&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, 0);
 	}
-	
+		
 	clif->chsys_quit(sd);
 	
 	clif->authfail_fd(sd->fd, 15);
 	
+	
+#ifdef AUTOTRADE_PERSISTENCY
+	pc->autotrade_prepare(sd);
+	
+	return false;/* we fail to not cause it to proceed on is_atcommand */
+#else
 	return true;
+#endif
 }
 
 /*==========================================
diff --git a/src/map/chrif.c b/src/map/chrif.c
index e9c3bbabf..7b5cbbe59 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -119,7 +119,7 @@ struct auth_node* chrif_auth_check(int account_id, int char_id, enum sd_state st
 
 bool chrif_auth_delete(int account_id, int char_id, enum sd_state state) {
 	struct auth_node *node;
-	
+
 	if ( (node = chrif->auth_check(account_id, char_id, state) ) ) {
 		int fd = node->sd ? node->sd->fd : node->fd;
 		
@@ -128,7 +128,7 @@ bool chrif_auth_delete(int account_id, int char_id, enum sd_state state) {
 		
 		if ( node->char_dat )
 			aFree(node->char_dat);
-		
+
 		if ( node->sd )
 			aFree(node->sd);
 		
@@ -486,6 +486,7 @@ int chrif_reconnect(DBKey key, DBData *data, va_list ap) {
 
 /// Called when all the connection steps are completed.
 void chrif_on_ready(void) {
+	static bool once = false;
 	ShowStatus("Map Server is now online.\n");
 	
 	chrif->state = 2;
@@ -503,6 +504,13 @@ void chrif_on_ready(void) {
 
 	//Re-save any guild castles that were modified in the disconnection time.
 	guild->castle_reconnect(-1, 0, 0);
+	
+	if( !once ) {
+#ifdef AUTOTRADE_PERSISTENCY
+		pc->autotrade_load();
+#endif
+		once = true;
+	}
 }
 
 
@@ -544,22 +552,23 @@ int chrif_scdata_request(int account_id, int char_id) {
 /*==========================================
  * Request auth confirmation
  *------------------------------------------*/
-void chrif_authreq(struct map_session_data *sd) {
+void chrif_authreq(struct map_session_data *sd, bool hstandalone) {
 	struct auth_node *node= chrif->search(sd->bl.id);
-
+	
 	if( node != NULL || !chrif->isconnected() ) {
 		set_eof(sd->fd);
 		return;
 	}
 
-	WFIFOHEAD(chrif->fd,19);
+	WFIFOHEAD(chrif->fd,20);
 	WFIFOW(chrif->fd,0) = 0x2b26;
 	WFIFOL(chrif->fd,2) = sd->status.account_id;
 	WFIFOL(chrif->fd,6) = sd->status.char_id;
 	WFIFOL(chrif->fd,10) = sd->login_id1;
 	WFIFOB(chrif->fd,14) = sd->status.sex;
 	WFIFOL(chrif->fd,15) = htonl(session[sd->fd]->client_addr);
-	WFIFOSET(chrif->fd,19);
+	WFIFOB(chrif->fd,19) = hstandalone ? 1 : 0;
+	WFIFOSET(chrif->fd,20);
 	chrif->sd_to_auth(sd, ST_LOGIN);
 }
 
diff --git a/src/map/chrif.h b/src/map/chrif.h
index b69d34210..24b92908d 100644
--- a/src/map/chrif.h
+++ b/src/map/chrif.h
@@ -79,7 +79,7 @@ struct chrif_interface {
 	bool (*auth_delete) (int account_id, int char_id, enum sd_state state);
 	bool (*auth_finished) (struct map_session_data* sd);
 	
-	void (*authreq) (struct map_session_data* sd);
+	void (*authreq) (struct map_session_data* sd, bool hstandalone);
 	void (*authok) (int fd);
 	int (*scdata_request) (int account_id, int char_id);
 	int (*save) (struct map_session_data* sd, int flag);
diff --git a/src/map/clif.c b/src/map/clif.c
index b442d6279..e69748809 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -9188,7 +9188,7 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd) {
 	WFIFOSET(fd,packet_len(0x283));
 #endif
 
-	chrif->authreq(sd);
+	chrif->authreq(sd,false);
 }
 void clif_hercules_chsys_mjoin(struct map_session_data *sd) {
 	if( !map->list[sd->bl.m].channel ) {
diff --git a/src/map/map.c b/src/map/map.c
index aef34ef00..922807158 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1676,6 +1676,9 @@ int map_quit(struct map_session_data *sd) {
 	if( sd->bg_id && !sd->bg_queue.arena ) /* TODO: dump this chunk after bg_queue is fully enabled */
 		bg->team_leave(sd,1);
 
+	if( sd->state.autotrade && runflag != MAPSERVER_ST_SHUTDOWN && !hChSys.closing )
+		pc->autotrade_update(sd,PAUC_REMOVE);
+
 	skill->cooldown_save(sd);
 	pc->itemcd_do(sd,false);
 
@@ -3606,6 +3609,10 @@ int inter_config_read(char *cfgName) {
 			map->db_use_sql_mob_skill_db = config_switch(w2);
 			ShowStatus ("Using monster skill database as SQL: '%s'\n", w2);
 		}
+		else if(strcmpi(w1,"autotrade_merchants_db")==0)
+			strcpy(map->autotrade_merchants_db, w2);
+		else if(strcmpi(w1,"autotrade_data_db")==0)
+			strcpy(map->autotrade_data_db, w2);
 		/* sql log db */
 		else if(strcmpi(w1,"log_db_ip")==0)
 			strcpy(logs->db_ip, w2);
diff --git a/src/map/map.h b/src/map/map.h
index 906202f83..a39cc7f86 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -839,6 +839,8 @@ struct map_interface {
 	char mob_skill_db_db[32];
 	char mob_skill_db2_db[32];
 	char interreg_db[32];
+	char autotrade_merchants_db[32];
+	char autotrade_data_db[32];
 
 	char default_codepage[32];
 	
diff --git a/src/map/pc.c b/src/map/pc.c
index fc1d56b6d..9e819bcac 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1330,7 +1330,7 @@ int pc_reg_received(struct map_session_data *sd)
 
 	if( npc->motd ) /* [Ind/Hercules] */
 		script->run(npc->motd->u.scr.script, 0, sd->bl.id, npc->fake_nd->bl.id);
-
+	
 	return 1;
 }
 
@@ -10291,6 +10291,12 @@ void pc_scdata_received(struct map_session_data *sd) {
 		
 		pc->expire_check(sd);
 	}
+	
+	if( sd->state.standalone ) {
+		clif->pLoadEndAck(0,sd);
+		pc->autotrade_populate(sd);
+		pc->autotrade_start(sd);
+	}
 }
 int pc_expiration_timer(int tid, int64 tick, int id, intptr_t data) {
 	struct map_session_data *sd = map->id2sd(id);
@@ -10342,14 +10348,211 @@ void pc_expire_check(struct map_session_data *sd) {
 
 	sd->expiration_tid = timer->add(timer->gettick() + (int64)(sd->expiration_time - time(NULL))*1000, pc->expiration_timer, sd->bl.id, 0);
 }
+/**
+ * Loads autotraders
+ ***/
+void pc_autotrade_load(void) {
+	struct map_session_data *sd;
+	char *data;
+	
+	if (SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT `account_id`,`char_id`,`sex`,`title` FROM `%s`",map->autotrade_merchants_db))
+		Sql_ShowDebug(map->mysql_handle);
+	
+	while( SQL_SUCCESS == SQL->NextRow(map->mysql_handle) ) {
+		int account_id, char_id;
+		char title[MESSAGE_SIZE];
+		unsigned char sex;
+		
+		SQL->GetData(map->mysql_handle, 0, &data, NULL); account_id = atoi(data);
+		SQL->GetData(map->mysql_handle, 1, &data, NULL); char_id = atoi(data);
+		SQL->GetData(map->mysql_handle, 2, &data, NULL); sex = atoi(data);
+		SQL->GetData(map->mysql_handle, 3, &data, NULL); safestrncpy(title, data, sizeof(title));
 
-/*==========================================
- * pc Init/Terminate
- *------------------------------------------*/
-void do_final_pc(void) {
+		CREATE(sd, TBL_PC, 1);
+		
+		pc->setnewpc(sd, account_id, char_id, 0, 0, sex, 0);
+		
+		safestrncpy(sd->message, title, MESSAGE_SIZE);
+		
+		sd->state.standalone = 1;
+		sd->group = pcg->get_dummy_group();
+		
+		chrif->authreq(sd,true);
+	}
+		
+	SQL->FreeResult(map->mysql_handle);
+}
+/**
+ * Loads vending data and sets it up, is triggered when char server data that pc_autotrade_load requested arrives
+ **/
+void pc_autotrade_start(struct map_session_data *sd) {
+	unsigned int count = 0;
+	int i;
+	char *data;
 
-	db_destroy(pc->itemcd_db);
+	if (SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT `itemkey`,`amount`,`price` FROM `%s` WHERE `char_id` = '%d'",map->autotrade_data_db,sd->status.char_id))
+		Sql_ShowDebug(map->mysql_handle);
+
+	while( SQL_SUCCESS == SQL->NextRow(map->mysql_handle) ) {
+		int itemkey, amount, price;
+		
+		SQL->GetData(map->mysql_handle, 0, &data, NULL); itemkey = atoi(data);
+		SQL->GetData(map->mysql_handle, 1, &data, NULL); amount = atoi(data);
+		SQL->GetData(map->mysql_handle, 2, &data, NULL); price = atoi(data);
 
+		ARR_FIND(0, MAX_CART, i, sd->status.cart[i].id == itemkey);
+				
+		if( i != MAX_CART && itemdb_cantrade(&sd->status.cart[i], 0, 0) ) {
+			if( amount > sd->status.cart[i].amount )
+				amount = sd->status.cart[i].amount;
+			
+			if( amount ) {
+				sd->vending[count].index = i;
+				sd->vending[count].amount = amount;
+				sd->vending[count].value = cap_value(price, 0, (unsigned int)battle_config.vending_max_value);
+
+				count++;
+			}
+		}
+	}
+		
+	if( !count ) {
+		pc->autotrade_update(sd,PAUC_REMOVE);
+		map->quit(sd);
+	} else {
+		sd->state.autotrade = 1;
+		sd->vender_id = ++vending->next_id;
+		sd->vend_num = count;
+		sd->state.vending = true;
+		idb_put(vending->db, sd->status.char_id, sd);
+		if( map->list[sd->bl.m].users )
+			clif->showvendingboard(&sd->bl,sd->message,0);
+	}
+}
+/**
+ * Perform a autotrade action
+ **/
+void pc_autotrade_update(struct map_session_data *sd, enum e_pc_autotrade_update_action action) {
+	int i;
+	
+	/* either way, this goes down */
+	if( action != PAUC_START ) {
+		if (SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'",map->autotrade_data_db,sd->status.char_id))
+			Sql_ShowDebug(map->mysql_handle);
+	}
+	
+	switch( action ) {
+		case PAUC_REMOVE:
+			if (SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' LIMIT 1",map->autotrade_merchants_db,sd->status.char_id))
+				Sql_ShowDebug(map->mysql_handle);
+			break;
+		case PAUC_START:
+			if (SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s` (`account_id`,`char_id`,`sex`,`title`) VALUES ('%d','%d','%d','%s')",
+										map->autotrade_merchants_db,
+										sd->status.account_id,
+										sd->status.char_id,
+										sd->status.sex,
+										sd->message
+										))
+				Sql_ShowDebug(map->mysql_handle);
+			/* yes we want it to fall */
+		case PAUC_REFRESH:
+			for( i = 0; i < sd->vend_num; i++ ) {
+				if( sd->vending[i].amount == 0 )
+					continue;
+				
+				if (SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s` (`char_id`,`itemkey`,`amount`,`price`) VALUES ('%d','%d','%d','%d')",
+											map->autotrade_data_db,
+											sd->status.char_id,
+											sd->status.cart[sd->vending[i].index].id,
+											sd->vending[i].amount,
+											sd->vending[i].value
+											))
+					Sql_ShowDebug(map->mysql_handle);
+			}
+			break;
+	}
+}
+/**
+ * Handles characters upon @autotrade usage
+ **/
+void pc_autotrade_prepare(struct map_session_data *sd) {
+	struct autotrade_vending *data;
+	int i, cursor = 0;
+	int account_id, char_id;
+	char title[MESSAGE_SIZE];
+	unsigned char sex;
+
+	CREATE(data, struct autotrade_vending, 1);
+	
+	memcpy(data->vending, sd->vending, sizeof(sd->vending));
+	
+	for(i = 0; i < sd->vend_num; i++) {
+		if( sd->vending[i].amount ) {
+			memcpy(&data->list[cursor],&sd->status.cart[sd->vending[i].index],sizeof(struct item));
+			cursor++;
+		}
+	}
+	
+	data->vend_num = (unsigned char)cursor;
+	
+	idb_put(pc->at_db, sd->status.char_id, data);
+	
+	account_id = sd->status.account_id;
+	char_id = sd->status.char_id;
+	sex = sd->status.sex;
+	safestrncpy(title, sd->message, sizeof(title));
+	
+	map->quit(sd);
+	chrif->auth_delete(account_id, char_id, ST_LOGOUT);
+
+	CREATE(sd, TBL_PC, 1);
+	
+	pc->setnewpc(sd, account_id, char_id, 0, 0, sex, 0);
+	
+	safestrncpy(sd->message, title, MESSAGE_SIZE);
+	
+	sd->state.standalone = 1;
+	sd->group = pcg->get_dummy_group();
+
+	chrif->authreq(sd,true);
+}
+/**
+ * Prepares autotrade data from pc->at_db from a player that has already returned from char server
+ **/
+void pc_autotrade_populate(struct map_session_data *sd) {
+	struct autotrade_vending *data;
+	int i, j, cursor = 0;
+
+	if( !(data = idb_get(pc->at_db,sd->status.char_id)) )
+		return;
+
+	for(i = 0; i < data->vend_num; i++) {
+		if( !data->vending[i].amount )
+			continue;
+		
+		ARR_FIND(0, MAX_CART, j, !memcmp((char*)(&data->list[i]) + sizeof(data->list[0].id), (char*)(&sd->status.cart[j]) + sizeof(data->list[0].id), sizeof(struct item) - sizeof(data->list[0].id)));
+		
+		if( j != MAX_CART ) {
+			sd->vending[cursor].index = j;
+			sd->vending[cursor].amount = data->vending[i].amount;
+			sd->vending[cursor].value = data->vending[i].value;
+			
+			cursor++;
+		}
+	}
+	
+	sd->vend_num = cursor;
+
+	pc->autotrade_update(sd,PAUC_START);
+	
+	idb_remove(pc->at_db, sd->status.char_id);
+}
+void do_final_pc(void) {
+	
+	db_destroy(pc->itemcd_db);
+	db_destroy(pc->at_db);
+	
 	pcg->final();
 	
 	ers_destroy(pc->sc_display_ers);
@@ -10359,11 +10562,12 @@ void do_final_pc(void) {
 void do_init_pc(bool minimal) {
 	if (minimal)
 		return;
-
+	
 	pc->itemcd_db = idb_alloc(DB_OPT_RELEASE_DATA);
-
+	pc->at_db = idb_alloc(DB_OPT_RELEASE_DATA);
+	
 	pc->readdb();
-
+	
 	timer->add_func_list(pc->invincible_timer, "pc_invincible_timer");
 	timer->add_func_list(pc->eventtimer, "pc_eventtimer");
 	timer->add_func_list(pc->inventory_rental_end, "pc_inventory_rental_end");
@@ -10375,28 +10579,27 @@ void do_init_pc(bool minimal) {
 	timer->add_func_list(pc->charm_timer, "pc_charm_timer");
 	timer->add_func_list(pc->global_expiration_timer,"pc_global_expiration_timer");
 	timer->add_func_list(pc->expiration_timer,"pc_expiration_timer");
-
+	
 	timer->add(timer->gettick() + map->autosave_interval, pc->autosave, 0, 0);
-
+	
 	// 0=day, 1=night [Yor]
 	map->night_flag = battle_config.night_at_start ? 1 : 0;
-
+	
 	if (battle_config.day_duration > 0 && battle_config.night_duration > 0) {
 		int day_duration = battle_config.day_duration;
 		int night_duration = battle_config.night_duration;
 		// add night/day timer [Yor]
 		timer->add_func_list(pc->map_day_timer, "pc_map_day_timer");
 		timer->add_func_list(pc->map_night_timer, "pc_map_night_timer");
-
+		
 		pc->day_timer_tid   = timer->add_interval(timer->gettick() + (map->night_flag ? 0 : day_duration) + night_duration, pc->map_day_timer,   0, 0, day_duration + night_duration);
 		pc->night_timer_tid = timer->add_interval(timer->gettick() + day_duration + (map->night_flag ? night_duration : 0), pc->map_night_timer, 0, 0, day_duration + night_duration);
 	}
-
+	
 	pcg->init();
 	
 	pc->sc_display_ers = ers_new(sizeof(struct sc_display_entry), "pc.c:sc_display_ers", ERS_OPT_NONE);
 }
-
 /*=====================================
 * Default Functions : pc.h 
 * Generated by HerculesInterfaceMaker
@@ -10414,6 +10617,7 @@ void pc_defaults(void) {
 	pc = &pc_s;
 
 	/* vars */
+	pc->at_db = NULL;
 	pc->itemcd_db = NULL;
 	/* */
 	pc->day_timer_tid = INVALID_TIMER;
@@ -10681,4 +10885,13 @@ void pc_defaults(void) {
 	pc->expiration_timer = pc_expiration_timer;
 	pc->global_expiration_timer = pc_global_expiration_timer;
 	pc->expire_check = pc_expire_check;
+	
+	/**
+	 * Autotrade persistency [Ind/Hercules <3]
+	 **/
+	pc->autotrade_load = pc_autotrade_load;
+	pc->autotrade_update = pc_autotrade_update;
+	pc->autotrade_start = pc_autotrade_start;
+	pc->autotrade_prepare = pc_autotrade_prepare;
+	pc->autotrade_populate = pc_autotrade_populate;
 }
diff --git a/src/map/pc.h b/src/map/pc.h
index 5264fa557..2f143f15c 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -180,6 +180,7 @@ struct map_session_data {
 		unsigned int snovice_call_flag : 3; //Summon Angel (stage 1~3)
 		unsigned int hpmeter_visible : 1;
 		unsigned int itemcheck : 1;
+		unsigned int standalone : 1;/* [Ind/Hercules <3] */
 	} state;
 	struct {
 		unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
@@ -724,6 +725,21 @@ struct item_cd {
 	short nameid[MAX_ITEMDELAYS];//skill id
 };
 
+enum e_pc_autotrade_update_action {
+	PAUC_START,
+	PAUC_REFRESH,
+	PAUC_REMOVE,
+};
+
+/**
+ * Used to temporarily remember vending data
+ **/
+struct autotrade_vending {
+	struct item list[MAX_VENDING];
+	struct s_vending vending[MAX_VENDING];
+	unsigned char vend_num;
+};
+
 /*=====================================
 * Interface : pc.h 
 * Generated by HerculesInterfaceMaker
@@ -731,6 +747,8 @@ struct item_cd {
 *-------------------------------------*/
 struct pc_interface {
 
+	/* */
+	DBMap *at_db;/* char id -> struct autotrade_vending */
 	/* */
 	DBMap* itemcd_db;
 	/* */
@@ -1000,6 +1018,15 @@ struct pc_interface {
 	int (*expiration_timer) (int tid, int64 tick, int id, intptr_t data);
 	int (*global_expiration_timer) (int tid, int64 tick, int id, intptr_t data);
 	void (*expire_check) (struct map_session_data *sd);
+	
+	/**
+	 * Autotrade persistency [Ind/Hercules <3]
+	 **/
+	void (*autotrade_load) (void);
+	void (*autotrade_update) (struct map_session_data *sd, enum e_pc_autotrade_update_action action);
+	void (*autotrade_start) (struct map_session_data *sd);
+	void (*autotrade_prepare) (struct map_session_data *sd);
+	void (*autotrade_populate) (struct map_session_data *sd);
 };
 
 struct pc_interface *pc;
diff --git a/src/map/vending.c b/src/map/vending.c
index 7d248351c..78bc79a31 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -212,7 +212,8 @@ void vending_purchasereq(struct map_session_data* sd, int aid, unsigned int uid,
 			//Close Vending (this was automatically done by the client, we have to do it manually for autovenders) [Skotlex]
 			vending->close(vsd);
 			map->quit(vsd); //They have no reason to stay around anymore, do they?
-		}
+		} else
+			pc->autotrade_update(vsd,PAUC_REFRESH);
 	}
 }
 
-- 
cgit v1.2.3-70-g09d2


From 82b583b5ef4e729ad2c3c74b26adce16a145605a Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Sat, 11 Jan 2014 14:02:59 -0200
Subject: Hercules 1st 2014 MegaPatch

http://hercules.ws/board/topic/3886-hercules-1st-2014-megapatch/
Signed-off-by: shennetsind <ind@henn.et>
---
 conf/inter-server.conf                   |   7 +-
 sql-files/main.sql                       |  99 +++-
 sql-files/upgrades/2014-01-04--16-47.sql |  61 +++
 sql-files/upgrades/index.txt             |   1 +
 src/char/char.c                          | 112 ++++-
 src/char/char.h                          |  15 +-
 src/char/inter.c                         | 417 +++++++++------
 src/common/db.c                          | 175 ++++++-
 src/common/db.h                          | 124 +++--
 src/common/mmo.h                         |  41 +-
 src/common/socket.c                      |   4 +-
 src/login/account.h                      |  10 +-
 src/login/account_sql.c                  | 271 +++++++---
 src/login/login.c                        |  51 +-
 src/login/login.h                        |   5 +-
 src/map/atcommand.c                      |  12 +-
 src/map/battleground.c                   |   6 +-
 src/map/chrif.c                          |  10 +-
 src/map/clif.c                           |   2 +-
 src/map/duel.c                           |   4 +-
 src/map/instance.c                       |   5 +-
 src/map/instance.h                       |   5 +-
 src/map/intif.c                          | 259 +++++++---
 src/map/intif.h                          |   2 +-
 src/map/mapreg.h                         |  18 +-
 src/map/mapreg_sql.c                     |  99 ++--
 src/map/mob.c                            |   4 +-
 src/map/pc.c                             | 589 ++++++++++------------
 src/map/pc.h                             |  63 ++-
 src/map/script.c                         | 835 +++++++++++++++++++------------
 src/map/script.h                         |  73 ++-
 src/map/skill.c                          |  16 +-
 src/map/trade.c                          |   2 +-
 src/map/unit.c                           |  21 +-
 34 files changed, 2144 insertions(+), 1274 deletions(-)
 create mode 100644 sql-files/upgrades/2014-01-04--16-47.sql

(limited to 'sql-files/main.sql')

diff --git a/conf/inter-server.conf b/conf/inter-server.conf
index d4a75ee51..96d43973b 100644
--- a/conf/inter-server.conf
+++ b/conf/inter-server.conf
@@ -76,6 +76,8 @@ mysql_reconnect_count:1
 
 //Shared
 interreg_db: interreg
+global_acc_reg_num_db: global_acc_reg_num_db
+global_acc_reg_str_db: global_acc_reg_str_db
 
 // Char Database Tables
 char_db: char
@@ -85,7 +87,6 @@ cart_db: cart_inventory
 inventory_db: inventory
 charlog_db: charlog
 storage_db: storage
-reg_db: global_reg_value
 skill_db: skill
 interlog_db: interlog
 memo_db: memo
@@ -110,6 +111,10 @@ mercenary_owner_db: mercenary_owner
 ragsrvinfo_db: ragsrvinfo
 elemental_db: elemental
 account_data_db: account_data
+acc_reg_num_db: acc_reg_num_db
+acc_reg_str_db: acc_reg_str_db
+char_reg_str_db: char_reg_str_db
+char_reg_num_db: char_reg_num_db
 
 // Map Database Tables
 item_db_db: item_db
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 30882546e..398bdcfe4 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -188,20 +188,6 @@ CREATE TABLE IF NOT EXISTS `hotkey` (
 	PRIMARY KEY (`char_id`,`hotkey`)
 ) ENGINE=MyISAM;
 
---
--- Table structure for table `global_reg_value`
---
-
-CREATE TABLE IF NOT EXISTS `global_reg_value` (
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `str` varchar(255) NOT NULL default '',
-  `value` varchar(255) NOT NULL default '0',
-  `type` tinyint(1) NOT NULL default '3',
-  `account_id` int(11) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`char_id`,`str`,`account_id`),
-  KEY `account_id` (`account_id`)
-) ENGINE=MyISAM;
-
 --
 -- Table structure for table `guild`
 --
@@ -462,11 +448,10 @@ INSERT INTO `login` (`account_id`, `userid`, `user_pass`, `sex`, `email`) VALUES
 --
 
 CREATE TABLE IF NOT EXISTS `mapreg` (
-  `varname` varchar(32) NOT NULL,
+  `varname` varchar(32) BINARY NOT NULL,
   `index` int(11) unsigned NOT NULL default '0',
   `value` varchar(255) NOT NULL,
-  KEY `varname` (`varname`),
-  KEY `index` (`index`)
+  PRIMARY KEY  (`varname`,`index`)
 ) ENGINE=MyISAM;
 
 --
@@ -672,6 +657,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1383955424);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1384545461);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1384588175);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1387844126);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1388854043);
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1389028967);
 
 --
@@ -744,6 +730,85 @@ CREATE TABLE IF NOT EXISTS `npc_market_data` (
   PRIMARY KEY  (`name`,`itemid`)
 ) ENGINE=MyISAM;
 
+--
+-- Table structure for table `acc_reg_num_db`
+--
+
+CREATE TABLE IF NOT EXISTS `acc_reg_num_db` (
+  `account_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `acc_reg_str_db`
+--
+
+CREATE TABLE IF NOT EXISTS `acc_reg_str_db` (
+  `account_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` varchar(254) NOT NULL default '0',
+  PRIMARY KEY  (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `char_reg_num_db`
+--
+
+CREATE TABLE IF NOT EXISTS `char_reg_num_db` (
+  `char_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`char_id`,`key`,`index`),
+  KEY `char_id` (`char_id`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `char_reg_str_db`
+--
+
+CREATE TABLE IF NOT EXISTS `char_reg_str_db` (
+  `char_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` varchar(254) NOT NULL default '0',
+  PRIMARY KEY  (`char_id`,`key`,`index`),
+  KEY `char_id` (`char_id`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `global_acc_reg_num_db`
+--
+
+CREATE TABLE IF NOT EXISTS `global_acc_reg_num_db` (
+  `account_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `global_acc_reg_str_db`
+--
+
+
+CREATE TABLE IF NOT EXISTS `global_acc_reg_str_db` (
+  `account_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` varchar(254) NOT NULL default '0',
+  PRIMARY KEY  (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+
 --
 -- Table structure for table `autotrade_merchants`
 --
diff --git a/sql-files/upgrades/2014-01-04--16-47.sql b/sql-files/upgrades/2014-01-04--16-47.sql
new file mode 100644
index 000000000..a60ec1d24
--- /dev/null
+++ b/sql-files/upgrades/2014-01-04--16-47.sql
@@ -0,0 +1,61 @@
+#1388854043
+ALTER TABLE `mapreg` ADD PRIMARY KEY (`varname`, `index`);
+ALTER TABLE `mapreg` DROP INDEX `varname`;
+ALTER TABLE `mapreg` DROP INDEX `index`;
+ALTER TABLE `mapreg` MODIFY `varname` varchar(32) BINARY NOT NULL;
+CREATE TABLE IF NOT EXISTS `acc_reg_num_db` (
+  `account_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+CREATE TABLE IF NOT EXISTS `acc_reg_str_db` (
+  `account_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` varchar(254) NOT NULL default '0',
+  PRIMARY KEY  (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+CREATE TABLE IF NOT EXISTS `char_reg_num_db` (
+  `char_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`char_id`,`key`,`index`),
+  KEY `char_id` (`char_id`)
+) ENGINE=MyISAM;
+CREATE TABLE IF NOT EXISTS `char_reg_str_db` (
+  `char_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` varchar(254) NOT NULL default '0',
+  PRIMARY KEY  (`char_id`,`key`,`index`),
+  KEY `char_id` (`char_id`)
+) ENGINE=MyISAM;
+CREATE TABLE IF NOT EXISTS `global_acc_reg_num_db` (
+  `account_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+CREATE TABLE IF NOT EXISTS `global_acc_reg_str_db` (
+  `account_id` int(11) unsigned NOT NULL default '0',
+  `key` varchar(32) BINARY NOT NULL default '',
+  `index` int(11) unsigned NOT NULL default '0',
+  `value` varchar(254) NOT NULL default '0',
+  PRIMARY KEY  (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+INSERT INTO `acc_reg_num_db` (`account_id`, `key`, `index`, `value`) SELECT `account_id`, `str`, 0, `value` FROM `global_reg_value` WHERE `type` = 2 AND `str` NOT LIKE '%$';
+INSERT INTO `acc_reg_str_db` (`account_id`, `key`, `index`, `value`) SELECT `account_id`, `str`, 0, `value` FROM `global_reg_value` WHERE `type` = 2 AND `str` LIKE '%$';
+INSERT INTO `char_reg_num_db` (`char_id`, `key`, `index`, `value`) SELECT `char_id`, `str`, 0, `value` FROM `global_reg_value` WHERE `type` = 3 AND `str` NOT LIKE '%$';
+INSERT INTO `char_reg_str_db` (`char_id`, `key`, `index`, `value`) SELECT `char_id`, `str`, 0, `value` FROM `global_reg_value` WHERE `type` = 3 AND `str` LIKE '%$';
+INSERT INTO `global_acc_reg_num_db` (`account_id`, `key`, `index`, `value`) SELECT `account_id`, `str`, 0, `value` FROM `global_reg_value` WHERE `type` = 1 AND `str` NOT LIKE '%$';
+INSERT INTO `global_acc_reg_str_db` (`account_id`, `key`, `index`, `value`) SELECT `account_id`, `str`, 0, `value` FROM `global_reg_value` WHERE `type` = 1 AND `str` LIKE '%$';
+#DROP TABLE `global_reg_value`;
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1388854043);
\ No newline at end of file
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index ce75fa882..bf404d919 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -16,4 +16,5 @@
 2013-11-16--07-49.sql
 2013-11-18--08-23.sql
 2013-12-24--00-15.sql
+2014-01-04--16-47.sql
 2014-01-06--17-22.sql
\ No newline at end of file
diff --git a/src/char/char.c b/src/char/char.c
index 9b3f1443d..a6588dc09 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -45,7 +45,6 @@ char inventory_db[256] = "inventory";
 char charlog_db[256] = "charlog";
 char storage_db[256] = "storage";
 char interlog_db[256] = "interlog";
-char reg_db[256] = "global_reg_value";
 char skill_db[256] = "skill";
 char memo_db[256] = "memo";
 char guild_db[256] = "guild";
@@ -71,6 +70,10 @@ char ragsrvinfo_db[256] = "ragsrvinfo";
 char elemental_db[256] = "elemental";
 char interreg_db[32] = "interreg";
 char account_data_db[256] = "account_data";
+char acc_reg_num_db[32] = "acc_reg_num_db";
+char acc_reg_str_db[32] = "acc_reg_str_db";
+char char_reg_str_db[32] = "char_reg_str_db";
+char char_reg_num_db[32] = "char_reg_num_db";
 
 // show loading/saving messages
 int save_log = 1;
@@ -1793,7 +1796,9 @@ int delete_char_sql(int char_id)
 		Sql_ShowDebug(sql_handle);
 
 	/* delete character registry */
-	if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
+	if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", char_reg_str_db, char_id) )
+		Sql_ShowDebug(sql_handle);
+	if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", char_reg_num_db, char_id) )
 		Sql_ShowDebug(sql_handle);
 
 	/* delete skills */
@@ -2460,17 +2465,12 @@ int parse_fromlogin(int fd) {
 			break;
 
 			// reply to an account_reg2 registry request
-			case 0x2729:
+			case 0x3804:
 				if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
 					return 0;
-
-			{	//Receive account_reg2 registry, forward to map servers.
-				unsigned char buf[13+ACCOUNT_REG2_NUM*sizeof(struct global_reg)];
-				memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2));
-				WBUFW(buf,0) = 0x3804; //Map server can now receive all kinds of reg values with the same packet. [Skotlex]
-				mapif_sendall(buf, WBUFW(buf,2));
+				//Receive account_reg2 registry, forward to map servers.
+				mapif_sendall(RFIFOP(fd, 0), RFIFOW(fd,2));
 				RFIFOSKIP(fd, RFIFOW(fd,2));
-			}
 			break;
 
 			// State change of account/ban notification (from login-server)
@@ -2603,21 +2603,76 @@ int request_accreg2(int account_id, int char_id)
 	}
 	return 0;
 }
-
-//Send packet forward to login-server for account saving
-int save_accreg2(unsigned char* buf, int len)
-{
-	if (login_fd > 0) {
-		WFIFOHEAD(login_fd,len+4);
-		memcpy(WFIFOP(login_fd,4), buf, len);
-		WFIFOW(login_fd,0) = 0x2728;
-		WFIFOW(login_fd,2) = len+4;
-		WFIFOSET(login_fd,len+4);
-		return 1;
+/**
+ * Handles global account reg saving that continues with global_accreg_to_login_add and global_accreg_to_send
+ **/
+void global_accreg_to_login_start (int account_id, int char_id) {
+	WFIFOHEAD(login_fd, 60000 + 300);
+	WFIFOW(login_fd,0)  = 0x2728;
+	WFIFOW(login_fd,2)  = 14;
+	WFIFOL(login_fd,4)  = account_id;
+	WFIFOL(login_fd,8)  = char_id;
+	WFIFOW(login_fd,12) = 0;/* count */
+}
+/**
+ * Completes global account reg saving that starts global_accreg_to_login_start and continues with global_accreg_to_login_add
+ **/
+void global_accreg_to_login_send (void) {
+	WFIFOSET(login_fd, WFIFOW(login_fd,2));
+}
+/**
+ * Handles global account reg saving that starts global_accreg_to_login_start and ends with global_accreg_to_send
+ **/
+void global_accreg_to_login_add (const char *key, unsigned int index, intptr_t val, bool is_string) {
+	int nlen = WFIFOW(login_fd, 2);
+	size_t len;
+	
+	len = strlen(key)+1;
+	
+	WFIFOB(login_fd, nlen) = (unsigned char)len;/* won't be higher; the column size is 32 */
+	nlen += 1;
+	
+	safestrncpy((char*)WFIFOP(login_fd,nlen), key, len);
+	nlen += len;
+	
+	WFIFOL(login_fd, nlen) = index;
+	nlen += 4;
+	
+	if( is_string ) {
+		WFIFOB(login_fd, nlen) = val ? 2 : 3;
+		nlen += 1;
+		
+		if( val ) {
+			char *sval = (char*)val;
+			len = strlen(sval)+1;
+			
+			WFIFOB(login_fd, nlen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+			nlen += 1;
+			
+			safestrncpy((char*)WFIFOP(login_fd,nlen), sval, len);
+			nlen += len;
+		}
+		
+	} else {
+		WFIFOB(login_fd, nlen) = val ? 0 : 1;
+		nlen += 1;
+		
+		if( val ) {
+			WFIFOL(login_fd, nlen) = (int)val;
+			nlen += 4;
+		}
+		
+	}
+	
+	WFIFOW(login_fd,12) += 1;
+	
+	WFIFOW(login_fd, 2) = nlen;
+	if( WFIFOW(login_fd, 2) > 60000 ) {
+		int account_id = WFIFOL(login_fd,4), char_id = WFIFOL(login_fd,8);
+		global_accreg_to_login_send();
+		global_accreg_to_login_start(account_id,char_id);/* prepare next */
 	}
-	return 0;
 }
-
 void char_read_fame_list(void) {
 	int i;
 	char* data;
@@ -4901,8 +4956,6 @@ void sql_config_read(const char* cfgName)
 			safestrncpy(charlog_db, w2, sizeof(charlog_db));
 		else if(!strcmpi(w1,"storage_db"))
 			safestrncpy(storage_db, w2, sizeof(storage_db));
-		else if(!strcmpi(w1,"reg_db"))
-			safestrncpy(reg_db, w2, sizeof(reg_db));
 		else if(!strcmpi(w1,"skill_db"))
 			safestrncpy(skill_db, w2, sizeof(skill_db));
 		else if(!strcmpi(w1,"interlog_db"))
@@ -4955,6 +5008,15 @@ void sql_config_read(const char* cfgName)
 			safestrncpy(interreg_db,w2,sizeof(interreg_db));
 		else if(!strcmpi(w1,"account_data_db"))
 			safestrncpy(account_data_db,w2,sizeof(account_data_db));
+		else if(!strcmpi(w1,"char_reg_num_db"))
+			safestrncpy(char_reg_num_db, w2, sizeof(char_reg_num_db));
+		else if(!strcmpi(w1,"char_reg_str_db"))
+			safestrncpy(char_reg_str_db, w2, sizeof(char_reg_str_db));
+		else if(!strcmpi(w1,"acc_reg_str_db"))
+			safestrncpy(acc_reg_str_db, w2, sizeof(acc_reg_str_db));
+		else if(!strcmpi(w1,"acc_reg_num_db"))
+			safestrncpy(acc_reg_num_db, w2, sizeof(acc_reg_num_db));
+
 		//support the import command, just like any other config
 		else if(!strcmpi(w1,"import"))
 			sql_config_read(w2);
diff --git a/src/char/char.h b/src/char/char.h
index c6aa1b66d..3e3774c1f 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -1,5 +1,6 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Portions Copyright (c) Athena Dev Teams
 
 #ifndef _CHAR_SQL_H_
 #define _CHAR_SQL_H_
@@ -68,7 +69,6 @@ int char_child(int parent_id, int child_id);
 int char_family(int pl1,int pl2,int pl3);
 
 int request_accreg2(int account_id, int char_id);
-int save_accreg2(unsigned char* buf, int len);
 int login_fd;
 extern int char_name_option;
 extern char char_name_letters[];
@@ -83,7 +83,6 @@ extern char inventory_db[256];
 extern char charlog_db[256];
 extern char storage_db[256];
 extern char interlog_db[256];
-extern char reg_db[256];
 extern char skill_db[256];
 extern char memo_db[256];
 extern char guild_db[256];
@@ -106,6 +105,10 @@ extern char mercenary_owner_db[256];
 extern char ragsrvinfo_db[256];
 extern char elemental_db[256];
 extern char interreg_db[32];
+extern char acc_reg_num_db[32];
+extern char acc_reg_str_db[32];
+extern char char_reg_str_db[32];
+extern char char_reg_num_db[32];
 
 extern int db_use_sql_item_db;
 extern int db_use_sql_mob_db;
@@ -114,4 +117,8 @@ extern int db_use_sql_mob_skill_db;
 extern int guild_exp_rate;
 extern int log_inter;
 
+void global_accreg_to_login_start (int account_id, int char_id);
+void global_accreg_to_login_send (void);
+void global_accreg_to_login_add (const char *key, unsigned int index, intptr_t val, bool is_string);
+
 #endif /* _CHAR_SQL_H_ */
diff --git a/src/char/inter.c b/src/char/inter.c
index 63e1564ff..34ecebd36 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -42,7 +42,6 @@ char char_server_pw[32] = "ragnarok";
 char char_server_db[32] = "ragnarok";
 char default_codepage[32] = ""; //Feature by irmin.
 
-static struct accreg *accreg_pt;
 unsigned int party_share_level = 10;
 
 // recv. packet list
@@ -592,127 +591,225 @@ void mapif_parse_accinfo(int fd) {
 
 	return;
 }
-//--------------------------------------------------------
-// Save registry to sql
-int inter_accreg_tosql(int account_id, int char_id, struct accreg* reg, int type)
-{
-	struct global_reg* r;
-	StringBuf buf;
-	int i;
-
-	if( account_id <= 0 )
-		return 0;
-	reg->account_id = account_id;
-	reg->char_id = char_id;
-
-	//`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
-	switch( type )
-	{
-	case 3: //Char Reg
-		if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
-			Sql_ShowDebug(sql_handle);
-		account_id = 0;
-		break;
-	case 2: //Account Reg
-		if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) )
-			Sql_ShowDebug(sql_handle);
-		char_id = 0;
-		break;
-	case 1: //Account2 Reg
-		ShowError("inter_accreg_tosql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
-		return 0;
-	default:
-		ShowError("inter_accreg_tosql: Invalid type %d\n", type);
-		return 0;
-	}
-
-	if( reg->reg_num <= 0 )
-		return 0;
-
-	StrBuf->Init(&buf);
-	StrBuf->Printf(&buf, "INSERT INTO `%s` (`type`,`account_id`,`char_id`,`str`,`value`) VALUES ", reg_db);
-
-	for( i = 0; i < reg->reg_num; ++i ) {
-		r = &reg->reg[i];
-		if( r->str[0] != '\0' && r->value[0] != '\0' ) {
-			char str[32];
-			char val[256];
-
-			if( i > 0 )
-				StrBuf->AppendStr(&buf, ",");
-
-			SQL->EscapeString(sql_handle, str, r->str);
-			SQL->EscapeString(sql_handle, val, r->value);
-
-			StrBuf->Printf(&buf, "('%d','%d','%d','%s','%s')", type, account_id, char_id, str, val);
+/**
+ * Handles save reg data from map server and distributes accordingly.
+ *
+ * @param val either str or int, depending on type
+ * @param type false when int, true otherwise
+ **/
+void inter_savereg(int account_id, int char_id, const char *key, unsigned int index, intptr_t val, bool is_string) {
+	/* to login server we go! */
+	if( key[0] == '#' && key[1] == '#' ) {/* global account reg */
+		global_accreg_to_login_add(key,index,val,is_string);
+	} else if ( key[0] == '#' ) {/* local account reg */
+		if( is_string ) {
+			if( val ) {
+				if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", acc_reg_str_db, account_id, key, index, (char*)val) )
+					Sql_ShowDebug(sql_handle);
+			} else {
+				if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", acc_reg_str_db, account_id, key, index) )
+					Sql_ShowDebug(sql_handle);
+			}
+		} else {
+			if( val ) {
+				if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", acc_reg_num_db, account_id, key, index, (int)val) )
+					Sql_ShowDebug(sql_handle);
+			} else {
+				if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", acc_reg_num_db, account_id, key, index) )
+					Sql_ShowDebug(sql_handle);
+			}
+		}
+	} else { /* char reg */
+		if( is_string ) {
+			if( val ) {
+				if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", char_reg_str_db, char_id, key, index, (char*)val) )
+					Sql_ShowDebug(sql_handle);
+			} else {
+				if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", char_reg_str_db, char_id, key, index) )
+					Sql_ShowDebug(sql_handle);
+			}
+		} else {
+			if( val ) {
+				if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", char_reg_num_db, char_id, key, index, (int)val) )
+					Sql_ShowDebug(sql_handle);
+			} else {
+				if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", char_reg_num_db, char_id, key, index) )
+					Sql_ShowDebug(sql_handle);
+			}
 		}
 	}
-
-	if( SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) ) {
-		Sql_ShowDebug(sql_handle);
-	}
-
-	StrBuf->Destroy(&buf);
-
-	return 1;
+		
 }
 
 // Load account_reg from sql (type=2)
-int inter_accreg_fromsql(int account_id,int char_id, struct accreg *reg, int type)
+int inter_accreg_fromsql(int account_id,int char_id, int fd, int type)
 {
-	struct global_reg* r;
 	char* data;
 	size_t len;
-	int i;
+	unsigned int plen = 0;
 
-	if( reg == NULL)
-		return 0;
-
-	memset(reg, 0, sizeof(struct accreg));
-	reg->account_id = account_id;
-	reg->char_id = char_id;
+	switch( type ) {
+		case 3: //char reg
+			if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%d'", char_reg_str_db, char_id) )
+				Sql_ShowDebug(sql_handle);
+			break;
+		case 2: //account reg
+			if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", acc_reg_str_db, account_id) )
+				Sql_ShowDebug(sql_handle);
+			break;
+		case 1: //account2 reg
+			ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
+			return 0;
+		default:
+			ShowError("inter_accreg_fromsql: Invalid type %d\n", type);
+			return 0;
+	}
+	
+	WFIFOHEAD(fd, 60000 + 300);
+	WFIFOW(fd, 0) = 0x3804;
+	/* 0x2 = length, set prior to being sent */
+	WFIFOL(fd, 4) = account_id;
+	WFIFOL(fd, 8) = char_id;
+	WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+	WFIFOB(fd, 13) = 1;/* is string type */
+	WFIFOW(fd, 14) = 0;/* count */
+	plen = 16;
+	
+	/**
+	 * Vessel!
+	 *
+	 * str type
+	 * { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) }
+	 **/
+	while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) {
+					
+		SQL->GetData(sql_handle, 0, &data, NULL);
+		len = strlen(data)+1;
+		
+		WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */
+		plen += 1;
+		
+		safestrncpy((char*)WFIFOP(fd,plen), data, len);
+		plen += len;
+		
+		SQL->GetData(sql_handle, 1, &data, NULL);
+
+		WFIFOL(fd, plen) = (unsigned int)atol(data);
+		plen += 4;
+
+		SQL->GetData(sql_handle, 2, &data, NULL);
+		len = strlen(data)+1;
+
+		WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+		plen += 1;
+		
+		safestrncpy((char*)WFIFOP(fd,plen), data, len);
+		plen += len;
+
+		WFIFOW(fd, 14) += 1;
+		
+		if( plen > 60000 ) {
+			WFIFOW(fd, 2) = plen;
+			WFIFOSET(fd, plen);
+			
+			/* prepare follow up */
+			WFIFOHEAD(fd, 60000 + 300);
+			WFIFOW(fd, 0) = 0x3804;
+			/* 0x2 = length, set prior to being sent */
+			WFIFOL(fd, 4) = account_id;
+			WFIFOL(fd, 8) = char_id;
+			WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+			WFIFOB(fd, 13) = 1;/* is string type */
+			WFIFOW(fd, 14) = 0;/* count */
+			plen = 16;
+		}
+	}
+	
+	/* mark & go. */
+	WFIFOW(fd, 2) = plen;
+	WFIFOSET(fd, plen);
 
-	//`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
-	switch( type )
-	{
-	case 3: //char reg
-		if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
-			Sql_ShowDebug(sql_handle);
-		break;
-	case 2: //account reg
-		if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) )
-			Sql_ShowDebug(sql_handle);
-		break;
-	case 1: //account2 reg
-		ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
-		return 0;
-	default:
-		ShowError("inter_accreg_fromsql: Invalid type %d\n", type);
-		return 0;
+	SQL->FreeResult(sql_handle);
+	
+	switch( type ) {
+		case 3: //char reg
+			if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%d'", char_reg_num_db, char_id) )
+				Sql_ShowDebug(sql_handle);
+			break;
+		case 2: //account reg
+			if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", acc_reg_num_db, account_id) )
+				Sql_ShowDebug(sql_handle);
+			break;
+		case 1: //account2 reg
+			ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
+			return 0;
 	}
-	for( i = 0; i < MAX_REG_NUM && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i )
-	{
-		r = &reg->reg[i];
-		// str
-		SQL->GetData(sql_handle, 0, &data, &len);
-		memcpy(r->str, data, min(len, sizeof(r->str)));
-		// value
-		SQL->GetData(sql_handle, 1, &data, &len);
-		memcpy(r->value, data, min(len, sizeof(r->value)));
+
+	WFIFOHEAD(fd, 60000 + 300);
+	WFIFOW(fd, 0) = 0x3804;
+	/* 0x2 = length, set prior to being sent */
+	WFIFOL(fd, 4) = account_id;
+	WFIFOL(fd, 8) = char_id;
+	WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+	WFIFOB(fd, 13) = 0;/* is int type */
+	WFIFOW(fd, 14) = 0;/* count */
+	plen = 16;
+	
+	/**
+	 * Vessel!
+	 *
+	 * int type
+	 * { keyLength(B), key(<keyLength>), index(L), value(L) }
+	 **/
+	while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) {
+		
+		SQL->GetData(sql_handle, 0, &data, NULL);
+		len = strlen(data)+1;
+		
+		WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */
+		plen += 1;
+		
+		safestrncpy((char*)WFIFOP(fd,plen), data, len);
+		plen += len;
+		
+		SQL->GetData(sql_handle, 1, &data, NULL);
+		
+		WFIFOL(fd, plen) = (unsigned int)atol(data);
+		plen += 4;
+		
+		SQL->GetData(sql_handle, 2, &data, NULL);
+		
+		WFIFOL(fd, plen) = atoi(data);
+		plen += 4;
+		
+		WFIFOW(fd, 14) += 1;
+		
+		if( plen > 60000 ) {
+			WFIFOW(fd, 2) = plen;
+			WFIFOSET(fd, plen);
+			
+			/* prepare follow up */
+			WFIFOHEAD(fd, 60000 + 300);
+			WFIFOW(fd, 0) = 0x3804;
+			/* 0x2 = length, set prior to being sent */
+			WFIFOL(fd, 4) = account_id;
+			WFIFOL(fd, 8) = char_id;
+			WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+			WFIFOB(fd, 13) = 0;/* is int type */
+			WFIFOW(fd, 14) = 0;/* count */
+			plen = 16;
+		}
 	}
-	reg->reg_num = i;
+	
+	/* mark as complete & go. */
+	WFIFOB(fd, 12) = type;
+	WFIFOW(fd, 2) = plen;
+	WFIFOSET(fd, plen);
+	
 	SQL->FreeResult(sql_handle);
 	return 1;
 }
 
-// Initialize
-int inter_accreg_sql_init(void)
-{
-	CREATE(accreg_pt, struct accreg, 1);
-	return 0;
-
-}
-
 /*==========================================
  * read config file
  *------------------------------------------*/
@@ -833,7 +930,6 @@ int inter_init_sql(const char *file)
 	inter_homunculus_sql_init();
 	inter_mercenary_sql_init();
 	inter_elemental_sql_init();
-	inter_accreg_sql_init();
 	inter_mail_sql_init();
 	inter_auction_sql_init();
 
@@ -857,8 +953,6 @@ void inter_final(void)
 	inter_mail_sql_final();
 	inter_auction_sql_final();
 
-	if (accreg_pt) aFree(accreg_pt);
-
 	do_final_msg();
 	return;
 }
@@ -921,36 +1015,15 @@ int mapif_wis_end(struct WisData *wd, int flag)
 }
 
 // Account registry transfer to map-server
-static void mapif_account_reg(int fd, unsigned char *src)
-{
-	WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO
-	mapif_sendallwos(fd, src, WBUFW(src,2));
-}
+//static void mapif_account_reg(int fd, unsigned char *src)
+//{
+//	WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO
+//	mapif_sendallwos(fd, src, WBUFW(src,2));
+//}
 
 // Send the requested account_reg
-int mapif_account_reg_reply(int fd,int account_id,int char_id, int type)
-{
-	struct accreg *reg=accreg_pt;
-	WFIFOHEAD(fd, 13 + 5000);
-	inter_accreg_fromsql(account_id,char_id,reg,type);
-
-	WFIFOW(fd,0)=0x3804;
-	WFIFOL(fd,4)=account_id;
-	WFIFOL(fd,8)=char_id;
-	WFIFOB(fd,12)=type;
-	if(reg->reg_num==0){
-		WFIFOW(fd,2)=13;
-	}else{
-		int i,p;
-		for (p=13,i = 0; i < reg->reg_num && p < 5000; i++) {
-			p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].str)+1; //We add 1 to consider the '\0' in place.
-			p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].value)+1;
-		}
-		WFIFOW(fd,2)=p;
-		if (p>= 5000)
-			ShowWarning("Too many acc regs for %d:%d, not all values were loaded.\n", account_id, char_id);
-	}
-	WFIFOSET(fd,WFIFOW(fd,2));
+int mapif_account_reg_reply(int fd,int account_id,int char_id, int type) {
+	inter_accreg_fromsql(account_id,char_id,fd,type);
 	return 0;
 }
 
@@ -1128,34 +1201,50 @@ int mapif_parse_WisToGM(int fd)
 // Save account_reg into sql (type=2)
 int mapif_parse_Registry(int fd)
 {
-	int j,p,len, max;
-	struct accreg *reg=accreg_pt;
-
-	memset(accreg_pt,0,sizeof(struct accreg));
-	switch (RFIFOB(fd, 12)) {
-	case 3: //Character registry
-		max = GLOBAL_REG_NUM;
-	break;
-	case 2: //Account Registry
-		max = ACCOUNT_REG_NUM;
-	break;
-	case 1: //Account2 registry, must be sent over to login server.
-		return save_accreg2(RFIFOP(fd,4), RFIFOW(fd,2)-4);
-	default:
-		return 1;
-	}
-	for(j=0,p=13;j<max && p<RFIFOW(fd,2);j++){
-		sscanf((char*)RFIFOP(fd,p), "%31c%n",reg->reg[j].str,&len);
-		reg->reg[j].str[len]='\0';
-		p +=len+1; //+1 to skip the '\0' between strings.
-		sscanf((char*)RFIFOP(fd,p), "%255c%n",reg->reg[j].value,&len);
-		reg->reg[j].value[len]='\0';
-		p +=len+1;
-	}
-	reg->reg_num=j;
+	int account_id = RFIFOL(fd, 4), char_id = RFIFOL(fd, 8), count = RFIFOW(fd, 12);
+	
+	if( count ) {
+		int cursor = 14, i;
+		char key[32], sval[254];
+		unsigned int index;
+		
+		global_accreg_to_login_start(account_id,char_id);
+		
+		for(i = 0; i < count; i++) {
+			safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
+			cursor += RFIFOB(fd, cursor) + 1;
+
+			index = RFIFOL(fd, cursor);
+			cursor += 4;
+
+			switch (RFIFOB(fd, cursor++)) {
+				/* int */
+				case 0:
+					inter_savereg(account_id,char_id,key,index,RFIFOL(fd, cursor),false);
+					cursor += 4;
+					break;
+				case 1:
+					inter_savereg(account_id,char_id,key,index,0,false);
+					break;
+				/* str */
+				case 2:
+					safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
+					cursor += RFIFOB(fd, cursor) + 1;
+					inter_savereg(account_id,char_id,key,index,(intptr_t)sval,true);
+					break;
+				case 3:
+					inter_savereg(account_id,char_id,key,index,0,true);
+					break;
+					
+				default:
+					ShowError("mapif_parse_Registry: unknown type %d\n",RFIFOB(fd, cursor - 1));
+					return 1;
+			}
 
-	inter_accreg_tosql(RFIFOL(fd,4),RFIFOL(fd,8),reg, RFIFOB(fd,12));
-	mapif_account_reg(fd,RFIFOP(fd,0));	// Send updated accounts to other map servers.
+		}
+		
+		global_accreg_to_login_send();
+	}
 	return 0;
 }
 
diff --git a/src/common/db.c b/src/common/db.c
index efe7ca8b2..ddfb032d4 100644
--- a/src/common/db.c
+++ b/src/common/db.c
@@ -47,6 +47,7 @@
  *  - create a db that organizes itself by splaying
  *
  *  HISTORY:
+ *    2013/08/25 - Added int64/uint64 support for keys [Ind/Hercules]
  *    2013/04/27 - Added ERS to speed up iterator memory allocation [Ind/Hercules]
  *    2012/03/09 - Added enum for data types (int, uint, void*)
  *    2008/02/19 - Fixed db_obj_get not handling deleted entries correctly.
@@ -236,10 +237,14 @@ static struct db_stats {
 	uint32 db_uint_alloc;
 	uint32 db_string_alloc;
 	uint32 db_istring_alloc;
+	uint32 db_int64_alloc;
+	uint32 db_uint64_alloc;
 	uint32 db_int_destroy;
 	uint32 db_uint_destroy;
 	uint32 db_string_destroy;
 	uint32 db_istring_destroy;
+	uint32 db_int64_destroy;
+	uint32 db_uint64_destroy;
 	// Function usage counters
 	uint32 db_rotate_left;
 	uint32 db_rotate_right;
@@ -256,10 +261,14 @@ static struct db_stats {
 	uint32 db_uint_cmp;
 	uint32 db_string_cmp;
 	uint32 db_istring_cmp;
+	uint32 db_int64_cmp;
+	uint32 db_uint64_cmp;
 	uint32 db_int_hash;
 	uint32 db_uint_hash;
 	uint32 db_string_hash;
 	uint32 db_istring_hash;
+	uint32 db_int64_hash;
+	uint32 db_uint64_hash;
 	uint32 db_release_nothing;
 	uint32 db_release_key;
 	uint32 db_release_data;
@@ -298,6 +307,8 @@ static struct db_stats {
 	uint32 db_i2key;
 	uint32 db_ui2key;
 	uint32 db_str2key;
+	uint32 db_i642key;
+	uint32 db_ui642key;
 	uint32 db_i2data;
 	uint32 db_ui2data;
 	uint32 db_ptr2data;
@@ -830,10 +841,14 @@ static void db_free_unlock(DBMap_impl* db)
  *  db_uint_cmp        - Default comparator for DB_UINT databases.           *
  *  db_string_cmp      - Default comparator for DB_STRING databases.         *
  *  db_istring_cmp     - Default comparator for DB_ISTRING databases.        *
+ *  db_int64_cmp       - Default comparator for DB_INT64 databases.          *
+ *  db_uint64_cmp      - Default comparator for DB_UINT64 databases.         *
  *  db_int_hash        - Default hasher for DB_INT databases.                *
  *  db_uint_hash       - Default hasher for DB_UINT databases.               *
  *  db_string_hash     - Default hasher for DB_STRING databases.             *
  *  db_istring_hash    - Default hasher for DB_ISTRING databases.            *
+ *  db_int64_hash      - Default hasher for DB_INT64 databases.              *
+ *  db_uint64_hash     - Default hasher for DB_UINT64 databases.             *
  *  db_release_nothing - Releaser that releases nothing.                     *
  *  db_release_key     - Releaser that only releases the key.                *
  *  db_release_data    - Releaser that only releases the data.               *
@@ -920,6 +935,51 @@ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
 	return strncasecmp((const char *)key1.str, (const char *)key2.str, maxlen);
 }
 
+/**
+ * Default comparator for DB_INT64 databases.
+ * Compares key1 to key2.
+ * Return 0 if equal, negative if lower and positive if higher.
+ * <code>maxlen</code> is ignored.
+ * @param key1 Key to be compared
+ * @param key2 Key being compared to
+ * @param maxlen Maximum length of the key to hash
+ * @return 0 if equal, negative if lower and positive if higher
+ * @see DBType#DB_INT64
+ * @see #DBComparator
+ * @see #db_default_cmp(DBType)
+ */
+static int db_int64_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
+{
+	(void)maxlen;//not used
+	DB_COUNTSTAT(db_int64_cmp);
+	if (key1.i64 < key2.i64) return -1;
+	if (key1.i64 > key2.i64) return 1;
+	return 0;
+}
+
+/**
+ * Default comparator for DB_UINT64 databases.
+ * Compares key1 to key2.
+ * Return 0 if equal, negative if lower and positive if higher.
+ * <code>maxlen</code> is ignored.
+ * @param key1 Key to be compared
+ * @param key2 Key being compared to
+ * @param maxlen Maximum length of the key to hash
+ * @return 0 if equal, negative if lower and positive if higher
+ * @see DBType#DB_UINT64
+ * @see #DBComparator
+ * @see #db_default_cmp(DBType)
+ */
+static int db_uint64_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
+{
+	(void)maxlen;//not used
+	DB_COUNTSTAT(db_uint64_cmp);
+	if (key1.ui64 < key2.ui64) return -1;
+	if (key1.ui64 > key2.ui64) return 1;
+	return 0;
+}
+
+
 /**
  * Default hasher for DB_INT databases.
  * Returns the value of the key as an unsigned int.
@@ -931,11 +991,11 @@ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
  * @see #DBHasher
  * @see #db_default_hash(DBType)
  */
-static unsigned int db_int_hash(DBKey key, unsigned short maxlen)
+static uint64 db_int_hash(DBKey key, unsigned short maxlen)
 {
 	(void)maxlen;//not used
 	DB_COUNTSTAT(db_int_hash);
-	return (unsigned int)key.i;
+	return (uint64)key.i;
 }
 
 /**
@@ -949,11 +1009,11 @@ static unsigned int db_int_hash(DBKey key, unsigned short maxlen)
  * @see #DBHasher
  * @see #db_default_hash(DBType)
  */
-static unsigned int db_uint_hash(DBKey key, unsigned short maxlen)
+static uint64 db_uint_hash(DBKey key, unsigned short maxlen)
 {
 	(void)maxlen;//not used
 	DB_COUNTSTAT(db_uint_hash);
-	return key.ui;
+	return (uint64)key.ui;
 }
 
 /**
@@ -965,7 +1025,7 @@ static unsigned int db_uint_hash(DBKey key, unsigned short maxlen)
  * @see #DBHasher
  * @see #db_default_hash(DBType)
  */
-static unsigned int db_string_hash(DBKey key, unsigned short maxlen)
+static uint64 db_string_hash(DBKey key, unsigned short maxlen)
 {
 	const char *k = key.str;
 	unsigned int hash = 0;
@@ -980,7 +1040,7 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen)
 			break;
 	}
 
-	return hash;
+	return (uint64)hash;
 }
 
 /**
@@ -991,7 +1051,7 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen)
  * @see DBType#DB_ISTRING
  * @see #db_default_hash(DBType)
  */
-static unsigned int db_istring_hash(DBKey key, unsigned short maxlen)
+static uint64 db_istring_hash(DBKey key, unsigned short maxlen)
 {
 	const char *k = key.str;
 	unsigned int hash = 0;
@@ -1006,7 +1066,43 @@ static unsigned int db_istring_hash(DBKey key, unsigned short maxlen)
 			break;
 	}
 
-	return hash;
+	return (uint64)hash;
+}
+
+/**
+ * Default hasher for DB_INT64 databases.
+ * Returns the value of the key as an unsigned int.
+ * <code>maxlen</code> is ignored.
+ * @param key Key to be hashed
+ * @param maxlen Maximum length of the key to hash
+ * @return hash of the key
+ * @see DBType#DB_INT64
+ * @see #DBHasher
+ * @see #db_default_hash(DBType)
+ */
+static uint64 db_int64_hash(DBKey key, unsigned short maxlen)
+{
+	(void)maxlen;//not used
+	DB_COUNTSTAT(db_int64_hash);
+	return (uint64)key.i64;
+}
+
+/**
+ * Default hasher for DB_UINT64 databases.
+ * Just returns the value of the key.
+ * <code>maxlen</code> is ignored.
+ * @param key Key to be hashed
+ * @param maxlen Maximum length of the key to hash
+ * @return hash of the key
+ * @see DBType#DB_UINT64
+ * @see #DBHasher
+ * @see #db_default_hash(DBType)
+ */
+static uint64 db_uint64_hash(DBKey key, unsigned short maxlen)
+{
+	(void)maxlen;//not used
+	DB_COUNTSTAT(db_uint64_hash);
+	return key.ui64;
 }
 
 /**
@@ -2122,6 +2218,8 @@ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args)
 		case DB_UINT: DB_COUNTSTAT(db_uint_destroy); break;
 		case DB_STRING: DB_COUNTSTAT(db_string_destroy); break;
 		case DB_ISTRING: DB_COUNTSTAT(db_istring_destroy); break;
+		case DB_INT64: DB_COUNTSTAT(db_int64_destroy); break;
+		case DB_UINT64: DB_COUNTSTAT(db_uint64_destroy); break;
 	}
 #endif /* DB_ENABLE_STATS */
 	db_free_lock(db);
@@ -2246,6 +2344,8 @@ static DBOptions db_obj_options(DBMap* self)
  *  db_i2key           - Manual cast from 'int' to 'DBKey'.
  *  db_ui2key          - Manual cast from 'unsigned int' to 'DBKey'.
  *  db_str2key         - Manual cast from 'unsigned char *' to 'DBKey'.
+ *  db_i642key         - Manual cast from 'int64' to 'DBKey'.
+ *  db_ui642key        - Manual cast from 'uin64' to 'DBKey'.
  *  db_i2data          - Manual cast from 'int' to 'DBData'.
  *  db_ui2data         - Manual cast from 'unsigned int' to 'DBData'.
  *  db_ptr2data        - Manual cast from 'void*' to 'DBData'.
@@ -2272,7 +2372,9 @@ DBOptions db_fix_options(DBType type, DBOptions options)
 	DB_COUNTSTAT(db_fix_options);
 	switch (type) {
 		case DB_INT:
-		case DB_UINT: // Numeric database, do nothing with the keys
+		case DB_UINT:
+		case DB_INT64:
+		case DB_UINT64: // Numeric database, do nothing with the keys
 			return (DBOptions)(options&~(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY));
 
 		default:
@@ -2292,6 +2394,8 @@ DBOptions db_fix_options(DBType type, DBOptions options)
  * @see #db_uint_cmp(DBKey,DBKey,unsigned short)
  * @see #db_string_cmp(DBKey,DBKey,unsigned short)
  * @see #db_istring_cmp(DBKey,DBKey,unsigned short)
+ * @see #db_int64_cmp(DBKey,DBKey,unsigned short)
+ * @see #db_uint64_cmp(DBKey,DBKey,unsigned short)
  */
 DBComparator db_default_cmp(DBType type)
 {
@@ -2301,6 +2405,8 @@ DBComparator db_default_cmp(DBType type)
 		case DB_UINT:    return &db_uint_cmp;
 		case DB_STRING:  return &db_string_cmp;
 		case DB_ISTRING: return &db_istring_cmp;
+		case DB_INT64:   return &db_int64_cmp;
+		case DB_UINT64:  return &db_uint64_cmp;
 		default:
 			ShowError("db_default_cmp: Unknown database type %u\n", type);
 			return NULL;
@@ -2316,6 +2422,8 @@ DBComparator db_default_cmp(DBType type)
  * @see #db_uint_hash(DBKey,unsigned short)
  * @see #db_string_hash(DBKey,unsigned short)
  * @see #db_istring_hash(DBKey,unsigned short)
+ * @see #db_int64_hash(DBKey,unsigned short)
+ * @see #db_uint64_hash(DBKey,unsigned short)
  */
 DBHasher db_default_hash(DBType type)
 {
@@ -2325,6 +2433,8 @@ DBHasher db_default_hash(DBType type)
 		case DB_UINT:    return &db_uint_hash;
 		case DB_STRING:  return &db_string_hash;
 		case DB_ISTRING: return &db_istring_hash;
+		case DB_INT64:   return &db_int64_hash;
+		case DB_UINT64:  return &db_uint64_hash;
 		default:
 			ShowError("db_default_hash: Unknown database type %u\n", type);
 			return NULL;
@@ -2412,6 +2522,8 @@ DBMap* db_alloc(const char *file, const char *func, int line, DBType type, DBOpt
 		case DB_UINT: DB_COUNTSTAT(db_uint_alloc); break;
 		case DB_STRING: DB_COUNTSTAT(db_string_alloc); break;
 		case DB_ISTRING: DB_COUNTSTAT(db_istring_alloc); break;
+		case DB_INT64: DB_COUNTSTAT(db_int64_alloc); break;
+		case DB_UINT64: DB_COUNTSTAT(db_uint64_alloc); break;
 	}
 #endif /* DB_ENABLE_STATS */
 	db = ers_alloc(db_alloc_ers, struct DBMap_impl);
@@ -2510,6 +2622,36 @@ DBKey db_str2key(const char *key)
 	return ret;
 }
 
+/**
+ * Manual cast from 'int64' to the union DBKey.
+ * @param key Key to be casted
+ * @return The key as a DBKey union
+ * @public
+ */
+DBKey db_i642key(int64 key)
+{
+	DBKey ret;
+	
+	DB_COUNTSTAT(db_i642key);
+	ret.i64 = key;
+	return ret;
+}
+
+/**
+ * Manual cast from 'uin64' to the union DBKey.
+ * @param key Key to be casted
+ * @return The key as a DBKey union
+ * @public
+ */
+DBKey db_ui642key(uint64 key)
+{
+	DBKey ret;
+	
+	DB_COUNTSTAT(db_ui642key);
+	ret.ui64 = key;
+	return ret;
+}
+
 /**
  * Manual cast from 'int' to the struct DBData.
  * @param data Data to be casted
@@ -2632,10 +2774,14 @@ void db_final(void)
 			"DB_UINT    : allocated %10u, destroyed %10u\n"
 			"DB_STRING  : allocated %10u, destroyed %10u\n"
 			"DB_ISTRING : allocated %10u, destroyed %10u\n",
+			"DB_INT64   : allocated %10u, destroyed %10u\n"
+			"DB_UINT64  : allocated %10u, destroyed %10u\n"
 			stats.db_int_alloc,     stats.db_int_destroy,
 			stats.db_uint_alloc,    stats.db_uint_destroy,
 			stats.db_string_alloc,  stats.db_string_destroy,
-			stats.db_istring_alloc, stats.db_istring_destroy);
+			stats.db_istring_alloc, stats.db_istring_destroy,
+			stats.db_int64_alloc,   stats.db_int64_destroy,
+			stats.db_uint64_alloc,  stats.db_uint64_destroy,);
 	ShowInfo(CL_WHITE"Database function counters"CL_RESET":\n"
 			"db_rotate_left     %10u, db_rotate_right    %10u,\n"
 			"db_rebalance       %10u, db_rebalance_erase %10u,\n"
@@ -2645,8 +2791,10 @@ void db_final(void)
 			"db_free_lock       %10u, db_free_unlock     %10u,\n"
 			"db_int_cmp         %10u, db_uint_cmp        %10u,\n"
 			"db_string_cmp      %10u, db_istring_cmp     %10u,\n"
+			"db_int64_cmp       %10u, db_uint64_cmp      %10u,\n"
 			"db_int_hash        %10u, db_uint_hash       %10u,\n"
 			"db_string_hash     %10u, db_istring_hash    %10u,\n"
+			"db_int64_hash      %10u, db_uint64_hash     %10u,\n"
 			"db_release_nothing %10u, db_release_key     %10u,\n"
 			"db_release_data    %10u, db_release_both    %10u,\n"
 			"dbit_first         %10u, dbit_last          %10u,\n"
@@ -2666,6 +2814,7 @@ void db_final(void)
 			"db_default_release %10u, db_custom_release  %10u,\n"
 			"db_alloc           %10u, db_i2key           %10u,\n"
 			"db_ui2key          %10u, db_str2key         %10u,\n"
+			"db_i642key         %10u, db_ui642key        %10u,\n"
 			"db_i2data          %10u, db_ui2data         %10u,\n"
 			"db_ptr2data        %10u, db_data2i          %10u,\n"
 			"db_data2ui         %10u, db_data2ptr        %10u,\n"
@@ -2678,8 +2827,10 @@ void db_final(void)
 			stats.db_free_lock,       stats.db_free_unlock,
 			stats.db_int_cmp,         stats.db_uint_cmp,
 			stats.db_string_cmp,      stats.db_istring_cmp,
+			stats.db_int64_cmp,       stats.db_uint64_cmp,
 			stats.db_int_hash,        stats.db_uint_hash,
 			stats.db_string_hash,     stats.db_istring_hash,
+			stats.db_int64_hash,      stats.db_uint64_hash,
 			stats.db_release_nothing, stats.db_release_key,
 			stats.db_release_data,    stats.db_release_both,
 			stats.dbit_first,         stats.dbit_last,
@@ -2699,6 +2850,7 @@ void db_final(void)
 			stats.db_default_release, stats.db_custom_release,
 			stats.db_alloc,           stats.db_i2key,
 			stats.db_ui2key,          stats.db_str2key,
+			stats.db_i642key,         stats.db_ui642key,
 			stats.db_i2data,          stats.db_ui2data,
 			stats.db_ptr2data,        stats.db_data2i,
 			stats.db_data2ui,         stats.db_data2ptr,
@@ -2855,4 +3007,7 @@ void db_defaults(void) {
 	DB->str2key = db_str2key;
 	DB->ui2data = db_ui2data;
 	DB->ui2key = db_ui2key;
+	DB->i642key = db_i642key;
+	DB->ui642key = db_ui642key;
+
 }
diff --git a/src/common/db.h b/src/common/db.h
index 5f4478909..9d7bdda10 100644
--- a/src/common/db.h
+++ b/src/common/db.h
@@ -20,6 +20,7 @@
  *  - see what functions need or should be added to the database interface   *
  *                                                                           *
  *  HISTORY:                                                                 *
+ *    2013/08/25 - Added int64/uint64 support for keys                       *
  *    2012/03/09 - Added enum for data types (int, uint, void*)              *
  *    2007/11/09 - Added an iterator to the database.                        *
  *    2.1 (Athena build #???#) - Portability fix                             *
@@ -83,6 +84,8 @@ typedef enum DBRelease {
  * @param DB_UINT Uses unsigned int's for keys
  * @param DB_STRING Uses strings for keys.
  * @param DB_ISTRING Uses case insensitive strings for keys.
+ * @param DB_INT64 Uses int64's for keys
+ * @param DB_UINT64 Uses uint64's for keys
  * @public
  * @see #DBOptions
  * @see #DBKey
@@ -96,7 +99,9 @@ typedef enum DBType {
 	DB_INT,
 	DB_UINT,
 	DB_STRING,
-	DB_ISTRING
+	DB_ISTRING,
+	DB_INT64,
+	DB_UINT64,
 } DBType;
 
 /**
@@ -145,6 +150,8 @@ typedef union DBKey {
 	int i;
 	unsigned int ui;
 	const char *str;
+	int64 i64;
+	uint64 ui64;
 } DBKey;
 
 /**
@@ -158,7 +165,7 @@ typedef union DBKey {
 typedef enum DBDataType {
 	DB_DATA_INT,
 	DB_DATA_UINT,
-	DB_DATA_PTR
+	DB_DATA_PTR,
 } DBDataType;
 
 /**
@@ -245,7 +252,7 @@ typedef int (*DBComparator)(DBKey key1, DBKey key2, unsigned short maxlen);
  * @public
  * @see #db_default_hash(DBType)
  */
-typedef unsigned int (*DBHasher)(DBKey key, unsigned short maxlen);
+typedef uint64 (*DBHasher)(DBKey key, unsigned short maxlen);
 
 /**
  * Format of the releaser used by the database system.
@@ -598,65 +605,86 @@ struct DBMap {
 
 // For easy access to the common functions.
 
-#define db_exists(db,k)    ( (db)->exists((db),(k)) )
-#define idb_exists(db,k)   ( (db)->exists((db),DB->i2key(k)) )
-#define uidb_exists(db,k)  ( (db)->exists((db),DB->ui2key(k)) )
-#define strdb_exists(db,k) ( (db)->exists((db),DB->str2key(k)) )
+#define db_exists(db,k)     ( (db)->exists((db),(k)) )
+#define idb_exists(db,k)    ( (db)->exists((db),DB->i2key(k)) )
+#define uidb_exists(db,k)   ( (db)->exists((db),DB->ui2key(k)) )
+#define strdb_exists(db,k)  ( (db)->exists((db),DB->str2key(k)) )
+#define i64db_exists(db,k)  ( (db)->exists((db),DB->i642key(k)) )
+#define ui64db_exists(db,k) ( (db)->exists((db),DB->ui642key(k)) )
 
 // Get pointer-type data from DBMaps of various key types
-#define db_get(db,k)    ( DB->data2ptr((db)->get((db),(k))) )
-#define idb_get(db,k)   ( DB->data2ptr((db)->get((db),DB->i2key(k))) )
-#define uidb_get(db,k)  ( DB->data2ptr((db)->get((db),DB->ui2key(k))) )
-#define strdb_get(db,k) ( DB->data2ptr((db)->get((db),DB->str2key(k))) )
+#define db_get(db,k)     ( DB->data2ptr((db)->get((db),(k))) )
+#define idb_get(db,k)    ( DB->data2ptr((db)->get((db),DB->i2key(k))) )
+#define uidb_get(db,k)   ( DB->data2ptr((db)->get((db),DB->ui2key(k))) )
+#define strdb_get(db,k)  ( DB->data2ptr((db)->get((db),DB->str2key(k))) )
+#define i64db_get(db,k)  ( DB->data2ptr((db)->get((db),DB->i642key(k))) )
+#define ui64db_get(db,k) ( DB->data2ptr((db)->get((db),DB->ui642key(k))) )
+
 
 // Get int-type data from DBMaps of various key types
-#define db_iget(db,k)    ( DB->data2i((db)->get((db),(k))) )
-#define idb_iget(db,k)   ( DB->data2i((db)->get((db),DB->i2key(k))) )
-#define uidb_iget(db,k)  ( DB->data2i((db)->get((db),DB->ui2key(k))) )
-#define strdb_iget(db,k) ( DB->data2i((db)->get((db),DB->str2key(k))) )
+#define db_iget(db,k)     ( DB->data2i((db)->get((db),(k))) )
+#define idb_iget(db,k)    ( DB->data2i((db)->get((db),DB->i2key(k))) )
+#define uidb_iget(db,k)   ( DB->data2i((db)->get((db),DB->ui2key(k))) )
+#define strdb_iget(db,k)  ( DB->data2i((db)->get((db),DB->str2key(k))) )
+#define i64db_iget(db,k)  ( DB->data2i((db)->get((db),DB->i642key(k))) )
+#define ui64db_iget(db,k) ( DB->data2i((db)->get((db),DB->ui642key(k))) )
 
 // Get uint-type data from DBMaps of various key types
-#define db_uiget(db,k)    ( DB->data2ui((db)->get((db),(k))) )
-#define idb_uiget(db,k)   ( DB->data2ui((db)->get((db),DB->i2key(k))) )
-#define uidb_uiget(db,k)  ( DB->data2ui((db)->get((db),DB->ui2key(k))) )
-#define strdb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->str2key(k))) )
+#define db_uiget(db,k)     ( DB->data2ui((db)->get((db),(k))) )
+#define idb_uiget(db,k)    ( DB->data2ui((db)->get((db),DB->i2key(k))) )
+#define uidb_uiget(db,k)   ( DB->data2ui((db)->get((db),DB->ui2key(k))) )
+#define strdb_uiget(db,k)  ( DB->data2ui((db)->get((db),DB->str2key(k))) )
+#define i64db_uiget(db,k)  ( DB->data2ui((db)->get((db),DB->i642key(k))) )
+#define ui64db_uiget(db,k) ( DB->data2ui((db)->get((db),DB->ui642key(k))) )
 
 // Put pointer-type data into DBMaps of various key types
-#define db_put(db,k,d)    ( (db)->put((db),(k),DB->ptr2data(d),NULL) )
-#define idb_put(db,k,d)   ( (db)->put((db),DB->i2key(k),DB->ptr2data(d),NULL) )
-#define uidb_put(db,k,d)  ( (db)->put((db),DB->ui2key(k),DB->ptr2data(d),NULL) )
-#define strdb_put(db,k,d) ( (db)->put((db),DB->str2key(k),DB->ptr2data(d),NULL) )
+#define db_put(db,k,d)     ( (db)->put((db),(k),DB->ptr2data(d),NULL) )
+#define idb_put(db,k,d)    ( (db)->put((db),DB->i2key(k),DB->ptr2data(d),NULL) )
+#define uidb_put(db,k,d)   ( (db)->put((db),DB->ui2key(k),DB->ptr2data(d),NULL) )
+#define strdb_put(db,k,d)  ( (db)->put((db),DB->str2key(k),DB->ptr2data(d),NULL) )
+#define i64db_put(db,k,d)  ( (db)->put((db),DB->i642key(k),DB->ptr2data(d),NULL) )
+#define ui64db_put(db,k,d) ( (db)->put((db),DB->ui642key(k),DB->ptr2data(d),NULL) )
 
 // Put int-type data into DBMaps of various key types
-#define db_iput(db,k,d)    ( (db)->put((db),(k),DB->i2data(d),NULL) )
-#define idb_iput(db,k,d)   ( (db)->put((db),DB->i2key(k),DB->i2data(d),NULL) )
-#define uidb_iput(db,k,d)  ( (db)->put((db),DB->ui2key(k),DB->i2data(d),NULL) )
-#define strdb_iput(db,k,d) ( (db)->put((db),DB->str2key(k),DB->i2data(d),NULL) )
+#define db_iput(db,k,d)     ( (db)->put((db),(k),DB->i2data(d),NULL) )
+#define idb_iput(db,k,d)    ( (db)->put((db),DB->i2key(k),DB->i2data(d),NULL) )
+#define uidb_iput(db,k,d)   ( (db)->put((db),DB->ui2key(k),DB->i2data(d),NULL) )
+#define strdb_iput(db,k,d)  ( (db)->put((db),DB->str2key(k),DB->i2data(d),NULL) )
+#define i64db_iput(db,k,d)  ( (db)->put((db),DB->i642key(k),DB->i2data(d),NULL) )
+#define ui64db_iput(db,k,d) ( (db)->put((db),DB->ui642key(k),DB->i2data(d),NULL) )
 
 // Put uint-type data into DBMaps of various key types
-#define db_uiput(db,k,d)    ( (db)->put((db),(k),DB->ui2data(d),NULL) )
-#define idb_uiput(db,k,d)   ( (db)->put((db),DB->i2key(k),DB->ui2data(d),NULL) )
-#define uidb_uiput(db,k,d)  ( (db)->put((db),DB->ui2key(k),DB->ui2data(d),NULL) )
-#define strdb_uiput(db,k,d) ( (db)->put((db),DB->str2key(k),DB->ui2data(d),NULL) )
+#define db_uiput(db,k,d)     ( (db)->put((db),(k),DB->ui2data(d),NULL) )
+#define idb_uiput(db,k,d)    ( (db)->put((db),DB->i2key(k),DB->ui2data(d),NULL) )
+#define uidb_uiput(db,k,d)   ( (db)->put((db),DB->ui2key(k),DB->ui2data(d),NULL) )
+#define strdb_uiput(db,k,d)  ( (db)->put((db),DB->str2key(k),DB->ui2data(d),NULL) )
+#define i64db_uiput(db,k,d)  ( (db)->put((db),DB->i642key(k),DB->ui2data(d),NULL) )
+#define ui64db_uiput(db,k,d) ( (db)->put((db),DB->ui642key(k),DB->ui2data(d),NULL) )
 
 // Remove entry from DBMaps of various key types
-#define db_remove(db,k)    ( (db)->remove((db),(k),NULL) )
-#define idb_remove(db,k)   ( (db)->remove((db),DB->i2key(k),NULL) )
-#define uidb_remove(db,k)  ( (db)->remove((db),DB->ui2key(k),NULL) )
-#define strdb_remove(db,k) ( (db)->remove((db),DB->str2key(k),NULL) )
+#define db_remove(db,k)     ( (db)->remove((db),(k),NULL) )
+#define idb_remove(db,k)    ( (db)->remove((db),DB->i2key(k),NULL) )
+#define uidb_remove(db,k)   ( (db)->remove((db),DB->ui2key(k),NULL) )
+#define strdb_remove(db,k)  ( (db)->remove((db),DB->str2key(k),NULL) )
+#define i64db_remove(db,k)  ( (db)->remove((db),DB->i642key(k),NULL) )
+#define ui64db_remove(db,k) ( (db)->remove((db),DB->ui642key(k),NULL) )
 
 //These are discarding the possible vargs you could send to the function, so those
 //that require vargs must not use these defines.
-#define db_ensure(db,k,f)    ( DB->data2ptr((db)->ensure((db),(k),(f))) )
-#define idb_ensure(db,k,f)   ( DB->data2ptr((db)->ensure((db),DB->i2key(k),(f))) )
-#define uidb_ensure(db,k,f)  ( DB->data2ptr((db)->ensure((db),DB->ui2key(k),(f))) )
-#define strdb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->str2key(k),(f))) )
+#define db_ensure(db,k,f)     ( DB->data2ptr((db)->ensure((db),(k),(f))) )
+#define idb_ensure(db,k,f)    ( DB->data2ptr((db)->ensure((db),DB->i2key(k),(f))) )
+#define uidb_ensure(db,k,f)   ( DB->data2ptr((db)->ensure((db),DB->ui2key(k),(f))) )
+#define strdb_ensure(db,k,f)  ( DB->data2ptr((db)->ensure((db),DB->str2key(k),(f))) )
+#define i64db_ensure(db,k,f)  ( DB->data2ptr((db)->ensure((db),DB->i642key(k),(f))) )
+#define ui64db_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->ui642key(k),(f))) )
 
 // Database creation and destruction macros
 #define idb_alloc(opt)            DB->alloc(__FILE__,__func__,__LINE__,DB_INT,(opt),sizeof(int))
 #define uidb_alloc(opt)           DB->alloc(__FILE__,__func__,__LINE__,DB_UINT,(opt),sizeof(unsigned int))
 #define strdb_alloc(opt,maxlen)   DB->alloc(__FILE__,__func__,__LINE__,DB_STRING,(opt),(maxlen))
 #define stridb_alloc(opt,maxlen)  DB->alloc(__FILE__,__func__,__LINE__,DB_ISTRING,(opt),(maxlen))
+#define i64db_alloc(opt)          DB->alloc(__FILE__,__func__,__LINE__,DB_INT64,(opt),sizeof(int64))
+#define ui64db_alloc(opt)         DB->alloc(__FILE__,__func__,__LINE__,DB_UINT64,(opt),sizeof(uint64))
 #define db_destroy(db)            ( (db)->destroy((db),NULL) )
 // Other macros
 #define db_clear(db)        ( (db)->clear((db),NULL) )
@@ -682,6 +710,8 @@ struct DBMap {
  *  db_i2key           - Manual cast from 'int' to 'DBKey'.                  *
  *  db_ui2key          - Manual cast from 'unsigned int' to 'DBKey'.         *
  *  db_str2key         - Manual cast from 'unsigned char *' to 'DBKey'.      *
+ *  db_i642key         - Manual cast from 'int64' to 'DBKey'.                *
+ *  db_ui642key        - Manual cast from 'uint64' to 'DBKey'.               *
  *  db_i2data          - Manual cast from 'int' to 'DBData'.                 *
  *  db_ui2data         - Manual cast from 'unsigned int' to 'DBData'.        *
  *  db_ptr2data        - Manual cast from 'void*' to 'DBData'.               *
@@ -802,6 +832,22 @@ DBKey (*ui2key) (unsigned int key);
  */
 DBKey (*str2key) (const char *key);
 
+/**
+ * Manual cast from 'int64' to the union DBKey.
+ * @param key Key to be casted
+ * @return The key as a DBKey union
+ * @public
+ */
+DBKey (*i642key) (int64 key);
+
+/**
+ * Manual cast from 'uint64' to the union DBKey.
+ * @param key Key to be casted
+ * @return The key as a DBKey union
+ * @public
+ */
+DBKey (*ui642key) (uint64 key);
+	
 /**
  * Manual cast from 'int' to the struct DBData.
  * @param data Data to be casted
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 273edc42b..594d1cb26 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -101,11 +101,6 @@
 //Update this max as necessary. 55 is the value needed for Super Baby currently
 //Raised to 84 since Expanded Super Novice needs it.
 #define MAX_SKILL_TREE 84
-#define GLOBAL_REG_NUM 256   // Max permanent character variables per char
-#define ACCOUNT_REG_NUM 64   // Max permanent local account variables per account
-#define ACCOUNT_REG2_NUM 16  // Max permanent global account variables per account
-//Should hold the max of GLOBAL/ACCOUNT/ACCOUNT2 (needed for some arrays that hold all three)
-#define MAX_REG_NUM 256
 #define DEFAULT_WALK_SPEED 150
 #define MIN_WALK_SPEED 20 /* below 20 clips animation */
 #define MAX_WALK_SPEED 1000
@@ -269,16 +264,19 @@ struct s_skill {
 	unsigned char flag; // See enum e_skill_flag
 };
 
-struct global_reg {
-	char str[32];
-	char value[256];
+struct script_reg_state {
+	unsigned int type   : 1;/* because I'm a memory hoarder and having them in the same struct would be a 8-byte/instance waste while ints outnumber str on a 10000-to-1 ratio. */
+	unsigned int update : 1;/* whether it needs to be sent to char server for insertion/update/delete */
 };
 
-// Holds array of global registries, used by the char server and converter.
-struct accreg {
-	int account_id, char_id;
-	int reg_num;
-	struct global_reg reg[MAX_REG_NUM];
+struct script_reg_num {
+	struct script_reg_state flag;
+	int value;
+};
+
+struct script_reg_str {
+	struct script_reg_state flag;
+	char *value;
 };
 
 // For saving status changes across sessions. [Skotlex]
@@ -483,15 +481,6 @@ struct auction_data {
 	int auction_end_timer;
 };
 
-struct registry {
-	int global_num;
-	struct global_reg global[GLOBAL_REG_NUM];
-	int account_num;
-	struct global_reg account[ACCOUNT_REG_NUM];
-	int account2_num;
-	struct global_reg account2[ACCOUNT_REG2_NUM];
-};
-
 struct party_member {
 	int account_id;
 	int char_id;
@@ -866,6 +855,14 @@ enum e_char_server_type {
 	CST_F2P         = 4,
 };
 
+enum e_pc_reg_loading {
+	PRL_NONE = 0x0,
+	PRL_CHAR = 0x1,
+	PRL_ACCL = 0x2,/* local */
+	PRL_ACCG = 0x4,/* global */
+	PRL_ALL  = 0xFF,
+};
+
 /* packet size constant for itemlist */
 #if MAX_INVENTORY > MAX_STORAGE && MAX_INVENTORY > MAX_CART
 #define MAX_ITEMLIST MAX_INVENTORY
diff --git a/src/common/socket.c b/src/common/socket.c
index 9c6938008..1ffa15708 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -1464,8 +1464,6 @@ void socket_datasync(int fd, bool send) {
 		{ sizeof(struct item) },
 		{ sizeof(struct point) },
 		{ sizeof(struct s_skill) },
-		{ sizeof(struct global_reg) },
-		{ sizeof(struct accreg) },
 		{ sizeof(struct status_change_data) },
 		{ sizeof(struct storage_data) },
 		{ sizeof(struct guild_storage) },
@@ -1476,7 +1474,6 @@ void socket_datasync(int fd, bool send) {
 		{ sizeof(struct s_friend) },
 		{ sizeof(struct mail_message) },
 		{ sizeof(struct mail_data) },
-		{ sizeof(struct registry) },
 		{ sizeof(struct party_member) },
 		{ sizeof(struct party) },
 		{ sizeof(struct guild_member) },
@@ -1487,6 +1484,7 @@ void socket_datasync(int fd, bool send) {
 		{ sizeof(struct guild) },
 		{ sizeof(struct guild_castle) },
 		{ sizeof(struct fame_list) },
+		{ PACKETVER },
 	};
 	unsigned short i;
 	unsigned int alen = ARRAYLENGTH(data_list);
diff --git a/src/login/account.h b/src/login/account.h
index f55e38b0c..74a9e9626 100644
--- a/src/login/account.h
+++ b/src/login/account.h
@@ -1,5 +1,6 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Portions Copyright (c) Athena Dev Teams
 
 #ifndef __ACCOUNT_H_INCLUDED__
 #define __ACCOUNT_H_INCLUDED__
@@ -32,8 +33,6 @@ struct mmo_account
 	char lastlogin[24];         // date+time of last successful login
 	char last_ip[16];           // save of last IP of connection
 	char birthdate[10+1];       // assigned birth date (format: YYYY-MM-DD, default: 0000-00-00)
-	int account_reg2_num;
-	struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
 };
 
 
@@ -137,4 +136,7 @@ struct AccountDB
 
 Sql *account_db_sql_up(AccountDB* self);
 
+void mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id);
+void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id);
+
 #endif // __ACCOUNT_H_INCLUDED__
diff --git a/src/login/account_sql.c b/src/login/account_sql.c
index 283eb3a0d..1483196ab 100644
--- a/src/login/account_sql.c
+++ b/src/login/account_sql.c
@@ -9,6 +9,7 @@
 #include "../common/strlib.h"
 #include "../common/timer.h"
 #include "../common/console.h"
+#include "../common/socket.h"
 #include "account.h"
 #include <stdlib.h>
 #include <string.h>
@@ -40,7 +41,9 @@ typedef struct AccountDB_SQL
 	// other settings
 	bool case_sensitive;
 	char account_db[32];
-	char accreg_db[32];
+	char global_acc_reg_num_db[32];
+	char global_acc_reg_str_db[32];
+
 
 } AccountDB_SQL;
 
@@ -106,7 +109,8 @@ AccountDB* account_db_sql(void)
 	// other settings
 	db->case_sensitive = false;
 	safestrncpy(db->account_db, "login", sizeof(db->account_db));
-	safestrncpy(db->accreg_db, "global_reg_value", sizeof(db->accreg_db));
+	safestrncpy(db->global_acc_reg_num_db, "global_acc_reg_num_db", sizeof(db->global_acc_reg_num_db));
+	safestrncpy(db->global_acc_reg_str_db, "global_acc_reg_str_db", sizeof(db->global_acc_reg_str_db));
 
 	return &db->vtable;
 }
@@ -250,8 +254,11 @@ static bool account_db_sql_get_property(AccountDB* self, const char* key, char*
 		if( strcmpi(key, "account_db") == 0 )
 			safesnprintf(buf, buflen, "%s", db->account_db);
 		else
-		if( strcmpi(key, "accreg_db") == 0 )
-			safesnprintf(buf, buflen, "%s", db->accreg_db);
+		if( strcmpi(key, "global_acc_reg_str_db") == 0 )
+			safesnprintf(buf, buflen, "%s", db->global_acc_reg_str_db);
+		else
+		if( strcmpi(key, "global_acc_reg_num_db") == 0 )
+			safesnprintf(buf, buflen, "%s", db->global_acc_reg_num_db);
 		else
 			return false;// not found
 		return true;
@@ -321,8 +328,11 @@ static bool account_db_sql_set_property(AccountDB* self, const char* key, const
 		if( strcmpi(key, "account_db") == 0 )
 			safestrncpy(db->account_db, value, sizeof(db->account_db));
 		else
-		if( strcmpi(key, "accreg_db") == 0 )
-			safestrncpy(db->accreg_db, value, sizeof(db->accreg_db));
+		if( strcmpi(key, "global_acc_reg_str_db") == 0 )
+			safestrncpy(db->global_acc_reg_str_db, value, sizeof(db->global_acc_reg_str_db));
+		else
+		if( strcmpi(key, "global_acc_reg_num_db") == 0 )
+			safestrncpy(db->global_acc_reg_num_db, value, sizeof(db->global_acc_reg_num_db));
 		else
 			return false;// not found
 		return true;
@@ -393,7 +403,9 @@ static bool account_db_sql_remove(AccountDB* self, const int account_id)
 
 	if( SQL_SUCCESS != SQL->QueryStr(sql_handle, "START TRANSACTION")
 	||  SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->account_db, account_id)
-	||  SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->accreg_db, account_id) )
+	||  SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->global_acc_reg_num_db, account_id)
+	||  SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->global_acc_reg_str_db, account_id)
+	)
 		Sql_ShowDebug(sql_handle);
 	else
 		result = true;
@@ -520,7 +532,6 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
 {
 	Sql* sql_handle = db->accounts;
 	char* data;
-	int i = 0;
 
 	// retrieve login entry for the specified account
 	if( SQL_ERROR == SQL->Query(sql_handle,
@@ -556,27 +567,6 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
 	
 	SQL->FreeResult(sql_handle);
 
-
-	// retrieve account regs for the specified user
-	if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`,`value` FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) )
-	{
-		Sql_ShowDebug(sql_handle);
-		return false;
-	}
-
-	acc->account_reg2_num = (int)SQL->NumRows(sql_handle);
-
-	while( SQL_SUCCESS == SQL->NextRow(sql_handle) )
-	{
-		SQL->GetData(sql_handle, 0, &data, NULL); safestrncpy(acc->account_reg2[i].str, data, sizeof(acc->account_reg2[i].str));
-		SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(acc->account_reg2[i].value, data, sizeof(acc->account_reg2[i].value));
-		++i;
-	}
-	SQL->FreeResult(sql_handle);
-
-	if( i != acc->account_reg2_num )
-		return false;
-
 	return true;
 }
 
@@ -585,7 +575,6 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
 	Sql* sql_handle = db->accounts;
 	SqlStmt* stmt = SQL->StmtMalloc(sql_handle);
 	bool result = false;
-	int i;
 
 	// try
 	do
@@ -647,34 +636,6 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
 		}
 	}
 
-	// remove old account regs
-	if( SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) )
-	{
-		Sql_ShowDebug(sql_handle);
-		break;
-	}
-	// insert new account regs
-	if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "INSERT INTO `%s` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , ? , ? );",  db->accreg_db, acc->account_id) )
-	{
-		SqlStmt_ShowDebug(stmt);
-		break;
-	}
-	for( i = 0; i < acc->account_reg2_num; ++i )
-	{
-		if( SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, (void*)acc->account_reg2[i].str, strlen(acc->account_reg2[i].str))
-		||  SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, (void*)acc->account_reg2[i].value, strlen(acc->account_reg2[i].value))
-		||  SQL_SUCCESS != SQL->StmtExecute(stmt)
-		) {
-			SqlStmt_ShowDebug(stmt);
-			break;
-		}
-	}
-	if( i < acc->account_reg2_num )
-	{
-		result = false;
-		break;
-	}
-
 	// if we got this far, everything was successful
 	result = true;
 
@@ -686,6 +647,7 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
 
 	return result;
 }
+
 Sql* account_db_sql_up(AccountDB* self) {
 	AccountDB_SQL* db = (AccountDB_SQL*)self;
 	Sql_HerculesUpdateCheck(db->accounts);
@@ -694,3 +656,196 @@ Sql* account_db_sql_up(AccountDB* self) {
 #endif
 	return db->accounts;
 }
+void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id) {
+	Sql* sql_handle = ((AccountDB_SQL*)self)->accounts;
+	AccountDB_SQL* db = (AccountDB_SQL*)self;
+	int count = RFIFOW(fd, 12);
+	
+	if( count ) {
+		int cursor = 14, i;
+		char key[32], sval[254];
+		unsigned int index;
+				
+		for(i = 0; i < count; i++) {
+			safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
+			cursor += RFIFOB(fd, cursor) + 1;
+			
+			index = RFIFOL(fd, cursor);
+			cursor += 4;
+			
+			switch (RFIFOB(fd, cursor++)) {
+				/* int */
+				case 0:
+					if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", db->global_acc_reg_num_db, account_id, key, index, RFIFOL(fd, cursor)) )
+						Sql_ShowDebug(sql_handle);
+					cursor += 4;
+					break;
+				case 1:
+					if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", db->global_acc_reg_num_db, account_id, key, index) )
+						Sql_ShowDebug(sql_handle);
+					break;
+				/* str */
+				case 2:
+					safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
+					cursor += RFIFOB(fd, cursor) + 1;
+					if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", db->global_acc_reg_str_db, account_id, key, index, sval) )
+						Sql_ShowDebug(sql_handle);
+					break;
+				case 3:
+					if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", db->global_acc_reg_str_db, account_id, key, index) )
+						Sql_ShowDebug(sql_handle);
+					break;
+					
+				default:
+					ShowError("mmo_save_accreg2: DA HOO UNKNOWN TYPE %d\n",RFIFOB(fd, cursor - 1));
+					return;
+			}
+			
+		}
+		
+	}
+
+}
+void mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id) {
+	Sql* sql_handle = ((AccountDB_SQL*)self)->accounts;
+	AccountDB_SQL* db = (AccountDB_SQL*)self;
+	char* data;
+	int plen = 0;
+	size_t len;
+	
+	if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", db->global_acc_reg_str_db, account_id) )
+		Sql_ShowDebug(sql_handle);
+
+	WFIFOHEAD(fd, 60000 + 300);
+	WFIFOW(fd, 0) = 0x3804;
+	/* 0x2 = length, set prior to being sent */
+	WFIFOL(fd, 4) = account_id;
+	WFIFOL(fd, 8) = char_id;
+	WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+	WFIFOB(fd, 13) = 1;/* is string type */
+	WFIFOW(fd, 14) = 0;/* count */
+	plen = 16;
+	
+	/**
+	 * Vessel!
+	 *
+	 * str type
+	 * { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) }
+	 **/
+	while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) {
+				
+		SQL->GetData(sql_handle, 0, &data, NULL);
+		len = strlen(data)+1;
+		
+		WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */
+		plen += 1;
+		
+		safestrncpy((char*)WFIFOP(fd,plen), data, len);
+		plen += len;
+		
+		SQL->GetData(sql_handle, 1, &data, NULL);
+		
+		WFIFOL(fd, plen) = (unsigned int)atol(data);
+		plen += 4;
+		
+		SQL->GetData(sql_handle, 2, &data, NULL);
+		len = strlen(data)+1;
+		
+		WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+		plen += 1;
+		
+		safestrncpy((char*)WFIFOP(fd,plen), data, len);
+		plen += len;
+		
+		WFIFOW(fd, 14) += 1;
+		
+		if( plen > 60000 ) {
+			WFIFOW(fd, 2) = plen;
+			WFIFOSET(fd, plen);
+			
+			/* prepare follow up */
+			WFIFOHEAD(fd, 60000 + 300);
+			WFIFOW(fd, 0) = 0x3804;
+			/* 0x2 = length, set prior to being sent */
+			WFIFOL(fd, 4) = account_id;
+			WFIFOL(fd, 8) = char_id;
+			WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+			WFIFOB(fd, 13) = 1;/* is string type */
+			WFIFOW(fd, 14) = 0;/* count */
+			plen = 16;
+		}
+	}
+	
+	/* mark & go. */
+	WFIFOW(fd, 2) = plen;
+	WFIFOSET(fd, plen);
+	
+	SQL->FreeResult(sql_handle);
+	
+	if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", db->global_acc_reg_num_db, account_id) )
+		Sql_ShowDebug(sql_handle);
+	
+	WFIFOHEAD(fd, 60000 + 300);
+	WFIFOW(fd, 0) = 0x3804;
+	/* 0x2 = length, set prior to being sent */
+	WFIFOL(fd, 4) = account_id;
+	WFIFOL(fd, 8) = char_id;
+	WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+	WFIFOB(fd, 13) = 0;/* is int type */
+	WFIFOW(fd, 14) = 0;/* count */
+	plen = 16;
+	
+	/**
+	 * Vessel!
+	 *
+	 * int type
+	 * { keyLength(B), key(<keyLength>), index(L), value(L) }
+	 **/
+	while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) {
+				
+		SQL->GetData(sql_handle, 0, &data, NULL);
+		len = strlen(data)+1;
+		
+		WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */
+		plen += 1;
+		
+		safestrncpy((char*)WFIFOP(fd,plen), data, len);
+		plen += len;
+		
+		SQL->GetData(sql_handle, 1, &data, NULL);
+		
+		WFIFOL(fd, plen) = (unsigned int)atol(data);
+		plen += 4;
+		
+		SQL->GetData(sql_handle, 2, &data, NULL);
+		
+		WFIFOL(fd, plen) = atoi(data);
+		plen += 4;
+		
+		WFIFOW(fd, 14) += 1;
+		
+		if( plen > 60000 ) {
+			WFIFOW(fd, 2) = plen;
+			WFIFOSET(fd, plen);
+			
+			/* prepare follow up */
+			WFIFOHEAD(fd, 60000 + 300);
+			WFIFOW(fd, 0) = 0x3804;
+			/* 0x2 = length, set prior to being sent */
+			WFIFOL(fd, 4) = account_id;
+			WFIFOL(fd, 8) = char_id;
+			WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */
+			WFIFOB(fd, 13) = 0;/* is int type */
+			WFIFOW(fd, 14) = 0;/* count */
+			
+			plen = 16;
+		}
+	}
+	
+	/* mark as complete & go. */
+	WFIFOB(fd, 12) = 1;
+	WFIFOW(fd, 2) = plen;
+	WFIFOSET(fd, plen);
+	
+	SQL->FreeResult(sql_handle);
+}
diff --git a/src/login/login.c b/src/login/login.c
index 57a2d0b74..e9d0eac9d 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -704,30 +704,8 @@ int parse_fromchar(int fd)
 
 			if( !accounts->load_num(accounts, &acc, account_id) )
 				ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
-			else
-			{
-				int len;
-				int p;
-				ShowNotice("char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n", server[id].name, account_id, ip);
-				for( j = 0, p = 13; j < ACCOUNT_REG2_NUM && p < RFIFOW(fd,2); ++j )
-				{
-					sscanf((char*)RFIFOP(fd,p), "%31c%n", acc.account_reg2[j].str, &len);
-					acc.account_reg2[j].str[len]='\0';
-					p +=len+1; //+1 to skip the '\0' between strings.
-					sscanf((char*)RFIFOP(fd,p), "%255c%n", acc.account_reg2[j].value, &len);
-					acc.account_reg2[j].value[len]='\0';
-					p +=len+1;
-					remove_control_chars(acc.account_reg2[j].str);
-					remove_control_chars(acc.account_reg2[j].value);
-				}
-				acc.account_reg2_num = j;
-
-				// Save
-				accounts->save(accounts, &acc);
-
-				// Sending information towards the other char-servers.
-				RFIFOW(fd,0) = 0x2729;// reusing read buffer
-				charif_sendallwos(fd, RFIFOP(fd,0), RFIFOW(fd,2));
+			else {
+				mmo_save_accreg2(accounts,fd,account_id,RFIFOL(fd, 8));
 			}
 			RFIFOSKIP(fd,RFIFOW(fd,2));
 		}
@@ -797,34 +775,11 @@ int parse_fromchar(int fd)
 			if (RFIFOREST(fd) < 10)
 				return 0;
 		{
-			struct mmo_account acc;
-			size_t off;
-
 			int account_id = RFIFOL(fd,2);
 			int char_id = RFIFOL(fd,6);
 			RFIFOSKIP(fd,10);
 
-			WFIFOHEAD(fd,ACCOUNT_REG2_NUM*sizeof(struct global_reg));
-			WFIFOW(fd,0) = 0x2729;
-			WFIFOL(fd,4) = account_id;
-			WFIFOL(fd,8) = char_id;
-			WFIFOB(fd,12) = 1; //Type 1 for Account2 registry
-
-			off = 13;
-			if( accounts->load_num(accounts, &acc, account_id) )
-			{
-				for( j = 0; j < acc.account_reg2_num; j++ )
-				{
-					if( acc.account_reg2[j].str[0] != '\0' )
-					{
-						off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].str)+1; //We add 1 to consider the '\0' in place.
-						off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].value)+1;
-					}
-				}
-			}
-
-			WFIFOW(fd,2) = (uint16)off;
-			WFIFOSET(fd,WFIFOW(fd,2));
+			mmo_send_accreg2(accounts,fd,account_id,char_id);
 		}
 		break;
 
diff --git a/src/login/login.h b/src/login/login.h
index 80cbee74b..d6a021125 100644
--- a/src/login/login.h
+++ b/src/login/login.h
@@ -1,5 +1,6 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Portions Copyright (c) Athena Dev Teams
 
 #ifndef _LOGIN_H_
 #define _LOGIN_H_
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index ffd6da9d5..d4b6c2382 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -8444,12 +8444,12 @@ ACMD(set) {
 				break;
 			case '#':
 				if( reg[1] == '#' )
-					data->u.str = pc_readaccountreg2str(sd, reg);// global
+					data->u.str = pc_readaccountreg2str(sd, script->add_str(reg));// global
 				else
-					data->u.str = pc_readaccountregstr(sd, reg);// local
+					data->u.str = pc_readaccountregstr(sd, script->add_str(reg));// local
 				break;
 			default:
-				data->u.str = pc_readglobalreg_str(sd, reg);
+				data->u.str = pc_readglobalreg_str(sd, script->add_str(reg));
 				break;
 		}
 		
@@ -8473,12 +8473,12 @@ ACMD(set) {
 				break;
 			case '#':
 				if( reg[1] == '#' )
-					data->u.num = pc_readaccountreg2(sd, reg);// global
+					data->u.num = pc_readaccountreg2(sd, script->add_str(reg));// global
 				else
-					data->u.num = pc_readaccountreg(sd, reg);// local
+					data->u.num = pc_readaccountreg(sd, script->add_str(reg));// local
 				break;
 			default:
-				data->u.num = pc_readglobalreg(sd, reg);
+				data->u.num = pc_readglobalreg(sd, script->add_str(reg));
 				break;
 		}
 		
diff --git a/src/map/battleground.c b/src/map/battleground.c
index 6029a8c35..96d39aa45 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -496,7 +496,7 @@ void bg_match_over(struct bg_arena *arena, bool canceled) {
 			if( canceled )
 				clif->colormes(sd->fd,COLOR_RED,"BG Match Cancelled: not enough players");
 			else {
-				pc_setglobalreg(sd, arena->delay_var, (unsigned int)time(NULL));
+				pc_setglobalreg(sd, script->add_str(arena->delay_var), (unsigned int)time(NULL));
 			}
 		}
 	}
@@ -693,7 +693,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_
 	
 	tsec = (unsigned int)time(NULL);
 	
-	if ( ( tick = pc_readglobalreg(sd, bg->gdelay_var) ) && tsec < tick ) {
+	if ( ( tick = pc_readglobalreg(sd, script->add_str(bg->gdelay_var)) ) && tsec < tick ) {
 		char response[100];
 		if( (tick-tsec) > 60 )
 			sprintf(response, "You are a deserter! Wait %d minute(s) before you can apply again",(tick-tsec)/60);
@@ -703,7 +703,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_
 		return BGQA_FAIL_DESERTER;
 	}
 	
-	if ( ( tick = pc_readglobalreg(sd, arena->delay_var) ) && tsec < tick ) {
+	if ( ( tick = pc_readglobalreg(sd, script->add_str(arena->delay_var)) ) && tsec < tick ) {
 		char response[100];
 		if( (tick-tsec) > 60 )
 			sprintf(response, "You can't reapply to this arena so fast. Apply to the different arena or wait %d minute(s)",(tick-tsec)/60);
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 7b5cbbe59..d66ec1d85 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -265,12 +265,8 @@ int chrif_save(struct map_session_data *sd, int flag) {
 		sd->state.storage_flag = 0; //Force close it.
 
 	//Saving of registry values. 
-	if (sd->state.reg_dirty&4)
-		intif->saveregistry(sd, 3); //Save char regs
-	if (sd->state.reg_dirty&2)
-		intif->saveregistry(sd, 2); //Save account regs
-	if (sd->state.reg_dirty&1)
-		intif->saveregistry(sd, 1); //Save account2 regs
+	if (sd->vars_dirty)
+		intif->saveregistry(sd);
 
 	WFIFOHEAD(chrif->fd, sizeof(sd->status) + 13);
 	WFIFOW(chrif->fd,0) = 0x2b01;
@@ -603,7 +599,7 @@ void chrif_authok(int fd) {
 	//Causes problems if the currently connected player tries to quit or this data belongs to an already connected player which is trying to re-auth.
 	if ( ( sd = map->id2sd(account_id) ) != NULL )
 		return;
-	
+
 	if ( ( node = chrif->search(account_id) ) == NULL )
 		return; // should not happen
 
diff --git a/src/map/clif.c b/src/map/clif.c
index 4ae6c8d34..5f61bafad 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -14419,7 +14419,7 @@ void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd)
 
 	sd->feel_map[i].index = map_id2index(sd->bl.m);
 	sd->feel_map[i].m = sd->bl.m;
-	pc_setglobalreg(sd,pc->sg_info[i].feel_var,sd->feel_map[i].index);
+	pc_setglobalreg(sd,script->add_str(pc->sg_info[i].feel_var),sd->feel_map[i].index);
 
 //Are these really needed? Shouldn't they show up automatically from the feel save packet?
 //	clif_misceffect2(&sd->bl, 0x1b0);
diff --git a/src/map/duel.c b/src/map/duel.c
index 5e305244a..30277be50 100644
--- a/src/map/duel.c
+++ b/src/map/duel.c
@@ -24,7 +24,7 @@ void duel_savetime(struct map_session_data* sd) {
 	time(&clock);
 	t = localtime(&clock);
 	
-	pc_setglobalreg(sd, "PC_LAST_DUEL_TIME", t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min);
+	pc_setglobalreg(sd, script->add_str("PC_LAST_DUEL_TIME"), t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min);
 }
 
 int duel_checktime(struct map_session_data* sd) {
@@ -35,7 +35,7 @@ int duel_checktime(struct map_session_data* sd) {
 	time(&clock);
 	t = localtime(&clock);
 	
-	diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, "PC_LAST_DUEL_TIME");
+	diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, script->add_str("PC_LAST_DUEL_TIME") );
 	
 	return !(diff >= 0 && diff < battle_config.duel_time_interval);
 }
diff --git a/src/map/instance.c b/src/map/instance.c
index 924bbfd14..7c092e6cb 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -109,7 +109,8 @@ int instance_create(int owner_id, const char *name, enum instance_owner_type typ
 	instance->list[i].num_map = 0;
 	instance->list[i].owner_id = owner_id;
 	instance->list[i].owner_type = type;
-	instance->list[i].vars = idb_alloc(DB_OPT_RELEASE_DATA);
+	instance->list[i].vars = i64db_alloc(DB_OPT_RELEASE_DATA);
+	instance->list[i].array_db = NULL;
 	instance->list[i].respawn.map = 0;
 	instance->list[i].respawn.y = 0;
 	instance->list[i].respawn.x = 0;
@@ -551,6 +552,8 @@ void instance_destroy(int instance_id) {
 	
 	if( instance->list[instance_id].vars )
 		db_destroy(instance->list[instance_id].vars);
+	if( instance->list[instance_id].array_db )
+		instance->list[instance_id].array_db->destroy(instance->list[instance_id].array_db,script->array_free_db);
 
 	if( instance->list[instance_id].progress_timer != INVALID_TIMER )
 		timer->delete( instance->list[instance_id].progress_timer, instance->destroy_timer);
diff --git a/src/map/instance.h b/src/map/instance.h
index 4f65d7db0..ddca3e36b 100644
--- a/src/map/instance.h
+++ b/src/map/instance.h
@@ -33,8 +33,9 @@ struct instance_data {
 	unsigned short num_map;
 	unsigned short users;
 
-	struct DBMap* vars; // Instance Variable for scripts
-
+	struct DBMap *vars; // Instance Variable for scripts
+	struct DBMap *array_db ;
+	
 	int progress_timer;
 	unsigned int progress_timeout;
 
diff --git a/src/map/intif.c b/src/map/intif.c
index b9d4d1746..0a36fbc3d 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -265,60 +265,117 @@ int intif_wis_message_to_gm(char *wisp_name, int permission, char *mes)
 	return 0;
 }
 
-int intif_regtostr(char* str, struct global_reg *reg, int qty)
-{
-	int len =0, i;
-
-	for (i = 0; i < qty; i++) {
-		len+= sprintf(str+len, "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place.
-		len+= sprintf(str+len, "%s", reg[i].value)+1;
-	}
-	return len;
-}
-
 //Request for saving registry values.
-int intif_saveregistry(struct map_session_data *sd, int type)
-{
-	struct global_reg *reg;
-	int count;
-	int i, p;
+int intif_saveregistry(struct map_session_data *sd) {
+	DBIterator *iter;
+	DBKey key;
+	DBData *data;
+	int plen = 0;
+	size_t len;
 
 	if (intif->CheckForCharServer())
 		return -1;
-
-	switch (type) {
-	case 3: //Character reg
-		reg = sd->save_reg.global;
-		count = sd->save_reg.global_num;
-		sd->state.reg_dirty &= ~0x4;
-	break;
-	case 2: //Account reg
-		reg = sd->save_reg.account;
-		count = sd->save_reg.account_num;
-		sd->state.reg_dirty &= ~0x2;
-	break;
-	case 1: //Account2 reg
-		reg = sd->save_reg.account2;
-		count = sd->save_reg.account2_num;
-		sd->state.reg_dirty &= ~0x1;
-	break;
-	default: //Broken code?
-		ShowError("intif_saveregistry: Invalid type %d\n", type);
-		return -1;
-	}
-	WFIFOHEAD(inter_fd, 288 * MAX_REG_NUM+13);
-	WFIFOW(inter_fd,0)=0x3004;
-	WFIFOL(inter_fd,4)=sd->status.account_id;
-	WFIFOL(inter_fd,8)=sd->status.char_id;
-	WFIFOB(inter_fd,12)=type;
-	for( p = 13, i = 0; i < count; i++ ) {
-		if (reg[i].str[0] != '\0' && reg[i].value[0] != '\0') {
-			p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place.
-			p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].value)+1;
+	
+	WFIFOHEAD(inter_fd, 60000 + 300);
+	WFIFOW(inter_fd,0)  = 0x3004;
+	/* 0x2 = length (set later) */
+	WFIFOL(inter_fd,4)  = sd->status.account_id;
+	WFIFOL(inter_fd,8)  = sd->status.char_id;
+	WFIFOW(inter_fd,12) = 0;/* count */
+
+	plen = 14;
+	
+	iter = db_iterator(sd->var_db);
+	for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) {
+		const char *varname = NULL;
+		void *src = NULL;
+		
+		if( data->type != DB_DATA_PTR ) /* its a @number */
+			continue;
+		
+		varname = script->get_str(script_getvarid(key.i64));
+		
+		if( varname[0] == '@' ) /* @string$ can get here, so we skip */
+			continue;
+		
+		src = DB->data2ptr(data);
+
+		/* no need! */
+		if( !((struct script_reg_state*)src)->update )
+			continue;
+		
+		((struct script_reg_state*)src)->update = false;
+				
+		len = strlen(varname)+1;
+		
+		WFIFOB(inter_fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */
+		plen += 1;
+		
+		safestrncpy((char*)WFIFOP(inter_fd,plen), varname, len);
+		plen += len;
+				
+		WFIFOL(inter_fd, plen) = script_getvaridx(key.i64);
+		plen += 4;
+		
+		if( ((struct script_reg_state*)src)->type ) {
+			struct script_reg_str *p = src;
+						
+			WFIFOB(inter_fd, plen) = p->value ? 2 : 3;
+			plen += 1;
+			
+			if( p->value ) {
+				len = strlen(p->value)+1;
+				
+				WFIFOB(inter_fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+				plen += 1;
+				
+				safestrncpy((char*)WFIFOP(inter_fd,plen), p->value, len);
+				plen += len;
+			} else {
+				script->reg_destroy_single(sd,key.i64,&p->flag);
+			}
+			
+		} else {
+			struct script_reg_num *p = src;
+
+			WFIFOB(inter_fd, plen) =  p->value ? 0 : 1;
+			plen += 1;
+		
+			if( p->value ) {
+				WFIFOL(inter_fd, plen) = p->value;
+				plen += 4;
+			} else {
+				script->reg_destroy_single(sd,key.i64,&p->flag);
+			}
+			
+		}
+		
+		WFIFOW(inter_fd,12) += 1;
+		
+		if( plen > 60000 ) {
+			WFIFOW(inter_fd, 2) = plen;
+			WFIFOSET(inter_fd, plen);
+			
+			/* prepare follow up */
+			WFIFOHEAD(inter_fd, 60000 + 300);
+			WFIFOW(inter_fd,0)  = 0x3004;
+			/* 0x2 = length (set later) */
+			WFIFOL(inter_fd,4)  = sd->status.account_id;
+			WFIFOL(inter_fd,8)  = sd->status.char_id;
+			WFIFOW(inter_fd,12) = 0;/* count */
+			
+			plen = 14;
 		}
+		
 	}
-	WFIFOW(inter_fd,2)=p;
-	WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
+	dbi_destroy(iter);
+
+	/* mark & go. */
+	WFIFOW(inter_fd, 2) = plen;
+	WFIFOSET(inter_fd, plen);
+	
+	sd->vars_dirty = false;
+	
 	return 0;
 }
 
@@ -327,10 +384,7 @@ int intif_request_registry(struct map_session_data *sd, int flag)
 {
 	nullpo_ret(sd);
 
-	sd->save_reg.account2_num = -1;
-	sd->save_reg.account_num = -1;
-	sd->save_reg.global_num = -1;
-
+	/* if char server aint online it doesn't load, shouldn't we kill the session then? */
 	if (intif->CheckForCharServer())
 		return 0;
 
@@ -927,54 +981,93 @@ void mapif_parse_WisToGM(int fd)
 // Request player registre
 void intif_parse_Registers(int fd)
 {
-	int j,p,len,max, flag;
+	int i, flag;
 	struct map_session_data *sd;
-	struct global_reg *reg;
-	int *qty;
 	int account_id = RFIFOL(fd,4), char_id = RFIFOL(fd,8);
 	struct auth_node *node = chrif->auth_check(account_id, char_id, ST_LOGIN);
+	char type = RFIFOB(fd, 13);
+
 	if (node)
 		sd = node->sd;
 	else { //Normally registries should arrive for in log-in chars.
 		sd = map->id2sd(account_id);
-		if (sd && RFIFOB(fd,12) == 3 && sd->status.char_id != char_id)
-			sd = NULL; //Character registry from another character.
 	}
-	if (!sd) return;
-
-	flag = (sd->save_reg.global_num == -1 || sd->save_reg.account_num == -1 || sd->save_reg.account2_num == -1);
-
+	
+	if (!sd || sd->status.char_id != char_id) {
+		return; //Character registry from another character.
+	}
+		
+	flag = ( sd->vars_received&PRL_ACCG && sd->vars_received&PRL_ACCL && sd->vars_received&PRL_CHAR ) ? 0 : 1;
+	
 	switch (RFIFOB(fd,12)) {
 		case 3: //Character Registry
-			reg = sd->save_reg.global;
-			qty = &sd->save_reg.global_num;
-			max = GLOBAL_REG_NUM;
-		break;
+			sd->vars_received |= PRL_CHAR;
+			break;
 		case 2: //Account Registry
-			reg = sd->save_reg.account;
-			qty = &sd->save_reg.account_num;
-			max = ACCOUNT_REG_NUM;
-		break;
+			sd->vars_received |= PRL_ACCL;
+			break;
 		case 1: //Account2 Registry
-			reg = sd->save_reg.account2;
-			qty = &sd->save_reg.account2_num;
-			max = ACCOUNT_REG2_NUM;
-		break;
+			sd->vars_received |= PRL_ACCG;
+			break;
+		case 0:
+			break;
 		default:
 			ShowError("intif_parse_Registers: Unrecognized type %d\n",RFIFOB(fd,12));
 			return;
 	}
-	for(j=0,p=13;j<max && p<RFIFOW(fd,2);j++){
-		sscanf((char*)RFIFOP(fd,p), "%31c%n", reg[j].str,&len);
-		reg[j].str[len]='\0';
-		p += len+1; //+1 to skip the '\0' between strings.
-		sscanf((char*)RFIFOP(fd,p), "%255c%n", reg[j].value,&len);
-		reg[j].value[len]='\0';
-		p += len+1;
+	/* have it not complain about insertion of vars before loading, and not set those vars as new or modified */
+	pc->reg_load = true;
+	
+	if( RFIFOW(fd, 14) ) {
+		char key[32], sval[254];
+		unsigned int index;
+		int max = RFIFOW(fd, 14), cursor = 16, ival;
+		
+		/**
+		 * Vessel!char_reg_num_db
+		 *
+		 * str type
+		 * { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) }
+		 **/
+		if( type ) {
+			for(i = 0; i < max; i++) {
+				safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
+				cursor += RFIFOB(fd, cursor) + 1;
+				
+				index = RFIFOL(fd, cursor);
+				cursor += 4;
+				
+				safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
+				cursor += RFIFOB(fd, cursor) + 1;
+								
+				script->set_reg(NULL,sd,reference_uid(script->add_str(key), index), key, (void*)sval, NULL);
+			}
+		/**
+		 * Vessel!
+		 *
+		 * int type
+		 * { keyLength(B), key(<keyLength>), index(L), value(L) }
+		 **/
+		} else {
+			for(i = 0; i < max; i++) {
+				safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor));
+				cursor += RFIFOB(fd, cursor) + 1;
+				
+				index = RFIFOL(fd, cursor);
+				cursor += 4;
+				
+				ival = RFIFOL(fd, cursor);
+				cursor += 4;
+								
+				script->set_reg(NULL,sd,reference_uid(script->add_str(key), index), key, (void*)__64BPTRSIZE(ival), NULL);
+			}
+		}
 	}
-	*qty = j;
-
-	if (flag && sd->save_reg.global_num > -1 && sd->save_reg.account_num > -1 && sd->save_reg.account2_num > -1)
+	
+	/* flag it back */
+	pc->reg_load = false;
+		
+	if (flag && sd->vars_received&PRL_ACCG && sd->vars_received&PRL_ACCL && sd->vars_received&PRL_CHAR)
 		pc->reg_received(sd); //Received all registry values, execute init scripts and what-not. [Skotlex]
 }
 
diff --git a/src/map/intif.h b/src/map/intif.h
index bd3908ce7..f0bb5c16e 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -45,7 +45,7 @@ struct intif_interface {
 	int (*main_message) (struct map_session_data* sd, const char* message);
 	int (*wis_message) (struct map_session_data *sd,char *nick,char *mes,size_t mes_len);
 	int (*wis_message_to_gm) (char *Wisp_name, int permission, char *mes);
-	int (*saveregistry) (struct map_session_data *sd, int type);
+	int (*saveregistry) (struct map_session_data *sd);
 	int (*request_registry) (struct map_session_data *sd, int flag);
 	int (*request_guild_storage) (int account_id, int guild_id);
 	int (*send_guild_storage) (int account_id, struct guild_storage *gstor);
diff --git a/src/map/mapreg.h b/src/map/mapreg.h
index c8f229cef..157e634cc 100644
--- a/src/map/mapreg.h
+++ b/src/map/mapreg.h
@@ -9,7 +9,7 @@
 #include "../common/db.h"
 
 struct mapreg_save {
-	int uid;
+	int64 uid;
 	union {
 		int i;
 		char *str;
@@ -19,19 +19,27 @@ struct mapreg_save {
 
 struct mapreg_interface {
 	DBMap *db; // int var_id -> int value
+	/* TODO duck str_db, use same */
 	DBMap *str_db; // int var_id -> char* value
+	/* */
+	DBMap *array_db;
+	/* */
+	bool skip_insert;
+	/* */
 	struct eri *ers; //[Ind/Hercules]
+	/* */
 	char table[32];
+	/* */
 	bool i_dirty;
 	bool str_dirty;
 	/* */
 	void (*init) (void);
 	void (*final) (void);
 	/* */
-	int (*readreg) (int uid);
-	char* (*readregstr) (int uid);
-	bool (*setreg) (int uid, int val);
-	bool (*setregstr) (int uid, const char *str);
+	int (*readreg) (int64 uid);
+	char* (*readregstr) (int64 uid);
+	bool (*setreg) (int64 uid, int val);
+	bool (*setregstr) (int64 uid, const char *str);
 	void (*load) (void);
 	void (*save) (void);
 	int (*save_timer) (int tid, int64 tick, int id, intptr_t data);
diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c
index 6a13ef2a0..6df614aac 100644
--- a/src/map/mapreg_sql.c
+++ b/src/map/mapreg_sql.c
@@ -21,51 +21,56 @@ struct mapreg_interface mapreg_s;
 #define MAPREG_AUTOSAVE_INTERVAL (300*1000)
 
 /// Looks up the value of an integer variable using its uid.
-int mapreg_readreg(int uid) {
-	struct mapreg_save *m = idb_get(mapreg->db, uid);
+int mapreg_readreg(int64 uid) {
+	struct mapreg_save *m = i64db_get(mapreg->db, uid);
 	return m?m->u.i:0;
 }
 
 /// Looks up the value of a string variable using its uid.
-char* mapreg_readregstr(int uid) {
-	struct mapreg_save *m = idb_get(mapreg->str_db, uid);
+char* mapreg_readregstr(int64 uid) {
+	struct mapreg_save *m = i64db_get(mapreg->str_db, uid);
 	return m?m->u.str:NULL;
 }
 
 /// Modifies the value of an integer variable.
-bool mapreg_setreg(int uid, int val) {
+bool mapreg_setreg(int64 uid, int val) {
 	struct mapreg_save *m;
-	int num = (uid & 0x00ffffff);
-	int i   = (uid & 0xff000000) >> 24;
+	int num = script_getvarid(uid);
+	unsigned int i = script_getvaridx(uid);
 	const char* name = script->get_str(num);
 
 	if( val != 0 ) {
-		if( (m = idb_get(mapreg->db,uid)) ) {
+		if( (m = i64db_get(mapreg->db,uid)) ) {
 			m->u.i = val;
 			if(name[1] != '@') {
 				m->save = true;
 				mapreg->i_dirty = true;
 			}
 		} else {
+			if( i )
+				script->array_update(&mapreg->array_db,uid,false);
+
 			m = ers_alloc(mapreg->ers, struct mapreg_save);
 
 			m->u.i = val;
 			m->uid = uid;
 			m->save = false;
 
-			if(name[1] != '@') {// write new variable to database
+			if(name[1] != '@' && !mapreg->skip_insert) {// write new variable to database
 				char tmp_str[32*2+1];
 				SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, 32));
 				if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%d')", mapreg->table, tmp_str, i, val) )
 					Sql_ShowDebug(map->mysql_handle);
 			}
-			idb_put(mapreg->db, uid, m);
+			i64db_put(mapreg->db, uid, m);
 		}
 	} else { // val == 0
-		if( (m = idb_get(mapreg->db,uid)) ) {
+		if( i )
+			script->array_update(&mapreg->array_db,uid,true);
+		if( (m = i64db_get(mapreg->db,uid)) ) {
 			ers_free(mapreg->ers, m);
 		}
-		idb_remove(mapreg->db,uid);
+		i64db_remove(mapreg->db,uid);
 
 		if( name[1] != '@' ) {// Remove from database because it is unused.
 			if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg->table, name, i) )
@@ -77,25 +82,27 @@ bool mapreg_setreg(int uid, int val) {
 }
 
 /// Modifies the value of a string variable.
-bool mapreg_setregstr(int uid, const char* str) {
+bool mapreg_setregstr(int64 uid, const char* str) {
 	struct mapreg_save *m;
-	int num = (uid & 0x00ffffff);
-	int i   = (uid & 0xff000000) >> 24;
+	int num = script_getvarid(uid);
+	unsigned int i   = script_getvaridx(uid);
 	const char* name = script->get_str(num);
 	
 	if( str == NULL || *str == 0 ) {
+		if( i )
+			script->array_update(&mapreg->array_db,uid,true);
 		if(name[1] != '@') {
 			if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg->table, name, i) )
 				Sql_ShowDebug(map->mysql_handle);
 		}
-		if( (m = idb_get(mapreg->str_db,uid)) ) {
+		if( (m = i64db_get(mapreg->str_db,uid)) ) {
 			if( m->u.str != NULL )
 				aFree(m->u.str);
 			ers_free(mapreg->ers, m);
 		}
-		idb_remove(mapreg->str_db,uid);
+		i64db_remove(mapreg->str_db,uid);
 	} else {
-		if( (m = idb_get(mapreg->str_db,uid)) ) {
+		if( (m = i64db_get(mapreg->str_db,uid)) ) {
 			if( m->u.str != NULL )
 				aFree(m->u.str);
 			m->u.str = aStrdup(str);
@@ -104,13 +111,16 @@ bool mapreg_setregstr(int uid, const char* str) {
 				m->save = true;
 			}
 		} else {
+			if( i )
+				script->array_update(&mapreg->array_db,uid,false);
+			
 			m = ers_alloc(mapreg->ers, struct mapreg_save);
 
 			m->uid = uid;
 			m->u.str = aStrdup(str);
 			m->save = false;
 			
-			if(name[1] != '@') { //put returned null, so we must insert.
+			if(name[1] != '@' && !mapreg->skip_insert) { //put returned null, so we must insert.
 				char tmp_str[32*2+1];
 				char tmp_str2[255*2+1];
 				SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, 32));
@@ -118,7 +128,7 @@ bool mapreg_setregstr(int uid, const char* str) {
 				if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg->table, tmp_str, i, tmp_str2) )
 					Sql_ShowDebug(map->mysql_handle);
 			}
-			idb_put(mapreg->str_db, uid, m);
+			i64db_put(mapreg->str_db, uid, m);
 		}
 	}
 
@@ -147,41 +157,36 @@ void script_load_mapreg(void) {
 		return;
 	}
 
+	mapreg->skip_insert = true;
+	
 	SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &varname[0], sizeof(varname), &length, NULL);
 	SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL);
 	SQL->StmtBindColumn(stmt, 2, SQLDT_STRING, &value[0], sizeof(value), NULL, NULL);
-	
+
 	while ( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) {
-		struct mapreg_save *m = NULL;
 		int s = script->add_str(varname);
 		int i = index;
+		
 
 		if( varname[length-1] == '$' ) {
-			if( idb_exists(mapreg->str_db, (i<<24)|s) ) {
+			if( i64db_exists(mapreg->str_db, reference_uid(s, i)) ) {
 				ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value);
 				continue;
 			}
+			script->set_reg(NULL,NULL,reference_uid(s, i), varname, (void*)value, NULL);
 		} else {
-			if( idb_exists(mapreg->db, (i<<24)|s) ) {
+			if( i64db_exists(mapreg->db, reference_uid(s, i)) ) {
 				ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value);
 				continue;
 			}
-		}
-		
-		m = ers_alloc(mapreg->ers, struct mapreg_save);
-		m->uid = (i<<24)|s;
-		m->save = false;
-		if( varname[length-1] == '$' ) {
-			m->u.str = aStrdup(value);
-			idb_put(mapreg->str_db, m->uid, m);
-		} else {
-			m->u.i = atoi(value);
-			idb_put(mapreg->db, m->uid, m);
+			script->set_reg(NULL,NULL,reference_uid(s, i), varname, (void*)__64BPTRSIZE(atoi(value)), NULL);
 		}
 	}
 	
 	SQL->StmtFree(stmt);
 
+	mapreg->skip_insert = false;
+	
 	mapreg->i_dirty = false;
 	mapreg->str_dirty = false;
 }
@@ -195,8 +200,8 @@ void script_save_mapreg(void) {
 		iter = db_iterator(mapreg->db);
 		for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) {
 			if( m->save ) {
-				int num = (m->uid & 0x00ffffff);
-				int i   = (m->uid & 0xff000000) >> 24;
+				int num = script_getvarid(m->uid);
+				int i   = script_getvaridx(m->uid);
 				const char* name = script->get_str(num);
 
 				if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, m->u.i, name, i) )
@@ -212,8 +217,8 @@ void script_save_mapreg(void) {
 		iter = db_iterator(mapreg->str_db);
 		for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) {
 			if( m->save ) {
-				int num = (m->uid & 0x00ffffff);
-				int i   = (m->uid & 0xff000000) >> 24;
+				int num = script_getvarid(m->uid);
+				int i   = script_getvaridx(m->uid);
 				const char* name = script->get_str(num);
 				char tmp_str2[2*255+1];
 
@@ -257,7 +262,10 @@ void mapreg_reload(void) {
 	
 	db_clear(mapreg->db);
 	db_clear(mapreg->str_db);
-
+	
+	if( mapreg->array_db )
+		mapreg->array_db->destroy(mapreg->array_db,script->array_free_db);
+	
 	mapreg->load();
 }
 
@@ -286,11 +294,14 @@ void mapreg_final(void) {
 	db_destroy(mapreg->str_db);
 	
 	ers_destroy(mapreg->ers);
+	
+	if( mapreg->array_db )
+		mapreg->array_db->destroy(mapreg->array_db,script->array_free_db);
 }
 
 void mapreg_init(void) {
-	mapreg->db = idb_alloc(DB_OPT_BASE);
-	mapreg->str_db = idb_alloc(DB_OPT_BASE);
+	mapreg->db = i64db_alloc(DB_OPT_BASE);
+	mapreg->str_db = i64db_alloc(DB_OPT_BASE);
 	mapreg->ers = ers_new(sizeof(struct mapreg_save), "mapreg_sql.c::mapreg_ers", ERS_OPT_CLEAN);
 
 	mapreg->load();
@@ -314,11 +325,15 @@ void mapreg_defaults(void) {
 	mapreg->db = NULL;
 	mapreg->str_db = NULL;
 	mapreg->ers = NULL;
+	mapreg->skip_insert = false;
 	
 	safestrncpy(mapreg->table, "mapreg", sizeof(mapreg->table));
 	mapreg->i_dirty = false;
 	mapreg->str_dirty = false;
 	
+	/* */
+	mapreg->array_db = NULL;
+	
 	/* */
 	mapreg->init = mapreg_init;
 	mapreg->final = mapreg_final;
diff --git a/src/map/mob.c b/src/map/mob.c
index d919e7478..6a8aa5f03 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -2552,11 +2552,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
 				if( ++sd->mission_count >= 100 && (temp = mob->get_random_id(0, 0xE, sd->status.base_level)) ) {
 					pc->addfame(sd, 1);
 					sd->mission_mobid = temp;
-					pc_setglobalreg(sd,"TK_MISSION_ID", temp);
+					pc_setglobalreg(sd,script->add_str("TK_MISSION_ID"), temp);
 					sd->mission_count = 0;
 					clif->mission_info(sd, temp, 0);
 				}
-				pc_setglobalreg(sd,"TK_MISSION_COUNT", sd->mission_count);
+				pc_setglobalreg(sd,script->add_str("TK_MISSION_COUNT"), sd->mission_count);
 			}
 
 			if( sd->status.party_id )
diff --git a/src/map/pc.c b/src/map/pc.c
index 9e819bcac..b090b7b17 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -968,7 +968,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
 	uint32 ip = session[sd->fd]->client_addr;
 
 	sd->login_id2 = login_id2;
-	
+
 	if (pc->set_group(sd, group_id) != 0) {
 		ShowWarning("pc_authok: %s (AID:%d) logged in with unknown group id (%d)! kicking...\n",
 			st->name, sd->status.account_id, group_id);
@@ -1108,6 +1108,11 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
 	sd->avail_quests = 0;
 	sd->save_quest = false;
 
+	sd->var_db = i64db_alloc(DB_OPT_BASE);
+	sd->vars_dirty = false;
+	sd->vars_ok = false;
+	sd->vars_received = 0x0;
+	
 	//warp player
 	if ((i=pc->setpos(sd,sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT)) != 0) {
 		ShowError ("Last_point_map %s - id %d not found (error code %d)\n", mapindex_id2name(sd->status.last_point.map), sd->status.last_point.map, i);
@@ -1214,7 +1219,7 @@ int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl)
 			return 0; //Wrong size
 	}
 	sd->hate_mob[pos] = class_;
-	pc_setglobalreg(sd,pc->sg_info[pos].hate_var,class_+1);
+	pc_setglobalreg(sd,script->add_str(pc->sg_info[pos].hate_var),class_+1);
 	clif->hate_info(sd, pos, class_, 1);
 	return 1;
 }
@@ -1226,55 +1231,58 @@ int pc_reg_received(struct map_session_data *sd)
 {
 	int i,j, idx = 0;
 
-	sd->change_level_2nd = pc_readglobalreg(sd,"jobchange_level");
-	sd->change_level_3rd = pc_readglobalreg(sd,"jobchange_level_3rd");
-	sd->die_counter = pc_readglobalreg(sd,"PC_DIE_COUNTER");
+	sd->vars_ok = true;
+
+	sd->change_level_2nd = pc_readglobalreg(sd,script->add_str("jobchange_level"));
+	sd->change_level_3rd = pc_readglobalreg(sd,script->add_str("jobchange_level_3rd"));
+	sd->die_counter = pc_readglobalreg(sd,script->add_str("PC_DIE_COUNTER"));
 
 	// Cash shop
-	sd->cashPoints = pc_readaccountreg(sd,"#CASHPOINTS");
-	sd->kafraPoints = pc_readaccountreg(sd,"#KAFRAPOINTS");
+	sd->cashPoints = pc_readaccountreg(sd,script->add_str("#CASHPOINTS"));
+	sd->kafraPoints = pc_readaccountreg(sd,script->add_str("#KAFRAPOINTS"));
 
 	// Cooking Exp
-	sd->cook_mastery = pc_readglobalreg(sd,"COOK_MASTERY");
+	sd->cook_mastery = pc_readglobalreg(sd,script->add_str("COOK_MASTERY"));
 
 	if( (sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON ) {
 		// Better check for class rather than skill to prevent "skill resets" from unsetting this
-		sd->mission_mobid = pc_readglobalreg(sd,"TK_MISSION_ID");
-		sd->mission_count = pc_readglobalreg(sd,"TK_MISSION_COUNT");
+		sd->mission_mobid = pc_readglobalreg(sd,script->add_str("TK_MISSION_ID"));
+		sd->mission_count = pc_readglobalreg(sd,script->add_str("TK_MISSION_COUNT"));
 	}
 
 	//SG map and mob read [Komurka]
 	for(i=0;i<MAX_PC_FEELHATE;i++) { //for now - someone need to make reading from txt/sql
-		if ((j = pc_readglobalreg(sd,pc->sg_info[i].feel_var))!=0) {
+		if ((j = pc_readglobalreg(sd,script->add_str(pc->sg_info[i].feel_var)))!=0) {
 			sd->feel_map[i].index = j;
 			sd->feel_map[i].m = map->mapindex2mapid(j);
 		} else {
 			sd->feel_map[i].index = 0;
 			sd->feel_map[i].m = -1;
 		}
-		sd->hate_mob[i] = pc_readglobalreg(sd,pc->sg_info[i].hate_var)-1;
+		sd->hate_mob[i] = pc_readglobalreg(sd,script->add_str(pc->sg_info[i].hate_var))-1;
 	}
 
 	if ((i = pc->checkskill(sd,RG_PLAGIARISM)) > 0) {
-		sd->cloneskill_id = pc_readglobalreg(sd,"CLONE_SKILL");
+		sd->cloneskill_id = pc_readglobalreg(sd,script->add_str("CLONE_SKILL"));
 		if (sd->cloneskill_id > 0 && (idx = skill->get_index(sd->cloneskill_id))) {
 			sd->status.skill[idx].id = sd->cloneskill_id;
-			sd->status.skill[idx].lv = pc_readglobalreg(sd,"CLONE_SKILL_LV");
+			sd->status.skill[idx].lv = pc_readglobalreg(sd,script->add_str("CLONE_SKILL_LV"));
 			if (sd->status.skill[idx].lv > i)
 				sd->status.skill[idx].lv = i;
 			sd->status.skill[idx].flag = SKILL_FLAG_PLAGIARIZED;
 		}
 	}
 	if ((i = pc->checkskill(sd,SC_REPRODUCE)) > 0) {
-		sd->reproduceskill_id = pc_readglobalreg(sd,"REPRODUCE_SKILL");
+		sd->reproduceskill_id = pc_readglobalreg(sd,script->add_str("REPRODUCE_SKILL"));
 		if( sd->reproduceskill_id > 0 && (idx = skill->get_index(sd->reproduceskill_id))) {
 			sd->status.skill[idx].id = sd->reproduceskill_id;
-			sd->status.skill[idx].lv = pc_readglobalreg(sd,"REPRODUCE_SKILL_LV");
+			sd->status.skill[idx].lv = pc_readglobalreg(sd,script->add_str("REPRODUCE_SKILL_LV"));
 			if( i < sd->status.skill[idx].lv)
 				sd->status.skill[idx].lv = i;
 			sd->status.skill[idx].flag = SKILL_FLAG_PLAGIARIZED;
 		}
 	}
+	
 	//Weird... maybe registries were reloaded?
 	if (sd->state.active)
 		return 0;
@@ -1652,7 +1660,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
 
 			}
 
-			pc_setglobalreg (sd, "jobchange_level", sd->change_level_2nd);
+			pc_setglobalreg (sd, script->add_str("jobchange_level"), sd->change_level_2nd);
 		}
 
 		if (skill_point < novice_skills + (sd->change_level_2nd - 1)) {
@@ -1665,7 +1673,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
 						- (sd->status.job_level - 1)
 						- (sd->change_level_2nd - 1)
 						- novice_skills;
-					pc_setglobalreg (sd, "jobchange_level_3rd", sd->change_level_3rd);
+					pc_setglobalreg (sd, script->add_str("jobchange_level_3rd"), sd->change_level_3rd);
 			}
 
 			if (skill_point < novice_skills + (sd->change_level_2nd - 1) + (sd->change_level_3rd - 1)) {
@@ -3777,8 +3785,8 @@ int pc_paycash(struct map_session_data *sd, int price, int points)
 		return -1;
 	}
 
-	pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints-cash);
-	pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints-points);
+	pc_setaccountreg(sd, script->add_str("#CASHPOINTS"), sd->cashPoints-cash);
+	pc_setaccountreg(sd, script->add_str("#KAFRAPOINTS"), sd->kafraPoints-points);
 
 	if( battle_config.cashshop_show_points )
 	{
@@ -3804,7 +3812,7 @@ int pc_getcash(struct map_session_data *sd, int cash, int points)
 			cash = MAX_ZENY-sd->cashPoints;
 		}
 
-		pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints+cash);
+		pc_setaccountreg(sd, script->add_str("#CASHPOINTS"), sd->cashPoints+cash);
 
 		if( battle_config.cashshop_show_points )
 		{
@@ -3827,7 +3835,7 @@ int pc_getcash(struct map_session_data *sd, int cash, int points)
 			points = MAX_ZENY-sd->kafraPoints;
 		}
 
-		pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints+points);
+		pc_setaccountreg(sd, script->add_str("#KAFRAPOINTS"), sd->kafraPoints+points);
 
 		if( battle_config.cashshop_show_points )
 		{
@@ -6505,7 +6513,7 @@ int pc_resetstate(struct map_session_data* sd)
 	if( sd->mission_mobid ) { //bugreport:2200
 		sd->mission_mobid = 0;
 		sd->mission_count = 0;
-		pc_setglobalreg(sd,"TK_MISSION_ID", 0);
+		pc_setglobalreg(sd,script->add_str("TK_MISSION_ID"), 0);
 	}
 
 	status_calc_pc(sd,SCO_NONE);
@@ -6637,7 +6645,7 @@ int pc_resetfeel(struct map_session_data* sd)
 	{
 		sd->feel_map[i].m = -1;
 		sd->feel_map[i].index = 0;
-		pc_setglobalreg(sd,pc->sg_info[i].feel_var,0);
+		pc_setglobalreg(sd,script->add_str(pc->sg_info[i].feel_var),0);
 	}
 
 	return 0;
@@ -6651,7 +6659,7 @@ int pc_resethate(struct map_session_data* sd)
 	for (i=0; i<3; i++)
 	{
 		sd->hate_mob[i] = -1;
-		pc_setglobalreg(sd,pc->sg_info[i].hate_var,0);
+		pc_setglobalreg(sd,script->add_str(pc->sg_info[i].hate_var),0);
 	}
 	return 0;
 }
@@ -6806,7 +6814,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
 	if (sd->npc_id && sd->st && sd->st->state != RUN)
 		npc->event_dequeue(sd);
 	
-	pc_setglobalreg(sd,"PC_DIE_COUNTER",sd->die_counter+1);
+	pc_setglobalreg(sd,script->add_str("PC_DIE_COUNTER"),sd->die_counter+1);
 	pc->setparam(sd, SP_KILLERRID, src?src->id:0);
 
 	if( sd->bg_id ) {/* TODO: purge when bgqueue is deemed ok */
@@ -7608,12 +7616,12 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
 	// changing from 1st to 2nd job
 	if ((b_class&JOBL_2) && !(sd->class_&JOBL_2) && (b_class&MAPID_UPPERMASK) != MAPID_SUPER_NOVICE) {
 		sd->change_level_2nd = sd->status.job_level;
-		pc_setglobalreg (sd, "jobchange_level", sd->change_level_2nd);
+		pc_setglobalreg (sd, script->add_str("jobchange_level"), sd->change_level_2nd);
 	}
 	// changing from 2nd to 3rd job
 	else if((b_class&JOBL_THIRD) && !(sd->class_&JOBL_THIRD)) {
 		sd->change_level_3rd = sd->status.job_level;
-		pc_setglobalreg (sd, "jobchange_level_3rd", sd->change_level_3rd);
+		pc_setglobalreg (sd, script->add_str("jobchange_level_3rd"), sd->change_level_3rd);
 	}
 
 	if(sd->cloneskill_id) {
@@ -7625,8 +7633,8 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
 			clif->deleteskill(sd,sd->cloneskill_id);
 		}
 		sd->cloneskill_id = 0;
-		pc_setglobalreg(sd, "CLONE_SKILL", 0);
-		pc_setglobalreg(sd, "CLONE_SKILL_LV", 0);
+		pc_setglobalreg(sd, script->add_str("CLONE_SKILL"), 0);
+		pc_setglobalreg(sd, script->add_str("CLONE_SKILL_LV"), 0);
 	}
 
 	if(sd->reproduceskill_id) {
@@ -7638,8 +7646,8 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
 			clif->deleteskill(sd,sd->reproduceskill_id);
 		}
 		sd->reproduceskill_id = 0;
-		pc_setglobalreg(sd, "REPRODUCE_SKILL",0);
-		pc_setglobalreg(sd, "REPRODUCE_SKILL_LV",0);
+		pc_setglobalreg(sd, script->add_str("REPRODUCE_SKILL"),0);
+		pc_setglobalreg(sd, script->add_str("REPRODUCE_SKILL_LV"),0);
 	}
 
 	if ( (b_class&MAPID_UPPERMASK) != (sd->class_&MAPID_UPPERMASK) ) { //Things to remove when changing class tree.
@@ -8044,341 +8052,245 @@ int pc_candrop(struct map_session_data *sd, struct item *item)
 		return 0;
 	return (itemdb_isdropable(item, pc_get_group_level(sd)));
 }
-
-/*==========================================
- * Read ram register for player sd
- * get val (int) from reg for player sd
- *------------------------------------------*/
-int pc_readreg(struct map_session_data* sd, int reg)
-{
-	int i;
-
-	nullpo_ret(sd);
-
-	ARR_FIND( 0, sd->reg_num, i,  sd->reg[i].index == reg );
-	return ( i < sd->reg_num ) ? sd->reg[i].data : 0;
+/**
+ * For '@type' variables (temporary numeric char reg)
+ **/
+int pc_readreg(struct map_session_data* sd, int64 reg) {
+	return i64db_iget(sd->var_db, reg);
 }
-/*==========================================
- * Set ram register for player sd
- * memo val(int) at reg for player sd
- *------------------------------------------*/
-int pc_setreg(struct map_session_data* sd, int reg, int val)
-{
-	int i;
-
-	nullpo_ret(sd);
-
-	ARR_FIND( 0, sd->reg_num, i, sd->reg[i].index == reg );
-	if( i < sd->reg_num )
-	{// overwrite existing entry
-		sd->reg[i].data = val;
-		return 1;
-	}
-
-	ARR_FIND( 0, sd->reg_num, i, sd->reg[i].data == 0 );
-	if( i == sd->reg_num )
-	{// nothing free, increase size
-		sd->reg_num++;
-		RECREATE(sd->reg, struct script_reg, sd->reg_num);
+/**
+ * For '@type' variables (temporary numeric char reg)
+ **/
+void pc_setreg(struct map_session_data* sd, int64 reg, int val) {
+	unsigned int index = script_getvaridx(reg);
+	
+	if( val ) {
+		i64db_iput(sd->var_db, reg, val);
+		if( index )
+			script->array_update(&sd->array_db,reg,false);
+	} else {
+		i64db_remove(sd->var_db, reg);
+		if( index )
+			script->array_update(&sd->array_db,reg,true);
 	}
-	sd->reg[i].index = reg;
-	sd->reg[i].data = val;
-
-	return 1;
 }
 
-/*==========================================
- * Read ram register for player sd
- * get val (str) from reg for player sd
- *------------------------------------------*/
-char* pc_readregstr(struct map_session_data* sd, int reg)
-{
-	int i;
-
-	nullpo_ret(sd);
+/**
+ * For '@type$' variables (temporary string char reg)
+ **/
+char* pc_readregstr(struct map_session_data* sd, int64 reg) {
+	struct script_reg_str *p = NULL;
 
-	ARR_FIND( 0, sd->regstr_num, i,  sd->regstr[i].index == reg );
-	return ( i < sd->regstr_num ) ? sd->regstr[i].data : NULL;
+	p = i64db_get(sd->var_db, reg);
+	
+	return p ? p->value : NULL;
 }
-/*==========================================
- * Set ram register for player sd
- * memo val(str) at reg for player sd
- *------------------------------------------*/
-int pc_setregstr(struct map_session_data* sd, int reg, const char* str)
-{
-	int i;
-
-	nullpo_ret(sd);
+/**
+ * For '@type$' variables (temporary string char reg)
+ **/
+void pc_setregstr(struct map_session_data* sd, int64 reg, const char* str) {
+	struct script_reg_str *p = NULL;
+	unsigned int index = script_getvaridx(reg);
+	DBData prev;
 
-	ARR_FIND( 0, sd->regstr_num, i, sd->regstr[i].index == reg );
-	if( i < sd->regstr_num )
-	{// found entry, update
-		if( str == NULL || *str == '\0' )
-		{// empty string
-			if( sd->regstr[i].data != NULL )
-				aFree(sd->regstr[i].data);
-			sd->regstr[i].data = NULL;
-		}
-		else if( sd->regstr[i].data )
-		{// recreate
-			size_t len = strlen(str)+1;
-			RECREATE(sd->regstr[i].data, char, len);
-			memcpy(sd->regstr[i].data, str, len*sizeof(char));
+	if( str[0] ) {
+		p = ers_alloc(pc->str_reg_ers, struct script_reg_str);
+		
+		p->value = aStrdup(str);
+		
+		if( sd->var_db->put(sd->var_db,DB->i642key(reg),DB->ptr2data(p),&prev) ) {
+			p = DB->data2ptr(&prev);
+			if( p->value )
+				aFree(p->value);
+			ers_free(pc->str_reg_ers, p);
+		} else {
+			if( index )
+				script->array_update(&sd->array_db,reg,false);
 		}
-		else
-		{// create
-			sd->regstr[i].data = aStrdup(str);
+	} else {
+		if( sd->var_db->remove(sd->var_db,DB->i642key(reg),&prev) ) {
+			p = DB->data2ptr(&prev);
+			if( p->value )
+				aFree(p->value);
+			ers_free(pc->str_reg_ers, p);
+			if( index )
+				script->array_update(&sd->array_db,reg,true);
 		}
-		return 1;
-	}
-
-	if( str == NULL || *str == '\0' )
-		return 1;// nothing to add, empty string
-
-	ARR_FIND( 0, sd->regstr_num, i, sd->regstr[i].data == NULL );
-	if( i == sd->regstr_num )
-	{// nothing free, increase size
-		sd->regstr_num++;
-		RECREATE(sd->regstr, struct script_regstr, sd->regstr_num);
 	}
-	sd->regstr[i].index = reg;
-	sd->regstr[i].data = aStrdup(str);
-
-	return 1;
 }
-
-int pc_readregistry(struct map_session_data *sd,const char *reg,int type)
-{
-	struct global_reg *sd_reg;
-	int i,max;
-
-	nullpo_ret(sd);
-	switch (type) {
-	case 3: //Char reg
-		sd_reg = sd->save_reg.global;
-		max = sd->save_reg.global_num;
-	break;
-	case 2: //Account reg
-		sd_reg = sd->save_reg.account;
-		max = sd->save_reg.account_num;
-	break;
-	case 1: //Account2 reg
-		sd_reg = sd->save_reg.account2;
-		max = sd->save_reg.account2_num;
-	break;
-	default:
-		return 0;
-	}
-	if (max == -1) {
-		ShowError("pc_readregistry: Trying to read reg value %s (type %d) before it's been loaded!\n", reg, type);
+/**
+ * Serves the following variable types:
+ * - 'type' (permanent nuneric char reg)
+ * - '#type' (permanent numeric account reg)
+ * - '##type' (permanent numeric account reg2)
+ **/
+int pc_readregistry(struct map_session_data *sd, int64 reg) {
+	struct script_reg_num *p = NULL;
+	
+	if (!sd->vars_ok) {
+		ShowError("pc_readregistry: Trying to read reg %s before it's been loaded!\n", script->get_str(script_getvarid(reg)));
 		//This really shouldn't happen, so it's possible the data was lost somewhere, we should request it again.
-		intif->request_registry(sd,type==3?4:type);
+		//intif->request_registry(sd,type==3?4:type);
+		set_eof(sd->fd);
 		return 0;
 	}
+	
+	p = i64db_get(sd->var_db, reg);
 
-	ARR_FIND( 0, max, i, strcmp(sd_reg[i].str,reg) == 0 );
-	return ( i < max ) ? atoi(sd_reg[i].value) : 0;
+	return p ? p->value : 0;
 }
-
-char* pc_readregistry_str(struct map_session_data *sd,const char *reg,int type)
-{
-	struct global_reg *sd_reg;
-	int i,max;
-
-	nullpo_ret(sd);
-	switch (type) {
-	case 3: //Char reg
-		sd_reg = sd->save_reg.global;
-		max = sd->save_reg.global_num;
-	break;
-	case 2: //Account reg
-		sd_reg = sd->save_reg.account;
-		max = sd->save_reg.account_num;
-	break;
-	case 1: //Account2 reg
-		sd_reg = sd->save_reg.account2;
-		max = sd->save_reg.account2_num;
-	break;
-	default:
-		return NULL;
-	}
-	if (max == -1) {
-		ShowError("pc_readregistry: Trying to read reg value %s (type %d) before it's been loaded!\n", reg, type);
+/**
+ * Serves the following variable types:
+ * - 'type$' (permanent str char reg)
+ * - '#type$' (permanent str account reg)
+ * - '##type$' (permanent str account reg2)
+ **/
+char* pc_readregistry_str(struct map_session_data *sd, int64 reg) {
+	struct script_reg_str *p = NULL;
+	
+	if (!sd->vars_ok) {
+		ShowError("pc_readregistry_str: Trying to read reg %s before it's been loaded!\n", script->get_str(script_getvarid(reg)));
 		//This really shouldn't happen, so it's possible the data was lost somewhere, we should request it again.
-		intif->request_registry(sd,type==3?4:type);
+		//intif->request_registry(sd,type==3?4:type);
+		set_eof(sd->fd);
 		return NULL;
 	}
 
-	ARR_FIND( 0, max, i, strcmp(sd_reg[i].str,reg) == 0 );
-	return ( i < max ) ? sd_reg[i].value : NULL;
+	p = i64db_get(sd->var_db, reg);
+	
+	return p ? p->value : NULL;
 }
+/**
+ * Serves the following variable types:
+ * - 'type' (permanent nuneric char reg)
+ * - '#type' (permanent numeric account reg)
+ * - '##type' (permanent numeric account reg2)
+ **/
+int pc_setregistry(struct map_session_data *sd, int64 reg, int val) {
+	struct script_reg_num *p = NULL;
+	int i;
+	const char *regname = script->get_str( script_getvarid(reg) );
+	unsigned int index = script_getvaridx(reg);
 
-int pc_setregistry(struct map_session_data *sd,const char *reg,int val,int type)
-{
-	struct global_reg *sd_reg;
-	int i,*max, regmax;
-
-	nullpo_ret(sd);
-
-	switch( type )
-	{
-	case 3: //Char reg
-		if( !strcmp(reg,"PC_DIE_COUNTER") && sd->die_counter != val )
-		{
-			i = (!sd->die_counter && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE);
-			sd->die_counter = val;
-			if( i )
-				status_calc_pc(sd,SCO_NONE); // Lost the bonus.
-		}
-		else if( !strcmp(reg,"COOK_MASTERY") && sd->cook_mastery != val )
-		{
-			val = cap_value(val, 0, 1999);
-			sd->cook_mastery = val;
-		}
-		sd_reg = sd->save_reg.global;
-		max = &sd->save_reg.global_num;
-		regmax = GLOBAL_REG_NUM;
-	break;
-	case 2: //Account reg
-		if( !strcmp(reg,"#CASHPOINTS") && sd->cashPoints != val )
-		{
-			val = cap_value(val, 0, MAX_ZENY);
-			sd->cashPoints = val;
-		}
-		else if( !strcmp(reg,"#KAFRAPOINTS") && sd->kafraPoints != val )
-		{
-			val = cap_value(val, 0, MAX_ZENY);
-			sd->kafraPoints = val;
-		}
-		sd_reg = sd->save_reg.account;
-		max = &sd->save_reg.account_num;
-		regmax = ACCOUNT_REG_NUM;
-	break;
-	case 1: //Account2 reg
-		sd_reg = sd->save_reg.account2;
-		max = &sd->save_reg.account2_num;
-		regmax = ACCOUNT_REG2_NUM;
-	break;
-	default:
-		return 0;
+	/* SAAD! those things should be stored elsewhere e.g. char ones in char table, the cash ones in account_data table! */
+	switch( regname[0] ) {
+		default: //Char reg
+			if( !strcmp(regname,"PC_DIE_COUNTER") && sd->die_counter != val ) {
+				i = (!sd->die_counter && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE);
+				sd->die_counter = val;
+				if( i )
+					status_calc_pc(sd,SCO_NONE); // Lost the bonus.
+			} else if( !strcmp(regname,"COOK_MASTERY") && sd->cook_mastery != val ) {
+				val = cap_value(val, 0, 1999);
+				sd->cook_mastery = val;
+			}
+			break;
+		case '#':
+			if( !strcmp(regname,"#CASHPOINTS") && sd->cashPoints != val ) {
+				val = cap_value(val, 0, MAX_ZENY);
+				sd->cashPoints = val;
+			} else if( !strcmp(regname,"#KAFRAPOINTS") && sd->kafraPoints != val ) {
+				val = cap_value(val, 0, MAX_ZENY);
+				sd->kafraPoints = val;
+			}
+			break;
 	}
-	if (*max == -1) {
-		ShowError("pc_setregistry : refusing to set %s (type %d) until vars are received.\n", reg, type);
-		return 1;
+	
+	if ( !pc->reg_load && !sd->vars_ok ) {
+		ShowError("pc_setregistry : refusing to set %s until vars are received.\n", regname);
+		return 0;
 	}
-
-	// delete reg
-	if (val == 0) {
-		ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
-		if( i < *max )
-		{
-			if (i != *max - 1)
-				memcpy(&sd_reg[i], &sd_reg[*max - 1], sizeof(struct global_reg));
-			memset(&sd_reg[*max - 1], 0, sizeof(struct global_reg));
-			(*max)--;
-			sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
+	
+	if( (p = i64db_get(sd->var_db, reg) ) ) {
+		if( val ) {
+			if( !p->value && index ) /* its a entry that was deleted, so we reset array */
+				script->array_update(&sd->array_db,reg,false);
+			p->value = val;
+		} else {
+			p->value = 0;
+			if( index )
+				script->array_update(&sd->array_db,reg,true);
+		}
+		if( !pc->reg_load )
+			p->flag.update = 1;/* either way, it will require either delete or replace */
+	} else if( val ) {
+		DBData prev;
+		
+		if( index )
+			script->array_update(&sd->array_db,reg,false);
+		
+		p = ers_alloc(pc->num_reg_ers, struct script_reg_num);
+		
+		p->value = val;
+		if( !pc->reg_load )
+			p->flag.update = 1;
+		
+		if( sd->var_db->put(sd->var_db,DB->i642key(reg),DB->ptr2data(p),&prev) ) {
+			p = DB->data2ptr(&prev);
+			ers_free(pc->num_reg_ers, p);
 		}
-		return 1;
-	}
-	// change value if found
-	ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
-	if( i < *max )
-	{
-		safesnprintf(sd_reg[i].value, sizeof(sd_reg[i].value), "%d", val);
-		sd->state.reg_dirty |= 1<<(type-1);
-		return 1;
-	}
-
-	// add value if not found
-	if (i < regmax) {
-		memset(&sd_reg[i], 0, sizeof(struct global_reg));
-		safestrncpy(sd_reg[i].str, reg, sizeof(sd_reg[i].str));
-		safesnprintf(sd_reg[i].value, sizeof(sd_reg[i].value), "%d", val);
-		(*max)++;
-		sd->state.reg_dirty |= 1<<(type-1);
-		return 1;
 	}
+	
+	if( !pc->reg_load && p )
+		sd->vars_dirty = true;
 
-	ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax);
-
-	return 0;
+	return 1;
 }
+/**
+ * Serves the following variable types:
+ * - 'type$' (permanent str char reg)
+ * - '#type$' (permanent str account reg)
+ * - '##type$' (permanent str account reg2)
+ **/
+int pc_setregistry_str(struct map_session_data *sd, int64 reg, const char *val) {
+	struct script_reg_str *p = NULL;
+	const char *regname = script->get_str( script_getvarid(reg) );
+	unsigned int index = script_getvaridx(reg);
 
-int pc_setregistry_str(struct map_session_data *sd,const char *reg,const char *val,int type)
-{
-	struct global_reg *sd_reg;
-	int i,*max, regmax;
-
-	nullpo_ret(sd);
-	if (reg[strlen(reg)-1] != '$') {
-		ShowError("pc_setregistry_str : reg %s must be string (end in '$') to use this!\n", reg);
-		return 0;
-	}
-
-	switch (type) {
-	case 3: //Char reg
-		sd_reg = sd->save_reg.global;
-		max = &sd->save_reg.global_num;
-		regmax = GLOBAL_REG_NUM;
-	break;
-	case 2: //Account reg
-		sd_reg = sd->save_reg.account;
-		max = &sd->save_reg.account_num;
-		regmax = ACCOUNT_REG_NUM;
-	break;
-	case 1: //Account2 reg
-		sd_reg = sd->save_reg.account2;
-		max = &sd->save_reg.account2_num;
-		regmax = ACCOUNT_REG2_NUM;
-	break;
-	default:
-		return 0;
-	}
-	if (*max == -1) {
-		ShowError("pc_setregistry_str : refusing to set %s (type %d) until vars are received.\n", reg, type);
+	if ( !pc->reg_load && !sd->vars_ok ) {
+		ShowError("pc_setregistry_str : refusing to set %s until vars are received.\n", regname);
 		return 0;
 	}
 
-	// delete reg
-	if (!val || strcmp(val,"")==0)
-	{
-		ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
-		if( i < *max )
-		{
-			if (i != *max - 1)
-				memcpy(&sd_reg[i], &sd_reg[*max - 1], sizeof(struct global_reg));
-			memset(&sd_reg[*max - 1], 0, sizeof(struct global_reg));
-			(*max)--;
-			sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
-			if (type!=3) intif->saveregistry(sd,type);
+	if( (p = i64db_get(sd->var_db, reg) ) ) {
+		if( val[0] ) {
+			if( p->value )
+				aFree(p->value);
+			else if ( index ) /* a entry that was deleted, so we reset */
+				script->array_update(&sd->array_db,reg,false);
+			p->value = aStrdup(val);
+		} else {
+			p->value = NULL;
+			if( index )
+				script->array_update(&sd->array_db,reg,true);
 		}
-		return 1;
-	}
+		if( !pc->reg_load )
+			p->flag.update = 1;/* either way, it will require either delete or replace */
+	} else if( val[0] ) {
+		DBData prev;
 
-	// change value if found
-	ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
-	if( i < *max )
-	{
-		safestrncpy(sd_reg[i].value, val, sizeof(sd_reg[i].value));
-		sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
-		if (type!=3) intif->saveregistry(sd,type);
-		return 1;
-	}
+		if( index )
+			script->array_update(&sd->array_db,reg,false);
 
-	// add value if not found
-	if (i < regmax) {
-		memset(&sd_reg[i], 0, sizeof(struct global_reg));
-		safestrncpy(sd_reg[i].str, reg, sizeof(sd_reg[i].str));
-		safestrncpy(sd_reg[i].value, val, sizeof(sd_reg[i].value));
-		(*max)++;
-		sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
-		if (type!=3) intif->saveregistry(sd,type);
-		return 1;
+		p = ers_alloc(pc->str_reg_ers, struct script_reg_str);
+		
+		p->value = aStrdup(val);
+		if( !pc->reg_load )
+			p->flag.update = 1;
+		p->flag.type = 1;
+		
+		if( sd->var_db->put(sd->var_db,DB->i642key(reg),DB->ptr2data(p),&prev) ) {
+			p = DB->data2ptr(&prev);
+			if( p->value )
+				aFree(p->value);
+			ers_free(pc->str_reg_ers, p);
+		}
 	}
-
-	ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax);
-
-	return 0;
+	
+	if( !pc->reg_load && p )
+		sd->vars_dirty = true;
+	
+	return 1;
 }
 
 /*==========================================
@@ -10556,6 +10468,9 @@ void do_final_pc(void) {
 	pcg->final();
 	
 	ers_destroy(pc->sc_display_ers);
+	ers_destroy(pc->num_reg_ers);
+	ers_destroy(pc->str_reg_ers);
+
 	return;
 }
 
@@ -10599,6 +10514,12 @@ void do_init_pc(bool minimal) {
 	pcg->init();
 	
 	pc->sc_display_ers = ers_new(sizeof(struct sc_display_entry), "pc.c:sc_display_ers", ERS_OPT_NONE);
+	pc->num_reg_ers = ers_new(sizeof(struct script_reg_num), "pc.c::num_reg_ers", ERS_OPT_CLEAN);
+	pc->str_reg_ers = ers_new(sizeof(struct script_reg_str), "pc.c::str_reg_ers", ERS_OPT_CLEAN);
+
+	ers_chunk_size(pc->sc_display_ers, 150);
+	ers_chunk_size(pc->num_reg_ers, 300);
+	ers_chunk_size(pc->str_reg_ers, 50);
 }
 /*=====================================
 * Default Functions : pc.h 
@@ -10613,7 +10534,6 @@ void pc_defaults(void) {
 	};
 	unsigned int equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARMENT,EQP_HEAD_LOW,EQP_HEAD_MID,EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_GARMENT,EQP_AMMO, EQP_SHADOW_ARMOR, EQP_SHADOW_WEAPON, EQP_SHADOW_SHIELD, EQP_SHADOW_SHOES, EQP_SHADOW_ACC_R, EQP_SHADOW_ACC_L };
 
-
 	pc = &pc_s;
 
 	/* vars */
@@ -10642,6 +10562,11 @@ void pc_defaults(void) {
 	pc->sc_display_ers = NULL;
 	/* */
 	pc->expiration_tid = INVALID_TIMER;
+	/* */
+	pc->num_reg_ers = NULL;
+	pc->str_reg_ers = NULL;
+	/* */
+	pc->reg_load = false;
 	/* funcs */
 	pc->init = do_init_pc;
 	pc->final = do_final_pc;
diff --git a/src/map/pc.h b/src/map/pc.h
index 2f143f15c..f64b20945 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -139,7 +139,6 @@ struct map_session_data {
 		unsigned int abra_flag : 2; // Abracadabra bugfix by Aru
 		unsigned int autocast : 1; // Autospell flag [Inkfish]
 		unsigned int autotrade : 1;	//By Fantik
-		unsigned int reg_dirty : 4; //By Skotlex (marks whether registry variables have been saved or not yet)
 		unsigned int showdelay :1;
 		unsigned int showexp :1;
 		unsigned int showzeny :1;
@@ -203,7 +202,6 @@ struct map_session_data {
 	unsigned int extra_temp_permissions; /* permissions from @addperm */
 	
 	struct mmo_charstatus status;
-	struct registry save_reg;
 	struct item_data* inventory_data[MAX_INVENTORY]; // direct pointers to itemdb entries (faster than doing item_id lookups)
 	short equip_index[EQI_MAX];
 	unsigned int weight,max_weight;
@@ -363,10 +361,6 @@ struct map_session_data {
 	short mission_mobid; //Stores the target mob_id for TK_MISSION
 	int die_counter; //Total number of times you've died
 	int devotion[5]; //Stores the account IDs of chars devoted to.
-	int reg_num; //Number of registries (type numeric)
-	int regstr_num; //Number of registries (type string)
-	struct script_reg *reg;
-	struct script_regstr *regstr;
 	int trade_partner;
 	struct {
 		struct {
@@ -531,6 +525,16 @@ struct map_session_data {
 	struct {
 		unsigned int second,third;
 	} sktree;
+	
+	/**
+	 * Account/Char variables & array control of those variables
+	 **/
+	DBMap *var_db;
+	DBMap *array_db;
+	unsigned char vars_received;/* char loading is only complete when you get it all. */
+	bool vars_ok;
+	bool vars_dirty;
+	
 	// temporary debugging of bug #3504
 	const char* delunit_prevfile;
 	int delunit_prevline;
@@ -672,18 +676,18 @@ enum equip_pos {
 #define pc_checkoverhp(sd) ((sd)->battle_status.hp == (sd)->battle_status.max_hp)
 #define pc_checkoversp(sd) ((sd)->battle_status.sp == (sd)->battle_status.max_sp)
 
-#define pc_readglobalreg(sd,reg)         (pc->readregistry((sd),(reg),3))
-#define pc_setglobalreg(sd,reg,val)      (pc->setregistry((sd),(reg),(val),3))
-#define pc_readglobalreg_str(sd,reg)     (pc->readregistry_str((sd),(reg),3))
-#define pc_setglobalreg_str(sd,reg,val)  (pc->setregistry_str((sd),(reg),(val),3))
-#define pc_readaccountreg(sd,reg)        (pc->readregistry((sd),(reg),2))
-#define pc_setaccountreg(sd,reg,val)     (pc->setregistry((sd),(reg),(val),2))
-#define pc_readaccountregstr(sd,reg)     (pc->readregistry_str((sd),(reg),2))
-#define pc_setaccountregstr(sd,reg,val)  (pc->setregistry_str((sd),(reg),(val),2))
-#define pc_readaccountreg2(sd,reg)       (pc->readregistry((sd),(reg),1))
-#define pc_setaccountreg2(sd,reg,val)    (pc->setregistry((sd),(reg),(val),1))
-#define pc_readaccountreg2str(sd,reg)    (pc->readregistry_str((sd),(reg),1))
-#define pc_setaccountreg2str(sd,reg,val) (pc->setregistry_str((sd),(reg),(val),1))
+#define pc_readglobalreg(sd,reg)         (pc->readregistry((sd),(reg)))
+#define pc_setglobalreg(sd,reg,val)      (pc->setregistry((sd),(reg),(val)))
+#define pc_readglobalreg_str(sd,reg)     (pc->readregistry_str((sd),(reg)))
+#define pc_setglobalreg_str(sd,reg,val)  (pc->setregistry_str((sd),(reg),(val)))
+#define pc_readaccountreg(sd,reg)        (pc->readregistry((sd),(reg)))
+#define pc_setaccountreg(sd,reg,val)     (pc->setregistry((sd),(reg),(val)))
+#define pc_readaccountregstr(sd,reg)     (pc->readregistry_str((sd),(reg)))
+#define pc_setaccountregstr(sd,reg,val)  (pc->setregistry_str((sd),(reg),(val)))
+#define pc_readaccountreg2(sd,reg)       (pc->readregistry((sd),(reg)))
+#define pc_setaccountreg2(sd,reg,val)    (pc->setregistry((sd),(reg),(val)))
+#define pc_readaccountreg2str(sd,reg)    (pc->readregistry_str((sd),(reg)))
+#define pc_setaccountreg2str(sd,reg,val) (pc->setregistry_str((sd),(reg),(val)))
 
 /* pc_groups easy access */
 #define pc_get_group_level(sd) ( (sd)->group->level )
@@ -772,6 +776,13 @@ struct pc_interface {
 	struct eri *sc_display_ers;
 	/* global expiration timer id */
 	int expiration_tid;
+	/**
+	 * ERS for the bulk of pc vars
+	 **/
+	struct eri *num_reg_ers;
+	struct eri *str_reg_ers;
+	/* */
+	bool reg_load;
 	/* funcs */
 	void (*init) (bool minimal);
 	void (*final) (void);
@@ -908,14 +919,14 @@ struct pc_interface {
 	
 	int (*readparam) (struct map_session_data *sd,int type);
 	int (*setparam) (struct map_session_data *sd,int type,int val);
-	int (*readreg) (struct map_session_data *sd,int reg);
-	int (*setreg) (struct map_session_data *sd,int reg,int val);
-	char * (*readregstr) (struct map_session_data *sd,int reg);
-	int (*setregstr) (struct map_session_data *sd,int reg,const char *str);
-	int (*readregistry) (struct map_session_data *sd,const char *reg,int type);
-	int (*setregistry) (struct map_session_data *sd,const char *reg,int val,int type);
-	char * (*readregistry_str) (struct map_session_data *sd,const char *reg,int type);
-	int (*setregistry_str) (struct map_session_data *sd,const char *reg,const char *val,int type);
+	int (*readreg) (struct map_session_data *sd, int64 reg);
+	void (*setreg) (struct map_session_data *sd, int64 reg,int val);
+	char * (*readregstr) (struct map_session_data *sd, int64 reg);
+	void (*setregstr) (struct map_session_data *sd, int64 reg, const char *str);
+	int (*readregistry) (struct map_session_data *sd, int64 reg);
+	int (*setregistry) (struct map_session_data *sd, int64 reg, int val);
+	char * (*readregistry_str) (struct map_session_data *sd, int64 reg);
+	int (*setregistry_str) (struct map_session_data *sd, int64 reg, const char *val);
 	
 	int (*addeventtimer) (struct map_session_data *sd,int tick,const char *name);
 	int (*deleventtimer) (struct map_session_data *sd,const char *name);
diff --git a/src/map/script.c b/src/map/script.c
index 8bd4bc028..21d4d289c 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -212,10 +212,7 @@ void script_reportdata(struct script_data* data)
 		case C_NAME:// reference
 			if( reference_tovariable(data) ) {// variable
 				const char* name = reference_getname(data);
-				if( not_array_variable(*name) )
-					ShowDebug("Data: variable name='%s'\n", name);
-				else
-					ShowDebug("Data: variable name='%s' index=%d\n", name, reference_getindex(data));
+				ShowDebug("Data: variable name='%s' index=%d\n", name, reference_getindex(data));
 			} else if( reference_toconstant(data) ) {// constant
 				ShowDebug("Data: constant name='%s' value=%d\n", reference_getname(data), reference_getconstant(data));
 			} else if( reference_toparam(data) ) {// param
@@ -2501,9 +2498,9 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
 				break;
 			case '#':
 				if( name[1] == '#' )
-					data->u.str = pc_readaccountreg2str(sd, name);// global
+					data->u.str = pc_readaccountreg2str(sd, data->u.num);// global
 				else
-					data->u.str = pc_readaccountregstr(sd, name);// local
+					data->u.str = pc_readaccountregstr(sd, data->u.num);// local
 				break;
 			case '.':
 				{
@@ -2512,21 +2509,21 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
 							st->stack->var_function : // instance/scope variable
 							st->script->script_vars;  // npc variable
 					if( n )
-						data->u.str = (char*)idb_get(n,reference_getuid(data));
+						data->u.str = (char*)i64db_get(n,reference_getuid(data));
 					else
 						data->u.str = NULL;
 				}
 				break;
 			case '\'':
 					if ( st->instance_id >= 0 ) {
-						data->u.str = (char*)idb_get(instance->list[st->instance_id].vars,reference_getuid(data));
+						data->u.str = (char*)i64db_get(instance->list[st->instance_id].vars,reference_getuid(data));
 					} else {
 						ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to \"\"\n", name);
 						data->u.str = NULL;
 					}
 				break;
 			default:
-				data->u.str = pc_readglobalreg_str(sd, name);
+				data->u.str = pc_readglobalreg_str(sd, data->u.num);
 				break;
 		}
 
@@ -2556,9 +2553,9 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
 					break;
 				case '#':
 					if( name[1] == '#' )
-						data->u.num = pc_readaccountreg2(sd, name);// global
+						data->u.num = pc_readaccountreg2(sd, data->u.num);// global
 					else
-						data->u.num = pc_readaccountreg(sd, name);// local
+						data->u.num = pc_readaccountreg(sd, data->u.num);// local
 					break;
 				case '.':
 					{
@@ -2567,21 +2564,21 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
 								st->stack->var_function : // instance/scope variable
 								st->script->script_vars;  // npc variable
 						if( n )
-							data->u.num = (int)idb_iget(n,reference_getuid(data));
+							data->u.num = (int)i64db_iget(n,reference_getuid(data));
 						else
 							data->u.num = 0;
 					}
 					break;
 				case '\'':
 						if( st->instance_id >= 0 )
-							data->u.num = (int)idb_iget(instance->list[st->instance_id].vars,reference_getuid(data));
+							data->u.num = (int)i64db_iget(instance->list[st->instance_id].vars,reference_getuid(data));
 						else {
 							ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to 0\n", name);
 							data->u.num = 0;
 						}
 					break;
 				default:
-					data->u.num = pc_readglobalreg(sd, name);
+					data->u.num = pc_readglobalreg(sd, data->u.num);
 					break;
 			}
 
@@ -2592,63 +2589,245 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
 
 /// Retrieves the value of a reference identified by uid (variable, constant, param)
 /// The value is left in the top of the stack and needs to be removed manually.
-void* get_val2(struct script_state* st, int uid, struct DBMap** ref) {
+void* get_val2(struct script_state* st, int64 uid, struct DBMap** ref) {
 	struct script_data* data;
 	script->push_val(st->stack, C_NAME, uid, ref);
 	data = script_getdatatop(st, -1);
 	script->get_val(st, data);
 	return (data->type == C_INT ? (void*)__64BPTRSIZE(data->u.num) : (void*)__64BPTRSIZE(data->u.str));
 }
+/**
+ * Returns array size by ID
+ **/
+unsigned int script_array_size(struct script_state *st, struct map_session_data *sd, const char *name) {
+	struct script_array *sa = NULL;
+	struct DBMap *src = script->array_src(st, sd, name);
+	
+	if( src )
+		sa = idb_get(src, script->search_str(name));
+	
+	return sa ? sa->size : 0;
+}
+/**
+ * Returns array's highest key (for that awful getarraysize implementation that doesn't really gets the array size)
+ **/
+unsigned int script_array_highest_key(struct script_state *st, struct map_session_data *sd, const char *name) {
+	struct script_array *sa = NULL;
+	struct DBMap *src = script->array_src(st, sd, name);
+		
+	if( src && ( sa = idb_get(src, script->search_str(name)) ) ) {
+		unsigned int i, highest_key = 0;
+		
+		for(i = 0; i < sa->size; i++) {
+			if( sa->members[i] > highest_key )
+				highest_key = sa->members[i];
+		}
+		
+		return highest_key + 1;
+	}
+	
+	return 0;
+}
+int script_free_array_db(DBKey key, DBData *data, va_list ap) {
+	struct script_array *sa = DB->data2ptr(data);
+	aFree(sa->members);
+	ers_free(script->array_ers, sa);
+	return 0;
+}
+/**
+ * Clears script_array and removes it from script->array_db
+ **/
+void script_array_delete(struct DBMap *src, struct script_array *sa) {
+	aFree(sa->members);
+	idb_remove(src, sa->id);
+	ers_free(script->array_ers, sa);
+}
+/**
+ * Removes a member from a script_array list
+ *
+ * @param idx the index of the member in script_array struct list, not of the actual array member
+ **/
+void script_array_remove_member(struct DBMap *src,struct script_array *sa, unsigned int idx) {
+	unsigned int i, cursor;
+	
+	/* its the only member left, no need to do anything other than delete the array data */
+	if( sa->size == 1 ) {
+		script->array_delete(src,sa);
+		return;
+	}
+	
+	sa->members[idx] = UINT_MAX;
+	
+	for(i = 0, cursor = 0; i < sa->size; i++) {
+		if( sa->members[i] == UINT_MAX )
+			continue;
+		if( i != cursor )
+			sa->members[cursor] = sa->members[i];
+		cursor++;
+	}
+	
+	sa->size = cursor;
+}
+/**
+ * Appends a new array index to the list in script_array
+ *
+ * @param idx the index of the array member being inserted
+ **/
+void script_array_add_member(struct script_array *sa, unsigned int idx) {
+	
+	RECREATE(sa->members, unsigned int, ++sa->size);
+	
+	sa->members[sa->size - 1] = idx;
 
+}
+/**
+ * Obtains the source of the array database for this type and scenario
+ * Initializes such database when not yet initialised.
+ **/
+struct DBMap *script_array_src(struct script_state *st, struct map_session_data *sd, const char *name) {
+	struct DBMap **src = NULL;
+	
+	switch( name[0] ) {
+		/* from player */
+		default: /* char reg */
+		case '@':/* temp char reg */
+		case '#':/* account reg */
+			src = &sd->array_db;
+			break;
+		case '$':/* map reg */
+			src = &mapreg->array_db;
+			break;
+		case '.':/* npc/script */
+			src = (name[1] == '@') ? &st->stack->array_function_db : &st->script->script_arrays_db;
+			break;
+		case '\'':/* instance */
+			if( st->instance_id >= 0 ) {
+				src = &instance->list[st->instance_id].array_db;
+			}
+			break;
+	}
+	
+	if( src ) {
+		if( !*src )
+			*src = idb_alloc(DB_OPT_BASE);
+		return *src;
+	}
+	
+	return NULL;
+}
+/**
+ * Processes a array member modification, and update data accordingly
+ **/
+void script_array_update(struct DBMap **src, int64 num, bool empty) {
+	struct script_array *sa = NULL;
+	int id = script_getvarid(num);
+	unsigned int index = script_getvaridx(num);
+	
+	if( !*src ) {
+		*src = idb_alloc(DB_OPT_BASE);
+	} else {
+		sa = idb_get(*src, id);
+	}
+			
+	if( sa ) {
+		unsigned int i;
+		
+		/* search */
+		for(i = 0; i < sa->size; i++) {
+			if( sa->members[i] == index )
+				break;
+		}
+		
+		/* if existent */
+		if( i != sa->size ) {
+			/* if empty, we gotta remove it */
+			if( empty ) {
+				script->array_remove_member(*src,sa,i);
+			}
+		} else if( !empty ) { /* new entry */
+			script->array_add_member(sa,index);
+			/* we do nothing if its empty, no point in modifying array data for a new empty member */
+		}
+	} else if ( !empty ) {/* we only move to create if not empty */
+		sa = ers_alloc(script->array_ers, struct script_array);
+		sa->id = id;
+		script->array_add_member(sa,index);
+		idb_put(*src, id, sa);
+	}
+}
 /*==========================================
  * Stores the value of a script variable
  * Return value is 0 on fail, 1 on success.
+ * TODO: return values are screwed up, have been for some time (reaad: years), e.g. some functions return 1 failure and success. 
  *------------------------------------------*/
-int set_reg(struct script_state* st, TBL_PC* sd, int num, const char* name, const void* value, struct DBMap** ref)
-{
+int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, const void* value, struct DBMap** ref) {
 	char prefix = name[0];
+	
+	if( is_string_variable(name) ) {// string variable
+		const char *str = (const char*)value;
 
-	if( is_string_variable(name) )
-	{// string variable
-		const char* str = (const char*)value;
 		switch (prefix) {
-		case '@':
-			return pc->setregstr(sd, num, str);
-		case '$':
-			return mapreg->setregstr(num, str);
-		case '#':
-			return (name[1] == '#') ?
-				pc_setaccountreg2str(sd, name, str) :
-				pc_setaccountregstr(sd, name, str);
-		case '.':
-			{
-				struct DBMap* n;
-				n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars;
-				if( n ) {
-					idb_remove(n, num);
-					if (str[0]) idb_put(n, num, aStrdup(str));
+			case '@':
+				pc->setregstr(sd, num, str);
+				return 1;
+			case '$':
+				return mapreg->setregstr(num, str);
+			case '#':
+				return (name[1] == '#') ?
+					pc_setaccountreg2str(sd, num, str) :
+					pc_setaccountregstr(sd, num, str);
+			case '.':
+				{
+					struct DBMap* n;
+					n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars;
+					if( n ) {
+						if (str[0])  {
+							i64db_put(n, num, aStrdup(str));
+							if( script_getvaridx(num) )
+								script->array_update(
+													 (name[1] == '@') ?
+														&st->stack->array_function_db :
+														&st->script->script_arrays_db,
+													 num,
+													 false);
+						} else {
+							i64db_remove(n, num);
+							if( script_getvaridx(num) )
+								script->array_update(
+													 (name[1] == '@') ?
+													 &st->stack->array_function_db :
+													 &st->script->script_arrays_db,
+													 num,
+													 true);
+						}
+					}
 				}
-			}
-			return 1;
-		case '\'':
-			if( st->instance_id >= 0 ) {
-				idb_remove(instance->list[st->instance_id].vars, num);
-				if( str[0] ) idb_put(instance->list[st->instance_id].vars, num, aStrdup(str));
-			}
-			return 1;
-		default:
-			return pc_setglobalreg_str(sd, name, str);
+				return 1;
+			case '\'':
+				if( st->instance_id >= 0 ) {
+					if( str[0] ) {
+						i64db_put(instance->list[st->instance_id].vars, num, aStrdup(str));
+						if( script_getvaridx(num) )
+							script->array_update(&instance->list[st->instance_id].array_db,num,false);
+					} else {
+						i64db_remove(instance->list[st->instance_id].vars, num);
+						if( script_getvaridx(num) )
+							script->array_update(&instance->list[st->instance_id].array_db,num,true);
+					}
+				} else {
+					ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name);
+					script_reportsrc(st);
+				}
+				return 1;
+			default:
+				return pc_setglobalreg_str(sd, num, str);
 		}
-	}
-	else
-	{// integer variable
+	} else {// integer variable
 		int val = (int)__64BPTRSIZE(value);
-		if(script->str_data[num&0x00ffffff].type == C_PARAM)
-		{
-			if( pc->setparam(sd, script->str_data[num&0x00ffffff].val, val) == 0 )
-			{
-				if( st != NULL )
-				{
+
+		if(script->str_data[script_getvarid(num)].type == C_PARAM) {
+			if( pc->setparam(sd, script->str_data[script_getvarid(num)].val, val) == 0 ) {
+				if( st != NULL ) {
 					ShowError("script:set_reg: failed to set param '%s' to %d.\n", name, val);
 					script->reportsrc(st);
 					st->state = END;
@@ -2659,34 +2838,60 @@ int set_reg(struct script_state* st, TBL_PC* sd, int num, const char* name, cons
 		}
 
 		switch (prefix) {
-		case '@':
-			return pc->setreg(sd, num, val);
-		case '$':
-			return mapreg->setreg(num, val);
-		case '#':
-			return (name[1] == '#') ?
-				pc_setaccountreg2(sd, name, val) :
-				pc_setaccountreg(sd, name, val);
-		case '.':
-			{
-				struct DBMap* n;
-				n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars;
-				if( n ) {
-					idb_remove(n, num);
-					if( val != 0 )
-						idb_iput(n, num, val);
+			case '@':
+				pc->setreg(sd, num, val);
+				return 1;
+			case '$':
+				return mapreg->setreg(num, val);
+			case '#':
+				return (name[1] == '#') ?
+					pc_setaccountreg2(sd, num, val) :
+					pc_setaccountreg(sd, num, val);
+			case '.':
+				{
+					struct DBMap* n;
+					n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars;
+					if( n ) {
+						if( val != 0 ) {
+							i64db_iput(n, num, val);
+							if( script_getvaridx(num) )
+								script->array_update(
+													 (name[1] == '@') ?
+													 &st->stack->array_function_db :
+													 &st->script->script_arrays_db,
+													 num,
+													 false);
+						} else {
+							i64db_remove(n, num);
+							if( script_getvaridx(num) )
+								script->array_update(
+													 (name[1] == '@') ?
+													 &st->stack->array_function_db :
+													 &st->script->script_arrays_db,
+													 num,
+													 true);
+						}
+					}
 				}
-			}
-			return 1;
-		case '\'':
-			if( st->instance_id >= 0 ) {
-				idb_remove(instance->list[st->instance_id].vars, num);
-				if( val != 0 )
-					idb_iput(instance->list[st->instance_id].vars, num, val);
-			}
-			return 1;
-		default:
-			return pc_setglobalreg(sd, name, val);
+				return 1;
+			case '\'':
+				if( st->instance_id >= 0 ) {
+					if( val != 0 ) {
+						i64db_iput(instance->list[st->instance_id].vars, num, val);
+						if( script_getvaridx(num) )
+							script->array_update(&instance->list[st->instance_id].array_db,num,false);
+					} else {
+						i64db_remove(instance->list[st->instance_id].vars, num);
+						if( script_getvaridx(num) )
+							script->array_update(&instance->list[st->instance_id].array_db,num,true);
+					}
+				} else {
+					ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name);
+					script_reportsrc(st);
+				}
+				return 1;
+			default:
+				return pc_setglobalreg(sd, num, val);
 		}
 	}
 }
@@ -2712,7 +2917,7 @@ const char* conv_str(struct script_state* st, struct script_data* data)
 	else if( data_isint(data) )
 	{// int -> string
 		CREATE(p, char, ITEM_NAME_LENGTH);
-		snprintf(p, ITEM_NAME_LENGTH, "%d", data->u.num);
+		snprintf(p, ITEM_NAME_LENGTH, "%lld", data->u.num);
 		p[ITEM_NAME_LENGTH-1] = '\0';
 		data->type = C_STR;
 		data->u.str = p;
@@ -2786,7 +2991,7 @@ int conv_num(struct script_state* st, struct script_data* data) {
 		data->u.num = 0;
 	}
 #endif
-	return data->u.num;
+	return (int)data->u.num;
 }
 
 //
@@ -2803,7 +3008,7 @@ void stack_expand(struct script_stack* stack) {
 }
 
 /// Pushes a value into the stack (with reference)
-struct script_data* push_val(struct script_stack* stack, enum c_op type, int val, struct DBMap** ref) {
+struct script_data* push_val(struct script_stack* stack, enum c_op type, int64 val, struct DBMap** ref) {
 	if( stack->sp >= stack->sp_max )
 		script->stack_expand(stack);
 	stack->stack_data[stack->sp].type  = type;
@@ -2932,6 +3137,8 @@ void script_free_vars(struct DBMap* var_storage) {
 void script_free_code(struct script_code* code)
 {
 	script->free_vars( code->script_vars );
+	if( code->script_arrays_db )
+		code->script_arrays_db->destroy(code->script_arrays_db,script->array_free_db);
 	aFree( code->script_buf );
 	aFree( code );
 }
@@ -2952,7 +3159,8 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
 	st->stack->sp_max = 64;
 	CREATE(st->stack->stack_data, struct script_data, st->stack->sp_max);
 	st->stack->defsp = st->stack->sp;
-	st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
+	st->stack->var_function = i64db_alloc(DB_OPT_RELEASE_DATA);
+	st->stack->array_function_db = NULL;
 	st->state = RUN;
 	st->script = rootscript;
 	st->pos = pos;
@@ -2962,7 +3170,7 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
 	st->npc_item_flag = battle_config.item_enabled_npc;
 
 	if( !st->script->script_vars )
-		st->script->script_vars = idb_alloc(DB_OPT_RELEASE_DATA);
+		st->script->script_vars = i64db_alloc(DB_OPT_RELEASE_DATA);
 
 	st->id = script->next_id++;
 	script->active_scripts++;
@@ -2985,14 +3193,22 @@ void script_free_state(struct script_state* st) {
 			timer->delete(st->sleep.timer, script->run_timer);
 		if( st->stack ) {
 			script->free_vars(st->stack->var_function);
+			if( st->stack->array_function_db )
+				st->stack->array_function_db->destroy(st->stack->array_function_db,script->array_free_db);
 			script->pop_stack(st, 0, st->stack->sp);
 			aFree(st->stack->stack_data);
 			ers_free(script->stack_ers, st->stack);
 			st->stack = NULL;
 		}
-		if( st->script && st->script->script_vars && !db_size(st->script->script_vars) ) {
-			script->free_vars(st->script->script_vars);
-			st->script->script_vars = NULL;
+		if( st->script ) {
+			if( st->script->script_vars && !db_size(st->script->script_vars) ) {
+				script->free_vars(st->script->script_vars);
+				st->script->script_vars = NULL;
+			}
+			if( st->script->script_arrays_db && !db_size(st->script->script_arrays_db) ) {
+				script->free_vars(st->script->script_arrays_db);
+				st->script->script_arrays_db = NULL;
+			}
 		}
 		st->pos = -1;
 		idb_remove(script->st_db, st->id);
@@ -3037,20 +3253,6 @@ int get_num(unsigned char *scriptbuf,int *pos)
 	return i+((scriptbuf[(*pos)++]&0x7f)<<j);
 }
 
-/*==========================================
- * Remove the value from the stack
- *------------------------------------------*/
-int pop_val(struct script_state* st)
-{
-	if(st->stack->sp<=0)
-		return 0;
-	st->stack->sp--;
-	script->get_val(st,&(st->stack->stack_data[st->stack->sp]));
-	if(st->stack->stack_data[st->stack->sp].type==C_INT)
-		return st->stack->stack_data[st->stack->sp].u.num;
-	return 0;
-}
-
 /// Ternary operators
 /// test ? if_true : if_false
 void op_3(struct script_state* st, int op)
@@ -3064,7 +3266,7 @@ void op_3(struct script_state* st, int op)
 	if( data_isstring(data) )
 		flag = data->u.str[0];// "" -> false
 	else if( data_isint(data) )
-		flag = data->u.num;// 0 -> false
+		flag = data->u.num == 0 ? 0 : 1;// 0 -> false
 	else
 	{
 		ShowError("script:op_3: invalid data for the ternary operator test\n");
@@ -3234,8 +3436,8 @@ void op_2(struct script_state *st, int op)
 	}
 	else if( data_isint(left) && data_isint(right) )
 	{// ii => op_2num
-		int i1 = left->u.num;
-		int i2 = right->u.num;
+		int i1 = (int)left->u.num;
+		int i2 = (int)right->u.num;
 
 		script_removetop(st, leftref.type == C_NOP ? -2 : -1, 0);
 		script->op_2num(st, op, i1, i2);
@@ -3277,19 +3479,18 @@ void op_1(struct script_state* st, int op)
 		return;
 	}
 
-	i1 = data->u.num;
+	i1 = (int)data->u.num;
 	script_removetop(st, -1, 0);
-	switch( op )
-	{
-	case C_NEG: i1 = -i1; break;
-	case C_NOT: i1 = ~i1; break;
-	case C_LNOT: i1 = !i1; break;
-	default:
-		ShowError("script:op_1: unexpected operator %s i1=%d\n", script->op2name(op), i1);
-		script->reportsrc(st);
-		script_pushnil(st);
-		st->state = END;
-		return;
+	switch( op ) {
+		case C_NEG: i1 = -i1; break;
+		case C_NOT: i1 = ~i1; break;
+		case C_LNOT: i1 = !i1; break;
+		default:
+			ShowError("script:op_1: unexpected operator %s i1=%d\n", script->op2name(op), i1);
+			script->reportsrc(st);
+			script_pushnil(st);
+			st->state = END;
+			return;
 	}
 	script_pushint(st, i1);
 }
@@ -3400,7 +3601,7 @@ int run_func(struct script_state *st)
 
 	data = &st->stack->stack_data[st->start];
 	if( data->type == C_NAME && script->str_data[data->u.num].type == C_FUNC )
-		func = data->u.num;
+		func = (int)data->u.num;
 	else
 	{
 		ShowError("script:run_func: not a buildin command.\n");
@@ -3418,7 +3619,7 @@ int run_func(struct script_state *st)
 		if (!(script->str_data[func].func(st))) //Report error
 			script->reportsrc(st);
 	} else {
-		ShowError("script:run_func: '%s' (id=%d type=%s) has no C function. please report this!!!\n", script->get_str(func), func, script->op2name(script->str_data[func].type));
+		ShowError("script:run_func: '%s' (id=%lld type=%s) has no C function. please report this!!!\n", script->get_str(func), func, script->op2name(script->str_data[func].type));
 		script->reportsrc(st);
 		st->state = END;
 	}
@@ -3723,10 +3924,8 @@ void run_script_main(struct script_state *st) {
 			}
 			//Restore previous script if any.
 			script->detach_state(st, true);
-			if (sd->state.reg_dirty&2)
-				intif->saveregistry(sd,2);
-			if (sd->state.reg_dirty&1)
-				intif->saveregistry(sd,1);
+			if (sd->vars_dirty)
+				intif->saveregistry(sd);
 		}
 		script->free_state(st);
 		st = NULL;
@@ -3813,70 +4012,99 @@ void script_add_autobonus(const char *autobonus)
 
 
 /// resets a temporary character array variable to given value
-void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value)
-{
+void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value) {
+	struct script_array *sa = NULL;
+	struct DBMap *src = NULL;
+	unsigned int i, *list = NULL, size = 0;
 	int key;
-	uint8 idx;
-
-	if( not_array_variable(varname[0]) || !not_server_variable(varname[0]) )
-	{
-		ShowError("script_cleararray_pc: Variable '%s' has invalid scope (char_id=%d).\n", varname, sd->status.char_id);
-		return;
-	}
 
 	key = script->add_str(varname);
-
-	if( is_string_variable(varname) )
-	{
-		for( idx = 0; idx < SCRIPT_MAX_ARRAYSIZE; idx++ )
-		{
-			pc->setregstr(sd, reference_uid(key, idx), (const char*)value);
-		}
-	}
-	else
-	{
-		for( idx = 0; idx < SCRIPT_MAX_ARRAYSIZE; idx++ )
-		{
-			pc->setreg(sd, reference_uid(key, idx), (int)__64BPTRSIZE(value));
-		}
+	
+	if( !(src = script->array_src(NULL,sd,varname) ) )
+		return;
+	
+	if( !(sa = idb_get(src, key)) ) /* non-existent array, nothing to empty */
+		return;
+	
+	size = sa->size;
+	list = script->array_cpy_list(sa);
+	
+	for(i = 0; i < size; i++) {
+		script->set_reg(NULL,sd,reference_uid(key, list[i]),varname,value,NULL);
 	}
 }
 
 
 /// sets a temporary character array variable element idx to given value
 /// @param refcache Pointer to an int variable, which keeps a copy of the reference to varname and must be initialized to 0. Can be NULL if only one element is set.
-void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 idx, void* value, int* refcache)
-{
+void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32 idx, void* value, int* refcache) {
 	int key;
-
-	if( not_array_variable(varname[0]) || !not_server_variable(varname[0]) )
-	{
-		ShowError("script_setarray_pc: Variable '%s' has invalid scope (char_id=%d).\n", varname, sd->status.char_id);
-		return;
-	}
-
-	if( idx >= SCRIPT_MAX_ARRAYSIZE )
-	{
-		ShowError("script_setarray_pc: Variable '%s' has invalid index '%d' (char_id=%d).\n", varname, (int)idx, sd->status.char_id);
+	
+	if( idx >= SCRIPT_MAX_ARRAYSIZE ) {
+		ShowError("script_setarray_pc: Variable '%s' has invalid index '%u' (char_id=%d).\n", varname, idx, sd->status.char_id);
 		return;
 	}
 
 	key = ( refcache && refcache[0] ) ? refcache[0] : script->add_str(varname);
-
-	if( is_string_variable(varname) )
-	{
-		pc->setregstr(sd, reference_uid(key, idx), (const char*)value);
-	}
-	else
-	{
-		pc->setreg(sd, reference_uid(key, idx), (int)__64BPTRSIZE(value));
-	}
-
+	
+	script->set_reg(NULL,sd,reference_uid(key, idx),varname,value,NULL);
+	
 	if( refcache )
 	{// save to avoid repeated script->add_str calls
 		refcache[0] = key;
 	}
 }
+/**
+ * Clears persistent variables from memory
+ **/
+int script_reg_destroy(DBKey key, DBData *data, va_list ap) {
+	void *src;
+	
+	if( data->type != DB_DATA_PTR )/* got no need for those! */
+		return 0;
+	
+	src = DB->data2ptr(data);
+	
+	if( ((struct script_reg_state*)src)->type ) {
+		struct script_reg_str *p = src;
+		
+		if( p->value )
+			aFree(p->value);
+		
+		ers_free(pc->str_reg_ers,p);
+	} else {
+		ers_free(pc->num_reg_ers,(struct script_reg_num*)src);
+	}
+	
+	return 0;
+}
+/**
+ * Clears a single persistent variable
+ **/
+void script_reg_destroy_single(struct map_session_data *sd, int64 reg, struct script_reg_state *data) {
+	i64db_remove(sd->var_db, reg);
+
+	if( data->type ) {
+		struct script_reg_str *p = (struct script_reg_str*)data;
+		
+		if( p->value )
+			aFree(p->value);
+		
+		ers_free(pc->str_reg_ers,p);
+	} else {
+		ers_free(pc->num_reg_ers,(struct script_reg_num*)data);
+	}
+}
+unsigned int *script_array_cpy_list(struct script_array *sa) {
+	if( sa->size > script->generic_ui_array_size )
+		script->generic_ui_array_expand(sa->size);
+	memcpy(script->generic_ui_array, sa->members, sizeof(unsigned int)*sa->size);
+	return script->generic_ui_array;
+}
+void script_generic_ui_array_expand (unsigned int plus) {
+	script->generic_ui_array_size += plus + 100;
+	RECREATE(script->generic_ui_array, unsigned int, script->generic_ui_array_size);
+}
 /*==========================================
  * Destructor
  *------------------------------------------*/
@@ -4005,6 +4233,11 @@ void do_final_script(void) {
 
 	if( script->labels != NULL )
 		aFree(script->labels);
+	
+	ers_destroy(script->array_ers);
+	
+	if( script->generic_ui_array )
+		aFree(script->generic_ui_array);
 }
 /*==========================================
  * Initialization
@@ -4016,6 +4249,7 @@ void do_init_script(bool minimal) {
 
 	script->st_ers = ers_new(sizeof(struct script_state), "script.c::st_ers", ERS_OPT_CLEAN);
 	script->stack_ers = ers_new(sizeof(struct script_stack), "script.c::script_stack", ERS_OPT_NONE);
+	script->array_ers = ers_new(sizeof(struct script_array), "script.c::array_ers", ERS_OPT_CLEAN|ERS_OPT_CLEAR);
 
 	ers_chunk_size(script->st_ers, 10);
 	ers_chunk_size(script->stack_ers, 10);
@@ -4073,7 +4307,7 @@ const char *script_getfuncname(struct script_state *st) {
 	data = &st->stack->stack_data[st->start];
 
 	if( data->type == C_NAME && script->str_data[data->u.num].type == C_FUNC )
-		return script->get_str(data->u.num);
+		return script->get_str(script_getvarid(data->u.num));
 
 	return NULL;
 }
@@ -4568,7 +4802,7 @@ BUILDIN(callfunc)
 	st->script = scr;
 	st->stack->defsp = st->stack->sp;
 	st->state = GOTO;
-	st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
+	st->stack->var_function = i64db_alloc(DB_OPT_RELEASE_DATA);
 
 	return true;
 }
@@ -4617,7 +4851,7 @@ BUILDIN(callsub)
 	st->pos = pos;
 	st->stack->defsp = st->stack->sp;
 	st->state = GOTO;
-	st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
+	st->stack->var_function = i64db_alloc(DB_OPT_RELEASE_DATA);
 
 	return true;
 }
@@ -5150,7 +5384,7 @@ BUILDIN(input)
 {
 	TBL_PC* sd;
 	struct script_data* data;
-	int uid;
+	int64 uid;
 	const char* name;
 	int min;
 	int max;
@@ -5214,7 +5448,7 @@ BUILDIN(setr) {
 	TBL_PC* sd = NULL;
 	struct script_data* data;
 	//struct script_data* datavalue;
-	int num;
+	int64 num;
 	const char* name;
 	char prefix;
 
@@ -5292,34 +5526,6 @@ BUILDIN(setr) {
 /// Array variables
 ///
 
-/// Returns the size of the specified array
-int32 getarraysize(struct script_state* st, int32 id, int32 idx, int isstring, struct DBMap** ref)
-{
-	int32 ret = idx;
-
-	if( isstring )
-	{
-		for( ; idx < SCRIPT_MAX_ARRAYSIZE; ++idx )
-		{
-			char* str = (char*)script->get_val2(st, reference_uid(id, idx), ref);
-			if( str && *str )
-				ret = idx + 1;
-			script_removetop(st, -1, 0);
-		}
-	}
-	else
-	{
-		for( ; idx < SCRIPT_MAX_ARRAYSIZE; ++idx )
-		{
-			int32 num = (int32)__64BPTRSIZE(script->get_val2(st, reference_uid(id, idx), ref));
-			if( num )
-				ret = idx + 1;
-			script_removetop(st, -1, 0);
-		}
-	}
-	return ret;
-}
-
 /// Sets values of an array, from the starting index.
 /// ex: setarray arr[1],1,2,3;
 ///
@@ -5346,13 +5552,6 @@ BUILDIN(setarray)
 	id = reference_getid(data);
 	start = reference_getindex(data);
 	name = reference_getname(data);
-	if( not_array_variable(*name) )
-	{
-		ShowError("script:setarray: illegal scope\n");
-		script->reportdata(data);
-		st->state = END;
-		return false;// not supported
-	}
 
 	if( not_server_variable(*name) )
 	{
@@ -5404,13 +5603,6 @@ BUILDIN(cleararray)
 	id = reference_getid(data);
 	start = reference_getindex(data);
 	name = reference_getname(data);
-	if( not_array_variable(*name) )
-	{
-		ShowError("script:cleararray: illegal scope\n");
-		script->reportdata(data);
-		st->state = END;
-		return false;// not supported
-	}
 
 	if( not_server_variable(*name) )
 	{
@@ -5469,14 +5661,6 @@ BUILDIN(copyarray)
 	idx2 = reference_getindex(data2);
 	name1 = reference_getname(data1);
 	name2 = reference_getname(data2);
-	if( not_array_variable(*name1) || not_array_variable(*name2) )
-	{
-		ShowError("script:copyarray: illegal scope\n");
-		script->reportdata(data1);
-		script->reportdata(data2);
-		st->state = END;
-		return false;// not supported
-	}
 
 	if( is_string_variable(name1) != is_string_variable(name2) )
 	{
@@ -5534,7 +5718,6 @@ BUILDIN(copyarray)
 BUILDIN(getarraysize)
 {
 	struct script_data* data;
-	const char* name;
 
 	data = script_getdata(st, 2);
 	if( !data_isreference(data) )
@@ -5546,19 +5729,12 @@ BUILDIN(getarraysize)
 		return false;// not a variable
 	}
 
-	name = reference_getname(data);
-	if( not_array_variable(*name) )
-	{
-		ShowError("script:getarraysize: illegal scope\n");
-		script->reportdata(data);
-		script_pushnil(st);
-		st->state = END;
-		return false;// not supported
-	}
-
-	script_pushint(st, script->getarraysize(st, reference_getid(data), reference_getindex(data), is_string_variable(name), reference_getref(data)));
+	script_pushint(st, script->array_highest_key(st,st->rid ? script->rid2sd(st) : NULL,reference_getname(data)));
 	return true;
 }
+int script_array_index_cmp(const void *a, const void *b) {
+	return ( *(unsigned int*)a - *(unsigned int*)b );
+}
 
 /// Deletes count or all the elements in an array, from the starting index.
 /// ex: deletearray arr[4],2;
@@ -5569,10 +5745,12 @@ BUILDIN(deletearray)
 {
 	struct script_data* data;
 	const char* name;
-	int start;
-	int end;
+	unsigned int start, end, i;
 	int id;
 	TBL_PC *sd = NULL;
+	struct script_array *sa = NULL;
+	struct DBMap *src = NULL;
+	void *value;
 
 	data = script_getdata(st, 2);
 	if( !data_isreference(data) )
@@ -5586,13 +5764,6 @@ BUILDIN(deletearray)
 	id = reference_getid(data);
 	start = reference_getindex(data);
 	name = reference_getname(data);
-	if( not_array_variable(*name) )
-	{
-		ShowError("script:deletearray: illegal scope\n");
-		script->reportdata(data);
-		st->state = END;
-		return false;// not supported
-	}
 
 	if( not_server_variable(*name) )
 	{
@@ -5601,39 +5772,81 @@ BUILDIN(deletearray)
 			return true;// no player attached
 	}
 
-	end = SCRIPT_MAX_ARRAYSIZE;
+	if( !(src = script->array_src(st,sd,name) ) ) {
+		ShowError("script:deletearray: not a array\n");
+		script->reportdata(data);
+		st->state = END;
+		return false;// not a variable
+	} else if ( !(sa = idb_get(src, id)) ) { /* non-existent array, nothing to empty */
+		ShowError("script:deletearray: unknown array\n");
+		script->reportdata(data);
+		st->state = END;
+		return false;// not a variable
+	}
 
+	end = script->array_highest_key(st,sd,name);
+	
 	if( start >= end )
 		return true;// nothing to free
 
-	if( script_hasdata(st,3) )
-	{
-		int count = script_getnum(st, 3);
+	if( is_string_variable(name) )
+		value = (void *)"";
+	else
+		value = (void *)0;
+	
+	if( script_hasdata(st,3) ) {
+		unsigned int count = script_getnum(st, 3);
 		if( count > end - start )
 			count = end - start;
 		if( count <= 0 )
 			return true;// nothing to free
 
-		// move rest of the elements backward
-		for( ; start + count < end; ++start )
-		{
-			void* v = script->get_val2(st, reference_uid(id, start + count), reference_getref(data));
-			script->set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data));
-			script_removetop(st, -1, 0);
+		if( end - start < sa->size ) {
+			// Better to iterate directly on the array, no speed-up from using sa
+			for( ; start + count < end; ++start ) {
+				// Compact and overwrite
+				void* v = script->get_val2(st, reference_uid(id, start + count), reference_getref(data));
+				script->set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data));
+				script_removetop(st, -1, 0);
+			}
+			for( ; start < end; start++ ) {
+				// Clean up any leftovers that weren't overwritten
+				script->set_reg(st, sd, reference_uid(id, start), name, value, reference_getref(data));
+			}
+		} else {
+			// using sa to speed up
+			unsigned int *list = NULL, size = 0;
+			list = script->array_cpy_list(sa);
+			size = sa->size;
+			qsort(list, size, sizeof(unsigned int), script_array_index_cmp);
+			
+			ARR_FIND(0, size, i, list[i] >= start);
+			
+			for( ; i < size && list[i] < start + count; i++ ) {
+				// Clear any entries between start and start+count, if they exist
+				script->set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data));
+			}
+			
+			for( ; i < size && list[i] < end; i++ ) {
+				// Move back count positions any entries between start+count to fill the gaps
+				void* v = script->get_val2(st, reference_uid(id, list[i]), reference_getref(data));
+				script->set_reg(st, sd, reference_uid(id, list[i]-count), name, v, reference_getref(data));
+				script_removetop(st, -1, 0);
+				// Clear their originals
+				script->set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data));
+			}
+		}
+	} else {
+		unsigned int *list = NULL, size = 0;
+		list = script->array_cpy_list(sa);
+		size = sa->size;
+		
+		for(i = 0; i < size; i++) {
+			if( list[i] >= start ) // Less expensive than sorting it, most likely
+				script->set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data));
 		}
 	}
 
-	// clear the rest of the array
-	if( is_string_variable(name) )
-	{
-		for( ; start < end; ++start )
-			script->set_reg(st, sd, reference_uid(id, start), name, (void *)"", reference_getref(data));
-	}
-	else
-	{
-		for( ; start < end; ++start )
-			script->set_reg(st, sd, reference_uid(id, start), name, (void*)0, reference_getref(data));
-	}
 	return true;
 }
 
@@ -5646,7 +5859,7 @@ BUILDIN(getelementofarray)
 	struct script_data* data;
 	const char* name;
 	int32 id;
-	int i;
+	int64 i;
 
 	data = script_getdata(st, 2);
 	if( !data_isreference(data) )
@@ -5659,27 +5872,18 @@ BUILDIN(getelementofarray)
 	}
 
 	id = reference_getid(data);
-	name = reference_getname(data);
-	if( not_array_variable(*name) )
-	{
-		ShowError("script:getelementofarray: illegal scope\n");
-		script->reportdata(data);
-		script_pushnil(st);
-		st->state = END;
-		return false;// not supported
-	}
 
 	i = script_getnum(st, 3);
 	if( i < 0 || i >= SCRIPT_MAX_ARRAYSIZE )
 	{
-		ShowWarning("script:getelementofarray: index out of range (%d)\n", i);
+		ShowWarning("script:getelementofarray: index out of range (%lld)\n", i);
 		script->reportdata(data);
 		script_pushnil(st);
 		st->state = END;
 		return false;// out of range
 	}
 
-	script->push_val(st->stack, C_NAME, reference_uid(id, i), reference_getref(data));
+	script->push_val(st->stack, C_NAME, reference_uid(id, (unsigned int)i), reference_getref(data));
 	return true;
 }
 
@@ -5976,19 +6180,13 @@ BUILDIN(checkweight2)
 	name_it = reference_getname(data_it);
 	name_nb = reference_getname(data_nb);
 
-	if( not_array_variable(*name_it) || not_array_variable(*name_nb))
-	{
-		ShowError("script:checkweight2: illegal scope\n");
-		script_pushint(st,0);
-		return false;// not supported
-	}
 	if(is_string_variable(name_it) || is_string_variable(name_nb)) {
 		ShowError("script:checkweight2: illegal type, need int\n");
 		script_pushint(st,0);
 		return false;// not supported
 	}
-	nb_it = script->getarraysize(st, id_it, idx_it, 0, reference_getref(data_it));
-	nb_nb = script->getarraysize(st, id_nb, idx_nb, 0, reference_getref(data_nb));
+	nb_it = script->array_highest_key(st,sd,reference_getname(data_it));
+	nb_nb = script->array_highest_key(st,sd,reference_getname(data_nb));
 	if(nb_it != nb_nb) {
 		ShowError("Size mistmatch: nb_it=%d, nb_nb=%d\n",nb_it,nb_nb);
 		fail = 1;
@@ -12810,7 +13008,7 @@ BUILDIN(getmapxy)
 	struct block_list *bl = NULL;
 	TBL_PC *sd=NULL;
 
-	int num;
+	int64 num;
 	const char *name;
 	char prefix;
 
@@ -12910,7 +13108,7 @@ BUILDIN(getmapxy)
 
 	//Set MapName$
 	num=st->stack->stack_data[st->start+2].u.num;
-	name=script->get_str(num&0x00ffffff);
+	name=script->get_str(script_getvarid(num));
 	prefix=*name;
 
 	if(not_server_variable(prefix))
@@ -12921,7 +13119,7 @@ BUILDIN(getmapxy)
 
 	//Set MapX
 	num=st->stack->stack_data[st->start+3].u.num;
-	name=script->get_str(num&0x00ffffff);
+	name=script->get_str(script_getvarid(num));
 	prefix=*name;
 
 	if(not_server_variable(prefix))
@@ -12932,7 +13130,7 @@ BUILDIN(getmapxy)
 
 	//Set MapY
 	num=st->stack->stack_data[st->start+4].u.num;
-	name=script->get_str(num&0x00ffffff);
+	name=script->get_str(script_getvarid(num));
 	prefix=*name;
 
 	if(not_server_variable(prefix))
@@ -13537,14 +13735,6 @@ BUILDIN(explode)
 	start = reference_getindex(data);
 	name = reference_getname(data);
 
-	if( not_array_variable(*name) )
-	{
-		ShowError("script:explode: illegal scope\n");
-		script->reportdata(data);
-		st->state = END;
-		return false;// not supported
-	}
-
 	if( !is_string_variable(name) )
 	{
 		ShowError("script:explode: not string array\n");
@@ -13586,7 +13776,7 @@ BUILDIN(implode)
 {
 	struct script_data* data = script_getdata(st, 2);
 	const char *glue = NULL, *name, *temp;
-	int32 array_size, id;
+	uint32 array_size, id;
 	size_t len = 0, glue_len = 0, k = 0;
 	int i;
 
@@ -13605,14 +13795,6 @@ BUILDIN(implode)
 	id = reference_getid(data);
 	name = reference_getname(data);
 
-	if( not_array_variable(*name) )
-	{
-		ShowError("script:implode: illegal scope\n");
-		script->reportdata(data);
-		st->state = END;
-		return false;// not supported
-	}
-
 	if( !is_string_variable(name) )
 	{
 		ShowError("script:implode: not string array\n");
@@ -13629,7 +13811,7 @@ BUILDIN(implode)
 	}
 
 	//count chars
-	array_size = script->getarraysize(st, id, reference_getindex(data), is_string_variable(name), reference_getref(data)) - 1;
+	array_size = script->array_highest_key(st,sd,name) - 1;
 
 	if(array_size == -1) {
 		//empty array check (AmsTaff)
@@ -14270,8 +14452,6 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle)
 					return false;
 				}
 			}
-			if( not_array_variable(*name) )
-				max_rows = 1;// not an array, limit to one row
 		} else {
 			ShowError("script:query_sql: not a variable\n");
 			script->reportdata(data);
@@ -14857,13 +15037,6 @@ BUILDIN(searchitem)
 	id = reference_getid(data);
 	start = reference_getindex(data);
 	name = reference_getname(data);
-	if( not_array_variable(*name) )
-	{
-		ShowError("script:searchitem: illegal scope\n");
-		script->reportdata(data);
-		st->state = END;
-		return false;// not supported
-	}
 
 	if( not_server_variable(*name) )
 	{
@@ -18811,11 +18984,11 @@ void script_defaults(void) {
 	script->next_id = 0;
 	script->st_ers = NULL;
 	script->stack_ers = NULL;
-
+	script->array_ers = NULL;
+	
 	script->hq = NULL;
 	script->hqi = NULL;
 	script->hqs = script->hqis = 0;
-	memset(&script->hqe, 0, sizeof(script->hqe));
 
 	script->buildin = NULL;
 	script->buildin_count = 0;
@@ -18868,6 +19041,9 @@ void script_defaults(void) {
 	script->potion_flag = script->potion_hp = script->potion_per_hp =
 	script->potion_sp = script->potion_per_sp = script->potion_target = 0;
 
+	script->generic_ui_array = NULL;
+	script->generic_ui_array_size = 0;
+	/* */
 	script->init = do_init_script;
 	script->final = do_final_script;
 	script->reload = script_reload;
@@ -18955,7 +19131,6 @@ void script_defaults(void) {
 	script->set_reg = set_reg;
 	script->stack_expand = stack_expand;
 	script->push_retinfo = push_retinfo;
-	script->pop_val = pop_val;
 	script->op_3 = op_3;
 	script->op_2str = op_2str;
 	script->op_2num = op_2num;
@@ -18968,7 +19143,6 @@ void script_defaults(void) {
 	script->menu_countoptions = menu_countoptions;
 	script->buildin_areawarp_sub = buildin_areawarp_sub;
 	script->buildin_areapercentheal_sub = buildin_areapercentheal_sub;
-	script->getarraysize = getarraysize;
 	script->buildin_delitem_delete = buildin_delitem_delete;
 	script->buildin_delitem_search = buildin_delitem_search;
 	script->buildin_killmonster_sub_strip = buildin_killmonster_sub_strip;
@@ -19033,4 +19207,23 @@ void script_defaults(void) {
 	script->global_casecheck.str_pos = 0;
 	memset(script->global_casecheck.str_hash, 0, sizeof(script->global_casecheck.str_hash));
 	// end ENABLE_CASE_CHECK
+	
+	/**
+	 * Array Handling
+	 **/
+	script->array_src = script_array_src;
+	script->array_update = script_array_update;
+	script->array_add_member = script_array_add_member;
+	script->array_remove_member = script_array_remove_member;
+	script->array_delete = script_array_delete;
+	script->array_size = script_array_size;
+	script->array_free_db = script_free_array_db;
+	script->array_highest_key = script_array_highest_key;
+	/* */
+	script->reg_destroy_single = script_reg_destroy_single;
+	script->reg_destroy = script_reg_destroy;
+	/* */
+	script->generic_ui_array_expand = script_generic_ui_array_expand;
+	script->array_cpy_list = script_array_cpy_list;
+	
 }
diff --git a/src/map/script.h b/src/map/script.h
index 2f7499569..65e11d3ca 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -6,6 +6,7 @@
 #define _SCRIPT_H_
 
 #include "../common/strlib.h" //StringBuf
+#include "../common/cbasetypes.h"
 #include "map.h" //EVENT_NAME_LENGTH
 
 #include <setjmp.h>
@@ -28,8 +29,8 @@ struct eri;
 
 #define NUM_WHISPER_VAR 10
 
-/// Maximum amount of elements in script arrays (soon getting ducked)
-#define SCRIPT_MAX_ARRAYSIZE 128
+/// Maximum amount of elements in script arrays
+#define SCRIPT_MAX_ARRAYSIZE (UINT_MAX - 1)
 
 #define SCRIPT_BLOCK_SIZE 512
 
@@ -127,9 +128,9 @@ struct eri;
 /// Returns the unique id of the reference (id and index)
 #define reference_getuid(data) ( (data)->u.num )
 /// Returns the id of the reference
-#define reference_getid(data) ( (int32)(reference_getuid(data) & 0x00ffffff) )
+#define reference_getid(data) ( (int32)(int64)(reference_getuid(data) & 0xFFFFFFFF) )
 /// Returns the array index of the reference
-#define reference_getindex(data) ( (int32)(((uint32)(reference_getuid(data) & 0xff000000)) >> 24) )
+#define reference_getindex(data) ( (uint32)(int64)((reference_getuid(data) >> 32) & 0xFFFFFFFF) )
 /// Returns the name of the reference
 #define reference_getname(data) ( script->str_buf + script->str_data[reference_getid(data)].str )
 /// Returns the linked list of uid-value pairs of the reference (can be NULL)
@@ -140,10 +141,12 @@ struct eri;
 #define reference_getparamtype(data) ( script->str_data[reference_getid(data)].val )
 
 /// Composes the uid of a reference from the id and the index
-#define reference_uid(id,idx) ( (int32)((((uint32)(id)) & 0x00ffffff) | (((uint32)(idx)) << 24)) )
+#define reference_uid(id,idx) ( (int64) ((uint64)(id) & 0xFFFFFFFF) | ((uint64)(idx) << 32) )
+
+#define script_getvarid(var)  ( (int32)(int64)(var & 0xFFFFFFFF) )
+#define script_getvaridx(var) ( (uint32)(int64)((var >> 32) & 0xFFFFFFFF) )
 
 #define not_server_variable(prefix) ( (prefix) != '$' && (prefix) != '.' && (prefix) != '\'')
-#define not_array_variable(prefix) ( (prefix) != '$' && (prefix) != '@' && (prefix) != '.' && (prefix) != '\'' )
 #define is_string_variable(name) ( (name)[strlen(name) - 1] == '$' )
 
 #define BUILDIN(x) bool buildin_ ## x (struct script_state* st)
@@ -339,7 +342,7 @@ struct script_retinfo {
 struct script_data {
 	enum c_op type;
 	union script_data_val {
-		int num;
+		int64 num;
 		char *str;
 		struct script_retinfo* ri;
 	} u;
@@ -350,8 +353,9 @@ struct script_data {
 // it must be saved when script state is RERUNLINE. [Eoe / jA 1094]
 struct script_code {
 	int script_size;
-	unsigned char* script_buf;
-	struct DBMap* script_vars;
+	unsigned char *script_buf;
+	struct DBMap *script_vars;
+	struct DBMap *script_arrays_db;
 };
 
 struct script_stack {
@@ -359,7 +363,8 @@ struct script_stack {
 	int sp_max;// capacity of the stack
 	int defsp;
 	struct script_data *stack_data;// stack
-	struct DBMap* var_function;// scope variables
+	struct DBMap *var_function;// scope variables
+	struct DBMap *array_function_db;
 };
 
 /* [Ind/Hercules] */
@@ -401,13 +406,14 @@ struct script_state {
 	unsigned int id;
 };
 
+/* TODO: HELLO DUCK THIS */
 struct script_reg {
-	int index;
+	int64 index;
 	int data;
 };
-
+/* TODO: HELLO DUCK THIS */
 struct script_regstr {
-	int index;
+	int64 index;
 	char* data;
 };
 
@@ -458,6 +464,12 @@ struct casecheck_data {
 	void (*clear) (void);
 };
 
+struct script_array {
+	unsigned int id;/* the first 32b of the 64b uid, aka the id */
+	unsigned int size;/* how many members */
+	unsigned int *members;/* member list */
+};
+
 /**
  * Interface
  **/
@@ -472,10 +484,13 @@ struct script_interface {
 	struct hQueue *hq;
 	struct hQueueIterator *hqi;
 	int hqs, hqis;
-	int hqe[HQO_MAX];
 	/*  */
 	char **buildin;
 	unsigned int buildin_count;
+	/**
+	 * used to generate quick script_array entries
+	 **/
+	struct eri *array_ers;
 	/* */
 	struct str_data_struct *str_data;
 	int str_data_size; // size of the data
@@ -531,6 +546,9 @@ struct script_interface {
 	int potion_flag; //For use on Alchemist improved potions/Potion Pitcher. [Skotlex]
 	int potion_hp, potion_per_hp, potion_sp, potion_per_sp;
 	int potion_target;
+	/* */
+	unsigned int *generic_ui_array;
+	unsigned int generic_ui_array_size;
 	/*  */
 	void (*init) (bool minimal);
 	void (*final) (void);
@@ -549,9 +567,9 @@ struct script_interface {
 	const char* (*conv_str) (struct script_state *st,struct script_data *data);
 	TBL_PC *(*rid2sd) (struct script_state *st);
 	void (*detach_rid) (struct script_state* st);
-	struct script_data* (*push_val)(struct script_stack* stack, enum c_op type, int val, struct DBMap** ref);
+	struct script_data* (*push_val)(struct script_stack* stack, enum c_op type, int64 val, struct DBMap** ref);
 	struct script_data *(*get_val) (struct script_state* st, struct script_data* data);
-	void* (*get_val2) (struct script_state* st, int uid, struct DBMap** ref);
+	void* (*get_val2) (struct script_state* st, int64 uid, struct DBMap** ref);
 	struct script_data* (*push_str) (struct script_stack* stack, enum c_op type, char* str);
 	struct script_data* (*push_copy) (struct script_stack* stack, int pos);
 	void (*pop_stack) (struct script_state* st, int start, int end);
@@ -571,7 +589,7 @@ struct script_interface {
 	void (*free_state) (struct script_state* st);
 	void (*run_autobonus) (const char *autobonus,int id, int pos);
 	void (*cleararray_pc) (struct map_session_data* sd, const char* varname, void* value);
-	void (*setarray_pc) (struct map_session_data* sd, const char* varname, uint8 idx, void* value, int* refcache);
+	void (*setarray_pc) (struct map_session_data* sd, const char* varname, uint32 idx, void* value, int* refcache);
 	int (*config_read) (char *cfgName);
 	int (*add_str) (const char* p);
 	const char* (*get_str) (int id);
@@ -615,10 +633,9 @@ struct script_interface {
 	void (*read_constdb) (void);
 	const char* (*print_line) (StringBuf *buf, const char *p, const char *mark, int line);
 	void (*errorwarning_sub) (StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos);
-	int (*set_reg) (struct script_state *st, TBL_PC *sd, int num, const char *name, const void *value, struct DBMap **ref);
+	int (*set_reg) (struct script_state *st, TBL_PC *sd, int64 num, const char *name, const void *value, struct DBMap **ref);
 	void (*stack_expand) (struct script_stack *stack);
 	struct script_data* (*push_retinfo) (struct script_stack *stack, struct script_retinfo *ri, DBMap **ref);
-	int (*pop_val) (struct script_state *st);
 	void (*op_3) (struct script_state *st, int op);
 	void (*op_2str) (struct script_state *st, int op, const char *s1, const char *s2);
 	void (*op_2num) (struct script_state *st, int op, int i1, int i2);
@@ -631,7 +648,6 @@ struct script_interface {
 	int (*menu_countoptions) (const char *str, int max_count, int *total);
 	int (*buildin_areawarp_sub) (struct block_list *bl, va_list ap);
 	int (*buildin_areapercentheal_sub) (struct block_list *bl, va_list ap);
-	int32 (*getarraysize) (struct script_state *st, int32 id, int32 idx, int isstring, struct DBMap **ref);
 	void (*buildin_delitem_delete) (struct map_session_data *sd, int idx, int *amount, bool delete_items);
 	bool (*buildin_delitem_search) (struct map_session_data *sd, struct item *it, bool exact_match);
 	int (*buildin_killmonster_sub_strip) (struct block_list *bl, va_list ap);
@@ -661,6 +677,23 @@ struct script_interface {
 	struct casecheck_data local_casecheck;
 	struct casecheck_data global_casecheck;
 	// end ENABLE_CASE_CHECK
+	/**
+	 * Array Handling
+	 **/
+	struct DBMap *(*array_src) (struct script_state *st, struct map_session_data *sd, const char *name);
+	void (*array_update) (struct DBMap **src, int64 num, bool empty);
+	void (*array_delete) (struct DBMap *src, struct script_array *sa);
+	void (*array_remove_member) (struct DBMap *src, struct script_array *sa, unsigned int idx);
+	void (*array_add_member) (struct script_array *sa, unsigned int idx);
+	unsigned int (*array_size) (struct script_state *st, struct map_session_data *sd, const char *name);
+	unsigned int (*array_highest_key) (struct script_state *st, struct map_session_data *sd, const char *name);
+	int (*array_free_db) (DBKey key, DBData *data, va_list ap);
+	/* */
+	void (*reg_destroy_single) (struct map_session_data *sd, int64 reg, struct script_reg_state *data);
+	int (*reg_destroy) (DBKey key, DBData *data, va_list ap);
+	/* */
+	void (*generic_ui_array_expand) (unsigned int plus);
+	unsigned int *(*array_cpy_list) (struct script_array *sa);
 };
 
 struct script_interface *script;
diff --git a/src/map/skill.c b/src/map/skill.c
index 28937048e..0804adf90 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2539,8 +2539,8 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
 				}
 
 				tsd->reproduceskill_id = copy_skill;
-				pc_setglobalreg(tsd, "REPRODUCE_SKILL", copy_skill);
-				pc_setglobalreg(tsd, "REPRODUCE_SKILL_LV", lv);
+				pc_setglobalreg(tsd, script->add_str("REPRODUCE_SKILL"), copy_skill);
+				pc_setglobalreg(tsd, script->add_str("REPRODUCE_SKILL_LV"), lv);
 
 				tsd->status.skill[cidx].id = copy_skill;
 				tsd->status.skill[cidx].lv = lv;
@@ -2562,8 +2562,8 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
 					lv = type;
 
 				tsd->cloneskill_id = copy_skill;
-				pc_setglobalreg(tsd, "CLONE_SKILL", copy_skill);
-				pc_setglobalreg(tsd, "CLONE_SKILL_LV", lv);
+				pc_setglobalreg(tsd, script->add_str("CLONE_SKILL"), copy_skill);
+				pc_setglobalreg(tsd, script->add_str("CLONE_SKILL_LV"), lv);
 
 				tsd->status.skill[cidx].id = copy_skill;
 				tsd->status.skill[cidx].lv = lv;
@@ -5660,7 +5660,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
 				}
 				sd->mission_mobid = id;
 				sd->mission_count = 0;
-				pc_setglobalreg(sd,"TK_MISSION_ID", id);
+				pc_setglobalreg(sd,script->add_str("TK_MISSION_ID"), id);
 				clif->mission_info(sd, id, 0);
 				clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
 			}
@@ -7414,7 +7414,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
 			if (skill_id == SL_SUPERNOVICE && dstsd && dstsd->die_counter && !(rnd()%100))
 			{	//Erase death count 1% of the casts
 				dstsd->die_counter = 0;
-				pc_setglobalreg(dstsd,"PC_DIE_COUNTER", 0);
+				pc_setglobalreg(dstsd,script->add_str("PC_DIE_COUNTER"), 0);
 				clif->specialeffect(bl, 0x152, AREA);
 				//SC_SOULLINK invokes status_calc_pc for us.
 			}
@@ -16597,7 +16597,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
 					{ //Cooking items.
 						clif->specialeffect(&sd->bl, 608, AREA);
 						if( sd->cook_mastery < 1999 )
-							pc_setglobalreg(sd, "COOK_MASTERY",sd->cook_mastery + ( 1 << ( (skill->produce_db[idx].itemlv - 11) / 2 ) ) * 5);
+							pc_setglobalreg(sd, script->add_str("COOK_MASTERY"),sd->cook_mastery + ( 1 << ( (skill->produce_db[idx].itemlv - 11) / 2 ) ) * 5);
 					}
 					break;
 			}
@@ -16698,7 +16698,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
 				{ //Cooking items.
 					clif->specialeffect(&sd->bl, 609, AREA);
 					if( sd->cook_mastery > 0 )
-						pc_setglobalreg(sd, "COOK_MASTERY", sd->cook_mastery - ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 ));
+						pc_setglobalreg(sd, script->add_str("COOK_MASTERY"), sd->cook_mastery - ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 ));
 				}
 		}
 	}
diff --git a/src/map/trade.c b/src/map/trade.c
index 6f079bdd3..44b669ebd 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -178,7 +178,7 @@ int impossible_trade_check(struct map_session_data *sd)
 	nullpo_retr(1, sd);
 
 	if(sd->deal.zeny > sd->status.zeny) {
-		pc_setglobalreg(sd,"ZENY_HACKER",1);
+		pc_setglobalreg(sd,script->add_str("ZENY_HACKER"),1);
 		return -1;
 	}
 
diff --git a/src/map/unit.c b/src/map/unit.c
index 7f722684d..d801a72f0 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -2352,20 +2352,13 @@ int unit_free(struct block_list *bl, clr_type clrtype) {
 			pc->delspiritball(sd,sd->spiritball,1);
 			for(i = 1; i < 5; i++)
 				pc->del_charm(sd, sd->charm[i], i);
-
-			if( sd->reg ) {	//Double logout already freed pointer fix... [Skotlex]
-				aFree(sd->reg);
-				sd->reg = NULL;
-				sd->reg_num = 0;
-			}
-			if( sd->regstr ) {
-				for( i = 0; i < sd->regstr_num; ++i )
-					if( sd->regstr[i].data )
-						aFree(sd->regstr[i].data);
-				aFree(sd->regstr);
-				sd->regstr = NULL;
-				sd->regstr_num = 0;
-			}
+			
+			if( sd->var_db )
+				sd->var_db->destroy(sd->var_db,script->reg_destroy);
+							
+			if( sd->array_db )
+				sd->array_db->destroy(sd->array_db,script->array_free_db);
+			
 			if( sd->st && sd->st->state != RUN ) {// free attached scripts that are waiting
 				script->free_state(sd->st);
 				sd->st = NULL;
-- 
cgit v1.2.3-70-g09d2


From dafba12dd41721e03ef7d1dc4ec4fa9c518838be Mon Sep 17 00:00:00 2001
From: Haru <haru@dotalux.com>
Date: Wed, 15 Jan 2014 04:13:10 +0100
Subject: Added some missing entries to the sql upgrades table in main.sql

- Follow-up to 9928044b, 4655f661
- Special thanks to Mumbles

Signed-off-by: Haru <haru@dotalux.com>
---
 sql-files/main.sql | 42 ++++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index 398bdcfe4..4a91aeef8 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -639,26 +639,28 @@ CREATE TABLE IF NOT EXISTS `sql_updates` (
 ) ENGINE=MyISAM;
 
 -- Existent updates to enter
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1360858500);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1360951560);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1362445531);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1362528000);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1362794218);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1364409316);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1366075474);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1366078541);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1381354728);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1381423003);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1382892428);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1383162785);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1383167577);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1383205740);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1383955424);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1384545461);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1384588175);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1387844126);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1388854043);
-INSERT INTO `sql_updates` (`timestamp`) VALUES (1389028967);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1360858500); -- 2013-02-14--16-15.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1360951560); -- 2013-02-15--18-06.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1362445531); -- 2013-03-05--01-05.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1362528000); -- 2013-03-06--00-00.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1362794218); -- 2013-03-09--01-56.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1364409316); -- 2013-03-27--18-35.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1366075474); -- 2013-04-16--01-24.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1366078541); -- 2013-04-16--02-15.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1381354728); -- 2013-10-09--21-38.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1381423003); -- 2013-10-10--16-36.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1382892428); -- 2013-10-27--16-47.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383162785); -- 2013-10-30--19-53.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383167577); -- 2013-10-30--21-12.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383205740); -- 2013-10-31--07-49.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1383955424); -- 2013-11-09--00-03.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1384473995); -- 2013-11-15--00-06.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1384545461); -- 2013-11-15--19-57.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1384588175); -- 2013-11-16--07-49.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1384763034); -- 2013-11-18--08-23.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1387844126); -- 2013-12-24--00-15.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1388854043); -- 2014-01-04--16-47.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1389028967); -- 2014-01-06--17-22.sql
 
 --
 -- Table structure for table `sstatus`
-- 
cgit v1.2.3-70-g09d2


From d0b9510cf0d7a47e53aa341462a1175326dfc09d Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Wed, 19 Feb 2014 15:16:46 -0300
Subject: Follow up 9132878d911cfe720eaad94ad3d4a5dd11958f99

Fixed issue (8023) with sc rows (only those of tick = -1, aka permanent scs) duplicating due to lack of primary index.
Special Thanks to Flash, Haru.
Note that the upgrade script will clear the permanent statuses from your sc_data table (e.g. lex aeterna, carts) to ensure no issues are left.

Signed-off-by: shennetsind <ind@henn.et>
---
 sql-files/main.sql                       | 4 +++-
 sql-files/upgrades/2014-02-19--17-57.sql | 4 ++++
 sql-files/upgrades/index.txt             | 3 ++-
 src/char/char.c                          | 4 ++++
 4 files changed, 13 insertions(+), 2 deletions(-)
 create mode 100644 sql-files/upgrades/2014-02-19--17-57.sql

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index 4a91aeef8..654eee9f0 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -468,7 +468,8 @@ CREATE TABLE IF NOT EXISTS `sc_data` (
   `val3` int(11) NOT NULL default '0',
   `val4` int(11) NOT NULL default '0',
   KEY (`account_id`),
-  KEY (`char_id`)
+  KEY (`char_id`),
+  PRIMARY KEY  (`account_id`,`char_id`,`type`)
 ) ENGINE=MyISAM;
 
 --
@@ -661,6 +662,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1384763034); -- 2013-11-18--08-2
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1387844126); -- 2013-12-24--00-15.sql
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1388854043); -- 2014-01-04--16-47.sql
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1389028967); -- 2014-01-06--17-22.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1392832626); -- 2014-02-19--17-57.sql
 
 --
 -- Table structure for table `sstatus`
diff --git a/sql-files/upgrades/2014-02-19--17-57.sql b/sql-files/upgrades/2014-02-19--17-57.sql
new file mode 100644
index 000000000..ebebe6665
--- /dev/null
+++ b/sql-files/upgrades/2014-02-19--17-57.sql
@@ -0,0 +1,4 @@
+#1392832626
+DELETE FROM `sc_data` WHERE `tick` = '-1';
+ALTER TABLE `sc_data` ADD PRIMARY KEY  (`account_id`,`char_id`,`type`);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1392832626);
\ No newline at end of file
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index bf404d919..39fbd0070 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -17,4 +17,5 @@
 2013-11-18--08-23.sql
 2013-12-24--00-15.sql
 2014-01-04--16-47.sql
-2014-01-06--17-22.sql
\ No newline at end of file
+2014-01-06--17-22.sql
+2014-02-19--17-57.sql
\ No newline at end of file
diff --git a/src/char/char.c b/src/char/char.c
index 1ee3cfd1d..5b497bd0c 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -3574,6 +3574,10 @@ int parse_frommap(int fd)
 				cid = RFIFOL(fd, 8);
 				count = RFIFOW(fd, 12);
 
+				/* clear; ensure no left overs e.g. permanent */
+				if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", scdata_db, aid, cid) )
+					Sql_ShowDebug(sql_handle);
+				
 				if( count > 0 )
 				{
 					struct status_change_data data;
-- 
cgit v1.2.3-70-g09d2


From 4b1cc23085b858364a332bdf03d634656778b1e6 Mon Sep 17 00:00:00 2001
From: panikon <panikon@zoho.com>
Date: Tue, 25 Mar 2014 20:23:39 -0300
Subject: Added new return values to make_new_char_sql Added char_id to charlog
 Corrected RE check in skill_magic_reflect (see commit c9310f3)

---
 sql-files/main.sql                       |  2 +
 sql-files/upgrades/2014-03-25--23-57.sql |  3 ++
 src/char/char.c                          | 75 ++++++++++++++++++++------------
 src/map/skill.c                          |  6 +--
 4 files changed, 55 insertions(+), 31 deletions(-)
 create mode 100644 sql-files/upgrades/2014-03-25--23-57.sql

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index 654eee9f0..49d35a287 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -127,6 +127,7 @@ CREATE TABLE IF NOT EXISTS `charlog` (
   `time` datetime NOT NULL default '0000-00-00 00:00:00',
   `char_msg` varchar(255) NOT NULL default 'char select',
   `account_id` int(11) NOT NULL default '0',
+  `char_id` int(11) unsigned NOT NULL default '0',
   `char_num` tinyint(4) NOT NULL default '0',
   `name` varchar(23) NOT NULL default '',
   `str` int(11) unsigned NOT NULL default '0',
@@ -663,6 +664,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1387844126); -- 2013-12-24--00-1
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1388854043); -- 2014-01-04--16-47.sql
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1389028967); -- 2014-01-06--17-22.sql
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1392832626); -- 2014-02-19--17-57.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1395789302); -- 2014-03-25--23-57.sql
 
 --
 -- Table structure for table `sstatus`
diff --git a/sql-files/upgrades/2014-03-25--23-57.sql b/sql-files/upgrades/2014-03-25--23-57.sql
new file mode 100644
index 000000000..f5c3aad00
--- /dev/null
+++ b/sql-files/upgrades/2014-03-25--23-57.sql
@@ -0,0 +1,3 @@
+#1395789302
+ALTER TABLE `charlog` ADD COLUMN `char_id` int(11) unsigned NOT NULL default '0' AFTER `account_id`;
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1395789302);
diff --git a/src/char/char.c b/src/char/char.c
index 0769067fd..d460e4c85 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -1509,9 +1509,10 @@ int rename_char_sql(struct char_session_data *sd, int char_id)
 	// log change
 	if( log_char )
 	{
-		if( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s` (`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
-			"VALUES (NOW(), '%s', '%d', '%d', '%s', '0', '0', '0', '0', '0', '0', '0', '0')",
-			charlog_db, "change char name", sd->account_id, char_dat.slot, esc_name) )
+		if( SQL_ERROR == SQL->Query(sql_handle,
+			"INSERT INTO `%s` (`time`, `char_msg`,`account_id`,`char_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
+			"VALUES (NOW(), '%s', '%d', '%d', '%d', '%s', '0', '0', '0', '0', '0', '0', '0', '0')",
+			charlog_db, "change char name", sd->account_id, char_dat.char_id, char_dat.slot, esc_name) )
 			Sql_ShowDebug(sql_handle);
 	}
 
@@ -1550,7 +1551,7 @@ int check_char_name(char * name, char * esc_name)
 	{ // letters/symbols in char_name_letters are forbidden
 		for( i = 0; i < NAME_LENGTH && name[i]; i++ )
 			if( strchr(char_name_letters, name[i]) != NULL )
-				return -2;
+				return -5;
 	}
 	if( name_ignoring_case ) {
 		if( SQL_ERROR == SQL->Query(sql_handle, "SELECT 1 FROM `%s` WHERE BINARY `name` = '%s' LIMIT 1", char_db, esc_name) ) {
@@ -1569,9 +1570,16 @@ int check_char_name(char * name, char * esc_name)
 	return 0;
 }
 
-//-----------------------------------
-// Function to create a new character
-//-----------------------------------
+/**
+ * Creates a new character
+ * Return values:
+ *  -1: 'Charname already exists'
+ *  -2: 'Char creation denied'/ Unknown error
+ *  -3: 'You are underaged'
+ *  -4: 'You are not elegible to open the Character Slot.'
+ *  -5: 'Symbols in Character Names are forbidden'
+ *  char_id: Success
+ **/
 #if PACKETVER >= 20120307
 int make_new_char_sql(struct char_session_data* sd, char* name_, int slot, int hair_color, int hair_style) {
 	int str = 1, agi = 1, vit = 1, int_ = 1, dex = 1, luk = 1;
@@ -1610,13 +1618,6 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag
 	if( sd->found_char[slot] != -1 )
 		return -2; /* character account limit exceeded */
 
-	// validation success, log result
-	if (log_char) {
-		if( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s` (`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
-			"VALUES (NOW(), '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
-			charlog_db, "make new char", sd->account_id, slot, esc_name, str, agi, vit, int_, dex, luk, hair_style, hair_color) )
-			Sql_ShowDebug(sql_handle);
-	}
 #if PACKETVER >= 20120307
 	//Insert the new char entry to the database
 	if( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `zeny`, `status_point`,`str`, `agi`, `vit`, `int`, `dex`, `luk`, `max_hp`, `hp`,"
@@ -1645,6 +1646,17 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag
 	//Retrieve the newly auto-generated char id
 	char_id = (int)SQL->LastInsertId(sql_handle);
 
+	if( !char_id )
+		return -2;
+
+	// Validation success, log result
+	if (log_char) {
+		if( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s` (`time`, `char_msg`,`account_id`,`char_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
+			"VALUES (NOW(), '%s', '%d', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
+			charlog_db, "make new char", sd->account_id, char_id, slot, esc_name, str, agi, vit, int_, dex, luk, hair_style, hair_color) )
+			Sql_ShowDebug(sql_handle);
+	}
+
 	//Give the char the default items
 	for (k = 0; k < ARRAYLENGTH(start_items) && start_items[k] != 0; k += 3) {
 		// FIXME: How to define if an item is stackable without having to lookup itemdb? [panikon]
@@ -1835,15 +1847,16 @@ int delete_char_sql(int char_id)
 		Sql_ShowDebug(sql_handle);
 #endif
 
-	if (log_char) {
-		if( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s`(`time`, `account_id`,`char_num`,`char_msg`,`name`) VALUES (NOW(), '%d', '%d', 'Deleted char (CID %d)', '%s')",
-			charlog_db, account_id, 0, char_id, esc_name) )
-			Sql_ShowDebug(sql_handle);
-	}
-
 	/* delete character */
 	if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", char_db, char_id) )
 		Sql_ShowDebug(sql_handle);
+	else if( log_char ) {
+		if( SQL_ERROR == SQL->Query(sql_handle,
+			"INSERT INTO `%s`(`time`, `account_id`, `char_id`, `char_num`, `char_msg`, `name`)"
+			" VALUES (NOW(), '%d', '%d', '%d', 'Deleted character', '%s')",
+			charlog_db, account_id, char_id, 0, esc_name) )
+			Sql_ShowDebug(sql_handle);
+	}
 
 	/* No need as we used inter_guild_leave [Skotlex]
 	// Also delete info from guildtables.
@@ -4311,10 +4324,11 @@ int parse_char(int fd)
 
 				if (log_char) {
 					char esc_name[NAME_LENGTH*2+1];
-
+					// FIXME: Why are we re-escaping the name if it was already escaped in rename/make_new_char? [Panikon]
 					SQL->EscapeStringLen(sql_handle, esc_name, char_dat.name, strnlen(char_dat.name, NAME_LENGTH));
-					if( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s`(`time`, `account_id`,`char_num`,`name`) VALUES (NOW(), '%d', '%d', '%s')",
-						charlog_db, sd->account_id, slot, esc_name) )
+					if( SQL_ERROR == SQL->Query(sql_handle,
+						"INSERT INTO `%s`(`time`, `account_id`, `char_id`, `char_num`, `name`) VALUES (NOW(), '%d', '%d', '%d', '%s')",
+						charlog_db, sd->account_id, cd->char_id, slot, esc_name) )
 						Sql_ShowDebug(sql_handle);
 				}
 				ShowInfo("Selected char: (Account %d: %d - %s)\n", sd->account_id, slot, char_dat.name);
@@ -4429,7 +4443,6 @@ int parse_char(int fd)
 					result = make_new_char_sql(sd, (char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOB(fd,27),RFIFOB(fd,28),RFIFOB(fd,29),RFIFOB(fd,30),RFIFOB(fd,31),RFIFOB(fd,32),RFIFOW(fd,33),RFIFOW(fd,35));
 	#endif
 
-				//'Charname already exists' (-1), 'Char creation denied' (-2) and 'You are underaged' (-3)
 				if (result < 0) {
 					WFIFOHEAD(fd,3);
 					WFIFOW(fd,0) = 0x6e;
@@ -4438,10 +4451,16 @@ int parse_char(int fd)
 					/* 0x03 = You are not elegible to open the Character Slot. */
 					/* 0x0B = This service is only available for premium users.  */
 					switch (result) {
-						case -1: WFIFOB(fd,2) = 0x00; break;
-						case -2: WFIFOB(fd,2) = 0xFF; break;
-						case -3: WFIFOB(fd,2) = 0x01; break;
-						case -4: WFIFOB(fd,2) = 0x03; break;
+						case -1: WFIFOB(fd,2) = 0x00; break; // 'Charname already exists'
+						case -2: WFIFOB(fd,2) = 0xFF; break; // 'Char creation denied'
+						case -3: WFIFOB(fd,2) = 0x01; break; // 'You are underaged'
+						case -4: WFIFOB(fd,2) = 0x03; break; // 'You are not elegible to open the Character Slot.'
+						case -5: WFIFOB(fd,2) = 0x02; break; // 'Symbols in Character Names are forbidden'
+
+						default:
+							ShowWarning("parse_char: Unknown result received from make_new_char_sql!\n");
+							WFIFOB(fd,2) = 0xFF;
+							break;
 					}
 					WFIFOSET(fd,3);
 				} else {
diff --git a/src/map/skill.c b/src/map/skill.c
index 0ed6f7780..612b205e9 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2201,12 +2201,12 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
 		 **/
 		#if MAGIC_REFLECTION_TYPE
 
-		#if defined(DISABLE_RENEWAL)
+		#ifdef RENEWAL
+			if( dmg.dmg_lv != ATK_MISS ) //Wiz SL cancelled and consumed fragment
+		#else
 			// issue:6415 in pre-renewal Kaite reflected the entire damage received
 			// regardless of caster's equipament (Aegis 11.1)
 			if( dmg.dmg_lv != ATK_MISS && type == 1 ) //Wiz SL cancelled and consumed fragment
-		#else
-			if( dmg.dmg_lv != ATK_MISS ) //Wiz SL cancelled and consumed fragment
 		#endif
 			{
 				short s_ele = skill->get_ele(skill_id, skill_lv);
-- 
cgit v1.2.3-70-g09d2


From dd49dbc3e8d2033c0dddc80f1d5b3c8e6710a419 Mon Sep 17 00:00:00 2001
From: Ibrahim Hossam <ibrahem.h.basyone@gmail.com>
Date: Tue, 8 Apr 2014 20:40:12 +0200
Subject: Rewritten NSI_UNIQUE_ID system to get rid of the cross-database
 interreg dependency

- Removes the need for map-server to access the interreg table to store the last used ID.
- Login, char and map databases can now be hosted separately.
- Note: the unique_id structure has changed, and it now contains the generator character ID in its upper 32 bits.
- Now NSI_UNIQUE_ID System is enabled always

Special thanks to Haruna.
---
 sql-files/main.sql                       |  3 +--
 sql-files/upgrades/2014-04-07--22-04.sql |  3 +++
 sql-files/upgrades/index.txt             |  3 ++-
 src/char/char.c                          | 16 +++++-------
 src/char/int_auction.c                   |  4 ---
 src/char/int_mail.c                      |  4 ---
 src/char/inter.c                         | 19 ---------------
 src/char/inter.h                         | 13 ----------
 src/common/mmo.h                         |  2 ++
 src/config/core.h                        |  4 ---
 src/map/itemdb.c                         | 42 +++-----------------------------
 src/map/itemdb.h                         |  3 +--
 src/map/pc.c                             |  6 ++---
 13 files changed, 21 insertions(+), 101 deletions(-)
 create mode 100644 sql-files/upgrades/2014-04-07--22-04.sql

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index 49d35a287..e6e71c2c1 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -111,6 +111,7 @@ CREATE TABLE IF NOT EXISTS `char` (
   `char_opt` INT( 11 ) unsigned NOT NULL default '0',
   `font` TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT  '0',
   `unban_time` int(11) unsigned NOT NULL default '0',
+  `uniqueitem_counter` bigint(20) NOT NULL,
   PRIMARY KEY  (`char_id`),
   UNIQUE KEY `name_key` (`name`),
   KEY `account_id` (`account_id`),
@@ -709,8 +710,6 @@ CREATE TABLE IF NOT EXISTS `interreg` (
   `value` varchar(20) NOT NULL,
    PRIMARY KEY (`varname`)
 ) ENGINE=InnoDB;
-INSERT INTO `interreg` (`varname`, `value`) VALUES
-('unique_id', '0');
 
 --
 -- Table structure for table `account_data`
diff --git a/sql-files/upgrades/2014-04-07--22-04.sql b/sql-files/upgrades/2014-04-07--22-04.sql
new file mode 100644
index 000000000..9e33d6aec
--- /dev/null
+++ b/sql-files/upgrades/2014-04-07--22-04.sql
@@ -0,0 +1,3 @@
+#1396893866
+ALTER TABLE `char` ADD COLUMN `uniqueitem_counter`  bigint(20) NOT NULL AFTER `unban_time`;
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1396893866);
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 1c25d8210..7ac2f9ceb 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -19,4 +19,5 @@
 2014-01-04--16-47.sql
 2014-01-06--17-22.sql
 2014-02-19--17-57.sql
-2014-03-25--23-57.sql
\ No newline at end of file
+2014-03-25--23-57.sql
+2014-04-07--22-04.sql
\ No newline at end of file
diff --git a/src/char/char.c b/src/char/char.c
index d460e4c85..a4bc9cef9 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -469,7 +469,8 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		(p->ele_id != cp->ele_id) || (p->shield != cp->shield) || (p->head_top != cp->head_top) ||
 		(p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || (p->delete_date != cp->delete_date) ||
 		(p->rename != cp->rename) || (p->slotchange != cp->slotchange) || (p->robe != cp->robe) ||
-		(p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font)
+		(p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font) ||
+		(p->uniqueitem_counter != cp->uniqueitem_counter )
 	) {	//Save status
 		unsigned int opt = 0;
 		
@@ -485,7 +486,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 			"`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`elemental_id`='%d',"
 			"`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
 			"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
-			"`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u'"
+			"`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u', `uniqueitem_counter` ='%u'"
 			" WHERE  `account_id`='%d' AND `char_id` = '%d'",
 			char_db, p->base_level, p->job_level,
 			p->base_exp, p->job_exp, p->zeny,
@@ -496,7 +497,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 			mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y,
 			mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
 			(unsigned long)p->delete_date,  // FIXME: platform-dependent size
-			p->robe,p->slotchange,opt,p->font,
+			p->robe,p->slotchange,opt,p->font,p->uniqueitem_counter,
 			p->account_id, p->char_id) )
 		{
 			Sql_ShowDebug(sql_handle);
@@ -841,10 +842,7 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
  		for( j = 0; j < MAX_SLOTS; ++j )
 			StrBuf->Printf(&buf, ", '%d'", items[i].card[j]);
 		StrBuf->AppendStr(&buf, ")");
-		
-		updateLastUid(items[i].unique_id); // Unique Non Stackable Item ID
 	}
-	dbUpdateUid(sql_handle); // Unique Non Stackable Item ID
 
 	if( found && SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) )
 	{
@@ -982,10 +980,7 @@ int inventory_to_sql(const struct item items[], int max, int id) {
  		for( j = 0; j < MAX_SLOTS; ++j )
 			StrBuf->Printf(&buf, ", '%d'", items[i].card[j]);
 		StrBuf->AppendStr(&buf, ")");
-
-		updateLastUid(items[i].unique_id);// Unique Non Stackable Item ID
 	}
-	dbUpdateUid(sql_handle);
 
 	if( found && SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) ) {
 		Sql_ShowDebug(sql_handle);
@@ -1130,7 +1125,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 		"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,"
 		"`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
 		"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`,`slotchange`,"
-		"`char_opt`,`font`"
+		"`char_opt`,`font`,`uniqueitem_counter`"
 		" FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
 	||	SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0)
 	||	SQL_ERROR == SQL->StmtExecute(stmt)
@@ -1189,6 +1184,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 52, SQLDT_USHORT, &p->slotchange, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 53, SQLDT_UINT,   &opt, 0, NULL, NULL)
 	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 54, SQLDT_UCHAR,  &p->font, 0, NULL, NULL)
+	||	SQL_ERROR == SQL->StmtBindColumn(stmt, 55, SQLDT_UINT,   &p->uniqueitem_counter, 0, NULL, NULL)
 	)
 	{
 		SqlStmt_ShowDebug(stmt);
diff --git a/src/char/int_auction.c b/src/char/int_auction.c
index 47f3421c3..924930867 100644
--- a/src/char/int_auction.c
+++ b/src/char/int_auction.c
@@ -90,10 +90,6 @@ unsigned int auction_create(struct auction_data *auction)
 	for( j = 0; j < MAX_SLOTS; j++ )
 		StrBuf->Printf(&buf, ",'%d'", auction->item.card[j]);
 	StrBuf->AppendStr(&buf, ")");
-	
-	//Unique Non Stackable Item ID
-	updateLastUid(auction->item.unique_id);
-	dbUpdateUid(sql_handle);
 
 	stmt = SQL->StmtMalloc(sql_handle);
 	if( SQL_SUCCESS != SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
diff --git a/src/char/int_mail.c b/src/char/int_mail.c
index b69824d4b..826771676 100644
--- a/src/char/int_mail.c
+++ b/src/char/int_mail.c
@@ -117,10 +117,6 @@ int mail_savemessage(struct mail_message* msg)
 	for (j = 0; j < MAX_SLOTS; j++)
 		StrBuf->Printf(&buf, ", '%d'", msg->item.card[j]);
 	StrBuf->AppendStr(&buf, ")");
-	
-	//Unique Non Stackable Item ID
-	updateLastUid(msg->item.unique_id);
-	dbUpdateUid(sql_handle);
 
 	// prepare and execute query
 	stmt = SQL->StmtMalloc(sql_handle);
diff --git a/src/char/inter.c b/src/char/inter.c
index 059c33784..6a8412b25 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -1372,23 +1372,4 @@ int inter_parse_frommap(int fd)
 	return 1;
 }
 
-uint64 inter_chk_lastuid(int8 flag, uint64 value){
-	static uint64 last_updt_uid = 0;
-	static int8 update = 0;
-	if(flag)
-	{
-		if(last_updt_uid < value){
-			last_updt_uid = value;
-			update = 1;
-		}
-
-		return 0;
-	}else if(update)
-	{
-		update = 0;
-		return last_updt_uid;
-	}
-	return 0;
-}
-
 
diff --git a/src/char/inter.h b/src/char/inter.h
index b484a1610..25b0c2a96 100644
--- a/src/char/inter.h
+++ b/src/char/inter.h
@@ -29,17 +29,4 @@ extern Sql* lsql_handle;
 
 int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type);
 
-uint64 inter_chk_lastuid(int8 flag, uint64 value);
-#ifdef NSI_UNIQUE_ID
-	#define updateLastUid(val_) inter_chk_lastuid(1, (val_))
-	#define dbUpdateUid(handler_) do { \
-		uint64 unique_id_ = inter_chk_lastuid(0, 0); \
-		if (unique_id_ && SQL_ERROR == SQL->Query((handler_), "UPDATE `%s` SET `value`='%"PRIu64"' WHERE `varname`='unique_id'", interreg_db, unique_id_)) \
-				Sql_ShowDebug(handler_);\
-	} while(0)
-#else
-	#define dbUpdateUid(handler_)
-	#define updateLastUid(val_)
-#endif
-
 #endif /* _CHAR_INTER_H_ */
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 019472acb..0dd8d0f09 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -435,6 +435,8 @@ struct mmo_charstatus {
 	unsigned short mod_exp,mod_drop,mod_death;
 	
 	unsigned char font;
+
+	uint32 uniqueitem_counter;
 };
 
 typedef enum mail_status {
diff --git a/src/config/core.h b/src/config/core.h
index edd5c2b2a..157d94b2f 100644
--- a/src/config/core.h
+++ b/src/config/core.h
@@ -57,10 +57,6 @@
 /// When uncommented the cap takes place after modifiers.
 //#define HMAP_ZONE_DAMAGE_CAP_TYPE
 
-/// Uncomment to enable Non Stackable items unique ID
-/// By enabling it, the system will create an unique id for each new non stackable item created
-//#define NSI_UNIQUE_ID
-
 /// Comment to disable Guild/Party Bound item system
 #define GP_BOUND_ITEMS
 
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index bfcc6f795..abe899412 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -1966,44 +1966,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;
-	}
-
-	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);
+uint64 itemdb_unique_id(struct map_session_data *sd) {
 
-	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++;
 }
 
 /**
@@ -2057,8 +2023,7 @@ void itemdb_read(bool minimal) {
 	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();
+
 }
 
 /**
@@ -2348,7 +2313,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;
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index eebcd5d4d..77fb2e2ec 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -576,8 +576,7 @@ struct itemdb_interface {
 	int (*readdb_libconfig_sub) (config_setting_t *it, int n, const char *source);
 	int (*readdb_libconfig) (const char *filename);
 	int (*readdb_sql) (const char *tablename);
-	uint64 (*unique_id) (int8 flag, int64 value);
-	int (*uid_load) ();
+	uint64 (*unique_id) (struct map_session_data *sd);
 	void (*read) (bool minimal);
 	void (*destroy_item_data) (struct item_data *self, int free_self);
 	int (*final_sub) (DBKey key, DBData *data, va_list ap);
diff --git a/src/map/pc.c b/src/map/pc.c
index 42b79ed92..f5327e0bd 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -3991,10 +3991,10 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
 		sd->inventory_data[i] = data;
 		clif->additem(sd,i,amount,0);
 	}
-#ifdef NSI_UNIQUE_ID
+
 	if( !itemdb->isstackable2(data) && !item_data->unique_id )
-		sd->status.inventory[i].unique_id = itemdb->unique_id(0,0);
-#endif
+		sd->status.inventory[i].unique_id = itemdb->unique_id(sd);
+
 	logs->pick_pc(sd, log_type, amount, &sd->status.inventory[i],sd->inventory_data[i]);
 
 	sd->weight += w;
-- 
cgit v1.2.3-70-g09d2


From 2f1d13680ef04aa255ce2881fa7e89f42a76e7ab Mon Sep 17 00:00:00 2001
From: Haru <haru@dotalux.com>
Date: Sun, 20 Apr 2014 07:07:33 +0200
Subject: Follow-up to dd49dbc3e8, added missing main.sql entry

Thanks to QQfoolsorellina

Signed-off-by: Haru <haru@dotalux.com>
---
 sql-files/main.sql | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index e6e71c2c1..b7cf01937 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -666,6 +666,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1388854043); -- 2014-01-04--16-4
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1389028967); -- 2014-01-06--17-22.sql
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1392832626); -- 2014-02-19--17-57.sql
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1395789302); -- 2014-03-25--23-57.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1396893866); -- 2014-04-07--22-04.sql
 
 --
 -- Table structure for table `sstatus`
@@ -837,4 +838,3 @@ CREATE TABLE IF NOT EXISTS `autotrade_data` (
   `price` int(11) NOT NULL default '0',
   PRIMARY KEY  (`char_id`,`itemkey`)
 ) ENGINE=MyISAM; 
-
-- 
cgit v1.2.3-70-g09d2


From 47fae87d899c486223c0a5dd58caf76efc56ffb4 Mon Sep 17 00:00:00 2001
From: MrKeiKun <the.keikun@gmail.com>
Date: Sat, 26 Apr 2014 15:36:30 +0800
Subject: Follow-up to 93584f7, Fixed issue with Character Creation, column
 doesn't contain default value.

Signed-off-by: MrKeiKun <the.keikun@gmail.com>
---
 sql-files/main.sql                       | 3 ++-
 sql-files/upgrades/2014-04-26--10-00.sql | 3 +++
 sql-files/upgrades/index.txt             | 3 ++-
 3 files changed, 7 insertions(+), 2 deletions(-)
 create mode 100644 sql-files/upgrades/2014-04-26--10-00.sql

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index b7cf01937..25045226a 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -111,7 +111,7 @@ CREATE TABLE IF NOT EXISTS `char` (
   `char_opt` INT( 11 ) unsigned NOT NULL default '0',
   `font` TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT  '0',
   `unban_time` int(11) unsigned NOT NULL default '0',
-  `uniqueitem_counter` bigint(20) NOT NULL,
+  `uniqueitem_counter` bigint(20) unsigned NOT NULL default '0',
   PRIMARY KEY  (`char_id`),
   UNIQUE KEY `name_key` (`name`),
   KEY `account_id` (`account_id`),
@@ -667,6 +667,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1389028967); -- 2014-01-06--17-2
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1392832626); -- 2014-02-19--17-57.sql
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1395789302); -- 2014-03-25--23-57.sql
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1396893866); -- 2014-04-07--22-04.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1398477600); -- 2014-04-26--10-00.sql
 
 --
 -- Table structure for table `sstatus`
diff --git a/sql-files/upgrades/2014-04-26--10-00.sql b/sql-files/upgrades/2014-04-26--10-00.sql
new file mode 100644
index 000000000..de3fbd4c8
--- /dev/null
+++ b/sql-files/upgrades/2014-04-26--10-00.sql
@@ -0,0 +1,3 @@
+#1398477600
+ALTER TABLE `char` CHANGE COLUMN `uniqueitem_counter` `uniqueitem_counter` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0' ;
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1398477600);
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 7ac2f9ceb..88019e12a 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -20,4 +20,5 @@
 2014-01-06--17-22.sql
 2014-02-19--17-57.sql
 2014-03-25--23-57.sql
-2014-04-07--22-04.sql
\ No newline at end of file
+2014-04-07--22-04.sql
+2014-04-26--10-00.sql
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 5f5380e8d5fa2e6042813e35101cb33b656e3972 Mon Sep 17 00:00:00 2001
From: Shido <the.keikun@gmail.com>
Date: Fri, 16 May 2014 21:42:25 +0800
Subject: Renamed incuvate of Pet System.

---
 sql-files/main.sql                          |  3 ++-
 sql-files/upgrades/2014-05-17--00-06.sql    |  3 +++
 sql-files/upgrades/index.txt                |  1 +
 src/char/char.c                             |  2 +-
 src/char/int_pet.c                          | 24 ++++++++++++------------
 src/common/mmo.h                            |  2 +-
 src/map/intif.c                             |  4 ++--
 src/map/intif.h                             |  2 +-
 src/map/pet.c                               | 14 +++++++-------
 src/plugins/HPMHooking/HPMHooking.Hooks.inc | 12 ++++++------
 10 files changed, 36 insertions(+), 31 deletions(-)
 create mode 100644 sql-files/upgrades/2014-05-17--00-06.sql

(limited to 'sql-files/main.sql')

diff --git a/sql-files/main.sql b/sql-files/main.sql
index 25045226a..9c2c1ca43 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -577,7 +577,7 @@ CREATE TABLE IF NOT EXISTS `pet` (
   `intimate` smallint(9) unsigned NOT NULL default '0',
   `hungry` smallint(9) unsigned NOT NULL default '0',
   `rename_flag` tinyint(4) unsigned NOT NULL default '0',
-  `incuvate` int(11) unsigned NOT NULL default '0',
+  `incubate` int(11) unsigned NOT NULL default '0',
   PRIMARY KEY  (`pet_id`)
 ) ENGINE=MyISAM;
 
@@ -668,6 +668,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1392832626); -- 2014-02-19--17-5
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1395789302); -- 2014-03-25--23-57.sql
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1396893866); -- 2014-04-07--22-04.sql
 INSERT INTO `sql_updates` (`timestamp`) VALUES (1398477600); -- 2014-04-26--10-00.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1400256139); -- 2014-05-17--00-06.sql
 
 --
 -- Table structure for table `sstatus`
diff --git a/sql-files/upgrades/2014-05-17--00-06.sql b/sql-files/upgrades/2014-05-17--00-06.sql
new file mode 100644
index 000000000..8f19c859f
--- /dev/null
+++ b/sql-files/upgrades/2014-05-17--00-06.sql
@@ -0,0 +1,3 @@
+#1400256139
+RENAME TABLE `incuvate` TO `incubate`
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1400256139);
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 2383c0775..ab8ee772d 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -22,3 +22,4 @@
 2014-03-25--23-57.sql
 2014-04-07--22-04.sql
 2014-04-26--10-00.sql
+2014-05-17--00-06.sql
diff --git a/src/char/char.c b/src/char/char.c
index 289df62a4..57031e3ee 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -1780,7 +1780,7 @@ int delete_char_sql(int char_id)
 
 	/* delete char's pet */
 	//Delete the hatched pet if you have one...
-	if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `incuvate` = '0'", pet_db, char_id) )
+	if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `incubate` = '0'", pet_db, char_id) )
 		Sql_ShowDebug(sql_handle);
 
 	//Delete all pets that are stored in eggs (inventory + cart)
diff --git a/src/char/int_pet.c b/src/char/int_pet.c
index 29c40eff9..0f7c683f8 100644
--- a/src/char/int_pet.c
+++ b/src/char/int_pet.c
@@ -25,7 +25,7 @@ struct s_pet *pet_pt;
 //---------------------------------------------------------
 int inter_pet_tosql(int pet_id, struct s_pet* p)
 {
-	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
+	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`)
 	char esc_name[NAME_LENGTH*2+1];// escaped pet name
 
 	SQL->EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
@@ -35,10 +35,10 @@ int inter_pet_tosql(int pet_id, struct s_pet* p)
 	if( pet_id == -1 )
 	{// New pet.
 		if( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s` "
-			"(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) "
+			"(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`) "
 			"VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
 			pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
-			p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate) )
+			p->equip, p->intimate, p->hungry, p->rename_flag, p->incubate) )
 		{
 			Sql_ShowDebug(sql_handle);
 			return 0;
@@ -47,9 +47,9 @@ int inter_pet_tosql(int pet_id, struct s_pet* p)
 	}
 	else
 	{// Update pet.
-		if( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incuvate`='%d' WHERE `pet_id`='%d'",
+		if( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incubate`='%d' WHERE `pet_id`='%d'",
 			pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
-			p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate, p->pet_id) )
+			p->equip, p->intimate, p->hungry, p->rename_flag, p->incubate, p->pet_id) )
 		{
 			Sql_ShowDebug(sql_handle);
 			return 0;
@@ -71,9 +71,9 @@ int inter_pet_fromsql(int pet_id, struct s_pet* p)
 #endif
 	memset(p, 0, sizeof(struct s_pet));
 
-	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
+	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`)
 
-	if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate` FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id) )
+	if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate` FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id) )
 	{
 		Sql_ShowDebug(sql_handle);
 		return 0;
@@ -92,7 +92,7 @@ int inter_pet_fromsql(int pet_id, struct s_pet* p)
 		SQL->GetData(sql_handle,  8, &data, NULL); p->intimate = atoi(data);
 		SQL->GetData(sql_handle,  9, &data, NULL); p->hungry = atoi(data);
 		SQL->GetData(sql_handle, 10, &data, NULL); p->rename_flag = atoi(data);
-		SQL->GetData(sql_handle, 11, &data, NULL); p->incuvate = atoi(data);
+		SQL->GetData(sql_handle, 11, &data, NULL); p->incubate = atoi(data);
 
 		SQL->FreeResult(sql_handle);
 
@@ -186,11 +186,11 @@ int mapif_delete_pet_ack(int fd, int flag){
 }
 
 int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short pet_lv, short pet_egg_id,
-	short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name)
+	short pet_equip, short intimate, short hungry, char rename_flag, char incubate, char *pet_name)
 {
 	memset(pet_pt, 0, sizeof(struct s_pet));
 	safestrncpy(pet_pt->name, pet_name, NAME_LENGTH);
-	if(incuvate == 1)
+	if(incubate == 1)
 		pet_pt->account_id = pet_pt->char_id = 0;
 	else {
 		pet_pt->account_id = account_id;
@@ -203,7 +203,7 @@ int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short
 	pet_pt->intimate = intimate;
 	pet_pt->hungry = hungry;
 	pet_pt->rename_flag = rename_flag;
-	pet_pt->incuvate = incuvate;
+	pet_pt->incubate = incubate;
 
 	if(pet_pt->hungry < 0)
 		pet_pt->hungry = 0;
@@ -229,7 +229,7 @@ int mapif_load_pet(int fd, int account_id, int char_id, int pet_id){
 	inter_pet_fromsql(pet_id, pet_pt);
 
 	if(pet_pt!=NULL) {
-		if(pet_pt->incuvate == 1) {
+		if(pet_pt->incubate == 1) {
 			pet_pt->account_id = pet_pt->char_id = 0;
 			mapif_pet_info(fd, account_id, pet_pt);
 		}
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 0003aa917..4ac7ee793 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -352,7 +352,7 @@ struct s_pet {
 	short hungry;//pet hungry
 	char name[NAME_LENGTH];
 	char rename_flag;
-	char incuvate;
+	char incubate;
 };
 
 struct s_homunculus { //[orn]
diff --git a/src/map/intif.c b/src/map/intif.c
index 75379f6c0..042896f4f 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -50,7 +50,7 @@ int CheckForCharServer(void)
 
 // pet
 int intif_create_pet(int account_id,int char_id,short pet_class,short pet_lv,short pet_egg_id,
-	short pet_equip,short intimate,short hungry,char rename_flag,char incuvate,char *pet_name)
+	short pet_equip,short intimate,short hungry,char rename_flag,char incubate,char *pet_name)
 {
 	if (intif->CheckForCharServer())
 		return 0;
@@ -65,7 +65,7 @@ int intif_create_pet(int account_id,int char_id,short pet_class,short pet_lv,sho
 	WFIFOW(inter_fd,18) = intimate;
 	WFIFOW(inter_fd,20) = hungry;
 	WFIFOB(inter_fd,22) = rename_flag;
-	WFIFOB(inter_fd,23) = incuvate;
+	WFIFOB(inter_fd,23) = incubate;
 	memcpy(WFIFOP(inter_fd,24),pet_name,NAME_LENGTH);
 	WFIFOSET(inter_fd,24+NAME_LENGTH);
 
diff --git a/src/map/intif.h b/src/map/intif.h
index d0eeccc6d..42a38ad41 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -42,7 +42,7 @@ struct intif_interface {
 	/* funcs */
 	int (*parse) (int fd);
 	int (*create_pet)(int account_id, int char_id, short pet_type, short pet_lv, short pet_egg_id,
-	                  short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name);
+	                  short pet_equip, short intimate, short hungry, char rename_flag, char incubate, char *pet_name);
 	int (*broadcast) (const char* mes, size_t len, int type);
 	int (*broadcast2) (const char* mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY);
 	int (*main_message) (struct map_session_data* sd, const char* message);
diff --git a/src/map/pet.c b/src/map/pet.c
index 6a458eae6..05bbfe7b3 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -303,7 +303,7 @@ int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
 		clif->additem(sd,0,0,flag);
 		map->addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
 	}
-	pd->pet.incuvate = 1;
+	pd->pet.incubate = 1;
 	unit->free(&pd->bl,CLR_OUTSIGHT);
 
 	status_calc_pc(sd,SCO_NONE);
@@ -327,8 +327,8 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *petinfo)
 	}
 	if (sd->status.pet_id != petinfo->pet_id) {
 		if (sd->status.pet_id) {
-			//Wrong pet?? Set incuvate to no and send it back for saving.
-			petinfo->incuvate = 1;
+			//Wrong pet?? Set incubate to no and send it back for saving.
+			petinfo->incubate = 1;
 			intif->save_petdata(sd->status.account_id,petinfo);
 			sd->status.pet_id = 0;
 			return 1;
@@ -392,12 +392,12 @@ int pet_birth_process(struct map_session_data *sd, struct s_pet *petinfo)
 
 	Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
 
-	if(sd->status.pet_id && petinfo->incuvate == 1) {
+	if(sd->status.pet_id && petinfo->incubate == 1) {
 		sd->status.pet_id = 0;
 		return 1;
 	}
 
-	petinfo->incuvate = 0;
+	petinfo->incubate = 0;
 	petinfo->account_id = sd->status.account_id;
 	petinfo->char_id = sd->status.char_id;
 	sd->status.pet_id = petinfo->pet_id;
@@ -433,7 +433,7 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag) {
 		sd->status.pet_id = 0;
 		return 1;
 	}
-	if(p->incuvate == 1) {
+	if(p->incubate == 1) {
 		int i;
 		//Delete egg from inventory. [Skotlex]
 		for (i = 0; i < MAX_INVENTORY; i++) {
@@ -596,7 +596,7 @@ int pet_menu(struct map_session_data *sd,int menunum)
 		return 1;
 	
 	//You lost the pet already.
-	if(!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incuvate)
+	if(!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incubate)
 		return 1;
 		
 	egg_id = itemdb->exists(sd->pd->petDB->EggID);
diff --git a/src/plugins/HPMHooking/HPMHooking.Hooks.inc b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
index 83af64c07..cbd822239 100644
--- a/src/plugins/HPMHooking/HPMHooking.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
@@ -28639,15 +28639,15 @@ int HP_intif_parse(int fd) {
 	}
 	return retVal___;
 }
-int HP_intif_create_pet(int account_id, int char_id, short pet_type, short pet_lv, short pet_egg_id, short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name) {
+int HP_intif_create_pet(int account_id, int char_id, short pet_type, short pet_lv, short pet_egg_id, short pet_equip, short intimate, short hungry, char rename_flag, char incubate, char *pet_name) {
 	int hIndex = 0;
 	int retVal___ = 0;
 	if( HPMHooks.count.HP_intif_create_pet_pre ) {
-		int (*preHookFunc) (int *account_id, int *char_id, short *pet_type, short *pet_lv, short *pet_egg_id, short *pet_equip, short *intimate, short *hungry, char *rename_flag, char *incuvate, char *pet_name);
+		int (*preHookFunc) (int *account_id, int *char_id, short *pet_type, short *pet_lv, short *pet_egg_id, short *pet_equip, short *intimate, short *hungry, char *rename_flag, char *incubate, char *pet_name);
 		*HPMforce_return = false;
 		for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_create_pet_pre; hIndex++ ) {
 			preHookFunc = HPMHooks.list.HP_intif_create_pet_pre[hIndex].func;
-			retVal___ = preHookFunc(&account_id, &char_id, &pet_type, &pet_lv, &pet_egg_id, &pet_equip, &intimate, &hungry, &rename_flag, &incuvate, pet_name);
+			retVal___ = preHookFunc(&account_id, &char_id, &pet_type, &pet_lv, &pet_egg_id, &pet_equip, &intimate, &hungry, &rename_flag, &incubate, pet_name);
 		}
 		if( *HPMforce_return ) {
 			*HPMforce_return = false;
@@ -28655,13 +28655,13 @@ int HP_intif_create_pet(int account_id, int char_id, short pet_type, short pet_l
 		}
 	}
 	{
-		retVal___ = HPMHooks.source.intif.create_pet(account_id, char_id, pet_type, pet_lv, pet_egg_id, pet_equip, intimate, hungry, rename_flag, incuvate, pet_name);
+		retVal___ = HPMHooks.source.intif.create_pet(account_id, char_id, pet_type, pet_lv, pet_egg_id, pet_equip, intimate, hungry, rename_flag, incubate, pet_name);
 	}
 	if( HPMHooks.count.HP_intif_create_pet_post ) {
-		int (*postHookFunc) (int retVal___, int *account_id, int *char_id, short *pet_type, short *pet_lv, short *pet_egg_id, short *pet_equip, short *intimate, short *hungry, char *rename_flag, char *incuvate, char *pet_name);
+		int (*postHookFunc) (int retVal___, int *account_id, int *char_id, short *pet_type, short *pet_lv, short *pet_egg_id, short *pet_equip, short *intimate, short *hungry, char *rename_flag, char *incubate, char *pet_name);
 		for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_create_pet_post; hIndex++ ) {
 			postHookFunc = HPMHooks.list.HP_intif_create_pet_post[hIndex].func;
-			retVal___ = postHookFunc(retVal___, &account_id, &char_id, &pet_type, &pet_lv, &pet_egg_id, &pet_equip, &intimate, &hungry, &rename_flag, &incuvate, pet_name);
+			retVal___ = postHookFunc(retVal___, &account_id, &char_id, &pet_type, &pet_lv, &pet_egg_id, &pet_equip, &intimate, &hungry, &rename_flag, &incubate, pet_name);
 		}
 	}
 	return retVal___;
-- 
cgit v1.2.3-70-g09d2


From 3ecf877ba3f6d92bc323522bd166248464f83f79 Mon Sep 17 00:00:00 2001
From: Shido <the.keikun@gmail.com>
Date: Fri, 30 May 2014 10:13:58 +0800
Subject: SQL Re-Organization.

Signed-off-by: KeiKun <the.keikun@gmail.com>
---
 sql-files/logs.sql            |  255 +++++-----
 sql-files/main.sql            | 1080 ++++++++++++++++++++---------------------
 sql-files/mob_db.sql          |  132 ++---
 sql-files/mob_db2.sql         |  140 +++---
 sql-files/mob_db_re.sql       |  132 ++---
 sql-files/mob_skill_db.sql    |  170 +++----
 sql-files/mob_skill_db2.sql   |   52 +-
 sql-files/mob_skill_db_re.sql |  170 +++----
 8 files changed, 1080 insertions(+), 1051 deletions(-)

(limited to 'sql-files/main.sql')

diff --git a/sql-files/logs.sql b/sql-files/logs.sql
index a281d632e..3d5f56710 100644
--- a/sql-files/logs.sql
+++ b/sql-files/logs.sql
@@ -1,128 +1,157 @@
-#PickLog types (M)onsters Drop, (P)layers Drop/Take, Mobs Drop (L)oot Drop/Take,
-# Players (T)rade Give/Take, Players (V)ending Sell/Take, (S)hop Sell/Take, (N)PC Give/Take,
-# (C)onsumable Items, (A)dministrators Create/Delete, Sto(R)age, (G)uild Storage,
-# (E)mail attachment,(B)uying Store, Pr(O)duced Items/Ingredients, Auct(I)oned Items,
-# (X) Other, (D) Stolen from mobs, (U) MVP Prizes
-
-#Database: ragnarok
-#Table: picklog
-CREATE TABLE `picklog` (
-  `id` int(11) NOT NULL auto_increment,
-  `time` datetime NOT NULL default '0000-00-00 00:00:00',
-  `char_id` int(11) NOT NULL default '0',
-  `type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U') NOT NULL default 'P',
-  `nameid` int(11) NOT NULL default '0',
-  `amount` int(11) NOT NULL default '1',
-  `refine` tinyint(3) unsigned NOT NULL default '0',
-  `card0` int(11) NOT NULL default '0',
-  `card1` int(11) NOT NULL default '0',
-  `card2` int(11) NOT NULL default '0',
-  `card3` int(11) NOT NULL default '0',
-  `unique_id` bigint(20) unsigned NOT NULL default '0',
-  `map` varchar(11) NOT NULL default '',
-  PRIMARY KEY  (`id`),
-  INDEX (`type`)
-) ENGINE=MyISAM AUTO_INCREMENT=1 ;
+-- PickLog Types
+--	(M)onsters Drop
+--	(P)layers Drop/Take
+--	Mobs Drop (L)oot Drop/Take
+--	Players (T)rade Give/Take
+--	Players (V)ending Sell/Take
+--	(S)hop Sell/Take
+--	(N)PC Give/Take
+--	(C)onsumable Items
+--	(A)dministrators Create/Delete
+--	Sto(R)age
+--	(G)uild Storage
+--	(E)mail attachment
+--	(B)uying Store
+--	Pr(O)duced Items/Ingredients
+--	Auct(I)oned Items
+--	(X) Other
+--	(D) Stolen from mobs
+--	(U) MVP Prizes
 
-#ZenyLog types (M)onsters,(T)rade,(V)ending Sell/Buy,(S)hop Sell/Buy,(N)PC Change amount,(A)dministrators,(E)Mail,(B)uying Store
-#Database: ragnarok
-#Table: zenylog
-CREATE TABLE `zenylog` (
-  `id` int(11) NOT NULL auto_increment,
-  `time` datetime NOT NULL default '0000-00-00 00:00:00',
-  `char_id` int(11) NOT NULL default '0',
-  `src_id` int(11) NOT NULL default '0',
-  `type` enum('T','V','P','M','S','N','D','C','A','E','I','B') NOT NULL default 'S',
-  `amount` int(11) NOT NULL default '0',
-  `map` varchar(11) NOT NULL default '',
-  PRIMARY KEY  (`id`),
-  INDEX (`type`)
-) ENGINE=MyISAM AUTO_INCREMENT=1 ;
+--
+-- Table structure for table `atcommandlog`
+--
 
-#Database: ragnarok
-#Table: branchlog
-CREATE TABLE `branchlog` (
-  `branch_id` mediumint(9) unsigned NOT NULL auto_increment,
-  `branch_date` datetime NOT NULL default '0000-00-00 00:00:00',
-  `account_id` int(11) NOT NULL default '0',
-  `char_id` int(11) NOT NULL default '0',
-  `char_name` varchar(25) NOT NULL default '',
-  `map` varchar(11) NOT NULL default '',
-  PRIMARY KEY  (`branch_id`),
+CREATE TABLE IF NOT EXISTS `atcommandlog` (
+  `atcommand_id` MEDIUMINT(9) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `atcommand_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `char_name` VARCHAR(25) NOT NULL DEFAULT '',
+  `map` VARCHAR(11) NOT NULL DEFAULT '',
+  `command` VARCHAR(255) NOT NULL DEFAULT '',
+  PRIMARY KEY (`atcommand_id`),
   INDEX (`account_id`),
   INDEX (`char_id`)
 ) ENGINE=MyISAM AUTO_INCREMENT=1 ;
 
-#Database: ragnarok
-#Table: mvplog
-CREATE TABLE `mvplog` (
-  `mvp_id` mediumint(9) unsigned NOT NULL auto_increment,
-  `mvp_date` datetime NOT NULL default '0000-00-00 00:00:00',
-  `kill_char_id` int(11) NOT NULL default '0',
-  `monster_id` smallint(6) NOT NULL default '0',
-  `prize` int(11) NOT NULL default '0',
-  `mvpexp` mediumint(9) NOT NULL default '0',
-  `map` varchar(11) NOT NULL default '',
-  PRIMARY KEY  (`mvp_id`)
-) ENGINE=MyISAM AUTO_INCREMENT=1 ;
+--
+-- Table structure for table `branchlog`
+--
 
-#Database: ragnarok
-#Table: atcommandlog
-CREATE TABLE `atcommandlog` (
-  `atcommand_id` mediumint(9) unsigned NOT NULL auto_increment,
-  `atcommand_date` datetime NOT NULL default '0000-00-00 00:00:00',
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `char_name` varchar(25) NOT NULL default '',
-  `map` varchar(11) NOT NULL default '',
-  `command` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`atcommand_id`),
+CREATE TABLE IF NOT EXISTS `branchlog` (
+  `branch_id` MEDIUMINT(9) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `branch_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `account_id` INT(11) NOT NULL DEFAULT '0',
+  `char_id` INT(11) NOT NULL DEFAULT '0',
+  `char_name` VARCHAR(25) NOT NULL DEFAULT '',
+  `map` VARCHAR(11) NOT NULL DEFAULT '',
+  PRIMARY KEY(`branch_id`),
   INDEX (`account_id`),
   INDEX (`char_id`)
-) ENGINE=MyISAM AUTO_INCREMENT=1 ;
+) ENGINE=MyISAM AUTO_INCREMENT=1;
 
-#Database: ragnarok
-#Table: npclog
-CREATE TABLE `npclog` (
-  `npc_id` mediumint(9) unsigned NOT NULL auto_increment,
-  `npc_date` datetime NOT NULL default '0000-00-00 00:00:00',
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `char_name` varchar(25) NOT NULL default '',
-  `map` varchar(11) NOT NULL default '',
-  `mes` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`npc_id`),
-  INDEX (`account_id`),
-  INDEX (`char_id`)
-) ENGINE=MyISAM AUTO_INCREMENT=1 ;
+--
+-- Table structure for table `chatlog`
+--
 
-#ChatLog types Gl(O)bal,(W)hisper,(P)arty,(G)uild,(M)ain chat
-#Database: ragnarok
-#Table: chatlog
-CREATE TABLE `chatlog` (
-  `id` bigint(20) NOT NULL auto_increment,
-  `time` datetime NOT NULL default '0000-00-00 00:00:00',
-  `type` enum('O','W','P','G','M') NOT NULL default 'O',
-  `type_id` int(11) NOT NULL default '0',
-  `src_charid` int(11) NOT NULL default '0',
-  `src_accountid` int(11) NOT NULL default '0',
-  `src_map` varchar(11) NOT NULL default '',
-  `src_map_x` smallint(4) NOT NULL default '0',
-  `src_map_y` smallint(4) NOT NULL default '0',
-  `dst_charname` varchar(25) NOT NULL default '',
-  `message` varchar(150) NOT NULL default '',
-  PRIMARY KEY  (`id`),
+CREATE TABLE IF NOT EXISTS `chatlog` (
+  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+  `time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `type` ENUM('O','W','P','G','M') NOT NULL DEFAULT 'O',
+  `type_id` INT(11) NOT NULL DEFAULT '0',
+  `src_charid` INT(11) NOT NULL DEFAULT '0',
+  `src_accountid` INT(11) NOT NULL DEFAULT '0',
+  `src_map` VARCHAR(11) NOT NULL DEFAULT '',
+  `src_map_x` SMALLINT(4) NOT NULL DEFAULT '0',
+  `src_map_y` SMALLINT(4) NOT NULL DEFAULT '0',
+  `dst_charname` VARCHAR(25) NOT NULL DEFAULT '',
+  `message` VARCHAR(150) NOT NULL DEFAULT '',
+  PRIMARY KEY (`id`),
   INDEX (`src_accountid`),
   INDEX (`src_charid`)
-) ENGINE=MyISAM AUTO_INCREMENT=1 ;
+) ENGINE=MyISAM AUTO_INCREMENT=1;
+
+--
+-- Table structure for table `loginlog`
+--
 
-#Database: ragnarok
-#Table: loginlog
-CREATE TABLE `loginlog` (
-  `time` datetime NOT NULL default '0000-00-00 00:00:00',
-  `ip` varchar(15) NOT NULL default '',
-  `user` varchar(23) NOT NULL default '',
-  `rcode` tinyint(4) NOT NULL default '0',
-  `log` varchar(255) NOT NULL default '',
+CREATE TABLE IF NOT EXISTS `loginlog` (
+  `time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `ip` VARCHAR(15) NOT NULL DEFAULT '',
+  `user` VARCHAR(23) NOT NULL DEFAULT '',
+  `rcode` TINYINT(4) NOT NULL DEFAULT '0',
+  `log` VARCHAR(255) NOT NULL DEFAULT '',
   INDEX (`ip`)
-) ENGINE=MyISAM ;
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `mvplog`
+--
+
+CREATE TABLE IF NOT EXISTS `mvplog` (
+  `mvp_id` MEDIUMINT(9) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `mvp_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `kill_char_id` INT(11) NOT NULL DEFAULT '0',
+  `monster_id` SMALLINT(6) NOT NULL DEFAULT '0',
+  `prize` INT(11) NOT NULL DEFAULT '0',
+  `mvpexp` MEDIUMINT(9) NOT NULL DEFAULT '0',
+  `map` VARCHAR(11) NOT NULL DEFAULT '',
+  PRIMARY KEY (`mvp_id`)
+) ENGINE=MyISAM AUTO_INCREMENT=1;
+
+--
+-- Table structure for table `npclog`
+--
+
+CREATE TABLE IF NOT EXISTS `npclog` (
+  `npc_id` MEDIUMINT(9) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `npc_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `char_name` VARCHAR(25) NOT NULL DEFAULT '',
+  `map` VARCHAR(11) NOT NULL DEFAULT '',
+  `mes` VARCHAR(255) NOT NULL DEFAULT '',
+  PRIMARY KEY (`npc_id`),
+  INDEX (`account_id`),
+  INDEX (`char_id`)
+) ENGINE=MyISAM AUTO_INCREMENT=1;
+
+--
+-- Table structure for table `picklog`
+--
+
+CREATE TABLE IF NOT EXISTS `picklog` (
+  `id` INT(11) NOT NULL AUTO_INCREMENT,
+  `time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `char_id` INT(11) NOT NULL DEFAULT '0',
+  `type` ENUM('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U') NOT NULL DEFAULT 'P',
+  `nameid` INT(11) NOT NULL DEFAULT '0',
+  `amount` INT(11) NOT NULL DEFAULT '1',
+  `refine` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `card0` INT(11) NOT NULL DEFAULT '0',
+  `card1` INT(11) NOT NULL DEFAULT '0',
+  `card2` INT(11) NOT NULL DEFAULT '0',
+  `card3` INT(11) NOT NULL DEFAULT '0',
+  `unique_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  `map` VARCHAR(11) NOT NULL DEFAULT '',
+  PRIMARY KEY (`id`),
+  INDEX (`type`)
+) ENGINE=MyISAM AUTO_INCREMENT=1;
+
+--
+-- Table structure for table `zenylog`
+--
+
+CREATE TABLE IF NOT EXISTS `zenylog` (
+  `id` INT(11) NOT NULL AUTO_INCREMENT,
+  `time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `char_id` INT(11) NOT NULL DEFAULT '0',
+  `src_id` INT(11) NOT NULL DEFAULT '0',
+  `type` ENUM('T','V','P','M','S','N','D','C','A','E','I','B') NOT NULL DEFAULT 'S',
+  `amount` INT(11) NOT NULL DEFAULT '0',
+  `map` VARCHAR(11) NOT NULL DEFAULT '',
+  PRIMARY KEY (`id`),
+  INDEX (`type`)
+) ENGINE=MyISAM AUTO_INCREMENT=1;
+
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 9c2c1ca43..22cba1660 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -1,51 +1,114 @@
+--
+--
+-- Table structure for table `account_data`
+
+CREATE TABLE IF NOT EXISTS `account_data` (
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `bank_vault` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `base_exp` TINYINT( 4 ) UNSIGNED NOT NULL DEFAULT '100',
+  `base_drop` TINYINT( 4 ) UNSIGNED NOT NULL DEFAULT '100',
+  `base_death` TINYINT( 4 ) UNSIGNED NOT NULL DEFAULT '100',
+  PRIMARY KEY (`account_id`)
+) ENGINE=MyISAM; 
+
+--
+-- Table structure for table `acc_reg_num_db`
+--
+
+CREATE TABLE IF NOT EXISTS `acc_reg_num_db` (
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `key` VARCHAR(32) BINARY NOT NULL DEFAULT '',
+  `index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `value` INT(11) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `acc_reg_str_db`
+--
+
+CREATE TABLE IF NOT EXISTS `acc_reg_str_db` (
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `key` VARCHAR(32) BINARY NOT NULL DEFAULT '',
+  `index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `value` VARCHAR(254) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+
 --
 -- Table structure for table `auction`
 --
 
 CREATE TABLE IF NOT EXISTS `auction` (
-  `auction_id` bigint(20) unsigned NOT NULL auto_increment,
-  `seller_id` int(11) unsigned NOT NULL default '0',
-  `seller_name` varchar(30) NOT NULL default '',
-  `buyer_id` int(11) unsigned NOT NULL default '0',
-  `buyer_name` varchar(30) NOT NULL default '',
-  `price` int(11) unsigned NOT NULL default '0',
-  `buynow` int(11) unsigned NOT NULL default '0',
-  `hours` smallint(6) NOT NULL default '0',
-  `timestamp` int(11) unsigned NOT NULL default '0',
-  `nameid` int(11) unsigned NOT NULL default '0',
-  `item_name` varchar(50) NOT NULL default '',
-  `type` smallint(6) NOT NULL default '0',
-  `refine` tinyint(3) unsigned NOT NULL default '0',
-  `attribute` tinyint(4) unsigned NOT NULL default '0',
-  `card0` smallint(11) NOT NULL default '0',
-  `card1` smallint(11) NOT NULL default '0',
-  `card2` smallint(11) NOT NULL default '0',
-  `card3` smallint(11) NOT NULL default '0',
-  `unique_id` bigint(20) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`auction_id`)
+  `auction_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `seller_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `seller_name` VARCHAR(30) NOT NULL DEFAULT '',
+  `buyer_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `buyer_name` VARCHAR(30) NOT NULL DEFAULT '',
+  `price` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `buynow` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `hours` SMALLINT(6) NOT NULL DEFAULT '0',
+  `timestamp` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `nameid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `item_name` VARCHAR(50) NOT NULL DEFAULT '',
+  `type` SMALLINT(6) NOT NULL DEFAULT '0',
+  `refine` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `attribute` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `card0` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card1` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card2` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card3` SMALLINT(11) NOT NULL DEFAULT '0',
+  `unique_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`auction_id`)
 ) ENGINE=MyISAM;
 
+--
+-- Table structure for table `autotrade_data`
+--
+
+CREATE TABLE IF NOT EXISTS `autotrade_data` (
+  `char_id` INT(11) NOT NULL DEFAULT '0',
+  `itemkey` INT(11) NOT NULL DEFAULT '0',
+  `amount` INT(11) NOT NULL DEFAULT '0',
+  `price` INT(11) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`char_id`,`itemkey`)
+) ENGINE=MyISAM; 
+
+--
+-- Table structure for table `autotrade_merchants`
+--
+
+CREATE TABLE IF NOT EXISTS `autotrade_merchants` (
+  `account_id` INT(11) NOT NULL DEFAULT '0',
+  `char_id` INT(11) NOT NULL DEFAULT '0',
+  `sex` TINYINT(2) NOT NULL DEFAULT '0',
+  `title` VARCHAR(80) NOT NULL DEFAULT 'Buy From Me!',
+  PRIMARY KEY (`account_id`,`char_id`)
+) ENGINE=MyISAM; 
+
 --
 -- Table structure for table `cart_inventory`
 --
 
 CREATE TABLE IF NOT EXISTS `cart_inventory` (
-  `id` int(11) NOT NULL auto_increment,
-  `char_id` int(11) NOT NULL default '0',
-  `nameid` int(11) NOT NULL default '0',
-  `amount` int(11) NOT NULL default '0',
-  `equip` int(11) unsigned NOT NULL default '0',
-  `identify` smallint(6) NOT NULL default '0',
-  `refine` tinyint(3) unsigned NOT NULL default '0',
-  `attribute` tinyint(4) NOT NULL default '0',
-  `card0` smallint(11) NOT NULL default '0',
-  `card1` smallint(11) NOT NULL default '0',
-  `card2` smallint(11) NOT NULL default '0',
-  `card3` smallint(11) NOT NULL default '0',
-  `expire_time` int(11) unsigned NOT NULL default '0',
-  `bound` tinyint(1) unsigned NOT NULL default '0',
-  `unique_id` bigint(20) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`),
+  `id` INT(11) NOT NULL AUTO_INCREMENT,
+  `char_id` INT(11) NOT NULL DEFAULT '0',
+  `nameid` INT(11) NOT NULL DEFAULT '0',
+  `amount` INT(11) NOT NULL DEFAULT '0',
+  `equip` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `identify` SMALLINT(6) NOT NULL DEFAULT '0',
+  `refine` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `attribute` TINYINT(4) NOT NULL DEFAULT '0',
+  `card0` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card1` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card2` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card3` SMALLINT(11) NOT NULL DEFAULT '0',
+  `expire_time` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `bound` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+  `unique_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`id`),
   KEY `char_id` (`char_id`)
 ) ENGINE=MyISAM;
 
@@ -54,65 +117,65 @@ CREATE TABLE IF NOT EXISTS `cart_inventory` (
 --
 
 CREATE TABLE IF NOT EXISTS `char` (
-  `char_id` int(11) unsigned NOT NULL auto_increment,
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `char_num` tinyint(1) NOT NULL default '0',
-  `name` varchar(30) NOT NULL DEFAULT '',
-  `class` smallint(6) unsigned NOT NULL default '0',
-  `base_level` smallint(6) unsigned NOT NULL default '1',
-  `job_level` smallint(6) unsigned NOT NULL default '1',
-  `base_exp` bigint(20) unsigned NOT NULL default '0',
-  `job_exp` bigint(20) unsigned NOT NULL default '0',
-  `zeny` int(11) unsigned NOT NULL default '0',
-  `str` smallint(4) unsigned NOT NULL default '0',
-  `agi` smallint(4) unsigned NOT NULL default '0',
-  `vit` smallint(4) unsigned NOT NULL default '0',
-  `int` smallint(4) unsigned NOT NULL default '0',
-  `dex` smallint(4) unsigned NOT NULL default '0',
-  `luk` smallint(4) unsigned NOT NULL default '0',
-  `max_hp` mediumint(8) unsigned NOT NULL default '0',
-  `hp` mediumint(8) unsigned NOT NULL default '0',
-  `max_sp` mediumint(6) unsigned NOT NULL default '0',
-  `sp` mediumint(6) unsigned NOT NULL default '0',
-  `status_point` int(11) unsigned NOT NULL default '0',
-  `skill_point` int(11) unsigned NOT NULL default '0',
-  `option` int(11) NOT NULL default '0',
-  `karma` tinyint(3) NOT NULL default '0',
-  `manner` smallint(6) NOT NULL default '0',
-  `party_id` int(11) unsigned NOT NULL default '0',
-  `guild_id` int(11) unsigned NOT NULL default '0',
-  `pet_id` int(11) unsigned NOT NULL default '0',
-  `homun_id` int(11) unsigned NOT NULL default '0',
-  `elemental_id` int(11) unsigned NOT NULL default '0',
-  `hair` tinyint(4) unsigned NOT NULL default '0',
-  `hair_color` smallint(5) unsigned NOT NULL default '0',
-  `clothes_color` smallint(5) unsigned NOT NULL default '0',
-  `weapon` smallint(6) unsigned NOT NULL default '0',
-  `shield` smallint(6) unsigned NOT NULL default '0',
-  `head_top` smallint(6) unsigned NOT NULL default '0',
-  `head_mid` smallint(6) unsigned NOT NULL default '0',
-  `head_bottom` smallint(6) unsigned NOT NULL default '0',
+  `char_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `char_num` TINYINT(1) NOT NULL DEFAULT '0',
+  `name` VARCHAR(30) NOT NULL DEFAULT '',
+  `class` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `base_level` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '1',
+  `job_level` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '1',
+  `base_exp` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  `job_exp` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  `zeny` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `str` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `agi` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `vit` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `INT` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `dex` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `luk` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `max_hp` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
+  `hp` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
+  `max_sp` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `sp` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `status_point` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `skill_point` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `option` INT(11) NOT NULL DEFAULT '0',
+  `karma` TINYINT(3) NOT NULL DEFAULT '0',
+  `manner` SMALLINT(6) NOT NULL DEFAULT '0',
+  `party_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `guild_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `pet_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `homun_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `elemental_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `hair` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `hair_color` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
+  `clothes_color` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
+  `weapon` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `shield` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `head_top` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `head_mid` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `head_bottom` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
   `robe` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
-  `last_map` varchar(11) NOT NULL default '',
-  `last_x` smallint(4) unsigned NOT NULL default '53',
-  `last_y` smallint(4) unsigned NOT NULL default '111',
-  `save_map` varchar(11) NOT NULL default '',
-  `save_x` smallint(4) unsigned NOT NULL default '53',
-  `save_y` smallint(4) unsigned NOT NULL default '111',
-  `partner_id` int(11) unsigned NOT NULL default '0',
-  `online` tinyint(2) NOT NULL default '0',
-  `father` int(11) unsigned NOT NULL default '0',
-  `mother` int(11) unsigned NOT NULL default '0',
-  `child` int(11) unsigned NOT NULL default '0',
-  `fame` int(11) unsigned NOT NULL default '0',
-  `rename` SMALLINT(3) unsigned NOT NULL default '0',
-  `delete_date` INT(11) unsigned NOT NULL DEFAULT '0',
-  `slotchange` SMALLINT(3) unsigned NOT NULL default '0',
-  `char_opt` INT( 11 ) unsigned NOT NULL default '0',
-  `font` TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT  '0',
-  `unban_time` int(11) unsigned NOT NULL default '0',
-  `uniqueitem_counter` bigint(20) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`char_id`),
+  `last_map` VARCHAR(11) NOT NULL DEFAULT '',
+  `last_x` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '53',
+  `last_y` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '111',
+  `save_map` VARCHAR(11) NOT NULL DEFAULT '',
+  `save_x` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '53',
+  `save_y` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '111',
+  `partner_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `online` TINYINT(2) NOT NULL DEFAULT '0',
+  `father` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `mother` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `child` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `fame` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `rename` SMALLINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `delete_date` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `slotchange` SMALLINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `char_opt` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `font` TINYINT(3) UNSIGNED NOT NULL DEFAULT  '0',
+  `unban_time` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `uniqueitem_counter` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`char_id`),
   UNIQUE KEY `name_key` (`name`),
   KEY `account_id` (`account_id`),
   KEY `party_id` (`party_id`),
@@ -120,25 +183,51 @@ CREATE TABLE IF NOT EXISTS `char` (
   KEY `online` (`online`)
 ) ENGINE=MyISAM AUTO_INCREMENT=150000; 
 
+--
+-- Table structure for table `char_reg_num_db`
+--
+
+CREATE TABLE IF NOT EXISTS `char_reg_num_db` (
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `key` VARCHAR(32) BINARY NOT NULL DEFAULT '',
+  `index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `value` INT(11) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`char_id`,`key`,`index`),
+  KEY `char_id` (`char_id`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `char_reg_str_db`
+--
+
+CREATE TABLE IF NOT EXISTS `char_reg_str_db` (
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `key` VARCHAR(32) BINARY NOT NULL DEFAULT '',
+  `index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `value` VARCHAR(254) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`char_id`,`key`,`index`),
+  KEY `char_id` (`char_id`)
+) ENGINE=MyISAM;
+
 --
 -- Table structure for table `charlog`
 --
 
 CREATE TABLE IF NOT EXISTS `charlog` (
-  `time` datetime NOT NULL default '0000-00-00 00:00:00',
-  `char_msg` varchar(255) NOT NULL default 'char select',
-  `account_id` int(11) NOT NULL default '0',
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `char_num` tinyint(4) NOT NULL default '0',
-  `name` varchar(23) NOT NULL default '',
-  `str` int(11) unsigned NOT NULL default '0',
-  `agi` int(11) unsigned NOT NULL default '0',
-  `vit` int(11) unsigned NOT NULL default '0',
-  `int` int(11) unsigned NOT NULL default '0',
-  `dex` int(11) unsigned NOT NULL default '0',
-  `luk` int(11) unsigned NOT NULL default '0',
-  `hair` tinyint(4) NOT NULL default '0',
-  `hair_color` int(11) NOT NULL default '0'
+  `time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `char_msg` VARCHAR(255) NOT NULL DEFAULT 'char select',
+  `account_id` INT(11) NOT NULL DEFAULT '0',
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `char_num` TINYINT(4) NOT NULL DEFAULT '0',
+  `name` VARCHAR(23) NOT NULL DEFAULT '',
+  `str` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `agi` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `vit` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `INT` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `dex` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `luk` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `hair` TINYINT(4) NOT NULL DEFAULT '0',
+  `hair_color` INT(11) NOT NULL DEFAULT '0'
 ) ENGINE=MyISAM; 
 
 --
@@ -146,24 +235,24 @@ CREATE TABLE IF NOT EXISTS `charlog` (
 --
 
 CREATE TABLE IF NOT EXISTS `elemental` (
-  `ele_id` int(11) unsigned NOT NULL auto_increment,
-  `char_id` int(11) NOT NULL,
-  `class` mediumint(9) unsigned NOT NULL default '0',
-  `mode` int(11) unsigned NOT NULL default '1',
-  `hp` int(12) NOT NULL default '1',
-  `sp` int(12) NOT NULL default '1',
-  `max_hp` mediumint(8) unsigned NOT NULL default '0',
-  `max_sp` mediumint(6) unsigned NOT NULL default '0',
-  `atk1` MEDIUMINT(6) unsigned NOT NULL default '0',
-  `atk2` MEDIUMINT(6) unsigned NOT NULL default '0',
-  `matk` MEDIUMINT(6) unsigned NOT NULL default '0',
-  `aspd` smallint(4) unsigned NOT NULL default '0',
-  `def` smallint(4) unsigned NOT NULL default '0',
-  `mdef` smallint(4) unsigned NOT NULL default '0',
-  `flee` smallint(4) unsigned NOT NULL default '0',
-  `hit` smallint(4) unsigned NOT NULL default '0',
-  `life_time` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ele_id`)
+  `ele_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `char_id` INT(11) NOT NULL,
+  `class` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `mode` INT(11) UNSIGNED NOT NULL DEFAULT '1',
+  `hp` INT(12) NOT NULL DEFAULT '1',
+  `sp` INT(12) NOT NULL DEFAULT '1',
+  `max_hp` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
+  `max_sp` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `atk1` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `atk2` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `matk` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `aspd` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `def` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `mdef` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `flee` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `hit` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `life_time` INT(11) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`ele_id`)
 ) ENGINE=MyISAM;
 
 --
@@ -171,9 +260,9 @@ CREATE TABLE IF NOT EXISTS `elemental` (
 --
 
 CREATE TABLE IF NOT EXISTS `friends` (
-  `char_id` int(11) NOT NULL default '0',
-  `friend_account` int(11) NOT NULL default '0',
-  `friend_id` int(11) NOT NULL default '0',
+  `char_id` INT(11) NOT NULL DEFAULT '0',
+  `friend_account` INT(11) NOT NULL DEFAULT '0',
+  `friend_id` INT(11) NOT NULL DEFAULT '0',
   KEY  `char_id` (`char_id`)
 ) ENGINE=MyISAM;
 
@@ -183,35 +272,61 @@ CREATE TABLE IF NOT EXISTS `friends` (
 
 CREATE TABLE IF NOT EXISTS `hotkey` (
 	`char_id` INT(11) NOT NULL,
-	`hotkey` TINYINT(2) unsigned NOT NULL,
-	`type` TINYINT(1) unsigned NOT NULL default '0',
-	`itemskill_id` INT(11) unsigned NOT NULL default '0',
-	`skill_lvl` TINYINT(4) unsigned NOT NULL default '0',
+	`hotkey` TINYINT(2) UNSIGNED NOT NULL,
+	`type` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+	`itemskill_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+	`skill_lvl` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
 	PRIMARY KEY (`char_id`,`hotkey`)
 ) ENGINE=MyISAM;
 
+--
+-- Table structure for table `global_acc_reg_num_db`
+--
+
+CREATE TABLE IF NOT EXISTS `global_acc_reg_num_db` (
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `key` VARCHAR(32) BINARY NOT NULL DEFAULT '',
+  `index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `value` INT(11) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `global_acc_reg_str_db`
+--
+
+CREATE TABLE IF NOT EXISTS `global_acc_reg_str_db` (
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `key` VARCHAR(32) BINARY NOT NULL DEFAULT '',
+  `index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `value` VARCHAR(254) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`account_id`,`key`,`index`),
+  KEY `account_id` (`account_id`)
+) ENGINE=MyISAM;
+
 --
 -- Table structure for table `guild`
 --
 
 CREATE TABLE IF NOT EXISTS `guild` (
-  `guild_id` int(11) unsigned NOT NULL auto_increment,
-  `name` varchar(24) NOT NULL default '',
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `master` varchar(24) NOT NULL default '',
-  `guild_lv` tinyint(6) unsigned NOT NULL default '0',
-  `connect_member` tinyint(6) unsigned NOT NULL default '0',
-  `max_member` tinyint(6) unsigned NOT NULL default '0',
-  `average_lv` smallint(6) unsigned NOT NULL default '1',
-  `exp` bigint(20) unsigned NOT NULL default '0',
-  `next_exp` int(11) unsigned NOT NULL default '0',
-  `skill_point` tinyint(11) unsigned NOT NULL default '0',
-  `mes1` varchar(60) NOT NULL default '',
-  `mes2` varchar(120) NOT NULL default '',
-  `emblem_len` int(11) unsigned NOT NULL default '0',
-  `emblem_id` int(11) unsigned NOT NULL default '0',
+  `guild_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `name` VARCHAR(24) NOT NULL DEFAULT '',
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `master` VARCHAR(24) NOT NULL DEFAULT '',
+  `guild_lv` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `connect_member` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `max_member` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `average_lv` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '1',
+  `exp` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  `next_exp` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `skill_point` TINYINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `mes1` VARCHAR(60) NOT NULL DEFAULT '',
+  `mes2` VARCHAR(120) NOT NULL DEFAULT '',
+  `emblem_len` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `emblem_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
   `emblem_data` blob,
-  PRIMARY KEY  (`guild_id`,`char_id`),
+  PRIMARY KEY (`guild_id`,`char_id`),
   UNIQUE KEY `guild_id` (`guild_id`),
   KEY `char_id` (`char_id`)
 ) ENGINE=MyISAM;
@@ -221,11 +336,11 @@ CREATE TABLE IF NOT EXISTS `guild` (
 --
 
 CREATE TABLE IF NOT EXISTS `guild_alliance` (
-  `guild_id` int(11) unsigned NOT NULL default '0',
-  `opposition` int(11) unsigned NOT NULL default '0',
-  `alliance_id` int(11) unsigned NOT NULL default '0',
-  `name` varchar(24) NOT NULL default '',
-  PRIMARY KEY  (`guild_id`,`alliance_id`),
+  `guild_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `opposition` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `alliance_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `name` VARCHAR(24) NOT NULL DEFAULT '',
+  PRIMARY KEY (`guild_id`,`alliance_id`),
   KEY `alliance_id` (`alliance_id`)
 ) ENGINE=MyISAM;
 
@@ -234,25 +349,25 @@ CREATE TABLE IF NOT EXISTS `guild_alliance` (
 --
 
 CREATE TABLE IF NOT EXISTS `guild_castle` (
-  `castle_id` int(11) unsigned NOT NULL default '0',
-  `guild_id` int(11) unsigned NOT NULL default '0',
-  `economy` int(11) unsigned NOT NULL default '0',
-  `defense` int(11) unsigned NOT NULL default '0',
-  `triggerE` int(11) unsigned NOT NULL default '0',
-  `triggerD` int(11) unsigned NOT NULL default '0',
-  `nextTime` int(11) unsigned NOT NULL default '0',
-  `payTime` int(11) unsigned NOT NULL default '0',
-  `createTime` int(11) unsigned NOT NULL default '0',
-  `visibleC` int(11) unsigned NOT NULL default '0',
-  `visibleG0` int(11) unsigned NOT NULL default '0',
-  `visibleG1` int(11) unsigned NOT NULL default '0',
-  `visibleG2` int(11) unsigned NOT NULL default '0',
-  `visibleG3` int(11) unsigned NOT NULL default '0',
-  `visibleG4` int(11) unsigned NOT NULL default '0',
-  `visibleG5` int(11) unsigned NOT NULL default '0',
-  `visibleG6` int(11) unsigned NOT NULL default '0',
-  `visibleG7` int(11) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`castle_id`),
+  `castle_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `guild_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `economy` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `defense` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `triggerE` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `triggerD` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `nextTime` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `payTime` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `createTime` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `visibleC` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `visibleG0` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `visibleG1` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `visibleG2` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `visibleG3` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `visibleG4` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `visibleG5` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `visibleG6` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `visibleG7` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`castle_id`),
   KEY `guild_id` (`guild_id`)
 ) ENGINE=MyISAM;
 
@@ -261,11 +376,11 @@ CREATE TABLE IF NOT EXISTS `guild_castle` (
 --
 
 CREATE TABLE IF NOT EXISTS `guild_expulsion` (
-  `guild_id` int(11) unsigned NOT NULL default '0',
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `name` varchar(24) NOT NULL default '',
-  `mes` varchar(40) NOT NULL default '',
-  PRIMARY KEY  (`guild_id`,`name`)
+  `guild_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `name` VARCHAR(24) NOT NULL DEFAULT '',
+  `mes` VARCHAR(40) NOT NULL DEFAULT '',
+  PRIMARY KEY (`guild_id`,`name`)
 ) ENGINE=MyISAM;
 
 --
@@ -273,20 +388,20 @@ CREATE TABLE IF NOT EXISTS `guild_expulsion` (
 --
 
 CREATE TABLE IF NOT EXISTS `guild_member` (
-  `guild_id` int(11) unsigned NOT NULL default '0',
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `hair` tinyint(6) unsigned NOT NULL default '0',
-  `hair_color` smallint(6) unsigned NOT NULL default '0',
-  `gender` tinyint(6) unsigned NOT NULL default '0',
-  `class` smallint(6) unsigned NOT NULL default '0',
-  `lv` smallint(6) unsigned NOT NULL default '0',
-  `exp` bigint(20) unsigned NOT NULL default '0',
-  `exp_payper` tinyint(11) unsigned NOT NULL default '0',
-  `online` tinyint(4) unsigned NOT NULL default '0',
-  `position` tinyint(6) unsigned NOT NULL default '0',
-  `name` varchar(24) NOT NULL default '',
-  PRIMARY KEY  (`guild_id`,`char_id`),
+  `guild_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `hair` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `hair_color` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `gender` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `class` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `lv` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `exp` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  `exp_payper` TINYINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `online` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `position` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `name` VARCHAR(24) NOT NULL DEFAULT '',
+  PRIMARY KEY (`guild_id`,`char_id`),
   KEY `char_id` (`char_id`)
 ) ENGINE=MyISAM;
 
@@ -295,12 +410,12 @@ CREATE TABLE IF NOT EXISTS `guild_member` (
 --
 
 CREATE TABLE IF NOT EXISTS `guild_position` (
-  `guild_id` int(9) unsigned NOT NULL default '0',
-  `position` tinyint(6) unsigned NOT NULL default '0',
-  `name` varchar(24) NOT NULL default '',
-  `mode` tinyint(11) unsigned NOT NULL default '0',
-  `exp_mode` tinyint(11) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`guild_id`,`position`)
+  `guild_id` INT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `position` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `name` VARCHAR(24) NOT NULL DEFAULT '',
+  `mode` TINYINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `exp_mode` TINYINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`guild_id`,`position`)
 ) ENGINE=MyISAM;
 
 --
@@ -308,10 +423,10 @@ CREATE TABLE IF NOT EXISTS `guild_position` (
 --
 
 CREATE TABLE IF NOT EXISTS `guild_skill` (
-  `guild_id` int(11) unsigned NOT NULL default '0',
-  `id` smallint(11) unsigned NOT NULL default '0',
-  `lv` tinyint(11) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`guild_id`,`id`)
+  `guild_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `id` SMALLINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `lv` TINYINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`guild_id`,`id`)
 ) ENGINE=MyISAM;
 
 --
@@ -319,22 +434,22 @@ CREATE TABLE IF NOT EXISTS `guild_skill` (
 --
 
 CREATE TABLE IF NOT EXISTS `guild_storage` (
-  `id` int(10) unsigned NOT NULL auto_increment,
-  `guild_id` int(11) unsigned NOT NULL default '0',
-  `nameid` int(11) unsigned NOT NULL default '0',
-  `amount` int(11) unsigned NOT NULL default '0',
-  `equip` int(11) unsigned NOT NULL default '0',
-  `identify` smallint(6) unsigned NOT NULL default '0',
-  `refine` tinyint(3) unsigned NOT NULL default '0',
-  `attribute` tinyint(4) unsigned NOT NULL default '0',
-  `card0` smallint(11) NOT NULL default '0',
-  `card1` smallint(11) NOT NULL default '0',
-  `card2` smallint(11) NOT NULL default '0',
-  `card3` smallint(11) NOT NULL default '0',
-  `expire_time` int(11) unsigned NOT NULL default '0',
-  `bound` tinyint(1) unsigned NOT NULL default '0',
-  `unique_id` bigint(20) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`),
+  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `guild_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `nameid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `amount` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `equip` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `identify` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `refine` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `attribute` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `card0` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card1` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card2` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card3` SMALLINT(11) NOT NULL DEFAULT '0',
+  `expire_time` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `bound` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+  `unique_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`id`),
   KEY `guild_id` (`guild_id`)
 ) ENGINE=MyISAM;
 
@@ -343,63 +458,73 @@ CREATE TABLE IF NOT EXISTS `guild_storage` (
 --
 
 CREATE TABLE IF NOT EXISTS `homunculus` (
-  `homun_id` int(11) NOT NULL auto_increment,
-  `char_id` int(11) NOT NULL,
-  `class` mediumint(9) unsigned NOT NULL default '0',
-  `prev_class` mediumint(9) NOT NULL default '0',
-  `name` varchar(24) NOT NULL default '',
-  `level` smallint(4) NOT NULL default '0',
-  `exp` int(12) NOT NULL default '0',
-  `intimacy` int(12) NOT NULL default '0',
-  `hunger` smallint(4) NOT NULL default '0',
-  `str` smallint(4) unsigned NOT NULL default '0',
-  `agi` smallint(4) unsigned NOT NULL default '0',
-  `vit` smallint(4) unsigned NOT NULL default '0',
-  `int` smallint(4) unsigned NOT NULL default '0',
-  `dex` smallint(4) unsigned NOT NULL default '0',
-  `luk` smallint(4) unsigned NOT NULL default '0',
-  `hp` int(12) NOT NULL default '1',
-  `max_hp` int(12) NOT NULL default '1',
-  `sp` int(12) NOT NULL default '1',
-  `max_sp` int(12) NOT NULL default '1',
-  `skill_point` smallint(4) unsigned NOT NULL default '0',
-  `alive` tinyint(2) NOT NULL default '1',
-  `rename_flag` tinyint(2) NOT NULL default '0',
-  `vaporize` tinyint(2) NOT NULL default '0',
-  PRIMARY KEY  (`homun_id`)
+  `homun_id` INT(11) NOT NULL AUTO_INCREMENT,
+  `char_id` INT(11) NOT NULL,
+  `class` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `prev_class` MEDIUMINT(9) NOT NULL DEFAULT '0',
+  `name` VARCHAR(24) NOT NULL DEFAULT '',
+  `level` SMALLINT(4) NOT NULL DEFAULT '0',
+  `exp` INT(12) NOT NULL DEFAULT '0',
+  `intimacy` INT(12) NOT NULL DEFAULT '0',
+  `hunger` SMALLINT(4) NOT NULL DEFAULT '0',
+  `str` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `agi` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `vit` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `INT` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `dex` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `luk` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `hp` INT(12) NOT NULL DEFAULT '1',
+  `max_hp` INT(12) NOT NULL DEFAULT '1',
+  `sp` INT(12) NOT NULL DEFAULT '1',
+  `max_sp` INT(12) NOT NULL DEFAULT '1',
+  `skill_point` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `alive` TINYINT(2) NOT NULL DEFAULT '1',
+  `rename_flag` TINYINT(2) NOT NULL DEFAULT '0',
+  `vaporize` TINYINT(2) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`homun_id`)
 ) ENGINE=MyISAM;
 
 -- 
--- Table structure for table `interlog`
+-- Table structure for table `INTerlog`
 --
 
-CREATE TABLE IF NOT EXISTS `interlog` (
-  `time` datetime NOT NULL default '0000-00-00 00:00:00',
-  `log` varchar(255) NOT NULL default ''
+CREATE TABLE IF NOT EXISTS `INTerlog` (
+  `time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `log` VARCHAR(255) NOT NULL DEFAULT ''
 ) ENGINE=MyISAM; 
 
+--
+-- Table structure for table `INTerreg`
+--
+
+CREATE TABLE IF NOT EXISTS `interreg` (
+  `varname` VARCHAR(11) NOT NULL,
+  `value` VARCHAR(20) NOT NULL,
+   PRIMARY KEY (`varname`)
+) ENGINE=InnoDB;
+
 --
 -- Table structure for table `inventory`
 --
 
 CREATE TABLE IF NOT EXISTS `inventory` (
-  `id` int(11) unsigned NOT NULL auto_increment,
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `nameid` int(11) unsigned NOT NULL default '0',
-  `amount` int(11) unsigned NOT NULL default '0',
-  `equip` int(11) unsigned NOT NULL default '0',
-  `identify` smallint(6) NOT NULL default '0',
-  `refine` tinyint(3) unsigned NOT NULL default '0',
-  `attribute` tinyint(4) unsigned NOT NULL default '0',
-  `card0` smallint(11) NOT NULL default '0',
-  `card1` smallint(11) NOT NULL default '0',
-  `card2` smallint(11) NOT NULL default '0',
-  `card3` smallint(11) NOT NULL default '0',
-  `expire_time` int(11) unsigned NOT NULL default '0',
-  `favorite` tinyint(3) unsigned NOT NULL default '0',
-  `bound` tinyint(1) unsigned NOT NULL default '0',
-  `unique_id` bigint(20) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`),
+  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `nameid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `amount` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `equip` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `identify` SMALLINT(6) NOT NULL DEFAULT '0',
+  `refine` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `attribute` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `card0` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card1` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card2` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card3` SMALLINT(11) NOT NULL DEFAULT '0',
+  `expire_time` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `favorite` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `bound` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+  `unique_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`id`),
   KEY `char_id` (`char_id`)
 ) ENGINE=MyISAM;
 
@@ -408,10 +533,10 @@ CREATE TABLE IF NOT EXISTS `inventory` (
 --
 
 CREATE TABLE IF NOT EXISTS `ipbanlist` (
-  `list` varchar(255) NOT NULL default '',
-  `btime` datetime NOT NULL default '0000-00-00 00:00:00',
-  `rtime` datetime NOT NULL default '0000-00-00 00:00:00',
-  `reason` varchar(255) NOT NULL default '',
+  `list` VARCHAR(255) NOT NULL DEFAULT '',
+  `btime` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `rtime` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `reason` VARCHAR(255) NOT NULL DEFAULT '',
   KEY (`list`)
 ) ENGINE=MyISAM;
 
@@ -420,28 +545,28 @@ CREATE TABLE IF NOT EXISTS `ipbanlist` (
 --
 
 CREATE TABLE IF NOT EXISTS `login` (
-  `account_id` int(11) unsigned NOT NULL auto_increment,
-  `userid` varchar(23) NOT NULL default '',
-  `user_pass` varchar(32) NOT NULL default '',
-  `sex` enum('M','F','S') NOT NULL default 'M',
-  `email` varchar(39) NOT NULL default '',
-  `group_id` tinyint(3) NOT NULL default '0',
-  `state` int(11) unsigned NOT NULL default '0',
-  `unban_time` int(11) unsigned NOT NULL default '0',
-  `expiration_time` int(11) unsigned NOT NULL default '0',
-  `logincount` mediumint(9) unsigned NOT NULL default '0',
-  `lastlogin` datetime NOT NULL default '0000-00-00 00:00:00',
-  `last_ip` varchar(100) NOT NULL default '',
+  `account_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `userid` VARCHAR(23) NOT NULL DEFAULT '',
+  `user_pass` VARCHAR(32) NOT NULL DEFAULT '',
+  `sex` ENUM('M','F','S') NOT NULL DEFAULT 'M',
+  `email` VARCHAR(39) NOT NULL DEFAULT '',
+  `group_id` TINYINT(3) NOT NULL DEFAULT '0',
+  `state` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `unban_time` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `expiration_time` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `logincount` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `lastlogin` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `last_ip` VARCHAR(100) NOT NULL DEFAULT '',
   `birthdate` DATE NOT NULL DEFAULT '0000-00-00',
-  `character_slots` TINYINT( 3 ) unsigned NOT NULL default '0',
-  `pincode` varchar(4) NOT NULL default '',
-  `pincode_change` int(11) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`account_id`),
+  `character_slots` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `pincode` VARCHAR(4) NOT NULL DEFAULT '',
+  `pincode_change` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`account_id`),
   KEY `name` (`userid`)
 ) ENGINE=MyISAM AUTO_INCREMENT=2000000; 
 
 -- added standard accounts for servers, VERY INSECURE!!!
--- inserted into the table called login which is above
+-- inserted INTo the table called login which is above
 
 INSERT INTO `login` (`account_id`, `userid`, `user_pass`, `sex`, `email`) VALUES ('1', 's1', 'p1', 'S','athena@athena.com');
 
@@ -450,10 +575,21 @@ INSERT INTO `login` (`account_id`, `userid`, `user_pass`, `sex`, `email`) VALUES
 --
 
 CREATE TABLE IF NOT EXISTS `mapreg` (
-  `varname` varchar(32) BINARY NOT NULL,
-  `index` int(11) unsigned NOT NULL default '0',
-  `value` varchar(255) NOT NULL,
-  PRIMARY KEY  (`varname`,`index`)
+  `varname` VARCHAR(32) BINARY NOT NULL,
+  `index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `value` VARCHAR(255) NOT NULL,
+  PRIMARY KEY (`varname`,`index`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `npc_market_data`
+--
+
+CREATE TABLE IF NOT EXISTS `npc_market_data` (
+  `name` VARCHAR(24) NOT NULL DEFAULT '',
+  `itemid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `amount` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`name`,`itemid`)
 ) ENGINE=MyISAM;
 
 --
@@ -461,17 +597,17 @@ CREATE TABLE IF NOT EXISTS `mapreg` (
 --
 
 CREATE TABLE IF NOT EXISTS `sc_data` (
-  `account_id` int(11) unsigned NOT NULL,
-  `char_id` int(11) unsigned NOT NULL,
-  `type` smallint(11) unsigned NOT NULL,
-  `tick` int(11) NOT NULL,
-  `val1` int(11) NOT NULL default '0',
-  `val2` int(11) NOT NULL default '0',
-  `val3` int(11) NOT NULL default '0',
-  `val4` int(11) NOT NULL default '0',
+  `account_id` INT(11) UNSIGNED NOT NULL,
+  `char_id` INT(11) UNSIGNED NOT NULL,
+  `type` SMALLINT(11) UNSIGNED NOT NULL,
+  `tick` INT(11) NOT NULL,
+  `val1` INT(11) NOT NULL DEFAULT '0',
+  `val2` INT(11) NOT NULL DEFAULT '0',
+  `val3` INT(11) NOT NULL DEFAULT '0',
+  `val4` INT(11) NOT NULL DEFAULT '0',
   KEY (`account_id`),
   KEY (`char_id`),
-  PRIMARY KEY  (`account_id`,`char_id`,`type`)
+  PRIMARY KEY (`account_id`,`char_id`,`type`)
 ) ENGINE=MyISAM;
 
 --
@@ -479,27 +615,27 @@ CREATE TABLE IF NOT EXISTS `sc_data` (
 --
 
 CREATE TABLE IF NOT EXISTS `mail` (
-  `id` bigint(20) unsigned NOT NULL auto_increment,
-  `send_name` varchar(30) NOT NULL default '',
-  `send_id` int(11) unsigned NOT NULL default '0',
-  `dest_name` varchar(30) NOT NULL default '',
-  `dest_id` int(11) unsigned NOT NULL default '0',
-  `title` varchar(45) NOT NULL default '',
-  `message` varchar(255) NOT NULL default '',
-  `time` int(11) unsigned NOT NULL default '0',
-  `status` tinyint(2) NOT NULL default '0',
-  `zeny` int(11) unsigned NOT NULL default '0',
-  `nameid` int(11) unsigned NOT NULL default '0',
-  `amount` int(11) unsigned NOT NULL default '0',
-  `refine` tinyint(3) unsigned NOT NULL default '0',
-  `attribute` tinyint(4) unsigned NOT NULL default '0',
-  `identify` smallint(6) NOT NULL default '0',
-  `card0` smallint(11) NOT NULL default '0',
-  `card1` smallint(11) NOT NULL default '0',
-  `card2` smallint(11) NOT NULL default '0',
-  `card3` smallint(11) NOT NULL default '0',
-  `unique_id` bigint(20) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`)
+  `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `send_name` VARCHAR(30) NOT NULL DEFAULT '',
+  `send_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `dest_name` VARCHAR(30) NOT NULL DEFAULT '',
+  `dest_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `title` VARCHAR(45) NOT NULL DEFAULT '',
+  `message` VARCHAR(255) NOT NULL DEFAULT '',
+  `time` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `status` TINYINT(2) NOT NULL DEFAULT '0',
+  `zeny` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `nameid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `amount` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `refine` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `attribute` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `identify` SMALLINT(6) NOT NULL DEFAULT '0',
+  `card0` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card1` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card2` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card3` SMALLINT(11) NOT NULL DEFAULT '0',
+  `unique_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`id`)
 ) ENGINE=MyISAM;
 
 --
@@ -507,12 +643,12 @@ CREATE TABLE IF NOT EXISTS `mail` (
 --
 
 CREATE TABLE IF NOT EXISTS `memo` (
-  `memo_id` int(11) unsigned NOT NULL auto_increment,
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `map` varchar(11) NOT NULL default '',
-  `x` smallint(4) unsigned NOT NULL default '0',
-  `y` smallint(4) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`memo_id`),
+  `memo_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `map` VARCHAR(11) NOT NULL DEFAULT '',
+  `x` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `y` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`memo_id`),
   KEY `char_id` (`char_id`)
 ) ENGINE=MyISAM;
 
@@ -521,14 +657,14 @@ CREATE TABLE IF NOT EXISTS `memo` (
 --
 
 CREATE TABLE IF NOT EXISTS `mercenary` (
-  `mer_id` int(11) unsigned NOT NULL auto_increment,
-  `char_id` int(11) NOT NULL,
-  `class` mediumint(9) unsigned NOT NULL default '0',
-  `hp` int(12) NOT NULL default '1',
-  `sp` int(12) NOT NULL default '1',
-  `kill_counter` int(11) NOT NULL,
-  `life_time` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`mer_id`)
+  `mer_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `char_id` INT(11) NOT NULL,
+  `class` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `hp` INT(12) NOT NULL DEFAULT '1',
+  `sp` INT(12) NOT NULL DEFAULT '1',
+  `kill_counter` INT(11) NOT NULL,
+  `life_time` INT(11) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`mer_id`)
 ) ENGINE=MyISAM;
 
 --
@@ -536,15 +672,15 @@ CREATE TABLE IF NOT EXISTS `mercenary` (
 --
 
 CREATE TABLE IF NOT EXISTS `mercenary_owner` (
-  `char_id` int(11) NOT NULL,
-  `merc_id` int(11) NOT NULL default '0',
-  `arch_calls` int(11) NOT NULL default '0',
-  `arch_faith` int(11) NOT NULL default '0',
-  `spear_calls` int(11) NOT NULL default '0',
-  `spear_faith` int(11) NOT NULL default '0',
-  `sword_calls` int(11) NOT NULL default '0',
-  `sword_faith` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`char_id`)
+  `char_id` INT(11) NOT NULL,
+  `merc_id` INT(11) NOT NULL DEFAULT '0',
+  `arch_calls` INT(11) NOT NULL DEFAULT '0',
+  `arch_faith` INT(11) NOT NULL DEFAULT '0',
+  `spear_calls` INT(11) NOT NULL DEFAULT '0',
+  `spear_faith` INT(11) NOT NULL DEFAULT '0',
+  `sword_calls` INT(11) NOT NULL DEFAULT '0',
+  `sword_faith` INT(11) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`char_id`)
 ) ENGINE=MyISAM;
 
 --
@@ -552,13 +688,13 @@ CREATE TABLE IF NOT EXISTS `mercenary_owner` (
 --
 
 CREATE TABLE IF NOT EXISTS `party` (
-  `party_id` int(11) unsigned NOT NULL auto_increment,
-  `name` varchar(24) NOT NULL default '',
-  `exp` tinyint(11) unsigned NOT NULL default '0',
-  `item` tinyint(11) unsigned NOT NULL default '0',
-  `leader_id` int(11) unsigned NOT NULL default '0',
-  `leader_char` int(11) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`party_id`)
+  `party_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `name` VARCHAR(24) NOT NULL DEFAULT '',
+  `exp` TINYINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `item` TINYINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `leader_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `leader_char` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`party_id`)
 ) ENGINE=MyISAM;
 
 --
@@ -566,19 +702,19 @@ CREATE TABLE IF NOT EXISTS `party` (
 --
 
 CREATE TABLE IF NOT EXISTS `pet` (
-  `pet_id` int(11) unsigned NOT NULL auto_increment,
-  `class` mediumint(9) unsigned NOT NULL default '0',
-  `name` varchar(24) NOT NULL default '',
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `level` smallint(4) unsigned NOT NULL default '0',
-  `egg_id` smallint(11) unsigned NOT NULL default '0',
-  `equip` mediumint(8) unsigned NOT NULL default '0',
-  `intimate` smallint(9) unsigned NOT NULL default '0',
-  `hungry` smallint(9) unsigned NOT NULL default '0',
-  `rename_flag` tinyint(4) unsigned NOT NULL default '0',
-  `incubate` int(11) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`pet_id`)
+  `pet_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `class` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `name` VARCHAR(24) NOT NULL DEFAULT '',
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `level` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `egg_id` SMALLINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `equip` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
+  `INTimate` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `hungry` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `rename_flag` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `incubate` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`pet_id`)
 ) ENGINE=MyISAM;
 
 --
@@ -586,14 +722,14 @@ CREATE TABLE IF NOT EXISTS `pet` (
 --
 
 CREATE TABLE IF NOT EXISTS `quest` (
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `quest_id` int(10) unsigned NOT NULL,
-  `state` enum('0','1','2') NOT NULL default '0',
-  `time` int(11) unsigned NOT NULL default '0',
-  `count1` mediumint(8) unsigned NOT NULL default '0',
-  `count2` mediumint(8) unsigned NOT NULL default '0',
-  `count3` mediumint(8) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`char_id`,`quest_id`)
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `quest_id` INT(10) UNSIGNED NOT NULL,
+  `state` ENUM('0','1','2') NOT NULL DEFAULT '0',
+  `time` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `count1` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
+  `count2` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
+  `count3` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`char_id`,`quest_id`)
 ) ENGINE=MyISAM;
 
 --
@@ -601,11 +737,11 @@ CREATE TABLE IF NOT EXISTS `quest` (
 --
 
 CREATE TABLE IF NOT EXISTS `ragsrvinfo` (
-  `index` int(11) NOT NULL default '0',
-  `name` varchar(255) NOT NULL default '',
-  `exp` int(11) unsigned NOT NULL default '0',
-  `jexp` int(11) unsigned NOT NULL default '0',
-  `drop` int(11) unsigned NOT NULL default '0'
+  `index` INT(11) NOT NULL DEFAULT '0',
+  `name` VARCHAR(255) NOT NULL DEFAULT '',
+  `exp` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `jexp` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `drop` INT(11) UNSIGNED NOT NULL DEFAULT '0'
 ) ENGINE=MyISAM;
 
 --
@@ -613,11 +749,11 @@ CREATE TABLE IF NOT EXISTS `ragsrvinfo` (
 --
 
 CREATE TABLE IF NOT EXISTS `skill` (
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `id` smallint(11) unsigned NOT NULL default '0',
-  `lv` tinyint(4) unsigned NOT NULL default '0',
-  `flag` TINYINT(1) UNSIGNED NOT NULL default 0,
-  PRIMARY KEY  (`char_id`,`id`)
+  `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `id` SMALLINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `lv` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `flag` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
+  PRIMARY KEY (`char_id`,`id`)
 ) ENGINE=MyISAM;
 
 --
@@ -625,10 +761,10 @@ CREATE TABLE IF NOT EXISTS `skill` (
 --
 
 CREATE TABLE IF NOT EXISTS `skill_homunculus` (
-  `homun_id` int(11) NOT NULL,
-  `id` int(11) NOT NULL,
-  `lv` smallint(6) NOT NULL,
-  PRIMARY KEY  (`homun_id`,`id`)
+  `homun_id` INT(11) NOT NULL,
+  `id` INT(11) NOT NULL,
+  `lv` SMALLINT(6) NOT NULL,
+  PRIMARY KEY (`homun_id`,`id`)
 ) ENGINE=MyISAM;
 
 --
@@ -636,8 +772,8 @@ CREATE TABLE IF NOT EXISTS `skill_homunculus` (
 --
 
 CREATE TABLE IF NOT EXISTS `sql_updates` (
-  `timestamp` int(11) unsigned NOT NULL,
-  `ignored` enum('Yes','No') NOT NULL DEFAULT 'No',
+  `timestamp` INT(11) UNSIGNED NOT NULL,
+  `ignored` ENUM('Yes','No') NOT NULL DEFAULT 'No',
   PRIMARY KEY (`timestamp`)
 ) ENGINE=MyISAM;
 
@@ -675,9 +811,9 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1400256139); -- 2014-05-17--00-0
 --
 
 CREATE TABLE IF NOT EXISTS `sstatus` (
-  `index` tinyint(4) unsigned NOT NULL default '0',
-  `name` varchar(255) NOT NULL default '',
-  `user` int(11) unsigned NOT NULL default '0'
+  `index` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `name` VARCHAR(255) NOT NULL DEFAULT '',
+  `user` INT(11) UNSIGNED NOT NULL DEFAULT '0'
 ) ENGINE=MyISAM;
 
 --
@@ -685,158 +821,22 @@ CREATE TABLE IF NOT EXISTS `sstatus` (
 --
 
 CREATE TABLE IF NOT EXISTS `storage` (
-  `id` int(11) unsigned NOT NULL auto_increment,
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `nameid` int(11) unsigned NOT NULL default '0',
-  `amount` smallint(11) unsigned NOT NULL default '0',
-  `equip` int(11) unsigned NOT NULL default '0',
-  `identify` smallint(6) unsigned NOT NULL default '0',
-  `refine` tinyint(3) unsigned NOT NULL default '0',
-  `attribute` tinyint(4) unsigned NOT NULL default '0',
-  `card0` smallint(11) NOT NULL default '0',
-  `card1` smallint(11) NOT NULL default '0',
-  `card2` smallint(11) NOT NULL default '0',
-  `card3` smallint(11) NOT NULL default '0',
-  `expire_time` int(11) unsigned NOT NULL default '0',
-  `bound` tinyint(1) unsigned NOT NULL default '0',
-  `unique_id` bigint(20) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`),
+  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `nameid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `amount` SMALLINT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `equip` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `identify` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `refine` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
+  `attribute` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `card0` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card1` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card2` SMALLINT(11) NOT NULL DEFAULT '0',
+  `card3` SMALLINT(11) NOT NULL DEFAULT '0',
+  `expire_time` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `bound` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+  `unique_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`id`),
   KEY `account_id` (`account_id`)
 ) ENGINE=MyISAM;
 
---
--- Table structure for table `interreg`
---
-
-CREATE TABLE IF NOT EXISTS `interreg` (
-  `varname` varchar(11) NOT NULL,
-  `value` varchar(20) NOT NULL,
-   PRIMARY KEY (`varname`)
-) ENGINE=InnoDB;
-
---
--- Table structure for table `account_data`
---
-
-CREATE TABLE IF NOT EXISTS `account_data` (
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `bank_vault` int(11) unsigned NOT NULL default '0',
-  `base_exp` TINYINT( 4 ) UNSIGNED NOT NULL default '100',
-  `base_drop` TINYINT( 4 ) UNSIGNED NOT NULL default '100',
-  `base_death` TINYINT( 4 ) UNSIGNED NOT NULL default '100',
-  PRIMARY KEY  (`account_id`)
-) ENGINE=MyISAM; 
-
---
--- Table structure for table `npc_market_data`
---
-
-CREATE TABLE IF NOT EXISTS `npc_market_data` (
-  `name` varchar(24) NOT NULL default '',
-  `itemid` int(11) unsigned NOT NULL default '0',
-  `amount` int(11) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`name`,`itemid`)
-) ENGINE=MyISAM;
-
---
--- Table structure for table `acc_reg_num_db`
---
-
-CREATE TABLE IF NOT EXISTS `acc_reg_num_db` (
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `key` varchar(32) BINARY NOT NULL default '',
-  `index` int(11) unsigned NOT NULL default '0',
-  `value` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`account_id`,`key`,`index`),
-  KEY `account_id` (`account_id`)
-) ENGINE=MyISAM;
-
---
--- Table structure for table `acc_reg_str_db`
---
-
-CREATE TABLE IF NOT EXISTS `acc_reg_str_db` (
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `key` varchar(32) BINARY NOT NULL default '',
-  `index` int(11) unsigned NOT NULL default '0',
-  `value` varchar(254) NOT NULL default '0',
-  PRIMARY KEY  (`account_id`,`key`,`index`),
-  KEY `account_id` (`account_id`)
-) ENGINE=MyISAM;
-
---
--- Table structure for table `char_reg_num_db`
---
-
-CREATE TABLE IF NOT EXISTS `char_reg_num_db` (
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `key` varchar(32) BINARY NOT NULL default '',
-  `index` int(11) unsigned NOT NULL default '0',
-  `value` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`char_id`,`key`,`index`),
-  KEY `char_id` (`char_id`)
-) ENGINE=MyISAM;
-
---
--- Table structure for table `char_reg_str_db`
---
-
-CREATE TABLE IF NOT EXISTS `char_reg_str_db` (
-  `char_id` int(11) unsigned NOT NULL default '0',
-  `key` varchar(32) BINARY NOT NULL default '',
-  `index` int(11) unsigned NOT NULL default '0',
-  `value` varchar(254) NOT NULL default '0',
-  PRIMARY KEY  (`char_id`,`key`,`index`),
-  KEY `char_id` (`char_id`)
-) ENGINE=MyISAM;
-
---
--- Table structure for table `global_acc_reg_num_db`
---
-
-CREATE TABLE IF NOT EXISTS `global_acc_reg_num_db` (
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `key` varchar(32) BINARY NOT NULL default '',
-  `index` int(11) unsigned NOT NULL default '0',
-  `value` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`account_id`,`key`,`index`),
-  KEY `account_id` (`account_id`)
-) ENGINE=MyISAM;
-
---
--- Table structure for table `global_acc_reg_str_db`
---
-
-
-CREATE TABLE IF NOT EXISTS `global_acc_reg_str_db` (
-  `account_id` int(11) unsigned NOT NULL default '0',
-  `key` varchar(32) BINARY NOT NULL default '',
-  `index` int(11) unsigned NOT NULL default '0',
-  `value` varchar(254) NOT NULL default '0',
-  PRIMARY KEY  (`account_id`,`key`,`index`),
-  KEY `account_id` (`account_id`)
-) ENGINE=MyISAM;
-
---
--- Table structure for table `autotrade_merchants`
---
-
-CREATE TABLE IF NOT EXISTS `autotrade_merchants` (
-  `account_id` int(11) NOT NULL default '0',
-  `char_id` int(11) NOT NULL default '0',
-  `sex` tinyint(2) NOT NULL default '0',
-  `title` varchar(80) NOT NULL default 'Buy From Me!',
-  PRIMARY KEY  (`account_id`,`char_id`)
-) ENGINE=MyISAM; 
-
---
--- Table structure for table `autotrade_data`
---
-
-CREATE TABLE IF NOT EXISTS `autotrade_data` (
-  `char_id` int(11) NOT NULL default '0',
-  `itemkey` int(11) NOT NULL default '0',
-  `amount` int(11) NOT NULL default '0',
-  `price` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`char_id`,`itemkey`)
-) ENGINE=MyISAM; 
diff --git a/sql-files/mob_db.sql b/sql-files/mob_db.sql
index 894c34650..89674e1de 100644
--- a/sql-files/mob_db.sql
+++ b/sql-files/mob_db.sql
@@ -1,74 +1,74 @@
-#
-# Table structure for table `mob_db`
-#
+--
+-- Table structure for table `mob_db`
+--
 
 DROP TABLE IF EXISTS `mob_db`;
 CREATE TABLE `mob_db` (
-  `ID` mediumint(9) unsigned NOT NULL default '0',
-  `Sprite` text NOT NULL,
-  `kName` text NOT NULL,
-  `iName` text NOT NULL,
-  `LV` tinyint(6) unsigned NOT NULL default '0',
-  `HP` int(9) unsigned NOT NULL default '0',
-  `SP` mediumint(9) unsigned NOT NULL default '0',
-  `EXP` mediumint(9) unsigned NOT NULL default '0',
-  `JEXP` mediumint(9) unsigned NOT NULL default '0',
-  `Range1` tinyint(4) unsigned NOT NULL default '0',
-  `ATK1` smallint(6) unsigned NOT NULL default '0',
-  `ATK2` smallint(6) unsigned NOT NULL default '0',
-  `DEF` smallint(6) unsigned NOT NULL default '0',
-  `MDEF` smallint(6) unsigned NOT NULL default '0',
-  `STR` smallint(6) unsigned NOT NULL default '0',
-  `AGI` smallint(6) unsigned NOT NULL default '0',
-  `VIT` smallint(6) unsigned NOT NULL default '0',
-  `INT` smallint(6) unsigned NOT NULL default '0',
-  `DEX` smallint(6) unsigned NOT NULL default '0',
-  `LUK` smallint(6) unsigned NOT NULL default '0',
-  `Range2` tinyint(4) unsigned NOT NULL default '0',
-  `Range3` tinyint(4) unsigned NOT NULL default '0',
-  `Scale` tinyint(4) unsigned NOT NULL default '0',
-  `Race` tinyint(4) unsigned NOT NULL default '0',
-  `Element` tinyint(4) unsigned NOT NULL default '0',
-  `Mode` smallint(6) unsigned NOT NULL default '0',
-  `Speed` smallint(6) unsigned NOT NULL default '0',
-  `aDelay` smallint(6) unsigned NOT NULL default '0',
-  `aMotion` smallint(6) unsigned NOT NULL default '0',
-  `dMotion` smallint(6) unsigned NOT NULL default '0',
-  `MEXP` mediumint(9) unsigned NOT NULL default '0',
-  `MVP1id` smallint(9) unsigned NOT NULL default '0',
-  `MVP1per` smallint(9) unsigned NOT NULL default '0',
-  `MVP2id` smallint(9) unsigned NOT NULL default '0',
-  `MVP2per` smallint(9) unsigned NOT NULL default '0',
-  `MVP3id` smallint(9) unsigned NOT NULL default '0',
-  `MVP3per` smallint(9) unsigned NOT NULL default '0',
-  `Drop1id` smallint(9) unsigned NOT NULL default '0',
-  `Drop1per` smallint(9) unsigned NOT NULL default '0',
-  `Drop2id` smallint(9) unsigned NOT NULL default '0',
-  `Drop2per` smallint(9) unsigned NOT NULL default '0',
-  `Drop3id` smallint(9) unsigned NOT NULL default '0',
-  `Drop3per` smallint(9) unsigned NOT NULL default '0',
-  `Drop4id` smallint(9) unsigned NOT NULL default '0',
-  `Drop4per` smallint(9) unsigned NOT NULL default '0',
-  `Drop5id` smallint(9) unsigned NOT NULL default '0',
-  `Drop5per` smallint(9) unsigned NOT NULL default '0',
-  `Drop6id` smallint(9) unsigned NOT NULL default '0',
-  `Drop6per` smallint(9) unsigned NOT NULL default '0',
-  `Drop7id` smallint(9) unsigned NOT NULL default '0',
-  `Drop7per` smallint(9) unsigned NOT NULL default '0',
-  `Drop8id` smallint(9) unsigned NOT NULL default '0',
-  `Drop8per` smallint(9) unsigned NOT NULL default '0',
-  `Drop9id` smallint(9) unsigned NOT NULL default '0',
-  `Drop9per` smallint(9) unsigned NOT NULL default '0',
-  `DropCardid` smallint(9) unsigned NOT NULL default '0',
-  `DropCardper` smallint(9) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`ID`)
+  `ID` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Sprite` TEXT NOT NULL,
+  `kName` TEXT NOT NULL,
+  `iName` TEXT NOT NULL,
+  `LV` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `HP` INT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `SP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `EXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `JEXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Range1` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `ATK1` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `ATK2` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `DEF` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `MDEF` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `STR` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `AGI` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `VIT` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `INT` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `DEX` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `LUK` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `Range2` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Range3` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Scale` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Race` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Element` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Mode` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `Speed` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `aDelay` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `aMotion` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `dMotion` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `MEXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP1id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP1per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP2id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP2per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP3id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP3per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop1id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop1per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop2id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop2per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop3id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop3per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop4id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop4per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop5id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop5per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop6id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop6per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop7id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop7per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop8id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop8per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop9id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop9per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `DropCardid` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `DropCardper` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`ID`)
 ) ENGINE=MyISAM;
 
-#  Monster Database
-# 
-#  Structure of Database :
-# REPLACE INTO `mob_db` VALUES ( ID,'Sprite_Name','kROName','iROName',LV,HP,SP,EXP,JEXP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Mode,Speed,aDelay,aMotion,dMotion,MEXP,MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per,Drop1id,Drop1per,Drop2id,Drop2per,Drop3id,Drop3per,Drop4id,Drop4per,Drop5id,Drop5per,Drop6id,Drop6per,Drop7id,Drop7per,Drop8id,Drop8per,Drop9id,Drop9per,DropCardid,DropCardper);
-#  Note: Keep the Sprite_Name field as it is in the game client.
+-- Monster Database
+--
+-- Structure of Database :
+-- REPLACE INTO `mob_db` VALUES (ID,'Sprite_Name','kROName','iROName',LV,HP,SP,EXP,JEXP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Mode,Speed,aDelay,aMotion,dMotion,MEXP,MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per,Drop1id,Drop1per,Drop2id,Drop2per,Drop3id,Drop3per,Drop4id,Drop4per,Drop5id,Drop5per,Drop6id,Drop6per,Drop7id,Drop7per,Drop8id,Drop8per,Drop9id,Drop9per,DropCardid,DropCardper);
+-- Note: Keep the Sprite_Name field as it is in the game client.
 REPLACE INTO `mob_db` VALUES (1001,'SCORPION','Scorpion','Scorpion',24,1109,0,287,176,1,80,135,30,0,1,24,24,5,52,5,10,12,0,4,23,0x3195,200,1564,864,576,0,0,0,0,0,0,0,990,70,904,5500,757,57,943,210,7041,100,508,200,625,20,0,0,0,0,4068,1);
 REPLACE INTO `mob_db` VALUES (1002,'PORING','Poring','Poring',1,50,0,2,1,1,7,10,0,5,1,1,1,0,6,30,10,12,1,3,21,0x83,400,1872,672,480,0,0,0,0,0,0,0,909,7000,1202,100,938,400,512,1000,713,1500,512,150,619,20,0,0,0,0,4001,1);
 # REPLACE INTO `mob_db` VALUES (1003,'TESTEGG','Test Egg','Test Egg',2,100000,0,10,10,0,3,9,99,0,1,99,1,1,1,1,10,12,0,4,22,0x0,512,0,512,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
diff --git a/sql-files/mob_db2.sql b/sql-files/mob_db2.sql
index a370e0f58..2367c634a 100644
--- a/sql-files/mob_db2.sql
+++ b/sql-files/mob_db2.sql
@@ -1,88 +1,88 @@
-#
-# Table structure for table `mob_db2`
-#
+--
+-- Table structure for table `mob_db2`
+--
 
 DROP TABLE IF EXISTS `mob_db2`;
 CREATE TABLE `mob_db2` (
-  `ID` mediumint(9) unsigned NOT NULL default '0',
-  `Sprite` text NOT NULL,
-  `kName` text NOT NULL,
-  `iName` text NOT NULL,
-  `LV` tinyint(6) unsigned NOT NULL default '0',
-  `HP` int(9) unsigned NOT NULL default '0',
-  `SP` mediumint(9) unsigned NOT NULL default '0',
-  `EXP` mediumint(9) unsigned NOT NULL default '0',
-  `JEXP` mediumint(9) unsigned NOT NULL default '0',
-  `Range1` tinyint(4) unsigned NOT NULL default '0',
-  `ATK1` smallint(6) unsigned NOT NULL default '0',
-  `ATK2` smallint(6) unsigned NOT NULL default '0',
-  `DEF` smallint(6) unsigned NOT NULL default '0',
-  `MDEF` smallint(6) unsigned NOT NULL default '0',
-  `STR` smallint(6) unsigned NOT NULL default '0',
-  `AGI` smallint(6) unsigned NOT NULL default '0',
-  `VIT` smallint(6) unsigned NOT NULL default '0',
-  `INT` smallint(6) unsigned NOT NULL default '0',
-  `DEX` smallint(6) unsigned NOT NULL default '0',
-  `LUK` smallint(6) unsigned NOT NULL default '0',
-  `Range2` tinyint(4) unsigned NOT NULL default '0',
-  `Range3` tinyint(4) unsigned NOT NULL default '0',
-  `Scale` tinyint(4) unsigned NOT NULL default '0',
-  `Race` tinyint(4) unsigned NOT NULL default '0',
-  `Element` tinyint(4) unsigned NOT NULL default '0',
-  `Mode` smallint(6) unsigned NOT NULL default '0',
-  `Speed` smallint(6) unsigned NOT NULL default '0',
-  `aDelay` smallint(6) unsigned NOT NULL default '0',
-  `aMotion` smallint(6) unsigned NOT NULL default '0',
-  `dMotion` smallint(6) unsigned NOT NULL default '0',
-  `MEXP` mediumint(9) unsigned NOT NULL default '0',
-  `MVP1id` smallint(9) unsigned NOT NULL default '0',
-  `MVP1per` smallint(9) unsigned NOT NULL default '0',
-  `MVP2id` smallint(9) unsigned NOT NULL default '0',
-  `MVP2per` smallint(9) unsigned NOT NULL default '0',
-  `MVP3id` smallint(9) unsigned NOT NULL default '0',
-  `MVP3per` smallint(9) unsigned NOT NULL default '0',
-  `Drop1id` smallint(9) unsigned NOT NULL default '0',
-  `Drop1per` smallint(9) unsigned NOT NULL default '0',
-  `Drop2id` smallint(9) unsigned NOT NULL default '0',
-  `Drop2per` smallint(9) unsigned NOT NULL default '0',
-  `Drop3id` smallint(9) unsigned NOT NULL default '0',
-  `Drop3per` smallint(9) unsigned NOT NULL default '0',
-  `Drop4id` smallint(9) unsigned NOT NULL default '0',
-  `Drop4per` smallint(9) unsigned NOT NULL default '0',
-  `Drop5id` smallint(9) unsigned NOT NULL default '0',
-  `Drop5per` smallint(9) unsigned NOT NULL default '0',
-  `Drop6id` smallint(9) unsigned NOT NULL default '0',
-  `Drop6per` smallint(9) unsigned NOT NULL default '0',
-  `Drop7id` smallint(9) unsigned NOT NULL default '0',
-  `Drop7per` smallint(9) unsigned NOT NULL default '0',
-  `Drop8id` smallint(9) unsigned NOT NULL default '0',
-  `Drop8per` smallint(9) unsigned NOT NULL default '0',
-  `Drop9id` smallint(9) unsigned NOT NULL default '0',
-  `Drop9per` smallint(9) unsigned NOT NULL default '0',
-  `DropCardid` smallint(9) unsigned NOT NULL default '0',
-  `DropCardper` smallint(9) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`ID`)
+  `ID` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Sprite` TEXT NOT NULL,
+  `kName` TEXT NOT NULL,
+  `iName` TEXT NOT NULL,
+  `LV` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `HP` INT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `SP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `EXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `JEXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Range1` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `ATK1` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `ATK2` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `DEF` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `MDEF` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `STR` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `AGI` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `VIT` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `INT` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `DEX` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `LUK` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `Range2` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Range3` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Scale` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Race` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Element` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Mode` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `Speed` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `aDelay` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `aMotion` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `dMotion` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `MEXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP1id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP1per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP2id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP2per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP3id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP3per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop1id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop1per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop2id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop2per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop3id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop3per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop4id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop4per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop5id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop5per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop6id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop6per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop7id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop7per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop8id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop8per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop9id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop9per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `DropCardid` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `DropCardper` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`ID`)
 ) ENGINE=MyISAM;
 
-#  Monsters Additional Database
-# 
-#  Structure of Database :
-# REPLACE INTO `mob_db2` VALUES ( ID,'Sprite_Name','kROName','iROName',LV,HP,SP,EXP,JEXP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Mode,Speed,aDelay,aMotion,dMotion,MEXP,MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per,Drop1id,Drop1per,Drop2id,Drop2per,Drop3id,Drop3per,Drop4id,Drop4per,Drop5id,Drop5per,Drop6id,Drop6per,Drop7id,Drop7per,Drop8id,Drop8per,Drop9id,Drop9per,DropCardid,DropCardper);
+-- Monsters Additional Database
+--
+-- Structure of Database :
+-- REPLACE INTO `mob_db2` VALUES (ID,'Sprite_Name','kROName','iROName',LV,HP,SP,EXP,JEXP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Mode,Speed,aDelay,aMotion,dMotion,MEXP,MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per,Drop1id,Drop1per,Drop2id,Drop2per,Drop3id,Drop3per,Drop4id,Drop4per,Drop5id,Drop5per,Drop6id,Drop6per,Drop7id,Drop7per,Drop8id,Drop8per,Drop9id,Drop9per,DropCardid,DropCardper);
 
-# rAthena Dev Team
+-- rAthena Dev Team
 #REPLACE INTO `mob_db2` VALUES (1900,'VALARIS','Valaris','Valaris',99,668000,0,107250,37895,2,3220,4040,35,45,1,152,96,85,120,95,10,10,2,6,67,0x1973,100,1068,768,576,13000,608,1000,750,400,923,3800,1466,200,2256,200,2607,800,714,500,617,3000,984,4300,985,5600,0,0,0,0,4147,1);
 #REPLACE INTO `mob_db2` VALUES (1901,'VALARIS_WORSHIPPER','Valaris\'s Worshipper','Valaris\'s Worshipper',50,8578,0,2706,1480,1,487,590,15,25,1,75,55,1,93,45,10,12,0,6,27,0x1685,100,868,480,120,0,0,0,0,0,0,0,923,500,984,63,1464,2,607,50,610,100,503,300,2405,50,0,0,0,0,4129,1);
 #REPLACE INTO `mob_db2` VALUES (1902,'MC_CAMERI','MC Cameri','MC Cameri',99,668000,0,107250,37895,2,3220,4040,35,45,1,152,96,85,120,95,10,10,2,6,67,0x1973,100,1068,768,576,13000,608,1000,750,400,923,3800,1466,200,2256,200,2607,800,714,500,617,3000,984,4300,985,5600,0,0,0,0,4147,1);
 #REPLACE INTO `mob_db2` VALUES (1903,'POKI','Poki#3','Poki#3',99,1349000,0,4093000,1526000,9,4892,9113,22,35,1,180,39,67,193,130,10,12,1,7,64,0x1973,120,500,672,480,92100,603,5500,617,3000,1723,1000,1228,100,1236,500,617,2500,1234,75,1237,125,1722,250,1724,100,1720,50,0,0,0,0);
 #REPLACE INTO `mob_db2` VALUES (1904,'SENTRY','Sentry','Sentry',99,668000,0,107250,37895,2,3220,4040,35,45,1,152,96,85,120,95,10,10,2,6,67,0x1973,100,1068,768,576,13000,608,1000,750,400,923,3800,1466,200,2256,200,2607,800,714,500,617,3000,984,4300,985,5600,0,0,0,0,4147,1);
 
-# Custom Hollow Poring (overrrides/collides with META_ANDRE)
+-- Custom Hollow Poring (overrrides/collides with META_ANDRE)
 #REPLACE INTO `mob_db2` VALUES (1237,'HOLLOW_PORING','Hollow Poring','Hollow Poring',1,50,0,2,1,1,7,10,0,5,1,1,1,0,6,30,10,12,1,3,21,0x83,400,1872,672,480,0,0,0,0,0,0,0,909,7000,1202,100,938,400,512,1000,713,1500,512,150,619,20,0,0,0,0,4001,10);
-# Custom Fire Poring. Warning, Colides with META_DENIRO
+-- Custom Fire Poring. Warning, Colides with META_DENIRO
 #REPLACE INTO `mob_db2` VALUES (1239,'FIRE_PORING','Fire Poring','Fire Poring',1,50,0,2,1,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,0x131,400,1872,672,480,0,0,0,0,0,0,0,909,7000,1202,100,938,400,512,1000,713,1500,741,5,619,20,0,0,0,0,4001,20);
 
-# Lunar New Year 2008 Event Monster overrides
-# Uncomment if event is enabled, as these drops modifications are nessecary.
+-- Lunar New Year 2008 Event Monster overrides
+-- Uncomment if event is enabled, as these drops modifications are nessecary.
 #REPLACE INTO `mob_db2` VALUES (1145,'MARTIN','Martin','Martin',18,1109,0,134,86,1,52,63,0,5,12,18,30,15,15,5,10,12,0,2,42,0x81,300,1480,480,480,0,0,0,0,0,0,0,1017,9000,1018,500,1251,10,2225,5,5009,1,10010,10,2224,15,7869,1500,0,0,4046,1);
 #REPLACE INTO `mob_db2` VALUES (1175,'TAROU','Tarou','Tarou',11,284,0,57,28,1,34,45,0,0,1,20,11,10,24,5,10,12,0,2,27,0x91,150,1744,1044,684,0,0,0,0,0,0,0,1016,9000,919,3000,949,800,528,1000,701,2,7869,2500,0,0,0,0,0,0,4028,1);
 #REPLACE INTO `mob_db2` VALUES (1209,'CRAMP','Cramp','Cramp',56,4720,0,2300,1513,1,395,465,0,5,1,85,35,5,65,60,10,12,0,2,45,0x3095,100,1000,500,1000,0,0,0,0,0,0,0,7007,4656,528,1000,726,80,746,110,568,250,510,70,984,95,7869,1500,0,0,4296,1);
diff --git a/sql-files/mob_db_re.sql b/sql-files/mob_db_re.sql
index bd2ab084f..8a2863b80 100644
--- a/sql-files/mob_db_re.sql
+++ b/sql-files/mob_db_re.sql
@@ -1,74 +1,74 @@
-#
-# Table structure for table `mob_db`
-#
+--
+-- Table structure for table `mob_db`
+-- 
 
 DROP TABLE IF EXISTS `mob_db`;
 CREATE TABLE `mob_db` (
-  `ID` mediumint(9) unsigned NOT NULL default '0',
-  `Sprite` text NOT NULL,
-  `kName` text NOT NULL,
-  `iName` text NOT NULL,
-  `LV` tinyint(6) unsigned NOT NULL default '0',
-  `HP` int(9) unsigned NOT NULL default '0',
-  `SP` mediumint(9) unsigned NOT NULL default '0',
-  `EXP` mediumint(9) unsigned NOT NULL default '0',
-  `JEXP` mediumint(9) unsigned NOT NULL default '0',
-  `Range1` tinyint(4) unsigned NOT NULL default '0',
-  `ATK1` smallint(6) unsigned NOT NULL default '0',
-  `ATK2` smallint(6) unsigned NOT NULL default '0',
-  `DEF` smallint(6) unsigned NOT NULL default '0',
-  `MDEF` smallint(6) unsigned NOT NULL default '0',
-  `STR` smallint(6) unsigned NOT NULL default '0',
-  `AGI` smallint(6) unsigned NOT NULL default '0',
-  `VIT` smallint(6) unsigned NOT NULL default '0',
-  `INT` smallint(6) unsigned NOT NULL default '0',
-  `DEX` smallint(6) unsigned NOT NULL default '0',
-  `LUK` smallint(6) unsigned NOT NULL default '0',
-  `Range2` tinyint(4) unsigned NOT NULL default '0',
-  `Range3` tinyint(4) unsigned NOT NULL default '0',
-  `Scale` tinyint(4) unsigned NOT NULL default '0',
-  `Race` tinyint(4) unsigned NOT NULL default '0',
-  `Element` tinyint(4) unsigned NOT NULL default '0',
-  `Mode` smallint(6) unsigned NOT NULL default '0',
-  `Speed` smallint(6) unsigned NOT NULL default '0',
-  `aDelay` smallint(6) unsigned NOT NULL default '0',
-  `aMotion` smallint(6) unsigned NOT NULL default '0',
-  `dMotion` smallint(6) unsigned NOT NULL default '0',
-  `MEXP` mediumint(9) unsigned NOT NULL default '0',
-  `MVP1id` smallint(9) unsigned NOT NULL default '0',
-  `MVP1per` smallint(9) unsigned NOT NULL default '0',
-  `MVP2id` smallint(9) unsigned NOT NULL default '0',
-  `MVP2per` smallint(9) unsigned NOT NULL default '0',
-  `MVP3id` smallint(9) unsigned NOT NULL default '0',
-  `MVP3per` smallint(9) unsigned NOT NULL default '0',
-  `Drop1id` smallint(9) unsigned NOT NULL default '0',
-  `Drop1per` smallint(9) unsigned NOT NULL default '0',
-  `Drop2id` smallint(9) unsigned NOT NULL default '0',
-  `Drop2per` smallint(9) unsigned NOT NULL default '0',
-  `Drop3id` smallint(9) unsigned NOT NULL default '0',
-  `Drop3per` smallint(9) unsigned NOT NULL default '0',
-  `Drop4id` smallint(9) unsigned NOT NULL default '0',
-  `Drop4per` smallint(9) unsigned NOT NULL default '0',
-  `Drop5id` smallint(9) unsigned NOT NULL default '0',
-  `Drop5per` smallint(9) unsigned NOT NULL default '0',
-  `Drop6id` smallint(9) unsigned NOT NULL default '0',
-  `Drop6per` smallint(9) unsigned NOT NULL default '0',
-  `Drop7id` smallint(9) unsigned NOT NULL default '0',
-  `Drop7per` smallint(9) unsigned NOT NULL default '0',
-  `Drop8id` smallint(9) unsigned NOT NULL default '0',
-  `Drop8per` smallint(9) unsigned NOT NULL default '0',
-  `Drop9id` smallint(9) unsigned NOT NULL default '0',
-  `Drop9per` smallint(9) unsigned NOT NULL default '0',
-  `DropCardid` smallint(9) unsigned NOT NULL default '0',
-  `DropCardper` smallint(9) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`ID`)
+  `ID` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Sprite` TEXT NOT NULL,
+  `kName` TEXT NOT NULL,
+  `iName` TEXT NOT NULL,
+  `LV` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `HP` int(9) UNSIGNED NOT NULL DEFAULT '0',
+  `SP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `EXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `JEXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Range1` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `ATK1` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `ATK2` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `DEF` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `MDEF` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `STR` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `AGI` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `VIT` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `INT` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `DEX` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `LUK` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `Range2` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Range3` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Scale` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Race` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Element` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  `Mode` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `Speed` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `aDelay` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `aMotion` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `dMotion` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',
+  `MEXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP1id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP1per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP2id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP2per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP3id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `MVP3per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop1id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop1per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop2id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop2per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop3id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop3per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop4id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop4per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop5id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop5per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop6id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop6per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop7id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop7per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop8id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop8per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop9id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `Drop9per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `DropCardid` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `DropCardper` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`ID`)
 ) ENGINE=MyISAM;
 
-#  Monster Database
-# 
-#  Structure of Database :
-# REPLACE INTO `mob_db` VALUES ( ID,'Sprite_Name','kROName','iROName',LV,HP,SP,EXP,JEXP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Mode,Speed,aDelay,aMotion,dMotion,MEXP,MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per,Drop1id,Drop1per,Drop2id,Drop2per,Drop3id,Drop3per,Drop4id,Drop4per,Drop5id,Drop5per,Drop6id,Drop6per,Drop7id,Drop7per,Drop8id,Drop8per,Drop9id,Drop9per,DropCardid,DropCardper);
-#  Note: Keep the Sprite_Name field as it is in the game client.
+-- Monster Database
+--
+-- Structure of Database :
+-- REPLACE INTO `mob_db` VALUES (ID,'Sprite_Name','kROName','iROName',LV,HP,SP,EXP,JEXP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Mode,Speed,aDelay,aMotion,dMotion,MEXP,MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per,Drop1id,Drop1per,Drop2id,Drop2per,Drop3id,Drop3per,Drop4id,Drop4per,Drop5id,Drop5per,Drop6id,Drop6per,Drop7id,Drop7per,Drop8id,Drop8per,Drop9id,Drop9per,DropCardid,DropCardper);
+-- Note: Keep the Sprite_Name field as it is in the game client.
 REPLACE INTO `mob_db` VALUES (1001,'SCORPION','Scorpion','Scorpion',16,153,1,108,81,1,33,40,16,5,12,15,10,5,19,5,10,12,0,4,23,0x3191,200,1564,864,576,0,0,0,0,0,0,0,990,70,904,5500,757,57,943,210,7041,100,508,200,625,20,0,0,0,0,4068,1);
 REPLACE INTO `mob_db` VALUES (1002,'PORING','Poring','Poring',1,60,1,27,20,1,8,9,2,5,6,1,1,0,6,5,10,12,1,3,21,0x83,400,1872,672,480,0,0,0,0,0,0,0,909,7000,1202,100,938,400,512,1000,713,1500,512,150,619,20,0,0,0,0,4001,1);
 # REPLACE INTO `mob_db` VALUES (1003,'TESTEGG','Test Egg','Test Egg',2,100000,0,10,10,0,3,9,99,0,1,99,1,1,1,1,10,12,0,4,22,0x0,512,0,512,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
diff --git a/sql-files/mob_skill_db.sql b/sql-files/mob_skill_db.sql
index 30e845d83..b240711cb 100644
--- a/sql-files/mob_skill_db.sql
+++ b/sql-files/mob_skill_db.sql
@@ -1,93 +1,93 @@
-#
-# Table structure for table `mob_skill_db`
-#
+--
+-- Table structure for table `mob_skill_db`
+--
 
 DROP TABLE IF EXISTS `mob_skill_db`;
 CREATE TABLE IF NOT EXISTS `mob_skill_db` (
-  `MOB_ID` smallint(6) NOT NULL,
-  `INFO` text NOT NULL,
-  `STATE` text NOT NULL,
-  `SKILL_ID` smallint(6) NOT NULL,
-  `SKILL_LV` tinyint(4) NOT NULL,
-  `RATE` smallint(4) NOT NULL,
-  `CASTTIME` mediumint(9) NOT NULL,
-  `DELAY` int(9) NOT NULL,
-  `CANCELABLE` text NOT NULL,
-  `TARGET` text NOT NULL,
-  `CONDITION` text NOT NULL,
-  `CONDITION_VALUE` text,
-  `VAL1` mediumint(9) DEFAULT NULL,
-  `VAL2` mediumint(9) DEFAULT NULL,
-  `VAL3` mediumint(9) DEFAULT NULL,
-  `VAL4` mediumint(9) DEFAULT NULL,
-  `VAL5` mediumint(9) DEFAULT NULL,
-  `EMOTION` text,
-  `CHAT` text
+  `MOB_ID` SMALLINT(6) NOT NULL,
+  `INFO` TEXT NOT NULL,
+  `STATE` TEXT NOT NULL,
+  `SKILL_ID` SMALLINT(6) NOT NULL,
+  `SKILL_LV` TINYINT(4) NOT NULL,
+  `RATE` SMALLINT(4) NOT NULL,
+  `CASTTIME` MEDIUMINT(9) NOT NULL,
+  `DELAY` INT(9) NOT NULL,
+  `CANCELABLE` TEXT NOT NULL,
+  `TARGET` TEXT NOT NULL,
+  `CONDITION` TEXT NOT NULL,
+  `CONDITION_VALUE` TEXT,
+  `VAL1` MEDIUMINT(9) DEFAULT NULL,
+  `VAL2` MEDIUMINT(9) DEFAULT NULL,
+  `VAL3` MEDIUMINT(9) DEFAULT NULL,
+  `VAL4` MEDIUMINT(9) DEFAULT NULL,
+  `VAL5` MEDIUMINT(9) DEFAULT NULL,
+  `EMOTION` TEXT,
+  `CHAT` TEXT
 ) ENGINE=MyISAM;
 
-# Based on Aegis Episode 11.3
-#
-# REPLACE INTO `mob_skill_db` VALUES (MOB_ID,'dummy value (info only)','STATE',SKILL_ID,SKILL_LV,rate (10000 = 100%),casttime,delay,'cancelable','target','condition type','condition value',val1,val2,val3,val4,val5,'emotion','chat');
-#Example
-#1001,Poring@TF_POISON,attack,52,3,100,1500,10000,no,target,always,0,,,,,7,
-#
-#rate refers to the chance of the skill being casted when the condition is fulfilled.
-#delay is the time in milliseconds that has to be pass before recasting the same skill.
-#
-#STATE:
-# any (except dead) / idle (in standby) / walk (in movement) / dead (on killed) /
-# loot /attack / angry (like attack, except player has not attacked mob yet) /
-# chase (following target, after being attacked) / follow (following
-# target, without being attacked)
-# anytarget (attack+angry+chase+follow)
-#
-#target: The target of the skill can be: target (current target) / self / friend /
-# master / randomtarget (any enemy within skill's range)
-# (the following are for ground-skills, a random target tile is selected from
-# the specified area):
-# around1 (3x3 area around self) / around2 (5x5 area around self) /
-# around3 (7x7 area around self) / around4 (9x9 area around self) /
-# around5 (3x3 area around target) / around6 (5x5 area around target) /
-# around7 (7x7 area around target) / around8 (9x9 area around target) /
-# around = around4
-#
-#conditions: (condition type) (value which specifies a condition value)
-#	always			unconditional
-#	onspawn			when the mob spawns/respawns.
-#	myhpltmaxrate		when the mob's hp drops to a certain %
-#	myhpinrate		when the mob's hp is in a certain % range ('a condition value'
-#                is the lower cap, while 'a value 1' is the upper cap).
-#	mystatuson		If the mob has any abnormalities in status (condition value)
-#	mystatusoff		If the mob has ended any abnormalities in status (condition value)
-#	friendhpltmaxrate	when the mob's friend's hp drops to a certain %
-#	friendhpinrate		when the mob's friend's hp is in a certain % range (range
-#                   defined the same way as in myhpinrate)
-#	friendstatuson		If the friend has any abnormalities in status (condition value)
-#	friendstatusoff		If the friend has ended any abnormalities in status (condition value)
-#	attackpcgt		Attack PC becomes more than the  number of specification
-#	attackpcge		Attack PC becomes equal or more than the number of specification.
-#	slavelt			when the number of slaves is lower than the original number of specification.
-#	slavele			when the number of slaves is lower or equal than the original number of specification.
-#	closedattacked		when melee attacked (close range attack)
-#	longrangeattacked	when long ranged attacked (like bows and far range weapons)
-#	skillused		when a skill is used on the mob
-#	afterskill		after the mob used certain skill.
-#	casttargeted		when a target is in cast range.
-#	rudeattacked		when a target is rude attacked
-#
-# The character's state which can be specified to be a condition value by the statuson/statusoff system
-#	anybad		any type of state change
-#	stone		condition of being in stone state
-#	freeze		condition of being in frozen state
-#	stun		condition of being in stunned state
-#	sleep		condition of being in sleep state
-#	poison		condition of being in poisoned state
-#	curse		condition of being in cursed state
-#	silence		condition of being in silenced state
-#	confusion	condition of being in confusion state
-#	blind		condition of being in blind state
-#	hiding		condition of being in hidden state
-#	sight		condition of being in unhidden state
+-- Based on Aegis Episode 11.3
+--
+-- REPLACE INTO `mob_skill_db` VALUES (MOB_ID,'dummy value (info only)','STATE',SKILL_ID,SKILL_LV,rate (10000 = 100%),casttime,delay,'cancelable','target','condition type','condition value',val1,val2,val3,val4,val5,'emotion','chat');
+-- Example
+-- 1001,Poring@TF_POISON,attack,52,3,100,1500,10000,no,target,always,0,,,,,7,
+--
+-- rate refers to the chance of the skill being casted when the condition is fulfilled.
+-- delay is the time in milliseconds that has to be pass before recasting the same skill.
+-- 
+-- STATE:
+--  any (except dead) / idle (in standby) / walk (in movement) / dead (on killed) /
+--  loot /attack / angry (like attack, except player has not attacked mob yet) /
+--  chase (following target, after being attacked) / follow (following
+--  target, without being attacked)
+--  anytarget (attack+angry+chase+follow)
+-- 
+-- target: The target of the skill can be: target (current target) / self / friend /
+--  master / randomtarget (any enemy within skill's range)
+--  (the following are for ground-skills, a random target tile is selected from
+--  the specified area):
+--  around1 (3x3 area around self) / around2 (5x5 area around self) /
+--  around3 (7x7 area around self) / around4 (9x9 area around self) /
+--  around5 (3x3 area around target) / around6 (5x5 area around target) /
+--  around7 (7x7 area around target) / around8 (9x9 area around target) /
+--  around = around4
+-- 
+-- conditions: (condition type) (value which specifies a condition value)
+-- 	always			unconditional
+-- 	onspawn			when the mob spawns/respawns.
+-- 	myhpltmaxrate		when the mob's hp drops to a certain %
+-- 	myhpinrate		when the mob's hp is in a certain % range ('a condition value'
+--                 is the lower cap, while 'a value 1' is the upper cap).
+-- 	mystatuson		If the mob has any abnormalities in status (condition value)
+-- 	mystatusoff		If the mob has ended any abnormalities in status (condition value)
+-- 	friendhpltmaxrate	when the mob's friend's hp drops to a certain %
+-- 	friendhpinrate		when the mob's friend's hp is in a certain % range (range
+--                    defined the same way as in myhpinrate)
+-- 	friendstatuson		If the friend has any abnormalities in status (condition value)
+-- 	friendstatusoff		If the friend has ended any abnormalities in status (condition value)
+-- 	attackpcgt		Attack PC becomes more than the  number of specification
+-- 	attackpcge		Attack PC becomes equal or more than the number of specification.
+-- 	slavelt			when the number of slaves is lower than the original number of specification.
+-- 	slavele			when the number of slaves is lower or equal than the original number of specification.
+-- 	closedattacked		when melee attacked (close range attack)
+-- 	longrangeattacked	when long ranged attacked (like bows and far range weapons)
+-- 	skillused		when a skill is used on the mob
+-- 	afterskill		after the mob used certain skill.
+-- 	casttargeted		when a target is in cast range.
+-- 	rudeattacked		when a target is rude attacked
+-- 
+--  The character's state which can be specified to be a condition value by the statuson/statusoff system
+-- 	anybad		any type of state change
+-- 	stone		condition of being in stone state
+-- 	freeze		condition of being in frozen state
+-- 	stun		condition of being in stunned state
+-- 	sleep		condition of being in sleep state
+-- 	poison		condition of being in poisoned state
+-- 	curse		condition of being in cursed state
+-- 	silence		condition of being in silenced state
+-- 	confusion	condition of being in confusion state
+-- 	blind		condition of being in blind state
+-- 	hiding		condition of being in hidden state
+-- 	sight		condition of being in unhidden state
 
 REPLACE INTO `mob_skill_db` VALUES (1001,'Scorpion@NPC_FIREATTACK','attack',186,1,2000,0,5000,'yes','target','always',0,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
 REPLACE INTO `mob_skill_db` VALUES (1001,'Scorpion@NPC_POISON','attack',176,3,500,800,5000,'no','target','always',0,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
diff --git a/sql-files/mob_skill_db2.sql b/sql-files/mob_skill_db2.sql
index b44ad3225..0df6e8de5 100644
--- a/sql-files/mob_skill_db2.sql
+++ b/sql-files/mob_skill_db2.sql
@@ -1,35 +1,35 @@
-#
-#  Table structure for table `mob_skill_db2`
-#
+--
+-- Table structure for table `mob_skill_db2`
+--
 
 DROP TABLE IF EXISTS `mob_skill_db2`;
 CREATE TABLE IF NOT EXISTS `mob_skill_db2` (
-  `MOB_ID` smallint(6) NOT NULL,
-  `INFO` text NOT NULL,
-  `STATE` text NOT NULL,
-  `SKILL_ID` smallint(6) NOT NULL,
+  `MOB_ID` SMALLINT(6) NOT NULL,
+  `INFO` TEXT NOT NULL,
+  `STATE` TEXT NOT NULL,
+  `SKILL_ID` SMALLINT(6) NOT NULL,
   `SKILL_LV` tinyint(4) NOT NULL,
-  `RATE` smallint(4) NOT NULL,
-  `CASTTIME` mediumint(9) NOT NULL,
-  `DELAY` int(9) NOT NULL,
-  `CANCELABLE` text NOT NULL,
-  `TARGET` text NOT NULL,
-  `CONDITION` text NOT NULL,
-  `CONDITION_VALUE` text,
-  `VAL1` mediumint(9) DEFAULT NULL,
-  `VAL2` mediumint(9) DEFAULT NULL,
-  `VAL3` mediumint(9) DEFAULT NULL,
-  `VAL4` mediumint(9) DEFAULT NULL,
-  `VAL5` mediumint(9) DEFAULT NULL,
-  `EMOTION` text,
-  `CHAT` text
+  `RATE` SMALLINT(4) NOT NULL,
+  `CASTTIME` MEDIUMINT(9) NOT NULL,
+  `DELAY` INT(9) NOT NULL,
+  `CANCELABLE` TEXT NOT NULL,
+  `TARGET` TEXT NOT NULL,
+  `CONDITION` TEXT NOT NULL,
+  `CONDITION_VALUE` TEXT,
+  `VAL1` MEDIUMINT(9) DEFAULT NULL,
+  `VAL2` MEDIUMINT(9) DEFAULT NULL,
+  `VAL3` MEDIUMINT(9) DEFAULT NULL,
+  `VAL4` MEDIUMINT(9) DEFAULT NULL,
+  `VAL5` MEDIUMINT(9) DEFAULT NULL,
+  `EMOTION` TEXT,
+  `CHAT` TEXT
 ) ENGINE=MyISAM;
 
-#  Mob Skill Database
-# 
-#  Structure of Database:
-#  INSERT INTO `mob_skill_db2` (`MOB_ID`, `INFO`, `STATE`, `SKILL_ID`, `SKILL_LV`, `RATE`, `CASTTIME`, `DELAY`, `CANCELABLE`, `TARGET`, `CONDITION`, `CONDITION_VALUE`, `VAL1`, `VAL2`, `VAL3`, `VAL4`, `VAL5`, `EMOTION`, `CHAT`);
-#
+-- Mob Skill Database
+-- 
+-- Structure of Database:
+-- INSERT INTO `mob_skill_db2` (`MOB_ID`, `INFO`, `STATE`, `SKILL_ID`, `SKILL_LV`, `RATE`, `CASTTIME`, `DELAY`, `CANCELABLE`, `TARGET`, `CONDITION`, `CONDITION_VALUE`, `VAL1`, `VAL2`, `VAL3`, `VAL4`, `VAL5`, `EMOTION`, `CHAT`);
+
 # REPLACE INTO mob_skill_db2 VALUES(1900, "Valaris@AL_TELEPORT", "idle", 26, 1, 10000, 0, 0, "yes", "self", "rudeattacked", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 # REPLACE INTO mob_skill_db2 VALUES(1900, "Valaris@AL_TELEPORT", "walk", 26, 1, 500, 0, 5000, "yes", "self", "rudeattacked", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 # REPLACE INTO mob_skill_db2 VALUES(1900, "Valaris@KN_BRANDISHSPEAR", "attack", 57, 10, 2000, 500, 5000, "no", "target", "always", 0, NULL, NULL, NULL, NULL, NULL, 29, NULL);
diff --git a/sql-files/mob_skill_db_re.sql b/sql-files/mob_skill_db_re.sql
index 41d690503..8810ef1e5 100644
--- a/sql-files/mob_skill_db_re.sql
+++ b/sql-files/mob_skill_db_re.sql
@@ -1,93 +1,93 @@
-#
-# Table structure for table `mob_skill_db`
-#
+--
+-- Table structure for table `mob_skill_db`
+--
 
 DROP TABLE IF EXISTS `mob_skill_db`;
 CREATE TABLE IF NOT EXISTS `mob_skill_db` (
-  `MOB_ID` smallint(6) NOT NULL,
-  `INFO` text NOT NULL,
-  `STATE` text NOT NULL,
-  `SKILL_ID` smallint(6) NOT NULL,
-  `SKILL_LV` tinyint(4) NOT NULL,
-  `RATE` smallint(4) NOT NULL,
-  `CASTTIME` mediumint(9) NOT NULL,
-  `DELAY` int(9) NOT NULL,
-  `CANCELABLE` text NOT NULL,
-  `TARGET` text NOT NULL,
-  `CONDITION` text NOT NULL,
-  `CONDITION_VALUE` text,
-  `VAL1` mediumint(9) DEFAULT NULL,
-  `VAL2` mediumint(9) DEFAULT NULL,
-  `VAL3` mediumint(9) DEFAULT NULL,
-  `VAL4` mediumint(9) DEFAULT NULL,
-  `VAL5` mediumint(9) DEFAULT NULL,
-  `EMOTION` text,
-  `CHAT` text
+  `MOB_ID` SMALLINT(6) NOT NULL,
+  `INFO` TEXT NOT NULL,
+  `STATE` TEXT NOT NULL,
+  `SKILL_ID` SMALLINT(6) NOT NULL,
+  `SKILL_LV` TINYINT(4) NOT NULL,
+  `RATE` SMALLINT(4) NOT NULL,
+  `CASTTIME` MEDIUMINT(9) NOT NULL,
+  `DELAY` INT(9) NOT NULL,
+  `CANCELABLE` TEXT NOT NULL,
+  `TARGET` TEXT NOT NULL,
+  `CONDITION` TEXT NOT NULL,
+  `CONDITION_VALUE` TEXT,
+  `VAL1` MEDIUMINT(9) DEFAULT NULL,
+  `VAL2` MEDIUMINT(9) DEFAULT NULL,
+  `VAL3` MEDIUMINT(9) DEFAULT NULL,
+  `VAL4` MEDIUMINT(9) DEFAULT NULL,
+  `VAL5` MEDIUMINT(9) DEFAULT NULL,
+  `EMOTION` TEXT,
+  `CHAT` TEXT
 ) ENGINE=MyISAM;
 
-# Based on Aegis Episode 11.3
-#
-# REPLACE INTO `mob_skill_db` VALUES (MOB_ID,'dummy value (info only)','STATE',SKILL_ID,SKILL_LV,rate (10000 = 100%),casttime,delay,'cancelable','target','condition type','condition value',val1,val2,val3,val4,val5,'emotion','chat');
-#Example
-#1001,Poring@TF_POISON,attack,52,3,100,1500,10000,no,target,always,0,,,,,7,
-#
-#rate refers to the chance of the skill being casted when the condition is fulfilled.
-#delay is the time in milliseconds that has to be pass before recasting the same skill.
-#
-#STATE:
-# any (except dead) / idle (in standby) / walk (in movement) / dead (on killed) /
-# loot /attack / angry (like attack, except player has not attacked mob yet) /
-# chase (following target, after being attacked) / follow (following
-# target, without being attacked)
-# anytarget (attack+angry+chase+follow)
-#
-#target: The target of the skill can be: target (current target) / self / friend /
-# master / randomtarget (any enemy within skill's range)
-# (the following are for ground-skills, a random target tile is selected from
-# the specified area):
-# around1 (3x3 area around self) / around2 (5x5 area around self) /
-# around3 (7x7 area around self) / around4 (9x9 area around self) /
-# around5 (3x3 area around target) / around6 (5x5 area around target) /
-# around7 (7x7 area around target) / around8 (9x9 area around target) /
-# around = around4
-#
-#conditions: (condition type) (value which specifies a condition value)
-#	always			unconditional
-#	onspawn			when the mob spawns/respawns.
-#	myhpltmaxrate		when the mob's hp drops to a certain %
-#	myhpinrate		when the mob's hp is in a certain % range ('a condition value'
-#                is the lower cap, while 'a value 1' is the upper cap).
-#	mystatuson		If the mob has any abnormalities in status (condition value)
-#	mystatusoff		If the mob has ended any abnormalities in status (condition value)
-#	friendhpltmaxrate	when the mob's friend's hp drops to a certain %
-#	friendhpinrate		when the mob's friend's hp is in a certain % range (range
-#                   defined the same way as in myhpinrate)
-#	friendstatuson		If the friend has any abnormalities in status (condition value)
-#	friendstatusoff		If the friend has ended any abnormalities in status (condition value)
-#	attackpcgt		Attack PC becomes more than the  number of specification
-#	attackpcge		Attack PC becomes equal or more than the number of specification.
-#	slavelt			when the number of slaves is lower than the original number of specification.
-#	slavele			when the number of slaves is lower or equal than the original number of specification.
-#	closedattacked		when melee attacked (close range attack)
-#	longrangeattacked	when long ranged attacked (like bows and far range weapons)
-#	skillused		when a skill is used on the mob
-#	afterskill		after the mob used certain skill.
-#	casttargeted		when a target is in cast range.
-#	rudeattacked		when a target is rude attacked
-#
-# The character's state which can be specified to be a condition value by the statuson/statusoff system
-#	anybad		any type of state change
-#	stone		condition of being in stone state
-#	freeze		condition of being in frozen state
-#	stun		condition of being in stunned state
-#	sleep		condition of being in sleep state
-#	poison		condition of being in poisoned state
-#	curse		condition of being in cursed state
-#	silence		condition of being in silenced state
-#	confusion	condition of being in confusion state
-#	blind		condition of being in blind state
-#	hiding		condition of being in hidden state
-#	sight		condition of being in unhidden state
+-- Based on Aegis Episode 11.3
+--
+-- REPLACE INTO `mob_skill_db` VALUES (MOB_ID,'dummy value (info only)','STATE',SKILL_ID,SKILL_LV,rate (10000 = 100%),casttime,delay,'cancelable','target','condition type','condition value',val1,val2,val3,val4,val5,'emotion','chat');
+-- Example
+-- 1001,Poring@TF_POISON,attack,52,3,100,1500,10000,no,target,always,0,,,,,7,
+-- 
+-- rate refers to the chance of the skill being casted when the condition is fulfilled.
+-- delay is the time in milliseconds that has to be pass before recasting the same skill.
+-- 
+-- STATE:
+--  any (except dead) / idle (in standby) / walk (in movement) / dead (on killed) /
+--  loot /attack / angry (like attack, except player has not attacked mob yet) /
+--  chase (following target, after being attacked) / follow (following
+--  target, without being attacked)
+--  anytarget (attack+angry+chase+follow)
+-- 
+-- target: The target of the skill can be: target (current target) / self / friend /
+--  master / randomtarget (any enemy within skill's range)
+--  (the following are for ground-skills, a random target tile is selected from
+--  the specified area):
+--  around1 (3x3 area around self) / around2 (5x5 area around self) /
+--  around3 (7x7 area around self) / around4 (9x9 area around self) /
+--  around5 (3x3 area around target) / around6 (5x5 area around target) /
+--  around7 (7x7 area around target) / around8 (9x9 area around target) /
+--  around = around4
+-- 
+-- conditions: (condition type) (value which specifies a condition value)
+-- 	always			unconditional
+-- 	onspawn			when the mob spawns/respawns.
+-- 	myhpltmaxrate		when the mob's hp drops to a certain %
+-- 	myhpinrate		when the mob's hp is in a certain % range ('a condition value'
+--                 is the lower cap, while 'a value 1' is the upper cap).
+-- 	mystatuson		If the mob has any abnormalities in status (condition value)
+-- 	mystatusoff		If the mob has ended any abnormalities in status (condition value)
+-- 	friendhpltmaxrate	when the mob's friend's hp drops to a certain %
+-- 	friendhpinrate		when the mob's friend's hp is in a certain % range (range
+--                    defined the same way as in myhpinrate)
+-- 	friendstatuson		If the friend has any abnormalities in status (condition value)
+-- 	friendstatusoff		If the friend has ended any abnormalities in status (condition value)
+-- 	attackpcgt		Attack PC becomes more than the  number of specification
+-- 	attackpcge		Attack PC becomes equal or more than the number of specification.
+-- 	slavelt			when the number of slaves is lower than the original number of specification.
+-- 	slavele			when the number of slaves is lower or equal than the original number of specification.
+-- 	closedattacked		when melee attacked (close range attack)
+-- 	longrangeattacked	when long ranged attacked (like bows and far range weapons)
+-- 	skillused		when a skill is used on the mob
+-- 	afterskill		after the mob used certain skill.
+-- 	casttargeted		when a target is in cast range.
+-- 	rudeattacked		when a target is rude attacked
+-- 
+--  The character's state which can be specified to be a condition value by the statuson/statusoff system
+-- 	anybad		any type of state change
+-- 	stone		condition of being in stone state
+-- 	freeze		condition of being in frozen state
+-- 	stun		condition of being in stunned state
+-- 	sleep		condition of being in sleep state
+-- 	poison		condition of being in poisoned state
+-- 	curse		condition of being in cursed state
+-- 	silence		condition of being in silenced state
+-- 	confusion	condition of being in confusion state
+-- 	blind		condition of being in blind state
+-- 	hiding		condition of being in hidden state
+--	sight		condition of being in unhidden state
 
 REPLACE INTO `mob_skill_db` VALUES (1001,'Scorpion@NPC_FIREATTACK','attack',186,1,2000,0,5000,'yes','target','always',0,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
 REPLACE INTO `mob_skill_db` VALUES (1001,'Scorpion@NPC_POISON','attack',176,3,500,800,5000,'no','target','always',0,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
-- 
cgit v1.2.3-70-g09d2


From f62ce0c0bae2c1b674aca5c1d7918ec97d9a7a74 Mon Sep 17 00:00:00 2001
From: Haru <haru@dotalux.com>
Date: Thu, 17 Jul 2014 21:32:55 +0200
Subject: Fixed minor issues in the sql files from 3ecf877b

Signed-off-by: Haru <haru@dotalux.com>
---
 sql-files/logs.sql | 36 ++++++++++++++++++------------------
 sql-files/main.sql | 22 +++++++++++-----------
 2 files changed, 29 insertions(+), 29 deletions(-)

(limited to 'sql-files/main.sql')

diff --git a/sql-files/logs.sql b/sql-files/logs.sql
index 3d5f56710..fe875ec62 100644
--- a/sql-files/logs.sql
+++ b/sql-files/logs.sql
@@ -1,22 +1,22 @@
 -- PickLog Types
---	(M)onsters Drop
---	(P)layers Drop/Take
---	Mobs Drop (L)oot Drop/Take
---	Players (T)rade Give/Take
---	Players (V)ending Sell/Take
---	(S)hop Sell/Take
---	(N)PC Give/Take
---	(C)onsumable Items
---	(A)dministrators Create/Delete
---	Sto(R)age
---	(G)uild Storage
---	(E)mail attachment
---	(B)uying Store
---	Pr(O)duced Items/Ingredients
---	Auct(I)oned Items
---	(X) Other
---	(D) Stolen from mobs
---	(U) MVP Prizes
+-- (M)onsters Drop
+-- (P)layers Drop/Take
+-- Mobs Drop (L)oot Drop/Take
+-- Players (T)rade Give/Take
+-- Players (V)ending Sell/Take
+-- (S)hop Sell/Take
+-- (N)PC Give/Take
+-- (C)onsumable Items
+-- (A)dministrators Create/Delete
+-- Sto(R)age
+-- (G)uild Storage
+-- (E)mail attachment
+-- (B)uying Store
+-- Pr(O)duced Items/Ingredients
+-- Auct(I)oned Items
+-- (X) Other
+-- (D) Stolen from mobs
+-- (U) MVP Prizes
 
 --
 -- Table structure for table `atcommandlog`
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 22cba1660..68b7fb52a 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -271,12 +271,12 @@ CREATE TABLE IF NOT EXISTS `friends` (
 --
 
 CREATE TABLE IF NOT EXISTS `hotkey` (
-	`char_id` INT(11) NOT NULL,
-	`hotkey` TINYINT(2) UNSIGNED NOT NULL,
-	`type` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
-	`itemskill_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
-	`skill_lvl` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
-	PRIMARY KEY (`char_id`,`hotkey`)
+  `char_id` INT(11) NOT NULL,
+  `hotkey` TINYINT(2) UNSIGNED NOT NULL,
+  `type` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+  `itemskill_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+  `skill_lvl` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
+  PRIMARY KEY (`char_id`,`hotkey`)
 ) ENGINE=MyISAM;
 
 --
@@ -485,16 +485,16 @@ CREATE TABLE IF NOT EXISTS `homunculus` (
 ) ENGINE=MyISAM;
 
 -- 
--- Table structure for table `INTerlog`
+-- Table structure for table `interlog`
 --
 
-CREATE TABLE IF NOT EXISTS `INTerlog` (
+CREATE TABLE IF NOT EXISTS `interlog` (
   `time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
   `log` VARCHAR(255) NOT NULL DEFAULT ''
 ) ENGINE=MyISAM; 
 
 --
--- Table structure for table `INTerreg`
+-- Table structure for table `interreg`
 --
 
 CREATE TABLE IF NOT EXISTS `interreg` (
@@ -566,7 +566,7 @@ CREATE TABLE IF NOT EXISTS `login` (
 ) ENGINE=MyISAM AUTO_INCREMENT=2000000; 
 
 -- added standard accounts for servers, VERY INSECURE!!!
--- inserted INTo the table called login which is above
+-- inserted into the table called login which is above
 
 INSERT INTO `login` (`account_id`, `userid`, `user_pass`, `sex`, `email`) VALUES ('1', 's1', 'p1', 'S','athena@athena.com');
 
@@ -710,7 +710,7 @@ CREATE TABLE IF NOT EXISTS `pet` (
   `level` SMALLINT(4) UNSIGNED NOT NULL DEFAULT '0',
   `egg_id` SMALLINT(11) UNSIGNED NOT NULL DEFAULT '0',
   `equip` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
-  `INTimate` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
+  `intimate` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
   `hungry` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
   `rename_flag` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
   `incubate` INT(11) UNSIGNED NOT NULL DEFAULT '0',
-- 
cgit v1.2.3-70-g09d2

