aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchesD <majklprofik@seznam.cz>2015-10-16 22:54:46 +0200
committerMitchesD <majklprofik@seznam.cz>2015-10-16 23:09:42 +0200
commit9fe29de260b704603f40a8912c66dccf76fd0db8 (patch)
tree9043feef93fbf09a17bc83f3db687494a6da737d
parent43f4e32cabc2d9329affda2cdabe0fc735cd849b (diff)
Core/Player: implemented Heirloom Collection
* implemented all things related to that collection * you can create heirloom by click on item in collection * also you can upgrade heirlooms by using specific kits * old heirlooms are converted to new ones
-rw-r--r--sql/base/auth_database.sql26
-rw-r--r--sql/base/characters_database.sql2
-rw-r--r--sql/updates/auth/2015_10_16_00_auth.sql8
-rw-r--r--sql/updates/characters/2015_10_16_00_characters.sql70
-rw-r--r--sql/updates/hotfixes/2015_10_16_00_hotfixes.sql32
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.cpp5
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.h3
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.cpp3
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.h3
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp14
-rw-r--r--src/server/game/DataStores/DB2Stores.h4
-rw-r--r--src/server/game/DataStores/DB2Structure.h13
-rw-r--r--src/server/game/DataStores/DB2fmt.h1
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.cpp185
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.h36
-rw-r--r--src/server/game/Entities/Player/Player.cpp54
-rw-r--r--src/server/game/Entities/Player/Player.h1
-rw-r--r--src/server/game/Server/Packets/MiscPackets.cpp20
-rw-r--r--src/server/game/Server/Packets/MiscPackets.h13
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.cpp6
-rw-r--r--src/server/game/Spells/Spell.h4
-rw-r--r--src/server/game/Spells/SpellEffects.cpp38
23 files changed, 533 insertions, 10 deletions
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 37868b368cc..02f04b1ea3d 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -250,6 +250,30 @@ LOCK TABLES `battlenet_account_bans` WRITE;
UNLOCK TABLES;
--
+-- Table structure for table `battlenet_account_heirlooms`
+--
+
+DROP TABLE IF EXISTS `battlenet_account_heirlooms`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `battlenet_account_heirlooms` (
+ `accountId` int(10) unsigned NOT NULL,
+ `itemId` int(11) unsigned NOT NULL DEFAULT '0',
+ `flags` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`accountId`,`itemId`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `battlenet_account_heirlooms`
+--
+
+LOCK TABLES `battlenet_account_heirlooms` WRITE;
+/*!40000 ALTER TABLE `battlenet_account_heirlooms` DISABLE KEYS */;
+/*!40000 ALTER TABLE `battlenet_account_heirlooms` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
-- Table structure for table `battlenet_account_toys`
--
@@ -688,7 +712,7 @@ CREATE TABLE `updates` (
LOCK TABLES `updates` WRITE;
/*!40000 ALTER TABLE `updates` DISABLE KEYS */;
-INSERT INTO `updates` VALUES ('2014_10_04_00_auth.sql','C3BC70A6EC381474B7308F442346F1E721176BC6','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_19_00_auth.sql','7472B490A4F86C9D3DA609CDD3197499CB80C87C','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_26_00_auth.sql','75CC67ADE2A3B2E54FD57D6B0DCAA8FE50F4EE35','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_03_00_auth.sql','5948C9F286CF0FEA8E241785C0259FF36B73BDC5','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_04_00_auth.sql','3AFC68B2375C2A417DDEA94583C53AFF83DE50DF','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_09_00_auth.sql','B8DD1A7047C0FDDB80344B239343EC33BF1A0D97','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth.sql','8FBA737A1D3FF4631A1E662A5B500A8BD304EC63','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth_from_335.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_23_00_auth.sql','0BBEB3EB3AED0FEF277A062819B6B2C00084A742','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_25_00_auth.sql','4F45CDB26BDBB3EE83F1988E3D7818C5926ADC02','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_05_00_auth.sql','6A7BBCEF43111C73A2D2C3CCB6911BE50DE7DD94','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_19_00_auth.sql','44D8E12FFF327AD07878FBDF8D9C16B6B7DCB122','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_20_00_auth.sql','4DAA02AE285C02AE6C82EA2C8B97AC71990F1085','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_25_00_auth.sql','61411930F482BC73FC7FD2C370C811E944F5FF92','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_27_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_28_00_auth.sql','0A913217610E76AFF119C27259737BBC523090E6','ARCHIVED','2015-03-21 16:55:52',0),('2015_02_22_00_auth.sql','21CCCF8B01252E16CA3D6C9E3E8DAA4C9B28ED6E','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_01_00_auth.sql','911881E273207FF6182D1FDAC8C85FFAE8F1C852','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_10_00_auth.sql','2CC8502C11412EFEB5C11BE166761A8754A59009','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_00_auth.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_01_auth.sql','5CCEDF20C8189FB1E8DF064A9F0DDC342841FBF0','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_02_auth.sql','85E4ACD9AA099C0C4AC034575F2BB07D348EAC72','ARCHIVED','2015-03-21 16:56:46',0),('2015_03_15_00_auth.sql','1D8E107FBEFE5E7F47E09F45240DFF499B77CDED','ARCHIVED','2015-05-02 13:57:57',0),('2015_03_26_00_auth.sql','34AC8543E6A9C6C832DE58EAB33618EEEF70B9F9','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_04_00_auth.sql','57146B35E54A2EC7869C945034AB078358020311','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_06_00_auth.sql','2A8049DC2923420A002D42FB6F02C2FFCC5CDD22','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_08_00_auth.sql','4D7D8EEF285C982BB676836602266501BEC26764','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_10_00_auth.sql','4AE68FD97A95CEE5143EA20FD33F5D557367AC1F','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_00_auth.sql','80A71C8921CFEBB547D264558B6DE27201685B84','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_01_auth.sql','3E88183E1A85D11BFD74CF9A32A725C44AE02EEC','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_21_00_auth.sql','1B3B48DBA06368B985C548D166C515C9DD598CB9','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_00_auth.sql','96AB595E0D2A088750E3F48B0AF0A8A14F3CFE1E','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_01_auth.sql','FB11FB834E488B0FD3AFDABCC1A3113092E7C2E5','ARCHIVED','2015-05-02 13:57:57',0),('2015_07_02_00_auth.sql','E5EE3842AB9B01851E49B360FBAF6FFEEAB2A8DA','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_06_00_auth.sql','6D1ADBA496DC6E6D7B3BF887DA8D4D17D3FBACE0','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_00_auth.sql','CB54020AFD1E31742FD8BF9CE16879625E289788','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_01_auth.sql','74D281CB82E0DA36D628BDC7AC797AE5498DB461','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_16_00_auth.sql','A057E95B5553B6A57A1642FE3FEC8E2E62EDE3C6','RELEASED','2015-10-10 08:30:48',0),('2015_07_29_00_auth.sql','0000FECBC413E96C7C45F303D162E263EFBA7116','RELEASED','2015-10-10 08:30:48',0),('2015_08_26_00_auth.sql','3071C02A2EB7DCBF4CEE10279FEFAB7C29A43A3A','RELEASED','2015-10-10 08:30:48',0),('2015_09_05_00_auth.sql','F765D82B37873FA67447347D5B83C99C159FB452','RELEASED','2015-10-10 08:30:48',0),('2015_09_05_01_auth.sql','97A72DBCBF14D27A1863834A22296905FF276086','RELEASED','2015-10-10 08:30:48',0),('2015_09_09_00_auth.sql','495A0CF1B1C49205D4A5D3C25A4E1EB95616D6B4','RELEASED','2015-10-10 08:30:48',0),('2015_09_15_00_auth.sql','D1FEFDA4C98F30384DF4B64D5A53187303EB5786','RELEASED','2015-10-10 08:30:48',0),('2015_10_09_00_auth.sql','B6D643D444C6AE711503F73B96B6252A852913D6','RELEASED','2015-10-10 08:30:48',0);
+INSERT INTO `updates` VALUES ('2014_10_04_00_auth.sql','C3BC70A6EC381474B7308F442346F1E721176BC6','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_19_00_auth.sql','7472B490A4F86C9D3DA609CDD3197499CB80C87C','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_26_00_auth.sql','75CC67ADE2A3B2E54FD57D6B0DCAA8FE50F4EE35','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_03_00_auth.sql','5948C9F286CF0FEA8E241785C0259FF36B73BDC5','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_04_00_auth.sql','3AFC68B2375C2A417DDEA94583C53AFF83DE50DF','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_09_00_auth.sql','B8DD1A7047C0FDDB80344B239343EC33BF1A0D97','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth.sql','8FBA737A1D3FF4631A1E662A5B500A8BD304EC63','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth_from_335.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_23_00_auth.sql','0BBEB3EB3AED0FEF277A062819B6B2C00084A742','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_25_00_auth.sql','4F45CDB26BDBB3EE83F1988E3D7818C5926ADC02','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_05_00_auth.sql','6A7BBCEF43111C73A2D2C3CCB6911BE50DE7DD94','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_19_00_auth.sql','44D8E12FFF327AD07878FBDF8D9C16B6B7DCB122','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_20_00_auth.sql','4DAA02AE285C02AE6C82EA2C8B97AC71990F1085','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_25_00_auth.sql','61411930F482BC73FC7FD2C370C811E944F5FF92','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_27_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_28_00_auth.sql','0A913217610E76AFF119C27259737BBC523090E6','ARCHIVED','2015-03-21 16:55:52',0),('2015_02_22_00_auth.sql','21CCCF8B01252E16CA3D6C9E3E8DAA4C9B28ED6E','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_01_00_auth.sql','911881E273207FF6182D1FDAC8C85FFAE8F1C852','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_10_00_auth.sql','2CC8502C11412EFEB5C11BE166761A8754A59009','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_00_auth.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_01_auth.sql','5CCEDF20C8189FB1E8DF064A9F0DDC342841FBF0','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_02_auth.sql','85E4ACD9AA099C0C4AC034575F2BB07D348EAC72','ARCHIVED','2015-03-21 16:56:46',0),('2015_03_15_00_auth.sql','1D8E107FBEFE5E7F47E09F45240DFF499B77CDED','ARCHIVED','2015-05-02 13:57:57',0),('2015_03_26_00_auth.sql','34AC8543E6A9C6C832DE58EAB33618EEEF70B9F9','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_04_00_auth.sql','57146B35E54A2EC7869C945034AB078358020311','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_06_00_auth.sql','2A8049DC2923420A002D42FB6F02C2FFCC5CDD22','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_08_00_auth.sql','4D7D8EEF285C982BB676836602266501BEC26764','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_10_00_auth.sql','4AE68FD97A95CEE5143EA20FD33F5D557367AC1F','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_00_auth.sql','80A71C8921CFEBB547D264558B6DE27201685B84','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_01_auth.sql','3E88183E1A85D11BFD74CF9A32A725C44AE02EEC','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_21_00_auth.sql','1B3B48DBA06368B985C548D166C515C9DD598CB9','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_00_auth.sql','96AB595E0D2A088750E3F48B0AF0A8A14F3CFE1E','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_01_auth.sql','FB11FB834E488B0FD3AFDABCC1A3113092E7C2E5','ARCHIVED','2015-05-02 13:57:57',0),('2015_07_02_00_auth.sql','E5EE3842AB9B01851E49B360FBAF6FFEEAB2A8DA','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_06_00_auth.sql','6D1ADBA496DC6E6D7B3BF887DA8D4D17D3FBACE0','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_00_auth.sql','CB54020AFD1E31742FD8BF9CE16879625E289788','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_01_auth.sql','74D281CB82E0DA36D628BDC7AC797AE5498DB461','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_16_00_auth.sql','A057E95B5553B6A57A1642FE3FEC8E2E62EDE3C6','RELEASED','2015-10-10 08:30:48',0),('2015_07_29_00_auth.sql','0000FECBC413E96C7C45F303D162E263EFBA7116','RELEASED','2015-10-10 08:30:48',0),('2015_08_26_00_auth.sql','3071C02A2EB7DCBF4CEE10279FEFAB7C29A43A3A','RELEASED','2015-10-10 08:30:48',0),('2015_09_05_00_auth.sql','F765D82B37873FA67447347D5B83C99C159FB452','RELEASED','2015-10-10 08:30:48',0),('2015_09_05_01_auth.sql','97A72DBCBF14D27A1863834A22296905FF276086','RELEASED','2015-10-10 08:30:48',0),('2015_09_09_00_auth.sql','495A0CF1B1C49205D4A5D3C25A4E1EB95616D6B4','RELEASED','2015-10-10 08:30:48',0),('2015_09_15_00_auth.sql','D1FEFDA4C98F30384DF4B64D5A53187303EB5786','RELEASED','2015-10-10 08:30:48',0),('2015_10_09_00_auth.sql','B6D643D444C6AE711503F73B96B6252A852913D6','RELEASED','2015-10-10 08:30:48',0),('2015_10_16_00_auth.sql','E4825FDAE15A219CD65D4A557ECF681F183A2387','RELEASED','2015-10-15 21:54:10',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql
index 1693a9a5397..1b28b1cb51a 100644
--- a/sql/base/characters_database.sql
+++ b/sql/base/characters_database.sql
@@ -3075,7 +3075,7 @@ CREATE TABLE `updates` (
LOCK TABLES `updates` WRITE;
/*!40000 ALTER TABLE `updates` DISABLE KEYS */;
-INSERT INTO `updates` VALUES ('2014_10_20_00_characters.sql','A5882DA0979CF4DAE33DA011EBAA006C24BE7230','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_00_characters.sql','E2AC4758133EE19B7F08464A445802154D1261C8','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_01_characters.sql','20029E6323D9773B32C34D84FFED1711CC60F09F','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_02_characters.sql','8A7A16886EE71E7ACDDB3DDA6D0ECAC2FD2FDCA8','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_24_00_characters.sql','D008FE81AE844FCA686439D6ECC5108FB0DD1EB9','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_25_00_characters.sql','A39C7BE46686B54776BDAB9D7A882D91EDEC51A4','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_26_00_characters.sql','C787954CC35FE34B4101FDE6527F14C027F4947C','ARCHIVED','2015-03-21 15:55:55',0),('2014_11_12_00_characters.sql','B160BB2313F1BD5F3B076A5A9279DC10D4796E34','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_23_00_characters.sql','3D9D648B2387B357F4BD090B33F80682F7924882','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_28_00_characters.sql','5362922FF4483A336311D73082A5727309CD9219','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_31_00_characters.sql','498DDF2DD936CF156D74A8208DC93DCE9FCAB5AA','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_02_00_characters.sql','E5940BE836F253982E07930120422E598D08BDE1','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_10_00_characters.sql','30796056C8623699B2FE1BF626A19D38262E9284','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_16_00_characters.sql','96642760A54C8D799AAFE438049A63AA521656F2','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_27_00_characters.sql','EB710E3EB9F2CAFD84AB62CDC84E898403A80A4F','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_13_00_characters.sql','405BEB4ED207DC6076442A37EE2AFB1F21E274A0','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_13_01_characters.sql','35F582D4F33BF55D1685A1BA89273ED895FD09C5','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_17_00_characters.sql','8D21FC5A55BF8B55D6DCDCE5F02CF2B640230E94','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_10_00_characters.sql','E565B89B145C340067742DFF2DEF1B74F5F1BD4E','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_00_characters.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_01_characters.sql','20BD68468C57FCF7E665B4DA185DCD52FACE8B3F','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_02_characters.sql','0296995DCD3676BA9AE6024CA7C91C5F39D927A3','ARCHIVED','2015-03-21 15:56:46',0),('2015_03_29_00_characters.sql','95D6A46BB746A8BD3EE3FE2086DF1A07F7C33B92','ARCHIVED','2015-05-02 15:43:06',0),('2015_04_21_00_characters.sql','F2032B9BF4EDA7EDE5065554724ED392FD91657D','ARCHIVED','2015-05-02 15:43:06',0),('2015_04_28_00_characters.sql','949F62DB3A3461D420A1230ECF7A6A3ED6435703','ARCHIVED','2015-05-02 15:43:06',0),('2015_05_08_00_characters.sql','0F14B7821618D1C872625B6EDDAA9A667B211167','ARCHIVED','2015-07-10 19:32:17',0),('2015_05_22_00_characters.sql','65B82152413FAB23BE413656E59A486A74447FF7','ARCHIVED','2015-07-10 19:32:17',0),('2015_07_08_00_characters.sql','DAB25360ACB5244C8F8E6214CF6BD97160588A5B','ARCHIVED','2015-07-10 19:32:17',0),('2015_07_11_00_characters.sql','B421B6C0E57BD0FD587071358863D9DABF4BA849','ARCHIVED','2015-07-13 21:50:02',0),('2015_07_12_00_characters.sql','E98E7FD61EF6426E7EDE8ED9AD8C15D8D7132589','ARCHIVED','2015-07-13 21:50:02',0),('2015_07_28_00_characters.sql','0711BC3A658D189EF71B0CB68DCFF2E9B781C4A0','RELEASED','2015-07-29 16:23:56',0),('2015_08_08_00_characters.sql','EA12BB2DC24FAF2300A96D0888A45BBEA158D5DC','RELEASED','2015-08-08 16:34:07',0),('2015_08_12_00_characters.sql','4FD7F89FE5DA51D4E0C33E520719986AA3EBD31B','RELEASED','2015-08-12 12:35:20',0),('2015_09_05_00_characters.sql','4C22BB29365BE4B6B95E64DAD84B63CA002304EA','RELEASED','2015-09-05 12:35:20',0),('2015_09_09_00_characters.sql','AFC32E693BC17CFD9A17919FE5317B8FE337ACAD','RELEASED','2015-09-09 12:35:20',0),('2015_09_10_00_characters.sql','4555A7F35C107E54C13D74D20F141039ED42943E','RELEASED','2015-09-10 22:50:42',0);
+INSERT INTO `updates` VALUES ('2014_10_20_00_characters.sql','A5882DA0979CF4DAE33DA011EBAA006C24BE7230','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_00_characters.sql','E2AC4758133EE19B7F08464A445802154D1261C8','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_01_characters.sql','20029E6323D9773B32C34D84FFED1711CC60F09F','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_02_characters.sql','8A7A16886EE71E7ACDDB3DDA6D0ECAC2FD2FDCA8','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_24_00_characters.sql','D008FE81AE844FCA686439D6ECC5108FB0DD1EB9','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_25_00_characters.sql','A39C7BE46686B54776BDAB9D7A882D91EDEC51A4','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_26_00_characters.sql','C787954CC35FE34B4101FDE6527F14C027F4947C','ARCHIVED','2015-03-21 15:55:55',0),('2014_11_12_00_characters.sql','B160BB2313F1BD5F3B076A5A9279DC10D4796E34','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_23_00_characters.sql','3D9D648B2387B357F4BD090B33F80682F7924882','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_28_00_characters.sql','5362922FF4483A336311D73082A5727309CD9219','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_31_00_characters.sql','498DDF2DD936CF156D74A8208DC93DCE9FCAB5AA','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_02_00_characters.sql','E5940BE836F253982E07930120422E598D08BDE1','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_10_00_characters.sql','30796056C8623699B2FE1BF626A19D38262E9284','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_16_00_characters.sql','96642760A54C8D799AAFE438049A63AA521656F2','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_27_00_characters.sql','EB710E3EB9F2CAFD84AB62CDC84E898403A80A4F','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_13_00_characters.sql','405BEB4ED207DC6076442A37EE2AFB1F21E274A0','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_13_01_characters.sql','35F582D4F33BF55D1685A1BA89273ED895FD09C5','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_17_00_characters.sql','8D21FC5A55BF8B55D6DCDCE5F02CF2B640230E94','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_10_00_characters.sql','E565B89B145C340067742DFF2DEF1B74F5F1BD4E','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_00_characters.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_01_characters.sql','20BD68468C57FCF7E665B4DA185DCD52FACE8B3F','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_02_characters.sql','0296995DCD3676BA9AE6024CA7C91C5F39D927A3','ARCHIVED','2015-03-21 15:56:46',0),('2015_03_29_00_characters.sql','95D6A46BB746A8BD3EE3FE2086DF1A07F7C33B92','ARCHIVED','2015-05-02 15:43:06',0),('2015_04_21_00_characters.sql','F2032B9BF4EDA7EDE5065554724ED392FD91657D','ARCHIVED','2015-05-02 15:43:06',0),('2015_04_28_00_characters.sql','949F62DB3A3461D420A1230ECF7A6A3ED6435703','ARCHIVED','2015-05-02 15:43:06',0),('2015_05_08_00_characters.sql','0F14B7821618D1C872625B6EDDAA9A667B211167','ARCHIVED','2015-07-10 19:32:17',0),('2015_05_22_00_characters.sql','65B82152413FAB23BE413656E59A486A74447FF7','ARCHIVED','2015-07-10 19:32:17',0),('2015_07_08_00_characters.sql','DAB25360ACB5244C8F8E6214CF6BD97160588A5B','ARCHIVED','2015-07-10 19:32:17',0),('2015_07_11_00_characters.sql','B421B6C0E57BD0FD587071358863D9DABF4BA849','ARCHIVED','2015-07-13 21:50:02',0),('2015_07_12_00_characters.sql','E98E7FD61EF6426E7EDE8ED9AD8C15D8D7132589','ARCHIVED','2015-07-13 21:50:02',0),('2015_07_28_00_characters.sql','0711BC3A658D189EF71B0CB68DCFF2E9B781C4A0','RELEASED','2015-07-29 16:23:56',0),('2015_08_08_00_characters.sql','EA12BB2DC24FAF2300A96D0888A45BBEA158D5DC','RELEASED','2015-08-08 16:34:07',0),('2015_08_12_00_characters.sql','4FD7F89FE5DA51D4E0C33E520719986AA3EBD31B','RELEASED','2015-08-12 12:35:20',0),('2015_09_05_00_characters.sql','4C22BB29365BE4B6B95E64DAD84B63CA002304EA','RELEASED','2015-09-05 12:35:20',0),('2015_09_09_00_characters.sql','AFC32E693BC17CFD9A17919FE5317B8FE337ACAD','RELEASED','2015-09-09 12:35:20',0),('2015_09_10_00_characters.sql','4555A7F35C107E54C13D74D20F141039ED42943E','RELEASED','2015-09-10 22:50:42',0),('2015_10_16_00_characters.sql','E3A3FFF0CB42F04A8DCF0CE4362143C16E2083AF','RELEASED','2015-10-15 21:54:11',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/auth/2015_10_16_00_auth.sql b/sql/updates/auth/2015_10_16_00_auth.sql
new file mode 100644
index 00000000000..1efefca6c9a
--- /dev/null
+++ b/sql/updates/auth/2015_10_16_00_auth.sql
@@ -0,0 +1,8 @@
+DROP TABLE IF EXISTS `battlenet_account_heirlooms`;
+
+CREATE TABLE `battlenet_account_heirlooms` (
+ `accountId` int(10) unsigned NOT NULL,
+ `itemId` int(11) unsigned NOT NULL DEFAULT '0',
+ `flags` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`accountId`,`itemId`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/sql/updates/characters/2015_10_16_00_characters.sql b/sql/updates/characters/2015_10_16_00_characters.sql
new file mode 100644
index 00000000000..549797fee96
--- /dev/null
+++ b/sql/updates/characters/2015_10_16_00_characters.sql
@@ -0,0 +1,70 @@
+--
+UPDATE `item_instance` SET `itemEntry`=122353 WHERE `itemEntry` IN(42947, 93854);
+UPDATE `item_instance` SET `itemEntry`=122365 WHERE `itemEntry` IN(44092, 93851);
+UPDATE `item_instance` SET `itemEntry`=122363 WHERE `itemEntry` IN(79131, 93844);
+UPDATE `item_instance` SET `itemEntry`=122352 WHERE `itemEntry` IN(42946, 93855);
+UPDATE `item_instance` SET `itemEntry`=122356 WHERE `itemEntry` IN(42950, 93887);
+UPDATE `item_instance` SET `itemEntry`=122349 WHERE `itemEntry` IN(42943, 93843);
+UPDATE `item_instance` SET `itemEntry`=122351 WHERE `itemEntry` IN(42945, 93856);
+UPDATE `item_instance` SET `itemEntry`=122376 WHERE `itemEntry` IN(44103, 93867);
+UPDATE `item_instance` SET `itemEntry`=122355 WHERE `itemEntry` IN(42949, 93890);
+UPDATE `item_instance` SET `itemEntry`=122358 WHERE `itemEntry` IN(42952, 93862);
+UPDATE `item_instance` SET `itemEntry`=122350 WHERE `itemEntry` IN(42944, 93857);
+UPDATE `item_instance` SET `itemEntry`=122359 WHERE `itemEntry` IN(42984, 93864);
+UPDATE `item_instance` SET `itemEntry`=122362 WHERE `itemEntry` IN(42992, 93897);
+UPDATE `item_instance` SET `itemEntry`=122357 WHERE `itemEntry` IN(42951, 93876);
+UPDATE `item_instance` SET `itemEntry`=122360 WHERE `itemEntry` IN(42985, 93859);
+UPDATE `item_instance` SET `itemEntry`=122377 WHERE `itemEntry` IN(44105, 93866);
+UPDATE `item_instance` SET `itemEntry`=122354 WHERE `itemEntry` IN(42948, 93853);
+UPDATE `item_instance` SET `itemEntry`=122364 WHERE `itemEntry` IN(44091, 93852);
+UPDATE `item_instance` SET `itemEntry`=122366 WHERE `itemEntry` IN(44093, 93841);
+UPDATE `item_instance` SET `itemEntry`=122367 WHERE `itemEntry` IN(44094, 93850);
+UPDATE `item_instance` SET `itemEntry`=122370 WHERE `itemEntry` IN(44097, 93898);
+UPDATE `item_instance` SET `itemEntry`=122368 WHERE `itemEntry` IN(44095, 93849);
+UPDATE `item_instance` SET `itemEntry`=122369 WHERE `itemEntry` IN(44096, 93848);
+UPDATE `item_instance` SET `itemEntry`=122361 WHERE `itemEntry` IN(42991, 93896);
+UPDATE `item_instance` SET `itemEntry`=122378 WHERE `itemEntry` IN(44107, 93861);
+UPDATE `item_instance` SET `itemEntry`=122372 WHERE `itemEntry` IN(44099, 93895);
+UPDATE `item_instance` SET `itemEntry`=122373 WHERE `itemEntry` IN(44100, 93894);
+UPDATE `item_instance` SET `itemEntry`=122374 WHERE `itemEntry` IN(44101, 93886);
+UPDATE `item_instance` SET `itemEntry`=122375 WHERE `itemEntry` IN(44102, 93889);
+UPDATE `item_instance` SET `itemEntry`=122371 WHERE `itemEntry` IN(44098, 93899);
+UPDATE `item_instance` SET `itemEntry`=122529 WHERE `itemEntry` IN(50255);
+UPDATE `item_instance` SET `itemEntry`=122384 WHERE `itemEntry` IN(48691, 93860);
+UPDATE `item_instance` SET `itemEntry`=122382 WHERE `itemEntry` IN(48687, 93865);
+UPDATE `item_instance` SET `itemEntry`=122383 WHERE `itemEntry` IN(48689, 93863);
+UPDATE `item_instance` SET `itemEntry`=122380 WHERE `itemEntry` IN(48683, 93885);
+UPDATE `item_instance` SET `itemEntry`=122381 WHERE `itemEntry` IN(48685, 93891);
+UPDATE `item_instance` SET `itemEntry`=122386 WHERE `itemEntry` IN(48718, 93846);
+UPDATE `item_instance` SET `itemEntry`=122385 WHERE `itemEntry` IN(48716, 93847);
+UPDATE `item_instance` SET `itemEntry`=122379 WHERE `itemEntry` IN(48677, 93888);
+UPDATE `item_instance` SET `itemEntry`=122261 WHERE `itemEntry` IN(62039);
+UPDATE `item_instance` SET `itemEntry`=122262 WHERE `itemEntry` IN(62040);
+UPDATE `item_instance` SET `itemEntry`=122260 WHERE `itemEntry` IN(62038);
+UPDATE `item_instance` SET `itemEntry`=122255 WHERE `itemEntry` IN(62027);
+UPDATE `item_instance` SET `itemEntry`=122251 WHERE `itemEntry` IN(62023);
+UPDATE `item_instance` SET `itemEntry`=122252 WHERE `itemEntry` IN(62024);
+UPDATE `item_instance` SET `itemEntry`=122253 WHERE `itemEntry` IN(62025);
+UPDATE `item_instance` SET `itemEntry`=122254 WHERE `itemEntry` IN(62026);
+UPDATE `item_instance` SET `itemEntry`=122245 WHERE `itemEntry` IN(61931);
+UPDATE `item_instance` SET `itemEntry`=122256 WHERE `itemEntry` IN(62029);
+UPDATE `item_instance` SET `itemEntry`=122249 WHERE `itemEntry` IN(61942);
+UPDATE `item_instance` SET `itemEntry`=122250 WHERE `itemEntry` IN(61958);
+UPDATE `item_instance` SET `itemEntry`=122248 WHERE `itemEntry` IN(61937);
+UPDATE `item_instance` SET `itemEntry`=122246 WHERE `itemEntry` IN(61935);
+UPDATE `item_instance` SET `itemEntry`=122247 WHERE `itemEntry` IN(61936);
+UPDATE `item_instance` SET `itemEntry`=122263 WHERE `itemEntry` IN(69887);
+UPDATE `item_instance` SET `itemEntry`=122264 WHERE `itemEntry` IN(69888);
+UPDATE `item_instance` SET `itemEntry`=122387 WHERE `itemEntry` IN(69889, 93892);
+UPDATE `item_instance` SET `itemEntry`=122388 WHERE `itemEntry` IN(69890, 93893);
+UPDATE `item_instance` SET `itemEntry`=122389 WHERE `itemEntry` IN(69893, 93845);
+UPDATE `item_instance` SET `itemEntry`=122266 WHERE `itemEntry` IN(69892);
+UPDATE `item_instance` SET `itemEntry`=122392 WHERE `itemEntry` IN(93903);
+UPDATE `item_instance` SET `itemEntry`=122396 WHERE `itemEntry` IN(92948, 93858);
+UPDATE `item_instance` SET `itemEntry`=122390 WHERE `itemEntry` IN(93904);
+UPDATE `item_instance` SET `itemEntry`=122530 WHERE `itemEntry` IN(93900);
+UPDATE `item_instance` SET `itemEntry`=122391 WHERE `itemEntry` IN(93902);
+UPDATE `item_instance` SET `itemEntry`=128173 WHERE `itemEntry` IN(44102, 93889);
+UPDATE `item_instance` SET `itemEntry`=128169 WHERE `itemEntry` IN(44102, 93889);
+UPDATE `item_instance` SET `itemEntry`=128172 WHERE `itemEntry` IN(44102, 93889);
+UPDATE `item_instance` SET `itemEntry`=128318 WHERE `itemEntry` IN(42992);
diff --git a/sql/updates/hotfixes/2015_10_16_00_hotfixes.sql b/sql/updates/hotfixes/2015_10_16_00_hotfixes.sql
new file mode 100644
index 00000000000..de01e908d49
--- /dev/null
+++ b/sql/updates/hotfixes/2015_10_16_00_hotfixes.sql
@@ -0,0 +1,32 @@
+DROP TABLE IF EXISTS `heirloom`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `heirloom` (
+ `ID` int(10) unsigned NOT NULL DEFAULT '0',
+ `ItemID` int(10) unsigned NOT NULL DEFAULT '0',
+ `Flags` int(10) unsigned NOT NULL DEFAULT '0',
+ `SourceText` text,
+ `Source` int(10) unsigned NOT NULL DEFAULT '0',
+ `OldItem1` int(10) unsigned NOT NULL DEFAULT '0',
+ `OldItem2` int(10) unsigned NOT NULL DEFAULT '0',
+ `NextDifficultyItemID` int(10) unsigned NOT NULL DEFAULT '0',
+ `UpgradeItemID1` int(10) unsigned NOT NULL DEFAULT '0',
+ `UpgradeItemID2` int(10) unsigned NOT NULL DEFAULT '0',
+ `ItemBonusListID1` int(10) unsigned NOT NULL DEFAULT '0',
+ `ItemBonusListID2` int(10) unsigned NOT NULL DEFAULT '0',
+ `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+DROP TABLE IF EXISTS `heirloom_locale`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `heirloom_locale` (
+ `ID` int(10) unsigned NOT NULL DEFAULT '0',
+ `locale` varchar(4) NOT NULL,
+ `SourceText_lang` text,
+ `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`ID`,`locale`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp
index 104b5e2bbc7..b9127642234 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.cpp
+++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp
@@ -188,6 +188,11 @@ void HotfixDatabaseConnection::DoPrepareStatements()
// GuildPerkSpells.db2
PrepareStatement(HOTFIX_SEL_GUILD_PERK_SPELLS, "SELECT ID, GuildLevel, SpellID FROM guild_perk_spells ORDER BY ID DESC", CONNECTION_SYNCH);
+ // Heirloom.db2
+ PrepareStatement(HOTFIX_SEL_HEIRLOOM, "SELECT ID, ItemID, Flags, SourceText, Source, OldItem1, OldItem2, NextDifficultyItemID, UpgradeItemID1, UpgradeItemID2, "
+ "ItemBonusListID1, ItemBonusListID2 FROM heirloom ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_HEIRLOOM, "SELECT ID, SourceText_lang FROM heirloom_locale WHERE locale = ?", CONNECTION_SYNCH);
+
// Holidays.db2
PrepareStatement(HOTFIX_SEL_HOLIDAYS, "SELECT ID, Duration1, Duration2, Duration3, Duration4, Duration5, Duration6, Duration7, Duration8, "
"Duration9, Duration10, Date1, Date2, Date3, Date4, Date5, Date6, Date7, Date8, Date9, Date10, Date11, Date12, Date13, Date14, Date15, "
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h
index 196d7602da7..6a513633575 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.h
+++ b/src/server/database/Database/Implementation/HotfixDatabase.h
@@ -118,6 +118,9 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_GUILD_PERK_SPELLS,
+ HOTFIX_SEL_HEIRLOOM,
+ HOTFIX_SEL_HEIRLOOM_LOCALE,
+
HOTFIX_SEL_HOLIDAYS,
HOTFIX_SEL_HOLIDAYS_LOCALE,
diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp
index 9526e012fa2..7e199659177 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/database/Database/Implementation/LoginDatabase.cpp
@@ -153,4 +153,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_BATTLE_PET_SLOTS, "SELECT id, battlePetGuid, locked FROM battle_pet_slots WHERE battlenetAccountId = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_INS_BATTLE_PET_SLOTS, "INSERT INTO battle_pet_slots (id, battlenetAccountId, battlePetGuid, locked) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_DEL_BATTLE_PET_SLOTS, "DELETE FROM battle_pet_slots WHERE battlenetAccountId = ?", CONNECTION_ASYNC);
+
+ PrepareStatement(LOGIN_SEL_ACCOUNT_HEIRLOOMS, "SELECT itemId, flags FROM battlenet_account_heirlooms WHERE accountId = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_REP_ACCOUNT_HEIRLOOMS, "REPLACE INTO battlenet_account_heirlooms (accountId, itemId, flags) VALUES (?, ?, ?)", CONNECTION_ASYNC);
}
diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h
index 9ef214a3120..5225561a539 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.h
+++ b/src/server/database/Database/Implementation/LoginDatabase.h
@@ -141,6 +141,9 @@ enum LoginDatabaseStatements
LOGIN_INS_BATTLE_PET_SLOTS,
LOGIN_DEL_BATTLE_PET_SLOTS,
+ LOGIN_SEL_ACCOUNT_HEIRLOOMS,
+ LOGIN_REP_ACCOUNT_HEIRLOOMS,
+
MAX_LOGINDATABASE_STATEMENTS
};
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index 61b5da47b7f..ddb99876152 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -60,6 +60,7 @@ DB2Storage<GarrSiteLevelEntry> sGarrSiteLevelStore("GarrSiteLev
DB2Storage<GarrSiteLevelPlotInstEntry> sGarrSiteLevelPlotInstStore("GarrSiteLevelPlotInst.db2", GarrSiteLevelPlotInstFormat, HOTFIX_SEL_GARR_SITE_LEVEL_PLOT_INST);
DB2Storage<GlyphSlotEntry> sGlyphSlotStore("GlyphSlot.db2", GlyphSlotFormat, HOTFIX_SEL_GLYPH_SLOT);
DB2Storage<GuildPerkSpellsEntry> sGuildPerkSpellsStore("GuildPerkSpells.db2", GuildPerkSpellsFormat, HOTFIX_SEL_GUILD_PERK_SPELLS);
+DB2Storage<HeirloomEntry> sHeirloomStore("Heirloom.db2", HeirloomFormat, HOTFIX_SEL_HEIRLOOM);
DB2Storage<HolidaysEntry> sHolidaysStore("Holidays.db2", HolidaysEntryFormat, HOTFIX_SEL_HOLIDAYS);
DB2Storage<ImportPriceArmorEntry> sImportPriceArmorStore("ImportPriceArmor.db2", ImportPriceArmorFormat, HOTFIX_SEL_IMPORT_PRICE_ARMOR);
DB2Storage<ImportPriceQualityEntry> sImportPriceQualityStore("ImportPriceQuality.db2", ImportPriceQualityFormat, HOTFIX_SEL_IMPORT_PRICE_QUALITY);
@@ -233,6 +234,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
LOAD_DB2(sGarrSiteLevelStore);
LOAD_DB2(sGlyphSlotStore);
LOAD_DB2(sGuildPerkSpellsStore);
+ LOAD_DB2(sHeirloomStore);
LOAD_DB2(sHolidaysStore);
LOAD_DB2(sImportPriceArmorStore);
LOAD_DB2(sImportPriceQualityStore);
@@ -489,6 +491,9 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
for (ToyEntry const* toy : sToyStore)
_toys.push_back(toy->ItemID);
+ for (HeirloomEntry const* heirloom : sHeirloomStore)
+ _heirlooms[heirloom->ItemID] = heirloom;
+
// error checks
if (bad_db2_files.size() >= DB2FilesCount)
{
@@ -846,3 +851,12 @@ bool DB2Manager::GetToyItemIdMatch(uint32 toy) const
{
return std::find(_toys.begin(), _toys.end(), toy) != _toys.end();
}
+
+HeirloomEntry const* DB2Manager::GetHeirloomByItemId(uint32 itemId) const
+{
+ auto itr = _heirlooms.find(itemId);
+ if (itr != _heirlooms.end())
+ return itr->second;
+
+ return nullptr;
+}
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index 0769e6e9739..80a14bc2778 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -56,6 +56,7 @@ extern DB2Storage<GarrSiteLevelEntry> sGarrSiteLevelStore;
extern DB2Storage<GarrSiteLevelPlotInstEntry> sGarrSiteLevelPlotInstStore;
extern DB2Storage<GlyphSlotEntry> sGlyphSlotStore;
extern DB2Storage<GuildPerkSpellsEntry> sGuildPerkSpellsStore;
+extern DB2Storage<HeirloomEntry> sHeirloomStore;
extern DB2Storage<HolidaysEntry> sHolidaysStore;
extern DB2Storage<ImportPriceArmorEntry> sImportPriceArmorStore;
extern DB2Storage<ImportPriceQualityEntry> sImportPriceQualityStore;
@@ -158,6 +159,7 @@ public:
typedef std::unordered_map<uint32, std::vector<SpellPowerEntry const*>> SpellPowerContainer;
typedef std::unordered_map<uint32, std::unordered_map<uint32, std::vector<SpellPowerEntry const*>>> SpellPowerDifficultyContainer;
typedef std::vector<uint32> ToyItemIdsContainer;
+ typedef std::unordered_map<uint32, HeirloomEntry const*> HeirloomItemsContainer;
static DB2Manager& Instance()
{
@@ -193,6 +195,7 @@ public:
std::vector<SpecializationSpellsEntry const*> const* GetSpecializationSpells(uint32 specId) const;
std::vector<SpellPowerEntry const*> GetSpellPowers(uint32 spellId, Difficulty difficulty = DIFFICULTY_NONE, bool* hasDifficultyPowers = nullptr) const;
bool GetToyItemIdMatch(uint32 toy) const;
+ HeirloomEntry const* GetHeirloomByItemId(uint32 itemId) const;
private:
StorageMap _stores;
@@ -218,6 +221,7 @@ private:
SpellPowerContainer _spellPowers;
SpellPowerDifficultyContainer _spellPowerDifficulties;
ToyItemIdsContainer _toys;
+ HeirloomItemsContainer _heirlooms;
};
#define sDB2Manager DB2Manager::Instance()
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index 0544ce82cea..5dbe3c0aa04 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -588,6 +588,19 @@ struct GuildPerkSpellsEntry
uint32 SpellID; // 2
};
+struct HeirloomEntry
+{
+ uint32 ID; // 0
+ uint32 ItemID; // 1
+ uint32 Flags; // 2
+ LocalizedString* SourceText; // 3
+ uint32 Source; // 4
+ uint32 OldItem[2]; // 5-6
+ uint32 NextDifficultyItemID; // 7
+ uint32 UpgradeItemID[2]; // 8-9
+ uint32 ItemBonusListID[2]; // 10-11
+};
+
#define MAX_HOLIDAY_DURATIONS 10
#define MAX_HOLIDAY_DATES 16
#define MAX_HOLIDAY_FLAGS 10
diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h
index ab9e2e0ae4e..599ada6df8c 100644
--- a/src/server/game/DataStores/DB2fmt.h
+++ b/src/server/game/DataStores/DB2fmt.h
@@ -53,6 +53,7 @@ char const GarrPlotInstanceFormat[] = "nis";
char const GarrSiteLevelFormat[] = "niiiiffiiii";
char const GarrSiteLevelPlotInstFormat[] = "niiffi";
char const GlyphSlotFormat[] = "nii";
+char const HeirloomFormat[] = "niisiiiiiiii";
char const GuildPerkSpellsFormat[] = "nii";
char const HolidaysEntryFormat[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisiii";
char const ImportPriceArmorFormat[] = "nffff";
diff --git a/src/server/game/Entities/Player/CollectionMgr.cpp b/src/server/game/Entities/Player/CollectionMgr.cpp
index 34e19fabc1a..9929c6362ef 100644
--- a/src/server/game/Entities/Player/CollectionMgr.cpp
+++ b/src/server/game/Entities/Player/CollectionMgr.cpp
@@ -52,7 +52,7 @@ void CollectionMgr::LoadAccountToys(PreparedQueryResult result)
void CollectionMgr::SaveAccountToys(SQLTransaction& trans)
{
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt = nullptr;
for (ToyBoxContainer::const_iterator itr = _toys.begin(); itr != _toys.end(); ++itr)
{
stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_ACCOUNT_TOYS);
@@ -76,3 +76,186 @@ void CollectionMgr::ToySetFavorite(uint32 itemId, bool favorite)
itr->second = favorite;
}
+
+void CollectionMgr::LoadAccountHeirlooms(PreparedQueryResult result)
+{
+ if (!result)
+ return;
+
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 itemId = fields[0].GetUInt32();
+ uint32 flags = fields[1].GetUInt32();
+
+ HeirloomEntry const* heirloom = sDB2Manager.GetHeirloomByItemId(itemId);
+ if (!heirloom)
+ continue;
+
+ uint32 bonusId = 0;
+
+ if (flags & HEIRLOOM_FLAG_BONUS_LEVEL_90)
+ bonusId = heirloom->ItemBonusListID[0];
+ if (flags & HEIRLOOM_FLAG_BONUS_LEVEL_100)
+ bonusId = heirloom->ItemBonusListID[1];
+
+ _heirlooms[itemId] = HeirloomData(flags, bonusId);
+ } while (result->NextRow());
+}
+
+void CollectionMgr::SaveAccountHeirlooms(SQLTransaction& trans)
+{
+ PreparedStatement* stmt = nullptr;
+ for (auto const& heirloom : _heirlooms)
+ {
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_ACCOUNT_HEIRLOOMS);
+ stmt->setUInt32(0, _owner->GetBattlenetAccountId());
+ stmt->setUInt32(1, heirloom.first);
+ stmt->setUInt32(2, heirloom.second.flags);
+ trans->Append(stmt);
+ }
+}
+
+bool CollectionMgr::UpdateAccountHeirlooms(uint32 itemId, uint32 flags)
+{
+ return _heirlooms.insert(HeirloomContainer::value_type(itemId, HeirloomData(flags, 0))).second;
+}
+
+uint32 CollectionMgr::GetHeirloomBonus(uint32 itemId) const
+{
+ HeirloomContainer::const_iterator itr = _heirlooms.find(itemId);
+ if (itr != _heirlooms.end())
+ return itr->second.bonusId;
+
+ return 0;
+}
+
+void CollectionMgr::LoadHeirlooms()
+{
+ for (auto const& item : _heirlooms)
+ {
+ _owner->GetPlayer()->AddDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOMS, item.first);
+ _owner->GetPlayer()->AddDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOM_FLAGS, item.second.flags);
+ }
+}
+
+void CollectionMgr::AddHeirloom(uint32 itemId, uint32 flags)
+{
+ if (UpdateAccountHeirlooms(itemId, flags))
+ {
+ _owner->GetPlayer()->AddDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOMS, itemId);
+ _owner->GetPlayer()->AddDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOM_FLAGS, flags);
+ }
+}
+
+void CollectionMgr::UpgradeHeirloom(uint32 itemId, uint32 castItem)
+{
+ Player* player = _owner->GetPlayer();
+ if (!player)
+ return;
+
+ HeirloomEntry const* heirloom = sDB2Manager.GetHeirloomByItemId(itemId);
+ if (!heirloom)
+ return;
+
+ HeirloomContainer::iterator itr = _heirlooms.find(itemId);
+ if (itr == _heirlooms.end())
+ return;
+
+ uint32 flags = itr->second.flags;
+ uint32 bonusId = 0;
+
+ if (heirloom->UpgradeItemID[0] == castItem)
+ {
+ flags |= HEIRLOOM_FLAG_BONUS_LEVEL_90;
+ bonusId = heirloom->ItemBonusListID[0];
+ }
+ if (heirloom->UpgradeItemID[1] == castItem)
+ {
+ flags |= HEIRLOOM_FLAG_BONUS_LEVEL_100;
+ bonusId = heirloom->ItemBonusListID[1];
+ }
+
+ for (Item* item : player->GetItemListByEntry(itemId, true))
+ item->AddBonuses(bonusId);
+
+ // Get heirloom offset to update only one part of dynamic field
+ std::vector<uint32> const& fields = player->GetDynamicValues(PLAYER_DYNAMIC_FIELD_HEIRLOOMS);
+ uint8 offset = std::find(fields.begin(), fields.end(), itemId) - fields.begin();
+
+ player->SetDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOM_FLAGS, offset, flags);
+ itr->second.flags = flags;
+ itr->second.bonusId = bonusId;
+}
+
+void CollectionMgr::CheckHeirloomUpgrades(Item* item)
+{
+ Player* player = _owner->GetPlayer();
+ if (!player)
+ return;
+
+ // Check already owned heirloom for upgrade kits
+ if (HeirloomEntry const* heirloom = sDB2Manager.GetHeirloomByItemId(item->GetEntry()))
+ {
+ HeirloomContainer::iterator itr = _heirlooms.find(item->GetEntry());
+ if (itr == _heirlooms.end())
+ return;
+
+ // Check for heirloom pairs (normal - heroic, heroic - mythic)
+ uint32 heirloomItemId = heirloom->NextDifficultyItemID;
+ uint32 newItemId = 0;
+ while (HeirloomEntry const* heirloomDiff = sDB2Manager.GetHeirloomByItemId(heirloomItemId))
+ {
+ if (player->GetItemByEntry(heirloomDiff->ItemID))
+ newItemId = heirloomDiff->ItemID;
+
+ if (HeirloomEntry const* heirloomSub = sDB2Manager.GetHeirloomByItemId(heirloomDiff->NextDifficultyItemID))
+ {
+ heirloomItemId = heirloomSub->ItemID;
+ continue;
+ }
+
+ break;
+ }
+
+ if (newItemId)
+ {
+ std::vector<uint32> const& fields = player->GetDynamicValues(PLAYER_DYNAMIC_FIELD_HEIRLOOMS);
+ uint8 offset = std::find(fields.begin(), fields.end(), itr->first) - fields.begin();
+
+ player->SetDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOMS, offset, newItemId);
+ player->SetDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOM_FLAGS, offset, 0);
+
+ _heirlooms.erase(itr);
+ _heirlooms[newItemId] = 0;
+
+ return;
+ }
+
+ std::vector<uint32> const& fields = item->GetDynamicValues(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS);
+
+ for (uint32 bonusId : fields)
+ if (bonusId != itr->second.bonusId)
+ item->ClearDynamicValue(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS);
+
+ if (std::find(fields.begin(), fields.end(), itr->second.bonusId) == fields.end())
+ item->AddBonuses(itr->second.bonusId);
+ }
+}
+
+bool CollectionMgr::CanApplyHeirloomXpBonus(uint32 itemId, uint32 level)
+{
+ if (!sDB2Manager.GetHeirloomByItemId(itemId))
+ return false;
+
+ HeirloomContainer::iterator itr = _heirlooms.find(itemId);
+ if (itr == _heirlooms.end())
+ return false;
+
+ if (itr->second.flags & HEIRLOOM_FLAG_BONUS_LEVEL_100)
+ return level <= 100;
+ if (itr->second.flags & HEIRLOOM_FLAG_BONUS_LEVEL_90)
+ return level <= 90;
+
+ return level <= 60;
+}
diff --git a/src/server/game/Entities/Player/CollectionMgr.h b/src/server/game/Entities/Player/CollectionMgr.h
index 1920447be9c..e023f093dd7 100644
--- a/src/server/game/Entities/Player/CollectionMgr.h
+++ b/src/server/game/Entities/Player/CollectionMgr.h
@@ -20,7 +20,30 @@
#include "WorldSession.h"
+enum HeirloomPlayerFlags
+{
+ HEIRLOOM_FLAG_NONE = 0x00,
+ HEIRLOOM_FLAG_BONUS_LEVEL_90 = 0x01,
+ HEIRLOOM_FLAG_BONUS_LEVEL_100 = 0x02
+};
+
+enum HeirloomItemFlags
+{
+ HEIRLOOM_ITEM_FLAG_NONE = 0x00,
+ HEIRLOOM_ITEM_FLAG_SHOW_ONLY_IF_KNOWN = 0x01,
+ HEIRLOOM_ITEM_FLAG_PVP = 0x02
+};
+
+struct HeirloomData
+{
+ HeirloomData(uint32 _flags = 0, uint32 _bonusId = 0) : flags(_flags), bonusId(_bonusId) { }
+
+ uint32 flags;
+ uint32 bonusId;
+};
+
typedef std::map<uint32, bool> ToyBoxContainer;
+typedef std::map<uint32, HeirloomData> HeirloomContainer;
class CollectionMgr
{
@@ -41,12 +64,25 @@ public:
ToyBoxContainer const& GetAccountToys() const { return _toys; }
// Account-wide heirlooms
+ void LoadHeirlooms();
+ void LoadAccountHeirlooms(PreparedQueryResult result);
+ void SaveAccountHeirlooms(SQLTransaction& trans);
+ void AddHeirloom(uint32 itemId, uint32 flags);
+ void UpgradeHeirloom(uint32 itemId, uint32 castItem);
+ void CheckHeirloomUpgrades(Item* item);
+
+ bool UpdateAccountHeirlooms(uint32 itemId, uint32 flags);
+ bool CanApplyHeirloomXpBonus(uint32 itemId, uint32 level);
+ uint32 GetHeirloomBonus(uint32 itemId) const;
+ HeirloomContainer const& GetAccountHeirlooms() const { return _heirlooms; }
+
// Account-wide mounts
private:
WorldSession* _owner;
ToyBoxContainer _toys;
+ HeirloomContainer _heirlooms;
};
#endif // CollectionMgr_h__
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index b079ce95eab..9d9ff325dc1 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -7905,6 +7905,11 @@ void Player::ApplyItemEquipSpell(Item* item, bool apply, bool formChange /*= fal
if (!spellproto)
continue;
+ if (spellproto->HasAura(GetMap()->GetDifficultyID(), SPELL_AURA_MOD_XP_PCT)
+ && !GetSession()->GetCollectionMgr()->CanApplyHeirloomXpBonus(item->GetEntry(), getLevel())
+ && sDB2Manager.GetHeirloomByItemId(item->GetEntry()))
+ continue;
+
ApplyEquipSpell(spellproto, item, apply, formChange);
}
}
@@ -8301,6 +8306,7 @@ void Player::_ApplyAllLevelScaleItemMods(bool apply)
continue;
_ApplyItemBonuses(m_items[i], i, apply);
+ ApplyItemEquipSpell(m_items[i], apply);
}
}
}
@@ -10869,7 +10875,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
ScalingStatDistributionEntry const* ssd = pProto->GetScalingStatDistribution() ? sScalingStatDistributionStore.LookupEntry(pProto->GetScalingStatDistribution()) : 0;
// check allowed level (extend range to upper values if MaxLevel more or equal max player level, this let GM set high level with 1...max range items)
- if (ssd && ssd->MaxLevel < DEFAULT_MAX_LEVEL && ssd->MaxLevel < getLevel())
+ if (ssd && ssd->MaxLevel < DEFAULT_MAX_LEVEL && ssd->MaxLevel < getLevel() && !sDB2Manager.GetHeirloomByItemId(pProto->GetId()))
return EQUIP_ERR_NOT_EQUIPPABLE;
uint8 eslot = FindEquipSlot(pProto, slot, swap);
@@ -11398,6 +11404,10 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat
ItemAddedQuestCheck(itemId, count);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, itemId, count);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, itemId, 1);
+
+ if (sDB2Manager.GetHeirloomByItemId(itemId))
+ GetSession()->GetCollectionMgr()->AddHeirloom(itemId, 0);
+
if (randomPropertyId)
item->SetItemRandomProperties(randomPropertyId);
@@ -12206,6 +12216,38 @@ Item* Player::GetItemByEntry(uint32 entry) const
return NULL;
}
+std::vector<Item*> Player::GetItemListByEntry(uint32 entry, bool inBankAlso) const
+{
+ std::vector<Item*> itemList = std::vector<Item*>();
+
+ for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i)
+ if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
+ if (item->GetEntry() == entry)
+ itemList.push_back(item);
+
+ for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
+ if (Bag* bag = GetBagByPos(i))
+ for (uint32 j = 0; j < bag->GetBagSize(); ++j)
+ if (Item* item = bag->GetItemByPos(j))
+ if (item->GetEntry() == entry)
+ itemList.push_back(item);
+
+ for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; ++i)
+ if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
+ if (item->GetEntry() == entry)
+ itemList.push_back(item);
+
+ if (inBankAlso)
+ {
+ for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i)
+ if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
+ if (item->GetEntry() == entry)
+ itemList.push_back(item);
+ }
+
+ return itemList;
+}
+
void Player::DestroyItemCount(Item* pItem, uint32 &count, bool update)
{
if (!pItem)
@@ -17045,6 +17087,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
_LoadTalents(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS));
_LoadSpells(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS));
GetSession()->GetCollectionMgr()->LoadToys();
+ GetSession()->GetCollectionMgr()->LoadHeirlooms();
LearnSpecializationSpells();
@@ -17496,6 +17539,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
ObjectGuid bagGuid = fields[21].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[21].GetUInt64()) : ObjectGuid::Empty;
uint8 slot = fields[22].GetUInt8();
+ GetSession()->GetCollectionMgr()->CheckHeirloomUpgrades(item);
+
uint8 err = EQUIP_ERR_OK;
// Item is not in bag
if (!bagGuid)
@@ -18992,6 +19037,7 @@ void Player::SaveToDB(bool create /*=false*/)
trans = LoginDatabase.BeginTransaction();
GetSession()->GetCollectionMgr()->SaveAccountToys(trans);
GetSession()->GetBattlePetMgr()->SaveToDB(trans);
+ GetSession()->GetCollectionMgr()->SaveAccountHeirlooms(trans);
LoginDatabase.CommitTransaction(trans);
// save pet (hunter pet level and experience and all type pets health/mana).
@@ -22447,6 +22493,12 @@ void Player::SendInitialPacketsBeforeAddToMap()
toysUpdate.Toys = &GetSession()->GetCollectionMgr()->GetAccountToys();
SendDirectMessage(toysUpdate.Write());
+ // SMSG_ACCOUNT_HEIRLOOM_UPDATE
+ WorldPackets::Misc::AccountHeirloomUpdate heirloomUpdate;
+ heirloomUpdate.IsFullUpdate = true;
+ heirloomUpdate.Heirlooms = &GetSession()->GetCollectionMgr()->GetAccountHeirlooms();
+ SendDirectMessage(heirloomUpdate.Write());
+
WorldPackets::Character::InitialSetup initialSetup;
initialSetup.ServerExpansionLevel = sWorld->getIntConfig(CONFIG_EXPANSION);
SendDirectMessage(initialSetup.Write());
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index ab894574f9f..60447757035 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1404,6 +1404,7 @@ class Player : public Unit, public GridObject<Player>
uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = NULL) const;
Item* GetItemByGuid(ObjectGuid guid) const;
Item* GetItemByEntry(uint32 entry) const;
+ std::vector<Item*> GetItemListByEntry(uint32 entry, bool inBankAlso = false) const;
Item* GetItemByPos(uint16 pos) const;
Item* GetItemByPos(uint8 bag, uint8 slot) const;
Item* GetUseableItemByPos(uint8 bag, uint8 slot) const;
diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp
index 8617e56a841..142530464f3 100644
--- a/src/server/game/Server/Packets/MiscPackets.cpp
+++ b/src/server/game/Server/Packets/MiscPackets.cpp
@@ -569,3 +569,23 @@ void WorldPackets::Misc::WorldTeleport::Read()
_worldPacket >> Pos;
_worldPacket >> Facing;
}
+
+WorldPacket const* WorldPackets::Misc::AccountHeirloomUpdate::Write()
+{
+ _worldPacket.WriteBit(IsFullUpdate);
+ _worldPacket.FlushBits();
+
+ _worldPacket << int32(Unk);
+
+ // both lists have to have the same size
+ _worldPacket << int32(Heirlooms->size());
+ _worldPacket << int32(Heirlooms->size());
+
+ for (auto const& item : *Heirlooms)
+ _worldPacket << uint32(item.first);
+
+ for (auto const& flags : *Heirlooms)
+ _worldPacket << uint32(flags.second.flags);
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h
index 423a6ccbc8d..b3c8955dba9 100644
--- a/src/server/game/Server/Packets/MiscPackets.h
+++ b/src/server/game/Server/Packets/MiscPackets.h
@@ -26,6 +26,7 @@
#include "Unit.h"
#include "Player.h"
#include "Weather.h"
+#include "CollectionMgr.h"
namespace WorldPackets
{
@@ -747,6 +748,18 @@ namespace WorldPackets
G3D::Vector3 Pos;
float Facing = 0.0f;
};
+
+ class AccountHeirloomUpdate final : public ServerPacket
+ {
+ public:
+ AccountHeirloomUpdate() : ServerPacket(SMSG_ACCOUNT_HEIRLOOM_UPDATE) { }
+
+ WorldPacket const* Write() override;
+
+ bool IsFullUpdate = false;
+ HeirloomContainer const* Heirlooms = nullptr;
+ int32 Unk = 0;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 4637093c8a9..c59a4bb3175 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -841,7 +841,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ABORT_NEW_WORLD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_CRITERIA_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HEIRLOOM_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HEIRLOOM_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_TOYS_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 1874403eb19..2189fbffeff 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -1160,6 +1160,7 @@ public:
GLOBAL_ACCOUNT_TOYS = 0,
BATTLE_PETS,
BATTLE_PET_SLOTS,
+ GLOBAL_ACCOUNT_HEIRLOOMS,
MAX_QUERIES
};
@@ -1182,6 +1183,10 @@ public:
stmt->setUInt32(0, battlenetAccountId);
ok = SetPreparedQuery(BATTLE_PET_SLOTS, stmt) && ok;
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_HEIRLOOMS);
+ stmt->setUInt32(0, battlenetAccountId);
+ ok = SetPreparedQuery(GLOBAL_ACCOUNT_HEIRLOOMS, stmt) && ok;
+
return ok;
}
};
@@ -1214,6 +1219,7 @@ void WorldSession::InitializeSessionCallback(SQLQueryHolder* realmHolder, SQLQue
LoadAccountData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA), GLOBAL_CACHE_MASK);
LoadTutorialsData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS));
_collectionMgr->LoadAccountToys(holder->GetPreparedResult(AccountInfoQueryHolder::GLOBAL_ACCOUNT_TOYS));
+ _collectionMgr->LoadAccountHeirlooms(holder->GetPreparedResult(AccountInfoQueryHolder::GLOBAL_ACCOUNT_HEIRLOOMS));
if (!m_inQueue)
SendAuthResponse(AUTH_OK, false);
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index d5ed0a3c0a8..0728ee46e8c 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -437,6 +437,8 @@ class Spell
void EffectHealBattlePetPct(SpellEffIndex effIndex);
void EffectEnableBattlePets(SpellEffIndex effIndex);
void EffectUncageBattlePet(SpellEffIndex effIndex);
+ void EffectCreateHeirloomItem(SpellEffIndex effIndex);
+ void EffectUpgradeHeirloom(SpellEffIndex effIndex);
typedef std::set<Aura*> UsedSpellMods;
@@ -507,7 +509,7 @@ class Spell
uint32 getState() const { return m_spellState; }
void setState(uint32 state) { m_spellState = state; }
- void DoCreateItem(uint32 i, uint32 itemtype);
+ void DoCreateItem(uint32 i, uint32 itemtype, std::vector<int32> const& bonusListIDs = std::vector<int32>());
bool CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect, Position const* losPosition) const;
bool CheckEffectTarget(GameObject const* target, SpellEffectInfo const* effect) const;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 2bea3a78137..77f3d2b905e 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -287,7 +287,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectNULL, //219 SPELL_EFFECT_219
&Spell::EffectAddGarrisonFollower, //220 SPELL_EFFECT_ADD_GARRISON_FOLLOWER
&Spell::EffectNULL, //221 SPELL_EFFECT_221
- &Spell::EffectNULL, //222 SPELL_EFFECT_CREATE_HEIRLOOM_ITEM
+ &Spell::EffectCreateHeirloomItem, //222 SPELL_EFFECT_CREATE_HEIRLOOM_ITEM
&Spell::EffectNULL, //223 SPELL_EFFECT_CHANGE_ITEM_BONUSES
&Spell::EffectActivateGarrisonBuilding, //224 SPELL_EFFECT_ACTIVATE_GARRISON_BUILDING
&Spell::EffectNULL, //225 SPELL_EFFECT_GRANT_BATTLEPET_LEVEL
@@ -310,7 +310,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectNULL, //242 SPELL_EFFECT_242
&Spell::EffectNULL, //243 SPELL_EFFECT_APPLY_ENCHANT_ILLUSION
&Spell::EffectNULL, //244 SPELL_EFFECT_LEARN_FOLLOWER_ABILITY
- &Spell::EffectNULL, //245 SPELL_EFFECT_UPGRADE_HEIRLOOM
+ &Spell::EffectUpgradeHeirloom, //245 SPELL_EFFECT_UPGRADE_HEIRLOOM
&Spell::EffectNULL, //246 SPELL_EFFECT_FINISH_GARRISON_MISSION
&Spell::EffectNULL, //247 SPELL_EFFECT_ADD_GARRISON_MISSION
&Spell::EffectNULL, //248 SPELL_EFFECT_FINISH_SHIPMENT
@@ -1414,7 +1414,7 @@ void Spell::EffectHealthLeech(SpellEffIndex /*effIndex*/)
}
}
-void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype)
+void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype, std::vector<int32> const& bonusListIDs)
{
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
@@ -1493,7 +1493,7 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype)
if (num_to_add)
{
// create the new item and store it
- Item* pItem = player->StoreNewItem(dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid));
+ Item* pItem = player->StoreNewItem(dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid), GuidSet(), bonusListIDs);
// was it successful? return error if not
if (!pItem)
@@ -5867,6 +5867,26 @@ void Spell::EffectAddGarrisonFollower(SpellEffIndex effIndex)
garrison->AddFollower(GetEffect(effIndex)->MiscValue);
}
+void Spell::EffectCreateHeirloomItem(SpellEffIndex effIndex)
+{
+ if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
+ return;
+
+ Player* player = m_caster->ToPlayer();
+ if (!player)
+ return;
+
+ CollectionMgr* collectionMgr = player->GetSession()->GetCollectionMgr();
+ if (!collectionMgr)
+ return;
+
+ std::vector<int32> bonusList;
+ bonusList.push_back(collectionMgr->GetHeirloomBonus(m_misc.Raw.Data[0]));
+
+ DoCreateItem(effIndex, m_misc.Raw.Data[0], bonusList);
+ ExecuteLogEffectCreateItem(effIndex, m_misc.Raw.Data[0]);
+}
+
void Spell::EffectActivateGarrisonBuilding(SpellEffIndex effIndex)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
@@ -5960,3 +5980,13 @@ void Spell::EffectUncageBattlePet(SpellEffIndex /*effIndex*/)
plr->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
m_CastItem = nullptr;
}
+
+void Spell::EffectUpgradeHeirloom(SpellEffIndex /*effIndex*/)
+{
+ if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
+ return;
+
+ if (Player* player = m_caster->ToPlayer())
+ if (CollectionMgr* collectionMgr = player->GetSession()->GetCollectionMgr())
+ collectionMgr->UpgradeHeirloom(m_misc.Raw.Data[0], m_castItemEntry);
+}