aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/macros/FindMySQL.cmake2
-rw-r--r--contrib/merge_updates_unix.sh1
-rw-r--r--contrib/merge_updates_windows.bat1
-rw-r--r--sql/base/characters_database.sql64
-rw-r--r--sql/updates/characters/2015_02_13_00_characters.sql9
-rw-r--r--sql/updates/characters/2015_02_13_01_characters.sql5
-rw-r--r--sql/updates/characters/2015_02_17_00_characters.sql28
-rw-r--r--sql/updates/world/2015_02_13_00_world.sql135
-rw-r--r--sql/updates/world/2015_02_18_00_world.sql4
-rw-r--r--src/server/bnetserver/Main.cpp19
-rw-r--r--src/server/game/AI/CoreAI/PetAI.cpp5
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp4
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp2
-rw-r--r--src/server/game/DataStores/DBCEnums.h2
-rw-r--r--src/server/game/DataStores/DBCStructure.h6
-rw-r--r--src/server/game/DataStores/DBCfmt.h4
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp79
-rw-r--r--src/server/game/Entities/Creature/Creature.h10
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.h8
-rw-r--r--src/server/game/Entities/Object/Object.cpp3
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp111
-rw-r--r--src/server/game/Entities/Pet/Pet.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp650
-rw-r--r--src/server/game/Entities/Player/Player.h25
-rw-r--r--src/server/game/Entities/Totem/Totem.cpp3
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp147
-rw-r--r--src/server/game/Entities/Unit/Unit.h47
-rw-r--r--src/server/game/Guilds/Guild.cpp1278
-rw-r--r--src/server/game/Guilds/Guild.h172
-rw-r--r--src/server/game/Guilds/GuildMgr.cpp114
-rw-r--r--src/server/game/Guilds/GuildMgr.h3
-rw-r--r--src/server/game/Handlers/BattlefieldHandler.cpp2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp4
-rw-r--r--src/server/game/Handlers/CombatHandler.cpp39
-rw-r--r--src/server/game/Handlers/GuildHandler.cpp662
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp51
-rw-r--r--src/server/game/Handlers/MailHandler.cpp2
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp17
-rw-r--r--src/server/game/Handlers/PetHandler.cpp20
-rw-r--r--src/server/game/Handlers/PetitionsHandler.cpp791
-rw-r--r--src/server/game/Handlers/QueryHandler.cpp4
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp2
-rw-r--r--src/server/game/Loot/LootMgr.h8
-rw-r--r--src/server/game/Reputation/ReputationMgr.cpp2
-rw-r--r--src/server/game/Server/Packets/CombatPackets.cpp31
-rw-r--r--src/server/game/Server/Packets/CombatPackets.h37
-rw-r--r--src/server/game/Server/Packets/GuildPackets.cpp752
-rw-r--r--src/server/game/Server/Packets/GuildPackets.h933
-rw-r--r--src/server/game/Server/Packets/ItemPackets.cpp90
-rw-r--r--src/server/game/Server/Packets/ItemPackets.h79
-rw-r--r--src/server/game/Server/Packets/MailPackets.h4
-rw-r--r--src/server/game/Server/Packets/MiscPackets.h2
-rw-r--r--src/server/game/Server/Packets/NPCPackets.cpp7
-rw-r--r--src/server/game/Server/Packets/NPCPackets.h10
-rw-r--r--src/server/game/Server/Packets/PacketUtilities.h19
-rw-r--r--src/server/game/Server/Packets/PetitionPackets.cpp192
-rw-r--r--src/server/game/Server/Packets/PetitionPackets.h246
-rw-r--r--src/server/game/Server/Packets/SpellPackets.cpp119
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h126
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp242
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h131
-rw-r--r--src/server/game/Server/WorldSession.cpp18
-rw-r--r--src/server/game/Server/WorldSession.h157
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h16
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp23
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp39
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h2
-rw-r--r--src/server/game/Spells/Spell.cpp181
-rw-r--r--src/server/game/Spells/Spell.h10
-rw-r--r--src/server/game/Spells/SpellEffects.cpp23
-rw-r--r--src/server/game/Spells/SpellHistory.cpp854
-rw-r--r--src/server/game/Spells/SpellHistory.h155
-rw-r--r--src/server/game/Spells/SpellInfo.cpp27
-rw-r--r--src/server/game/Spells/SpellInfo.h4
-rw-r--r--src/server/game/World/World.cpp16
-rw-r--r--src/server/game/World/World.h4
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp10
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp190
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp22
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h54
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp15
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp11
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp243
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp146
-rw-r--r--src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp7
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp3
-rw-r--r--src/server/scripts/Spells/spell_druid.cpp5
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp7
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp17
-rw-r--r--src/server/scripts/Spells/spell_item.cpp5
-rw-r--r--src/server/scripts/Spells/spell_mage.cpp21
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp3
-rw-r--r--src/server/scripts/Spells/spell_rogue.cpp29
-rw-r--r--src/server/scripts/Spells/spell_shaman.cpp15
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp7
-rw-r--r--src/server/scripts/World/npcs_special.cpp33
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp30
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.h16
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.cpp1
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.h1
-rw-r--r--src/server/worldserver/Main.cpp22
101 files changed, 5932 insertions, 4077 deletions
diff --git a/cmake/macros/FindMySQL.cmake b/cmake/macros/FindMySQL.cmake
index 2c393463c47..990f4918d6a 100644
--- a/cmake/macros/FindMySQL.cmake
+++ b/cmake/macros/FindMySQL.cmake
@@ -94,6 +94,7 @@ find_path(MYSQL_INCLUDE_DIR
"$ENV{ProgramFiles}/MySQL/*/include"
"$ENV{SystemDrive}/MySQL/*/include"
"c:/msys/local/include"
+ "$ENV{MYSQL_ROOT}/include"
DOC
"Specify the directory containing mysql.h."
)
@@ -159,6 +160,7 @@ if( WIN32 )
"$ENV{ProgramFiles}/MySQL/*/lib/opt"
"$ENV{SystemDrive}/MySQL/*/lib/opt"
"c:/msys/local/include"
+ "$ENV{MYSQL_ROOT}/lib"
DOC "Specify the location of the mysql library here."
)
endif( WIN32 )
diff --git a/contrib/merge_updates_unix.sh b/contrib/merge_updates_unix.sh
index d0093d03fc1..42499e68932 100644
--- a/contrib/merge_updates_unix.sh
+++ b/contrib/merge_updates_unix.sh
@@ -1 +1,2 @@
cat ../sql/updates/world/*.sql > world_update.sql
+cat ../sql/updates/hotfixes/*.sql > hotfixes_update.sql
diff --git a/contrib/merge_updates_windows.bat b/contrib/merge_updates_windows.bat
index c43d4adf907..f70bd1bcb5b 100644
--- a/contrib/merge_updates_windows.bat
+++ b/contrib/merge_updates_windows.bat
@@ -1 +1,2 @@
copy /a ..\sql\updates\world\*.sql /b world_updates.sql
+copy /a ..\sql\updates\hotfixes\*.sql /b hotfixes_updates.sql
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql
index 0528f355c81..b920bcba8cd 100644
--- a/sql/base/characters_database.sql
+++ b/sql/base/characters_database.sql
@@ -1232,6 +1232,31 @@ LOCK TABLES `character_spell` WRITE;
UNLOCK TABLES;
--
+-- Table structure for table `character_spell_charges`
+--
+
+DROP TABLE IF EXISTS `character_spell_charges`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `character_spell_charges` (
+ `guid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier, Low part',
+ `categoryId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'SpellCategory.dbc Identifier',
+ `rechargeStart` int(10) unsigned NOT NULL DEFAULT '0',
+ `rechargeEnd` int(10) unsigned NOT NULL DEFAULT '0',
+ KEY `idx_guid` (`guid`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `character_spell_charges`
+--
+
+LOCK TABLES `character_spell_charges` WRITE;
+/*!40000 ALTER TABLE `character_spell_charges` DISABLE KEYS */;
+/*!40000 ALTER TABLE `character_spell_charges` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
-- Table structure for table `character_spell_cooldown`
--
@@ -1240,7 +1265,7 @@ DROP TABLE IF EXISTS `character_spell_cooldown`;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `character_spell_cooldown` (
`guid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier, Low part',
- `spell` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Spell Identifier',
+ `spell` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Spell Identifier',
`item` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Item Identifier',
`time` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`guid`,`spell`)
@@ -1795,8 +1820,6 @@ CREATE TABLE `guild` (
`createdate` int(10) unsigned NOT NULL DEFAULT '0',
`BankMoney` bigint(20) unsigned NOT NULL DEFAULT '0',
`level` int(10) unsigned DEFAULT '1',
- `experience` bigint(20) unsigned DEFAULT '0',
- `todayExperience` bigint(20) unsigned DEFAULT '0',
PRIMARY KEY (`guildid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Guild System';
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -1932,8 +1955,8 @@ CREATE TABLE `guild_bank_right` (
`guildid` bigint(20) unsigned NOT NULL DEFAULT '0',
`TabId` tinyint(3) unsigned NOT NULL DEFAULT '0',
`rid` tinyint(3) unsigned NOT NULL DEFAULT '0',
- `gbright` tinyint(3) unsigned NOT NULL DEFAULT '0',
- `SlotPerDay` int(10) unsigned NOT NULL DEFAULT '0',
+ `gbright` tinyint(3) NOT NULL DEFAULT '0',
+ `SlotPerDay` int(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`guildid`,`TabId`,`rid`),
KEY `guildid_key` (`guildid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -2576,6 +2599,31 @@ LOCK TABLES `pet_spell` WRITE;
UNLOCK TABLES;
--
+-- Table structure for table `pet_spell_charges`
+--
+
+DROP TABLE IF EXISTS `pet_spell_charges`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `pet_spell_charges` (
+ `guid` int(10) unsigned NOT NULL,
+ `categoryId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'SpellCategory.dbc Identifier',
+ `rechargeStart` int(10) unsigned NOT NULL DEFAULT '0',
+ `rechargeEnd` int(10) unsigned NOT NULL DEFAULT '0',
+ KEY `idx_guid` (`guid`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `pet_spell_charges`
+--
+
+LOCK TABLES `pet_spell_charges` WRITE;
+/*!40000 ALTER TABLE `pet_spell_charges` DISABLE KEYS */;
+/*!40000 ALTER TABLE `pet_spell_charges` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
-- Table structure for table `pet_spell_cooldown`
--
@@ -2584,7 +2632,7 @@ DROP TABLE IF EXISTS `pet_spell_cooldown`;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `pet_spell_cooldown` (
`guid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier, Low part',
- `spell` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT 'Spell Identifier',
+ `spell` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Spell Identifier',
`time` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`guid`,`spell`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -2610,8 +2658,7 @@ CREATE TABLE `petition` (
`ownerguid` bigint(20) unsigned NOT NULL,
`petitionguid` bigint(20) unsigned DEFAULT '0',
`name` varchar(24) NOT NULL,
- `type` tinyint(3) unsigned NOT NULL DEFAULT '0',
- PRIMARY KEY (`ownerguid`,`type`),
+ PRIMARY KEY (`ownerguid`),
UNIQUE KEY `index_ownerguid_petitionguid` (`ownerguid`,`petitionguid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Guild System';
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -2637,7 +2684,6 @@ CREATE TABLE `petition_sign` (
`petitionguid` bigint(20) unsigned NOT NULL DEFAULT '0',
`playerguid` bigint(20) unsigned NOT NULL DEFAULT '0',
`player_account` int(10) unsigned NOT NULL DEFAULT '0',
- `type` tinyint(3) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`petitionguid`,`playerguid`),
KEY `Idx_playerguid` (`playerguid`),
KEY `Idx_ownerguid` (`ownerguid`)
diff --git a/sql/updates/characters/2015_02_13_00_characters.sql b/sql/updates/characters/2015_02_13_00_characters.sql
new file mode 100644
index 00000000000..1ed83e4e762
--- /dev/null
+++ b/sql/updates/characters/2015_02_13_00_characters.sql
@@ -0,0 +1,9 @@
+ALTER TABLE `guild` DROP COLUMN `experience`, DROP COLUMN `todayExperience`;
+
+ALTER TABLE `guild_bank_right` MODIFY COLUMN `gbright` mediumint(3) NOT NULL DEFAULT 0; -- temp type, can hold all values
+UPDATE `guild_bank_right` SET `gbright` = -1 WHERE `gbright` = 255;
+ALTER TABLE `guild_bank_right` MODIFY COLUMN `gbright` tinyint(3) NOT NULL DEFAULT 0;
+
+ALTER TABLE `guild_bank_right` MODIFY COLUMN `SlotPerDay` bigint(10) NOT NULL DEFAULT 0; -- temp type, can hold all values
+UPDATE `guild_bank_right` SET `SlotPerDay` = -1 WHERE `SlotPerDay` = 4294967295;
+ALTER TABLE `guild_bank_right` MODIFY COLUMN `SlotPerDay` int(10) NOT NULL DEFAULT 0;
diff --git a/sql/updates/characters/2015_02_13_01_characters.sql b/sql/updates/characters/2015_02_13_01_characters.sql
new file mode 100644
index 00000000000..52b7a7e4c2a
--- /dev/null
+++ b/sql/updates/characters/2015_02_13_01_characters.sql
@@ -0,0 +1,5 @@
+DELETE FROM `petition` WHERE `type` != 10; -- delete all non guild petitions
+ALTER TABLE `petition` DROP COLUMN `type`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ownerguid`);
+
+DELETE FROM `petition_sign` WHERE `type` != 10; -- delete all non guild petition signs
+ALTER TABLE `petition_sign` DROP COLUMN `type`;
diff --git a/sql/updates/characters/2015_02_17_00_characters.sql b/sql/updates/characters/2015_02_17_00_characters.sql
new file mode 100644
index 00000000000..ebf539c9a40
--- /dev/null
+++ b/sql/updates/characters/2015_02_17_00_characters.sql
@@ -0,0 +1,28 @@
+--
+-- Table structure for table `character_spell_charges`
+--
+
+DROP TABLE IF EXISTS `character_spell_charges`;
+CREATE TABLE `character_spell_charges` (
+ `guid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier, Low part',
+ `categoryId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'SpellCategory.dbc Identifier',
+ `rechargeStart` int(10) unsigned NOT NULL DEFAULT '0',
+ `rechargeEnd` int(10) unsigned NOT NULL DEFAULT '0',
+ KEY `idx_guid` (`guid`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `pet_spell_charges`
+--
+
+DROP TABLE IF EXISTS `pet_spell_charges`;
+CREATE TABLE `pet_spell_charges` (
+ `guid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier, Low part',
+ `categoryId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'SpellCategory.dbc Identifier',
+ `rechargeStart` int(10) unsigned NOT NULL DEFAULT '0',
+ `rechargeEnd` int(10) unsigned NOT NULL DEFAULT '0',
+ KEY `idx_guid` (`guid`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+ALTER TABLE `character_spell_cooldown` CHANGE `spell` `spell` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Spell Identifier';
+ALTER TABLE `pet_spell_cooldown` CHANGE `spell` `spell` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Spell Identifier';
diff --git a/sql/updates/world/2015_02_13_00_world.sql b/sql/updates/world/2015_02_13_00_world.sql
new file mode 100644
index 00000000000..f510682f090
--- /dev/null
+++ b/sql/updates/world/2015_02_13_00_world.sql
@@ -0,0 +1,135 @@
+DROP TABLE IF EXISTS `guild_xp_for_level`;
+
+ALTER TABLE `guild_rewards` CHANGE COLUMN `entry` `ItemID` mediumint(8) UNSIGNED NOT NULL DEFAULT 0;
+ALTER TABLE `guild_rewards` CHANGE COLUMN `standing` `MinGuildRep` tinyint(3) UNSIGNED NULL DEFAULT 0;
+ALTER TABLE `guild_rewards` CHANGE COLUMN `racemask` `RaceMask` int(11) NULL DEFAULT 0;
+ALTER TABLE `guild_rewards` CHANGE COLUMN `price` `Cost` bigint(20) UNSIGNED NULL DEFAULT 0;
+ALTER TABLE `guild_rewards` DROP COLUMN `achievement`;
+
+TRUNCATE TABLE `guild_rewards`;
+INSERT IGNORE INTO `guild_rewards` (`ItemID`, `MinGuildRep`, `RaceMask`, `Cost`) VALUES
+(89194, 5, -1, 1500000),
+(89195, 7, -1, 2000000),
+(114968, 6, 0, 3000000),
+(116666, 7, -1, 40000000),
+(63206, 5, 18875469, 3000000),
+(63207, 5, 33555378, 3000000),
+(65435, 5, 0, 1500000),
+(85666, 7, -1, 30000000),
+(67107, 7, 33555378, 15000000),
+(69887, 4, 0, 15000000),
+(69888, 5, -1, 17500000),
+(69892, 4, 0, 12000000),
+(71033, 7, 0, 15000000),
+(65498, 5, 0, 1500000),
+(120352, 7, 0, 1000000),
+(64398, 5, 18875469, 2000000),
+(64399, 5, 18875469, 3000000),
+(64400, 5, 33555378, 1500000),
+(64401, 5, 33555378, 2000000),
+(64402, 5, 33555378, 3000000),
+(61931, 4, 0, 15000000),
+(61935, 4, 0, 15000000),
+(61936, 4, 0, 15000000),
+(61937, 4, 0, 15000000),
+(61942, 4, 0, 15000000),
+(65274, 6, 33555378, 5000000),
+(61958, 4, 0, 15000000),
+(85508, 5, -1, 1000000),
+(85509, 5, -1, 1000000),
+(85510, 5, -1, 1000000),
+(63352, 5, 18875469, 1500000),
+(63353, 5, 33555378, 1500000),
+(62799, 5, 0, 1500000),
+(62800, 5, 0, 1500000),
+(63359, 5, 18875469, 1500000),
+(69209, 4, -1, 1250000),
+(69210, 5, -1, 2500000),
+(62286, 4, 0, 100000000),
+(62287, 6, 33555378, 200000000),
+(63398, 6, 0, 3000000),
+(63125, 7, 0, 30000000),
+(62298, 7, 18875469, 15000000),
+(62023, 5, -1, 17500000),
+(62024, 5, -1, 17500000),
+(62025, 5, -1, 17500000),
+(62026, 5, -1, 17500000),
+(62027, 5, -1, 17500000),
+(62029, 5, -1, 17500000),
+(63138, 7, -1, 3000000),
+(65360, 6, 18875469, 5000000),
+(65361, 5, 18875469, 3000000),
+(62038, 4, 0, 12000000),
+(65362, 5, 33555378, 3000000),
+(62039, 4, 0, 12000000),
+(65363, 6, 18875469, 5000000),
+(62040, 4, 0, 12000000),
+(65364, 6, 33555378, 5000000),
+(68136, 6, 18875469, 200000000),
+(89190, 5, -1, 1500000),
+(89191, 7, -1, 2000000),
+(89192, 5, -1, 1500000),
+(89193, 7, -1, 2000000);
+
+DROP TABLE IF EXISTS `guild_rewards_req_achievements`;
+CREATE TABLE `guild_rewards_req_achievements` (
+ `ItemID` mediumint(8) unsigned NOT NULL DEFAULT '0',
+ `AchievementRequired` mediumint(8) unsigned DEFAULT '0',
+ PRIMARY KEY (`ItemID`,`AchievementRequired`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+INSERT IGNORE INTO `guild_rewards_req_achievements` (`ItemID`, `AchievementRequired`) VALUES
+(89194, 6681),
+(89190, 6681),
+(89192, 6681),
+(89191, 6644),
+(89191, 6664),
+(89193, 6644),
+(89193, 6664),
+(89195, 6644),
+(89195, 6664),
+(114968, 9651),
+(116666, 9669),
+(65435, 5465),
+(85666, 6682),
+(69888, 6626),
+(62023, 6626),
+(62024, 6626),
+(62025, 6626),
+(62026, 6626),
+(62027, 6626),
+(62029, 6626),
+(71033, 5840),
+(65498, 5024),
+(120352, 9388),
+(64398, 5143),
+(64401, 5143),
+(64399, 5422),
+(64402, 5422),
+(64400, 4860),
+(63359, 4860),
+(65274, 5035),
+(65360, 5035),
+(85508, 7448),
+(85509, 7448),
+(85510, 7448),
+(85508, 7449),
+(85509, 7449),
+(85510, 7449),
+(63352, 4989),
+(63353, 4989),
+(62799, 5467),
+(62800, 5036),
+(62286, 5196),
+(62287, 5158),
+(62287, 4949),
+(68136, 5152),
+(68136, 4949),
+(65361, 5031),
+(65362, 5179),
+(65363, 5201),
+(65364, 5201),
+(63398, 5144),
+(63125, 4988),
+(63138, 5812),
+(63138, 5892);
diff --git a/sql/updates/world/2015_02_18_00_world.sql b/sql/updates/world/2015_02_18_00_world.sql
new file mode 100644
index 00000000000..6a4c12347a3
--- /dev/null
+++ b/sql/updates/world/2015_02_18_00_world.sql
@@ -0,0 +1,4 @@
+--
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceGroup`=1 AND `SourceEntry`=52654;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 52654, 0, 0, 31, 0, 3, 28823, 0, 0, 0, 0, '', 'Temper only target Volkhan\'s Anvil');
diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp
index 5f4f63287e5..ab7c91512e2 100644
--- a/src/server/bnetserver/Main.cpp
+++ b/src/server/bnetserver/Main.cpp
@@ -61,7 +61,7 @@ boost::asio::deadline_timer _dbPingTimer(_ioService);
uint32 _dbPingInterval;
LoginDatabaseWorkerPool LoginDatabase;
-int main(int argc, char** argv)
+int mainImpl(int argc, char** argv)
{
std::string configFile = _TRINITY_BNET_CONFIG;
auto vm = GetConsoleArguments(argc, argv, configFile);
@@ -156,6 +156,23 @@ int main(int argc, char** argv)
return 0;
}
+int main(int argc, char** argv)
+{
+ try
+ {
+ return mainImpl(argc, argv);
+ }
+ catch (std::exception& ex)
+ {
+ std::cerr << "Top-level exception caught:" << ex.what() << "\n";
+
+#ifndef NDEBUG // rethrow exception for the debugger
+ throw;
+#else
+ return 1;
+#endif
+ }
+}
/// Initialize connection to the database
bool StartDB()
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index 3e2087cd017..7d36fd9de67 100644
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -29,6 +29,7 @@
#include "Util.h"
#include "Group.h"
#include "SpellInfo.h"
+#include "SpellHistory.h"
int PetAI::Permissible(const Creature* creature)
{
@@ -147,7 +148,7 @@ void PetAI::UpdateAI(uint32 diff)
if (!spellInfo)
continue;
- if (me->GetCharmInfo() && me->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
+ if (me->GetCharmInfo() && me->GetSpellHistory()->HasGlobalCooldown(spellInfo))
continue;
if (spellInfo->IsPositive())
@@ -155,7 +156,7 @@ void PetAI::UpdateAI(uint32 diff)
if (spellInfo->CanBeUsedInCombat())
{
// check spell cooldown
- if (me->HasSpellCooldown(spellInfo->Id))
+ if (!me->GetSpellHistory()->IsReady(spellInfo))
continue;
// Check if we're in combat or commanded to attack
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index d1b87468797..4932a83d665 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -997,8 +997,8 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type,
, GetOwner()->GetGUID().ToString().c_str(), AchievementGlobalMgr::GetCriteriaTypeString(type), type, miscValue1, miscValue2, miscValue3);
// Lua_GetGuildLevelEnabled() is checked in achievement UI to display guild tab
- if (IsGuild<T>() && !sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED))
- return;
+ //if (IsGuild<T>() && !sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED))
+ // return;
AchievementCriteriaList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type, IsGuild<T>());
for (AchievementCriteria const* achievementCriteria : achievementCriteriaList)
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index 380ce22c1bb..77aa29536e4 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -139,7 +139,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid)
// Remove all player signatures from other petitions
// This will prevent player from joining too many arena teams and corrupt arena team data integrity
- Player::RemovePetitionsAndSigns(playerGuid, GetType());
+ //Player::RemovePetitionsAndSigns(playerGuid, GetType()); /// @todo arena teams removed in 5.4
// Feed data to the struct
ArenaTeamMember newMember;
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 72994461add..cc97e50fa3e 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -494,7 +494,7 @@ enum SpellCategoryFlags
{
SPELL_CATEGORY_FLAG_COOLDOWN_SCALES_WITH_WEAPON_SPEED = 0x01, // unused
SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT = 0x04,
- SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_MIDNIGHT = 0x08
+ SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_DAILY_RESET = 0x08
};
enum TotemCategoryType
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 0bad082801d..c5b6fe52ae4 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -1577,7 +1577,7 @@ struct SpellCategoriesEntry
uint32 Mechanic; // 6
uint32 PreventionType; // 7
uint32 StartRecoveryCategory; // 8
- //uint32 ChargeCategory; // 9
+ uint32 ChargeCategory; // 9
};
typedef std::set<uint32> SpellCategorySet;
@@ -1601,8 +1601,8 @@ struct SpellCategoryEntry
//uint8 UsesPerWeek; // 2
//uint8 Padding[3]; // 2
//char* Name_lang; // 3
- //uint32 MaxCharges; // 4
- //uint32 ChargeRecoveryTime; // 5
+ int32 MaxCharges; // 4
+ int32 ChargeRecoveryTime; // 5
};
struct SpellFocusObjectEntry
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index 1d404d66311..f6612fca298 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -137,8 +137,8 @@ char const SkillTiersfmt[] = "niiiiiiiiiiiiiiii";
char const SoundEntriesfmt[] = "nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char const SpecializationSpellsEntryfmt[] = "niiix";
char const SpellCastTimefmt[] = "nixx";
-char const SpellCategoriesEntryfmt[] = "diiiiiiiix";
-char const SpellCategoryfmt[] = "nixxxx";
+char const SpellCategoriesEntryfmt[] = "diiiiiiiii";
+char const SpellCategoryfmt[] = "nixxii";
char const SpellDurationfmt[] = "niii";
char const SpellEffectEntryfmt[] = "iiifiiiffiiiiiifiifiiiiifiiiiif";
const std::string CustomSpellEffectEntryfmt = "ppppppppppppppappppppppppp";
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index f6a3a5c600c..096b4b749be 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -157,8 +157,6 @@ m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(
for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
m_spells[i] = 0;
- m_CreatureSpellCooldowns.clear();
- m_CreatureCategoryCooldowns.clear();
DisableReputationGain = false;
m_SightDistance = sWorld->getFloatConfig(CONFIG_SIGHT_MONSTER);
@@ -2181,83 +2179,6 @@ void Creature::SetInCombatWithZone()
}
}
-void Creature::_AddCreatureSpellCooldown(uint32 spell_id, time_t end_time)
-{
- m_CreatureSpellCooldowns[spell_id] = end_time;
-}
-
-void Creature::_AddCreatureCategoryCooldown(uint32 category, time_t apply_time)
-{
- m_CreatureCategoryCooldowns[category] = apply_time;
-}
-
-void Creature::AddCreatureSpellCooldown(uint32 spellid)
-{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid);
- if (!spellInfo)
- return;
-
- uint32 cooldown = spellInfo->GetRecoveryTime();
- if (Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellid, SPELLMOD_COOLDOWN, cooldown);
-
- if (cooldown)
- _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown/IN_MILLISECONDS);
-
- if (spellInfo->GetCategory())
- _AddCreatureCategoryCooldown(spellInfo->GetCategory(), time(NULL));
-}
-
-bool Creature::HasCategoryCooldown(uint32 spell_id) const
-{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
- if (!spellInfo)
- return false;
-
- CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.find(spellInfo->GetCategory());
- return(itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / IN_MILLISECONDS)) > time(NULL));
-}
-
-uint32 Creature::GetCreatureSpellCooldownDelay(uint32 spellId) const
-{
- CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spellId);
- time_t t = time(NULL);
- return uint32(itr != m_CreatureSpellCooldowns.end() && itr->second > t ? itr->second - t : 0);
-}
-
-bool Creature::HasSpellCooldown(uint32 spell_id) const
-{
- CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spell_id);
- return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)) || HasCategoryCooldown(spell_id);
-}
-
-void Creature::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
-{
- time_t curTime = time(NULL);
- for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
- {
- if (m_spells[i] == 0)
- continue;
-
- uint32 unSpellId = m_spells[i];
- SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(unSpellId);
-
- // Not send cooldown for this spells
- if (spellInfo->IsCooldownStartedOnEvent())
- continue;
-
- if (spellInfo->PreventionType != SPELL_PREVENTION_TYPE_SILENCE)
- continue;
-
- if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs)
- {
- _AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs/IN_MILLISECONDS);
- if (UnitAI* ai = GetAI())
- ai->SpellInterrupted(unSpellId, unTimeMs);
- }
- }
-}
-
bool Creature::HasSpell(uint32 spellID) const
{
uint8 i;
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index a3230dd98ba..43de647c00a 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -529,14 +529,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
SpellSchoolMask GetMeleeDamageSchoolMask() const override { return m_meleeDamageSchoolMask; }
void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); }
- void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time);
- void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time);
- void AddCreatureSpellCooldown(uint32 spellid);
- bool HasSpellCooldown(uint32 spell_id) const;
- bool HasCategoryCooldown(uint32 spell_id) const;
- uint32 GetCreatureSpellCooldownDelay(uint32 spellId) const;
- virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) override;
-
bool HasSpell(uint32 spellID) const override;
bool UpdateEntry(uint32 entry, CreatureData const* data = nullptr);
@@ -610,8 +602,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
SpellInfo const* reachWithSpellCure(Unit* victim);
uint32 m_spells[CREATURE_MAX_SPELLS];
- CreatureSpellCooldowns m_CreatureSpellCooldowns;
- CreatureSpellCooldowns m_CreatureCategoryCooldowns;
bool CanStartAttack(Unit const* u, bool force) const;
float GetAttackDistance(Unit const* player) const;
diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h
index d1d27a314d6..0a089a09b15 100644
--- a/src/server/game/Entities/Item/ItemTemplate.h
+++ b/src/server/game/Entities/Item/ItemTemplate.h
@@ -198,6 +198,13 @@ enum ItemFlagsExtra
ITEM_FLAGS_EXTRA_CAN_TRANSMOG = 0x00800000,
};
+enum ItemFlags3
+{
+ ITEM_FLAG3_IGNORE_ITEM_LEVEL_DELTAS = 0x080, // Ignore item level adjustments from PLAYER_FIELD_ITEM_LEVEL_DELTA
+ ITEM_FLAG3_IGNORE_PVP_ITEM_LEVEL_CAP = 0x100,
+ ITEM_FLAG3_HEIRLOOM_QUALITY = 0x200, // Item appears as having heirloom quality ingame regardless of its real quality (does not affect stat calculation)
+};
+
enum ItemFlagsCustom
{
ITEM_FLAGS_CU_DURATION_REAL_TIME = 0x0001, // Item duration will tick even if player is offline
@@ -223,6 +230,7 @@ enum CurrencyCategory
enum ItemVendorType
{
+ ITEM_VENDOR_TYPE_NONE = 0,
ITEM_VENDOR_TYPE_ITEM = 1,
ITEM_VENDOR_TYPE_CURRENCY = 2,
};
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 335df6505a6..761f5702441 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1058,8 +1058,7 @@ bool Object::RemoveGuidValue(uint16 index, ObjectGuid const& value)
ASSERT(index + 3 < m_valuesCount || PrintIndexError(index, true));
if (!value.IsEmpty() && *((ObjectGuid*)&(m_uint32Values[index])) == value)
{
- m_uint32Values[index] = 0;
- m_uint32Values[index + 1] = 0;
+ ((ObjectGuid*)&(m_uint32Values[index]))->Clear();
_changesMask.SetBit(index);
_changesMask.SetBit(index + 1);
_changesMask.SetBit(index + 2);
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 429af16f132..a59866c402f 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -26,6 +26,7 @@
#include "Formulas.h"
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
#include "CreatureAI.h"
#include "Unit.h"
#include "Util.h"
@@ -408,7 +409,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
RemoveAllAuras();
_SaveSpells(trans);
- _SaveSpellCooldowns(trans);
+ GetSpellHistory()->SaveToDB<Pet>(trans);
CharacterDatabase.CommitTransaction(trans);
// current/stable/not_in_slot
@@ -511,6 +512,10 @@ void Pet::DeleteFromDB(uint32 guidlow)
stmt->setUInt32(0, guidlow);
trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_CHARGES);
+ stmt->setUInt32(0, guidlow);
+ trans->Append(stmt);
+
CharacterDatabase.CommitTransaction(trans);
}
@@ -1072,77 +1077,15 @@ uint32 Pet::GetCurrentFoodBenefitLevel(uint32 itemlevel) const
void Pet::_LoadSpellCooldowns()
{
- m_CreatureSpellCooldowns.clear();
- m_CreatureCategoryCooldowns.clear();
-
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_COOLDOWN);
stmt->setUInt32(0, m_charmInfo->GetPetNumber());
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (result)
- {
- time_t curTime = time(NULL);
-
- PacketCooldowns cooldowns;
- WorldPacket data;
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 spell_id = fields[0].GetUInt32();
- time_t db_time = time_t(fields[1].GetUInt32());
-
- if (!sSpellMgr->GetSpellInfo(spell_id))
- {
- TC_LOG_ERROR("entities.pet", "Pet %u have unknown spell %u in `pet_spell_cooldown`, skipping.", m_charmInfo->GetPetNumber(), spell_id);
- continue;
- }
-
- // skip outdated cooldown
- if (db_time <= curTime)
- continue;
-
- cooldowns[spell_id] = uint32(db_time - curTime)*IN_MILLISECONDS;
-
- _AddCreatureSpellCooldown(spell_id, db_time);
-
- TC_LOG_DEBUG("entities.pet", "Pet (Number: %u) spell %u cooldown loaded (%u secs).", m_charmInfo->GetPetNumber(), spell_id, uint32(db_time-curTime));
- }
- while (result->NextRow());
-
- if (!cooldowns.empty())
- {
- BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, cooldowns);
- GetOwner()->GetSession()->SendPacket(&data);
- }
- }
-}
+ PreparedQueryResult cooldownsResult = CharacterDatabase.Query(stmt);
-void Pet::_SaveSpellCooldowns(SQLTransaction& trans)
-{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_COOLDOWNS);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_CHARGES);
stmt->setUInt32(0, m_charmInfo->GetPetNumber());
- trans->Append(stmt);
-
- time_t curTime = time(NULL);
+ PreparedQueryResult chargesResult = CharacterDatabase.Query(stmt);
- // remove oudated and save active
- for (CreatureSpellCooldowns::iterator itr = m_CreatureSpellCooldowns.begin(); itr != m_CreatureSpellCooldowns.end();)
- {
- if (itr->second <= curTime)
- m_CreatureSpellCooldowns.erase(itr++);
- else
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_SPELL_COOLDOWN);
- stmt->setUInt32(0, m_charmInfo->GetPetNumber());
- stmt->setUInt32(1, itr->first);
- stmt->setUInt32(2, uint32(itr->second));
- trans->Append(stmt);
-
- ++itr;
- }
- }
+ GetSpellHistory()->LoadFromDB<Pet>(cooldownsResult, chargesResult);
}
void Pet::_LoadSpells()
@@ -1983,40 +1926,6 @@ void Pet::SynchronizeLevelWithOwner()
}
}
-void Pet::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
-{
- PacketCooldowns cooldowns;
- WorldPacket data;
- time_t curTime = time(NULL);
- for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
- {
- if (itr->second.state == PETSPELL_REMOVED)
- continue;
-
- uint32 unSpellId = itr->first;
- SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(unSpellId);
-
- // Not send cooldown for this spells
- if (spellInfo->IsCooldownStartedOnEvent())
- continue;
-
- if (spellInfo->PreventionType != SPELL_PREVENTION_TYPE_SILENCE)
- continue;
-
- if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs)
- {
- cooldowns[unSpellId] = unTimeMs;
- _AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs/IN_MILLISECONDS);
- }
- }
-
- if (!cooldowns.empty())
- {
- BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, cooldowns);
- GetOwner()->GetSession()->SendPacket(&data);
- }
-}
-
Player* Pet::GetOwner() const
{
return Minion::GetOwner()->ToPlayer();
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index e9ace117dde..eb8868bf175 100644
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -106,7 +106,6 @@ class Pet : public Guardian
bool IsPetAura(Aura const* aura);
void _LoadSpellCooldowns();
- void _SaveSpellCooldowns(SQLTransaction& trans);
void _LoadAuras(uint32 timediff);
void _SaveAuras(SQLTransaction& trans);
void _LoadSpells();
@@ -119,7 +118,6 @@ class Pet : public Guardian
bool unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
void CleanupActionBar();
- virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) override;
PetSpellMap m_spells;
AutoSpellList m_autospells;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 361c651e882..d5d550ba4b9 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -74,6 +74,7 @@
#include "Spell.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
+#include "SpellHistory.h"
#include "SpellMgr.h"
#include "SpellPackets.h"
#include "Transport.h"
@@ -3939,152 +3940,19 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
}
}
-void Player::RemoveSpellCooldown(uint32 spell_id, bool update /* = false */)
-{
- m_spellCooldowns.erase(spell_id);
-
- if (update)
- SendClearCooldown(spell_id, this);
-}
-
-// I am not sure which one is more efficient
-void Player::RemoveCategoryCooldown(uint32 cat)
-{
- SpellCategoryStore::const_iterator i_scstore = sSpellsByCategoryStore.find(cat);
- if (i_scstore != sSpellsByCategoryStore.end())
- for (SpellCategorySet::const_iterator i_scset = i_scstore->second.begin(); i_scset != i_scstore->second.end(); ++i_scset)
- RemoveSpellCooldown(*i_scset, true);
-}
-
-void Player::RemoveSpellCategoryCooldown(uint32 cat, bool update /* = false */)
-{
- SpellCategoryStore::const_iterator ct = sSpellsByCategoryStore.find(cat);
- if (ct == sSpellsByCategoryStore.end())
- return;
-
- const SpellCategorySet& ct_set = ct->second;
- for (SpellCooldowns::const_iterator i = m_spellCooldowns.begin(); i != m_spellCooldowns.end();)
- {
- if (ct_set.find(i->first) != ct_set.end())
- RemoveSpellCooldown((i++)->first, update);
- else
- ++i;
- }
-}
-
void Player::RemoveArenaSpellCooldowns(bool removeActivePetCooldowns)
{
// remove cooldowns on spells that have < 10 min CD
-
- SpellCooldowns::iterator itr, next;
- for (itr = m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); itr = next)
+ GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr)
{
- next = itr;
- ++next;
- SpellInfo const* entry = sSpellMgr->GetSpellInfo(itr->first);
- // check if spellentry is present and if the cooldown is less than 10 min
- if (entry &&
- entry->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS &&
- entry->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS)
- {
- // remove & notify
- RemoveSpellCooldown(itr->first, true);
- }
- }
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
+ return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS;
+ }, true);
// pet cooldowns
if (removeActivePetCooldowns)
if (Pet* pet = GetPet())
- {
- // notify player
- for (CreatureSpellCooldowns::const_iterator itr2 = pet->m_CreatureSpellCooldowns.begin(); itr2 != pet->m_CreatureSpellCooldowns.end(); ++itr2)
- SendClearCooldown(itr2->first, pet);
-
- // actually clear cooldowns
- pet->m_CreatureSpellCooldowns.clear();
- }
-}
-
-void Player::RemoveAllSpellCooldown()
-{
- if (!m_spellCooldowns.empty())
- {
- SendClearAllCooldowns(this);
- m_spellCooldowns.clear();
- }
-}
-
-void Player::_LoadSpellCooldowns(PreparedQueryResult result)
-{
- // some cooldowns can be already set at aura loading...
-
- //QueryResult* result = CharacterDatabase.PQuery("SELECT spell, item, time FROM character_spell_cooldown WHERE guid = '%u'", GetGUIDLow());
-
- if (result)
- {
- time_t curTime = time(NULL);
-
- do
- {
- Field* fields = result->Fetch();
- uint32 spell_id = fields[0].GetUInt32();
- uint32 item_id = fields[1].GetUInt32();
- time_t db_time = time_t(fields[2].GetUInt32());
-
- if (!sSpellMgr->GetSpellInfo(spell_id))
- {
- TC_LOG_ERROR("entities.player.loading", "%s has unknown spell %u in `character_spell_cooldown`, skipping.", GetGUID().ToString().c_str(), spell_id);
- continue;
- }
-
- // skip outdated cooldown
- if (db_time <= curTime)
- continue;
-
- AddSpellCooldown(spell_id, item_id, db_time);
-
- TC_LOG_DEBUG("entities.player.loading", "Player (%s) spell %u, item %u cooldown loaded (%u secs).", GetGUID().ToString().c_str(), spell_id, item_id, uint32(db_time - curTime));
- }
- while (result->NextRow());
- }
-}
-
-void Player::_SaveSpellCooldowns(SQLTransaction& trans)
-{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_COOLDOWN);
- stmt->setUInt64(0, GetGUID().GetCounter());
- trans->Append(stmt);
-
- time_t curTime = time(NULL);
- time_t infTime = curTime + infinityCooldownDelayCheck;
-
- bool first_round = true;
- std::ostringstream ss;
-
- // remove outdated and save active
- for (SpellCooldowns::iterator itr = m_spellCooldowns.begin(); itr != m_spellCooldowns.end();)
- {
- if (itr->second.end <= curTime)
- m_spellCooldowns.erase(itr++);
- else if (itr->second.end <= infTime) // not save locked cooldowns, it will be reset or set at reload
- {
- if (first_round)
- {
- ss << "INSERT INTO character_spell_cooldown (guid, spell, item, time) VALUES ";
- first_round = false;
- }
- // next new/changed record prefix
- else
- ss << ',';
- ss << '(' << GetGUID().GetCounter() << ',' << itr->first << ',' << itr->second.itemid << ',' << uint64(itr->second.end) << ')';
- ++itr;
- }
- else
- ++itr;
- }
- // if something changed execute
- if (!first_round)
- trans->Append(ss.str().c_str());
+ pet->GetSpellHistory()->ResetAllCooldowns();
}
uint32 Player::GetNextResetTalentsCost() const
@@ -4389,7 +4257,7 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
RemoveFromGroup(group, playerguid);
// Remove signs from petitions (also remove petitions if owner);
- RemovePetitionsAndSigns(playerguid, 10);
+ RemovePetitionsAndSigns(playerguid);
switch (charDeleteMethod)
{
@@ -4578,7 +4446,11 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
stmt->setUInt64(0, guid);
trans->Append(stmt);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_COOLDOWN);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_COOLDOWNS);
+ stmt->setUInt64(0, guid);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_CHARGES);
stmt->setUInt64(0, guid);
trans->Append(stmt);
@@ -7287,7 +7159,7 @@ void Player::SetInGuild(ObjectGuid::LowType guildId)
else
SetGuidValue(OBJECT_FIELD_DATA, ObjectGuid::Empty);
- ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_GUILD_LEVEL_ENABLED, guildId != 0 && sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED));
+ ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_GUILD_LEVEL_ENABLED, guildId != 0);
SetUInt16Value(OBJECT_FIELD_TYPE, 1, guildId != 0);
}
@@ -11800,11 +11672,13 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update)
{
m_weaponChangeTimer = spellProto->StartRecoveryTime;
- GetGlobalCooldownMgr().AddGlobalCooldown(spellProto, m_weaponChangeTimer);
+ GetSpellHistory()->AddGlobalCooldown(spellProto, m_weaponChangeTimer);
- WorldPacket data;
- BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, cooldownSpell, 0);
- GetSession()->SendPacket(&data);
+ WorldPackets::Spells::SpellCooldown spellCooldown;
+ spellCooldown.Caster = GetGUID();
+ spellCooldown.Flags = SPELL_COOLDOWN_FLAG_INCLUDE_GCD;
+ spellCooldown.SpellCooldowns.emplace_back(cooldownSpell, 0);
+ GetSession()->SendPacket(spellCooldown.Write());
}
}
}
@@ -12997,12 +12871,11 @@ void Player::SendEquipError(InventoryResult msg, Item* item1 /*= nullptr*/, Item
void Player::SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 /*param*/)
{
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_BUY_FAILED");
- WorldPacket data(SMSG_BUY_FAILED, (8+4+4+1));
- data << (creature ? creature->GetGUID() : ObjectGuid::Empty);
- data << uint32(item);
- data << uint8(msg);
- GetSession()->SendPacket(&data);
+ WorldPackets::Item::BuyFailed packet;
+ packet.VendorGUID = creature ? creature->GetGUID() : ObjectGuid::Empty;
+ packet.Muid = item;
+ packet.Reason = msg;
+ GetSession()->SendPacket(packet.Write());
}
void Player::SendSellError(SellResult msg, Creature* creature, ObjectGuid guid)
@@ -14749,9 +14622,6 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
else
moneyRew = int32(quest->GetRewMoneyMaxLevel() * sWorld->getRate(RATE_DROP_MONEY));
- if (Guild* guild = sGuildMgr->GetGuildById(GetGuildId()))
- guild->GiveXP(uint32(quest->XPValue(getLevel()) * sWorld->getRate(RATE_XP_QUEST) * sWorld->getRate(RATE_XP_GUILD_MODIFIER)), this);
-
moneyRew += quest->GetRewMoney();
if (moneyRew)
@@ -17207,7 +17077,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
// has to be called after last Relocate() in Player::LoadFromDB
SetFallInformation(0, GetPositionZ());
- _LoadSpellCooldowns(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS));
+ GetSpellHistory()->LoadFromDB<Player>(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELL_CHARGES));
// Spell code allow apply any auras to dead character in load time in aura/spell/item loading
// Do now before stats re-calculation cleanup for ghost state unexpected auras
@@ -19095,7 +18965,7 @@ void Player::SaveToDB(bool create /*=false*/)
_SaveMonthlyQuestStatus(trans);
_SaveTalents(trans);
_SaveSpells(trans);
- _SaveSpellCooldowns(trans);
+ GetSpellHistory()->SaveToDB<Player>(trans);
_SaveActions(trans);
_SaveAuras(trans);
_SaveSkills(trans);
@@ -20394,41 +20264,8 @@ void Player::PetSpellInitialize()
data.put<uint8>(spellsCountPos, addlist);
- uint8 cooldownsCount = pet->m_CreatureSpellCooldowns.size() + pet->m_CreatureCategoryCooldowns.size();
- data << uint8(cooldownsCount);
-
- time_t curTime = time(NULL);
-
- for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr)
- {
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
- if (!spellInfo)
- {
- data << uint32(0);
- data << uint16(0);
- data << uint32(0);
- data << uint32(0);
- continue;
- }
-
- time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0;
- data << uint32(itr->first); // spell ID
-
- CreatureSpellCooldowns::const_iterator categoryitr = pet->m_CreatureCategoryCooldowns.find(spellInfo->GetCategory());
- if (categoryitr != pet->m_CreatureCategoryCooldowns.end())
- {
- time_t categoryCooldown = (categoryitr->second > curTime) ? (categoryitr->second - curTime) * IN_MILLISECONDS : 0;
- data << uint16(spellInfo->GetCategory()); // spell category
- data << uint32(cooldown); // spell cooldown
- data << uint32(categoryCooldown); // category cooldown
- }
- else
- {
- data << uint16(0);
- data << uint32(cooldown);
- data << uint32(0);
- }
- }
+ // Cooldowns
+ //pet->GetSpellHistory()->WritePacket(&petSpells);
GetSession()->SendPacket(&data);
}
@@ -20456,7 +20293,9 @@ void Player::PossessSpellInitialize()
charmInfo->BuildActionBar(&data);
data << uint8(0); // spells count
- data << uint8(0); // cooldowns count
+
+ // Cooldowns
+ //charm->GetSpellHistory()->WritePacket(&petSpells);
GetSession()->SendPacket(&data);
}
@@ -20467,7 +20306,7 @@ void Player::VehicleSpellInitialize()
if (!vehicle)
return;
- uint8 cooldownCount = vehicle->m_CreatureSpellCooldowns.size();
+ uint8 cooldownCount = 0;
WorldPacket data(SMSG_PET_SPELLS, 8 + 2 + 4 + 4 + 4 * 10 + 1 + 1 + cooldownCount * (4 + 2 + 4 + 4));
data << vehicle->GetGUID(); // Guid
@@ -20508,41 +20347,7 @@ void Player::VehicleSpellInitialize()
data << uint8(0); // Auras?
// Cooldowns
- data << uint8(cooldownCount);
-
- time_t now = sWorld->GetGameTime();
-
- for (CreatureSpellCooldowns::const_iterator itr = vehicle->m_CreatureSpellCooldowns.begin(); itr != vehicle->m_CreatureSpellCooldowns.end(); ++itr)
- {
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
- if (!spellInfo)
- {
- data << uint32(0);
- data << uint16(0);
- data << uint32(0);
- data << uint32(0);
- continue;
- }
-
- time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0;
- data << uint32(itr->first); // spell ID
-
- CreatureSpellCooldowns::const_iterator categoryitr = vehicle->m_CreatureCategoryCooldowns.find(spellInfo->GetCategory());
- if (categoryitr != vehicle->m_CreatureCategoryCooldowns.end())
- {
- time_t categoryCooldown = (categoryitr->second > now) ? (categoryitr->second - now) * IN_MILLISECONDS : 0;
- data << uint16(spellInfo->GetCategory()); // spell category
- data << uint32(cooldown); // spell cooldown
- data << uint32(categoryCooldown); // category cooldown
- }
- else
- {
- data << uint16(0);
- data << uint32(cooldown);
- data << uint32(0);
- }
- }
-
+ //vehicle->GetSpellHistory()->WritePacket(&petSpells);
GetSession()->SendPacket(&data);
}
@@ -20595,7 +20400,8 @@ void Player::CharmSpellInitialize()
}
}
- data << uint8(0); // cooldowns count
+ // Cooldowns
+ //charm->GetSpellHistory()->WritePacket(&petSpells);
GetSession()->SendPacket(&data);
}
@@ -20816,18 +20622,9 @@ void Player::SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
SendDirectMessage(packet.Write());
}
-void Player::RemovePetitionsAndSigns(ObjectGuid guid, uint32 type)
+void Player::RemovePetitionsAndSigns(ObjectGuid guid)
{
- PreparedStatement* stmt;
-
- if (type == 10)
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_GUID);
- else
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_GUID_TYPE);
- stmt->setUInt8(1, uint8(type));
- }
-
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_GUID);
stmt->setUInt64(0, guid.GetCounter());
PreparedQueryResult result = CharacterDatabase.Query(stmt);
@@ -20845,48 +20642,23 @@ void Player::RemovePetitionsAndSigns(ObjectGuid guid, uint32 type)
owner->GetSession()->SendPetitionQueryOpcode(petitionguid);
} while (result->NextRow());
- if (type == 10)
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ALL_PETITION_SIGNATURES);
-
- stmt->setUInt64(0, guid.GetCounter());
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ALL_PETITION_SIGNATURES);
- CharacterDatabase.Execute(stmt);
- }
- else
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE);
-
- stmt->setUInt64(0, guid.GetCounter());
- stmt->setUInt8(1, uint8(type));
+ stmt->setUInt64(0, guid.GetCounter());
- CharacterDatabase.Execute(stmt);
- }
+ CharacterDatabase.Execute(stmt);
}
SQLTransaction trans = CharacterDatabase.BeginTransaction();
- if (type == 10)
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_OWNER);
- stmt->setUInt64(0, guid.GetCounter());
- trans->Append(stmt);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER);
- stmt->setUInt64(0, guid.GetCounter());
- trans->Append(stmt);
- }
- else
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE);
- stmt->setUInt64(0, guid.GetCounter());
- stmt->setUInt8(1, uint8(type));
- trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_OWNER);
+ stmt->setUInt64(0, guid.GetCounter());
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER);
+ stmt->setUInt64(0, guid.GetCounter());
+ trans->Append(stmt);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE);
- stmt->setUInt64(0, guid.GetCounter());
- stmt->setUInt8(1, uint8(type));
- trans->Append(stmt);
- }
CharacterDatabase.CommitTransaction(trans);
}
@@ -21210,39 +20982,6 @@ void Player::ContinueTaxiFlight()
GetSession()->SendDoFlight(mountDisplayId, path, startNode);
}
-void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
-{
- PacketCooldowns cooldowns;
- WorldPacket data;
- time_t curTime = time(NULL);
- for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
- {
- if (itr->second->state == PLAYERSPELL_REMOVED)
- continue;
- uint32 unSpellId = itr->first;
- SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(unSpellId);
-
- // Not send cooldown for this spells
- if (spellInfo->IsCooldownStartedOnEvent())
- continue;
-
- if (spellInfo->PreventionType != SPELL_PREVENTION_TYPE_SILENCE)
- continue;
-
- if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetSpellCooldownDelay(unSpellId) < unTimeMs)
- {
- cooldowns[unSpellId] = unTimeMs;
- AddSpellCooldown(unSpellId, 0, curTime + unTimeMs/IN_MILLISECONDS);
- }
- }
-
- if (!cooldowns.empty())
- {
- BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, cooldowns);
- GetSession()->SendPacket(&data);
- }
-}
-
void Player::InitDataForForm(bool reapplyMods)
{
ShapeshiftForm form = GetShapeshiftForm();
@@ -21358,12 +21097,13 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
{
uint32 new_count = pVendor->UpdateVendorItemCurrentCount(crItem, count);
- WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
- data << pVendor->GetGUID();
- data << uint32(vendorslot + 1); // numbered from 1 at client
- data << int32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
- data << uint32(count);
- GetSession()->SendPacket(&data);
+ WorldPackets::Item::BuySucceeded packet;
+ packet.VendorGUID = pVendor->GetGUID();
+ packet.Muid = vendorslot + 1;
+ packet.NewQuantity = crItem->maxcount > 0 ? new_count : 0xFFFFFFFF;
+ packet.QuantityBought = count;
+ GetSession()->SendPacket(packet.Write());
+
SendNewItem(it, count, true, false, false);
if (!bStore)
@@ -21866,228 +21606,6 @@ void Player::UpdatePvP(bool state, bool override)
}
}
-bool Player::HasSpellCooldown(uint32 spell_id) const
-{
- SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id);
- return itr != m_spellCooldowns.end() && itr->second.end > time(NULL);
-}
-
-uint32 Player::GetSpellCooldownDelay(uint32 spell_id) const
-{
- SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id);
- time_t t = time(NULL);
- return uint32(itr != m_spellCooldowns.end() && itr->second.end > t ? itr->second.end - t : 0);
-}
-
-void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 itemId, Spell* spell, bool infinityCooldown)
-{
- // init cooldown values
- uint32 cat = 0;
- int32 rec = -1;
- int32 catrec = -1;
-
- // some special item spells without correct cooldown in SpellInfo
- // cooldown information stored in item prototype
- // This used in same way in WorldSession::HandleItemQuerySingleOpcode data sending to client.
-
- if (itemId)
- {
- if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId))
- {
- for (uint8 idx = 0; idx < proto->Effects.size(); ++idx)
- {
- if (uint32(proto->Effects[idx].SpellID) == spellInfo->Id)
- {
- cat = proto->Effects[idx].Category;
- rec = proto->Effects[idx].Cooldown;
- catrec = proto->Effects[idx].CategoryCooldown;
- break;
- }
- }
- }
- }
-
- // if no cooldown found above then base at DBC data
- if (rec < 0 && catrec < 0)
- {
- cat = spellInfo->GetCategory();
- rec = spellInfo->RecoveryTime;
- catrec = spellInfo->CategoryRecoveryTime;
- }
-
- time_t curTime = time(NULL);
-
- time_t catrecTime;
- time_t recTime;
-
- bool needsCooldownPacket = false;
-
- // overwrite time for selected category
- if (infinityCooldown)
- {
- // use +MONTH as infinity mark for spell cooldown (will checked as MONTH/2 at save ans skipped)
- // but not allow ignore until reset or re-login
- catrecTime = catrec > 0 ? curTime+infinityCooldownDelay : 0;
- recTime = rec > 0 ? curTime+infinityCooldownDelay : catrecTime;
- }
- else
- {
- // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
- // prevent 0 cooldowns set by another way
- if (rec <= 0 && catrec <= 0 && (cat == 76 || (spellInfo->IsAutoRepeatRangedSpell() && spellInfo->Id != 75)))
- rec = GetAttackTime(RANGED_ATTACK);
-
- // Now we have cooldown data (if found any), time to apply mods
- if (rec > 0)
- ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, rec, spell);
-
- if (catrec > 0 && !spellInfo->HasAttribute(SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS))
- ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell);
-
- if (int32 cooldownMod = GetTotalAuraModifier(SPELL_AURA_MOD_COOLDOWN))
- {
- // Apply SPELL_AURA_MOD_COOLDOWN only to own spells
- if (HasSpell(spellInfo->Id))
- {
- needsCooldownPacket = true;
- rec += cooldownMod * IN_MILLISECONDS; // SPELL_AURA_MOD_COOLDOWN does not affect category cooldows, verified with shaman shocks
- }
- }
-
- // Apply SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN modifiers
- // Note: This aura applies its modifiers to all cooldowns of spells with set category, not to category cooldown only
- if (cat)
- {
- if (int32 categoryModifier = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN, cat))
- {
- if (rec > 0)
- rec += categoryModifier;
-
- if (catrec > 0)
- catrec += categoryModifier;
- }
-
- SpellCategoryEntry const* categoryEntry = sSpellCategoryStore.LookupEntry(cat);
- ASSERT(categoryEntry);
- if (categoryEntry->Flags & SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_MIDNIGHT)
- {
- tm date;
- localtime_r(&curTime, &date);
- catrec = catrec * DAY - (date.tm_hour * HOUR + date.tm_min * MINUTE + date.tm_sec) * IN_MILLISECONDS;
- }
- }
-
- // replace negative cooldowns by 0
- if (rec < 0)
- rec = 0;
-
- if (catrec < 0)
- catrec = 0;
-
- // no cooldown after applying spell mods
- if (rec == 0 && catrec == 0)
- return;
-
- catrecTime = catrec ? curTime+catrec/IN_MILLISECONDS : 0;
- recTime = rec ? curTime+rec/IN_MILLISECONDS : catrecTime;
- }
-
- // self spell cooldown
- if (recTime > 0)
- {
- AddSpellCooldown(spellInfo->Id, itemId, recTime);
-
- if (needsCooldownPacket)
- {
- WorldPacket data;
- BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, spellInfo->Id, rec);
- SendDirectMessage(&data);
- }
- }
-
- // category spells
- if (cat && catrec > 0)
- {
- SpellCategoryStore::const_iterator i_scstore = sSpellsByCategoryStore.find(cat);
- if (i_scstore != sSpellsByCategoryStore.end())
- {
- for (SpellCategorySet::const_iterator i_scset = i_scstore->second.begin(); i_scset != i_scstore->second.end(); ++i_scset)
- {
- if (*i_scset == spellInfo->Id) // skip main spell, already handled above
- continue;
-
- AddSpellCooldown(*i_scset, itemId, catrecTime);
- }
- }
- }
-}
-
-void Player::AddSpellCooldown(uint32 spellid, uint32 itemid, time_t end_time)
-{
- SpellCooldown sc;
- sc.end = end_time;
- sc.itemid = itemid;
- m_spellCooldowns[spellid] = sc;
-}
-
-void Player::ModifySpellCooldown(uint32 spellId, int32 cooldown)
-{
- SpellCooldowns::iterator itr = m_spellCooldowns.find(spellId);
- if (itr == m_spellCooldowns.end())
- return;
-
- time_t now = time(NULL);
- if (itr->second.end + (cooldown / IN_MILLISECONDS) > now)
- itr->second.end += (cooldown / IN_MILLISECONDS);
- else
- m_spellCooldowns.erase(itr);
-
- WorldPacket data(SMSG_MODIFY_COOLDOWN, 4 + 8 + 4);
- data << uint32(spellId); // Spell ID
- data << GetGUID(); // Player GUID
- data << int32(cooldown); // Cooldown mod in milliseconds
- GetSession()->SendPacket(&data);
-
- TC_LOG_DEBUG("misc", "ModifySpellCooldown:: Player: %s (%s) Spell: %u cooldown: %u", GetName().c_str(), GetGUID().ToString().c_str(), spellId, GetSpellCooldownDelay(spellId));
-}
-
-void Player::SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId /*= 0*/, Spell* spell /*= NULL*/, bool setCooldown /*= true*/)
-{
- // start cooldowns at server side, if any
- if (setCooldown)
- AddSpellAndCategoryCooldowns(spellInfo, itemId, spell);
-
- // Send activate cooldown timer (possible 0) at client side
- WorldPackets::Spells::CooldownEvent packet(GetGUID(), spellInfo->Id);
- SendDirectMessage(packet.Write());
-
- uint32 cat = spellInfo->GetCategory();
- if (cat && spellInfo->CategoryRecoveryTime)
- {
- SpellCategoryStore::const_iterator ct = sSpellsByCategoryStore.find(cat);
- if (ct != sSpellsByCategoryStore.end())
- {
- SpellCategorySet const& catSet = ct->second;
- for (SpellCooldowns::const_iterator i = m_spellCooldowns.begin(); i != m_spellCooldowns.end(); ++i)
- {
- if (i->first == spellInfo->Id) // skip main spell, already handled above
- continue;
-
- SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(i->first);
- if (!spellInfo2 || !spellInfo2->IsCooldownStartedOnEvent())
- continue;
-
- if (catSet.find(i->first) != catSet.end())
- {
- // Send activate cooldown timer (possible 0) at client side
- WorldPackets::Spells::CooldownEvent packet(GetGUID(), i->first);
- SendDirectMessage(packet.Write());
- }
- }
- }
- }
-}
-
void Player::UpdatePotionCooldown(Spell* spell)
{
// no potion used i combat or still in combat
@@ -22102,11 +21620,11 @@ void Player::UpdatePotionCooldown(Spell* spell)
for (uint8 idx = 0; idx < proto->Effects.size(); ++idx)
if (proto->Effects[idx].Trigger == ITEM_SPELLTRIGGER_ON_USE)
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(proto->Effects[idx].SpellID))
- SendCooldownEvent(spellInfo, m_lastPotionId);
+ GetSpellHistory()->SendCooldownEvent(spellInfo, m_lastPotionId);
}
// from spell cases (m_lastPotionId set in Spell::SendSpellCooldown)
else
- SendCooldownEvent(spell->m_spellInfo, m_lastPotionId, spell);
+ GetSpellHistory()->SendCooldownEvent(spell->m_spellInfo, m_lastPotionId, spell);
m_lastPotionId = 0;
}
@@ -22860,8 +22378,15 @@ void Player::SendInitialPacketsBeforeAddToMap()
/// SMSG_SEND_UNLEARN_SPELLS
SendDirectMessage(WorldPackets::Spells::SendUnlearnSpells().Write());
- /// @todo: SMSG_SEND_SPELL_HISTORY
- /// @todo: SMSG_SEND_SPELL_CHARGES
+ /// SMSG_SEND_SPELL_HISTORY
+ WorldPackets::Spells::SendSpellHistory sendSpellHistory;
+ GetSpellHistory()->WritePacket(&sendSpellHistory);
+ SendDirectMessage(sendSpellHistory.Write());
+
+ /// SMSG_SEND_SPELL_CHARGES
+ WorldPackets::Spells::SendSpellCharges sendSpellCharges;
+ GetSpellHistory()->WritePacket(&sendSpellCharges);
+ SendDirectMessage(sendSpellCharges.Write());
/// SMSG_ACTION_BUTTONS
SendInitialActionButtons();
@@ -23029,7 +22554,7 @@ void Player::ApplyEquipCooldown(Item* pItem)
if (itr != m_spellCooldowns.end() && itr->second.itemid == pItem->GetEntry() && itr->second.end > time(NULL) + 30)
continue;
- AddSpellCooldown(effectData.SpellID, pItem->GetEntry(), time(NULL) + 30);
+ GetSpellHistory()->AddCooldown(effectData.SpellID, pItem->GetEntry(), std::chrono::seconds(30));
WorldPacket data(SMSG_ITEM_COOLDOWN, 12);
data << pItem->GetGUID();
@@ -23980,7 +23505,7 @@ uint32 Player::GetResurrectionSpellId()
}
// Reincarnation (passive spell) // prio: 1 // Glyph of Renewed Life
- if (prio < 1 && HasSpell(20608) && !HasSpellCooldown(21169) && (HasAura(58059) || HasItemCount(17030)))
+ if (prio < 1 && HasSpell(20608) && !GetSpellHistory()->HasCooldown(21169) && (HasAura(58059) || HasItemCount(17030)))
spell_id = 21169;
return spell_id;
@@ -25752,47 +25277,6 @@ void Player::RemoveAtLoginFlag(AtLoginFlags flags, bool persist /*= false*/)
}
}
-void Player::SendClearCooldown(uint32 spell_id, Unit* target)
-{
- WorldPacket data(SMSG_CLEAR_COOLDOWN, 4+8);
- data << uint32(spell_id);
- data << target->GetGUID();
- SendDirectMessage(&data);
-}
-
-void Player::SendClearAllCooldowns(Unit* target)
-{
- uint32 spellCount = m_spellCooldowns.size();
- ObjectGuid guid = target ? target->GetGUID() : ObjectGuid::Empty;
-
- WorldPacket data(SMSG_CLEAR_COOLDOWNS, 4+8);
- data.WriteBit(guid[1]);
- data.WriteBit(guid[3]);
- data.WriteBit(guid[6]);
- data.WriteBits(spellCount, 24); // Spell Count
- data.WriteBit(guid[7]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[2]);
- data.WriteBit(guid[4]);
- data.WriteBit(guid[0]);
-
- data.FlushBits();
-
- data.WriteByteSeq(guid[7]);
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[5]);
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[3]);
- for (SpellCooldowns::const_iterator itr = m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr)
- data << uint32(itr->first); // Spell ID
-
- data.WriteByteSeq(guid[0]);
- data.WriteByteSeq(guid[6]);
-
- SendDirectMessage(&data);
-}
-
void Player::ResetMap()
{
// this may be called during Map::Update
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 275a985585a..b981b316d0c 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -975,6 +975,7 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST,
PLAYER_LOGIN_QUERY_LOAD_HOME_BIND,
PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS,
+ PLAYER_LOGIN_QUERY_LOAD_SPELL_CHARGES,
PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES,
PLAYER_LOGIN_QUERY_LOAD_GUILD,
PLAYER_LOGIN_QUERY_LOAD_ARENA_INFO,
@@ -1948,27 +1949,7 @@ class Player : public Unit, public GridObject<Player>
void DropModCharge(SpellModifier* mod, Spell* spell);
void SetSpellModTakingSpell(Spell* spell, bool apply);
- static uint32 const infinityCooldownDelay = MONTH; // used for set "infinity cooldowns" for spells and check
- static uint32 const infinityCooldownDelayCheck = MONTH/2;
- bool HasSpellCooldown(uint32 spell_id) const;
- uint32 GetSpellCooldownDelay(uint32 spell_id) const;
- void AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = NULL, bool infinityCooldown = false);
- void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time);
- void ModifySpellCooldown(uint32 spellId, int32 cooldown);
- void SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId = 0, Spell* spell = NULL, bool setCooldown = true);
- void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) override;
- void RemoveSpellCooldown(uint32 spell_id, bool update = false);
- void RemoveSpellCategoryCooldown(uint32 cat, bool update = false);
- void SendClearCooldown(uint32 spell_id, Unit* target);
- void SendClearAllCooldowns(Unit* target);
-
- GlobalCooldownMgr& GetGlobalCooldownMgr() { return m_GlobalCooldownMgr; }
-
- void RemoveCategoryCooldown(uint32 cat);
void RemoveArenaSpellCooldowns(bool removeActivePetCooldowns = false);
- void RemoveAllSpellCooldown();
- void _LoadSpellCooldowns(PreparedQueryResult result);
- void _SaveSpellCooldowns(SQLTransaction& trans);
uint32 GetLastPotionId() { return m_lastPotionId; }
void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; }
void UpdatePotionCooldown(Spell* spell = NULL);
@@ -2045,7 +2026,7 @@ class Player : public Unit, public GridObject<Player>
static ObjectGuid::LowType GetGuildIdFromDB(ObjectGuid guid);
static uint8 GetRankFromDB(ObjectGuid guid);
ObjectGuid::LowType GetGuildIdInvited() { return m_GuildIdInvited; }
- static void RemovePetitionsAndSigns(ObjectGuid guid, uint32 type);
+ static void RemovePetitionsAndSigns(ObjectGuid guid);
// Arena Team
void SetInArenaTeam(uint32 ArenaTeamId, uint8 slot, uint8 type);
@@ -2844,8 +2825,6 @@ class Player : public Unit, public GridObject<Player>
std::unordered_map<uint32 /*overridenSpellId*/, std::unordered_set<uint32> /*newSpellId*/> m_overrideSpells;
uint32 m_lastPotionId; // last used health/mana potion in combat, that block next potion use
- GlobalCooldownMgr m_GlobalCooldownMgr;
-
PlayerTalentInfo* _talentMgr;
ActionButtonList m_actionButtons;
diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp
index 1a7a7fbb00a..724c1a3c3d9 100644
--- a/src/server/game/Entities/Totem/Totem.cpp
+++ b/src/server/game/Entities/Totem/Totem.cpp
@@ -22,6 +22,7 @@
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "Player.h"
+#include "SpellHistory.h"
#include "SpellMgr.h"
#include "SpellInfo.h"
#include "WorldPacket.h"
@@ -124,7 +125,7 @@ void Totem::UnSummon(uint32 msTime)
owner->SendAutoRepeatCancel(this);
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(GetUInt32Value(UNIT_CREATED_BY_SPELL)))
- owner->SendCooldownEvent(spell, 0, NULL, false);
+ GetSpellHistory()->SendCooldownEvent(spell, 0, nullptr, false);
if (Group* group = owner->GetGroup())
{
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 55cd53e523e..057b3b984ef 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -51,6 +51,7 @@
#include "SpellAuras.h"
#include "Spell.h"
#include "SpellInfo.h"
+#include "SpellHistory.h"
#include "SpellMgr.h"
#include "TemporarySummon.h"
#include "Totem.h"
@@ -193,7 +194,7 @@ Unit::Unit(bool isWorldObject) :
i_AI(NULL), i_disabledAI(NULL), m_AutoRepeatFirstCast(false), m_procDeep(0),
m_removedAurasCount(0), i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_ThreatManager(this),
m_vehicle(NULL), m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE),
- m_HostileRefManager(this), _lastDamagedTime(0)
+ m_HostileRefManager(this), _lastDamagedTime(0), _spellHistory(new SpellHistory(this))
{
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
@@ -290,24 +291,6 @@ Unit::Unit(bool isWorldObject) :
}
////////////////////////////////////////////////////////////
-// Methods of class GlobalCooldownMgr
-bool GlobalCooldownMgr::HasGlobalCooldown(SpellInfo const* spellInfo) const
-{
- GlobalCooldownList::const_iterator itr = m_GlobalCooldowns.find(spellInfo->StartRecoveryCategory);
- return itr != m_GlobalCooldowns.end() && itr->second.duration && getMSTimeDiff(itr->second.cast_time, getMSTime()) < itr->second.duration;
-}
-
-void GlobalCooldownMgr::AddGlobalCooldown(SpellInfo const* spellInfo, uint32 gcd)
-{
- m_GlobalCooldowns[spellInfo->StartRecoveryCategory] = GlobalCooldown(gcd, getMSTime());
-}
-
-void GlobalCooldownMgr::CancelGlobalCooldown(SpellInfo const* spellInfo)
-{
- m_GlobalCooldowns[spellInfo->StartRecoveryCategory].duration = 0;
-}
-
-////////////////////////////////////////////////////////////
// Methods of class Unit
Unit::~Unit()
{
@@ -324,6 +307,7 @@ Unit::~Unit()
delete i_motionMaster;
delete m_charmInfo;
delete movespline;
+ delete _spellHistory;
ASSERT(!m_duringRemoveFromWorld);
ASSERT(!m_attacking);
@@ -2124,21 +2108,11 @@ void Unit::SendMeleeAttackStart(Unit* victim)
packet.Attacker = GetGUID();
packet.Victim = victim->GetGUID();
SendMessageToSet(packet.Write(), true);
- TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTART");
}
void Unit::SendMeleeAttackStop(Unit* victim)
{
- WorldPackets::Combat::SAttackStop packet;
- packet.Attacker = GetGUID();
- if (victim)
- {
- packet.Victim = victim->GetGUID();
- packet.Dead = victim->isDead();
- }
-
- SendMessageToSet(packet.Write(), true);
- TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTOP");
+ SendMessageToSet(WorldPackets::Combat::SAttackStop(this, victim).Write(), true);
if (victim)
TC_LOG_INFO("entities.unit", "%s stopped attacking %s", GetGUID().ToString().c_str(), victim->GetGUID().ToString().c_str());
@@ -2709,6 +2683,8 @@ void Unit::_UpdateSpells(uint32 time)
++itr;
}
}
+
+ _spellHistory->Update();
}
void Unit::_UpdateAutoRepeatSpell()
@@ -4648,13 +4624,13 @@ void Unit::AddGameObject(GameObject* gameObj)
m_gameObj.push_back(gameObj);
gameObj->SetOwnerGUID(GetGUID());
- if (GetTypeId() == TYPEID_PLAYER && gameObj->GetSpellId())
+ if (gameObj->GetSpellId())
{
SpellInfo const* createBySpell = sSpellMgr->GetSpellInfo(gameObj->GetSpellId());
// Need disable spell use for owner
if (createBySpell && createBySpell->IsCooldownStartedOnEvent())
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
- ToPlayer()->AddSpellAndCategoryCooldowns(createBySpell, 0, NULL, true);
+ GetSpellHistory()->StartCooldown(createBySpell, 0, nullptr, true);
}
}
@@ -4679,14 +4655,11 @@ void Unit::RemoveGameObject(GameObject* gameObj, bool del)
{
RemoveAurasDueToSpell(spellid);
- if (GetTypeId() == TYPEID_PLAYER)
- {
- SpellInfo const* createBySpell = sSpellMgr->GetSpellInfo(spellid);
- // Need activate spell use for owner
- if (createBySpell && createBySpell->IsCooldownStartedOnEvent())
- // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
- ToPlayer()->SendCooldownEvent(createBySpell);
- }
+ SpellInfo const* createBySpell = sSpellMgr->GetSpellInfo(spellid);
+ // Need activate spell use for owner
+ if (createBySpell && createBySpell->IsCooldownStartedOnEvent())
+ // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
+ GetSpellHistory()->SendCooldownEvent(createBySpell);
}
m_gameObj.remove(gameObj);
@@ -5224,8 +5197,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster);
for (std::vector<uint32>::iterator itr = RandomSpells.begin(); itr != RandomSpells.end(); ++itr)
{
- if (!ToPlayer()->HasSpellCooldown(*itr))
- ToPlayer()->AddSpellCooldown(*itr, 0, time(NULL) + cooldown);
+ if (!GetSpellHistory()->HasCooldown(*itr))
+ GetSpellHistory()->AddCooldown(*itr, 0, std::chrono::seconds(cooldown));
}
break;
}
@@ -5270,8 +5243,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster);
for (std::vector<uint32>::iterator itr = RandomSpells.begin(); itr != RandomSpells.end(); ++itr)
{
- if (!ToPlayer()->HasSpellCooldown(*itr))
- ToPlayer()->AddSpellCooldown(*itr, 0, time(NULL) + cooldown);
+ if (!GetSpellHistory()->HasCooldown(*itr))
+ GetSpellHistory()->AddCooldown(*itr, 0, std::chrono::seconds(cooldown));
}
break;
}
@@ -5851,7 +5824,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return false;
// custom cooldown processing case
- if (cooldown && player->HasSpellCooldown(dummySpell->Id))
+ if (cooldown && GetSpellHistory()->HasCooldown(dummySpell->Id))
return false;
if (triggeredByAura->GetBase() && castItem->GetGUID() != triggeredByAura->GetBase()->GetCastItemGUID())
@@ -5898,7 +5871,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// apply cooldown before cast to prevent processing itself
if (cooldown)
- player->AddSpellCooldown(dummySpell->Id, 0, time(NULL) + cooldown);
+ player->GetSpellHistory()->AddCooldown(dummySpell->Id, 0, std::chrono::seconds(cooldown));
// Attack Twice
for (uint32 i = 0; i < 2; ++i)
@@ -6037,10 +6010,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
{
uint32 spell = 26364;
- // custom cooldown processing case
- if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(spell))
- ToPlayer()->RemoveSpellCooldown(spell);
-
+ GetSpellHistory()->ResetCooldown(spell);
CastSpell(target, spell, true, castItem, triggeredByAura);
return true;
}
@@ -6139,7 +6109,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (cooldown_spell_id == 0)
cooldown_spell_id = triggered_spell_id;
- if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(cooldown_spell_id))
+ if (cooldown && GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(cooldown_spell_id))
return false;
if (basepoints0)
@@ -6147,8 +6117,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
else
CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura, originalCaster);
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- ToPlayer()->AddSpellCooldown(cooldown_spell_id, 0, time(NULL) + cooldown);
+ if (cooldown)
+ GetSpellHistory()->AddCooldown(cooldown_spell_id, 0, std::chrono::seconds(cooldown));
return true;
}
@@ -6295,9 +6265,10 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura
*handled = true;
if (cooldown && GetTypeId() == TYPEID_PLAYER)
{
- if (ToPlayer()->HasSpellCooldown(100000))
+ if (GetSpellHistory()->HasCooldown(100000))
return false;
- ToPlayer()->AddSpellCooldown(100000, 0, time(NULL) + cooldown);
+
+ GetSpellHistory()->AddCooldown(100000, 0, std::chrono::seconds(cooldown));
}
return true;
}
@@ -6811,7 +6782,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
}
- if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(trigger_spell_id))
+ if (cooldown && GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(trigger_spell_id))
return false;
// extra attack should hit same target
@@ -6827,8 +6798,8 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
else
CastSpell(target, trigger_spell_id, true, castItem, triggeredByAura);
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- ToPlayer()->AddSpellCooldown(trigger_spell_id, 0, time(NULL) + cooldown);
+ if (cooldown)
+ GetSpellHistory()->AddCooldown(trigger_spell_id, 0, std::chrono::seconds(cooldown));
return true;
}
@@ -6883,13 +6854,13 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, Au
return false;
}
- if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(triggered_spell_id))
+ if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetSpellHistory()->HasCooldown(triggered_spell_id))
return false;
CastSpell(victim, triggered_spell_id, true, castItem, triggeredByAura);
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- ToPlayer()->AddSpellCooldown(triggered_spell_id, 0, time(NULL) + cooldown);
+ if (cooldown)
+ GetSpellHistory()->AddCooldown(triggered_spell_id, 0, std::chrono::seconds(cooldown));
return true;
}
@@ -7622,14 +7593,11 @@ void Unit::SetMinion(Minion *minion, bool apply)
if (minion->IsPetGhoul())
minion->setPowerType(POWER_ENERGY);
- if (GetTypeId() == TYPEID_PLAYER)
- {
- // Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
+ // Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
- if (spellInfo && (spellInfo->IsCooldownStartedOnEvent()))
- ToPlayer()->AddSpellAndCategoryCooldowns(spellInfo, 0, NULL, true);
- }
+ if (spellInfo && (spellInfo->IsCooldownStartedOnEvent()))
+ GetSpellHistory()->StartCooldown(spellInfo, 0, nullptr, true);
}
else
{
@@ -7663,13 +7631,10 @@ void Unit::SetMinion(Minion *minion, bool apply)
}
}
- if (GetTypeId() == TYPEID_PLAYER)
- {
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
- // Remove infinity cooldown
- if (spellInfo && (spellInfo->IsCooldownStartedOnEvent()))
- ToPlayer()->SendCooldownEvent(spellInfo);
- }
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
+ // Remove infinity cooldown
+ if (spellInfo && (spellInfo->IsCooldownStartedOnEvent()))
+ GetSpellHistory()->SendCooldownEvent(spellInfo);
//if (minion->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
{
@@ -11465,12 +11430,11 @@ void Unit::SetPower(Powers power, int32 val)
if (IsInWorld())
{
- WorldPacket data(SMSG_POWER_UPDATE, 8 + 4 + 1 + 4);
- data << GetPackGUID();
- data << uint32(1); //power count
- data << uint8(powerIndex);
- data << int32(val);
- SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER);
+ WorldPackets::Combat::PowerUpdate packet;
+ packet.Guid = GetGUID();
+ /// @todo: Support multiple counts ?
+ packet.Powers.emplace_back(val, powerIndex);
+ SendMessageToSet(packet.Write(), GetTypeId() == TYPEID_PLAYER);
}
// group update
@@ -16398,27 +16362,6 @@ void Unit::DestroyForPlayer(Player* target) const
WorldObject::DestroyForPlayer(target);
}
-void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown)
-{
- data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
- data << GetGUID();
- data << uint8(flags);
- data << uint32(spellId);
- data << uint32(cooldown);
-}
-
-void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns)
-{
- data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + (4 + 4) * cooldowns.size());
- data << GetGUID();
- data << uint8(flags);
- for (std::unordered_map<uint32, uint32>::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr)
- {
- data << uint32(itr->first);
- data << uint32(itr->second);
- }
-}
-
int32 Unit::GetHighestExclusiveSameEffectSpellGroupValue(AuraEffect const* aurEff, AuraType auraType, bool checkMiscValue /*= false*/, int32 miscValue /*= 0*/) const
{
int32 val = 0;
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 82f7240bc76..3f9570b548f 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -397,6 +397,7 @@ class Creature;
class Spell;
class SpellInfo;
class SpellEffectInfo;
+class SpellHistory;
class DynamicObject;
class GameObject;
class Item;
@@ -1105,30 +1106,6 @@ enum CurrentSpellTypes
#define CURRENT_FIRST_NON_MELEE_SPELL 1
#define CURRENT_MAX_SPELL 4
-struct GlobalCooldown
-{
- explicit GlobalCooldown(uint32 _dur = 0, uint32 _time = 0) : duration(_dur), cast_time(_time) { }
-
- uint32 duration;
- uint32 cast_time;
-};
-
-typedef std::unordered_map<uint32 /*category*/, GlobalCooldown> GlobalCooldownList;
-
-class GlobalCooldownMgr // Shared by Player and CharmInfo
-{
-public:
- GlobalCooldownMgr() { }
-
-public:
- bool HasGlobalCooldown(SpellInfo const* spellInfo) const;
- void AddGlobalCooldown(SpellInfo const* spellInfo, uint32 gcd);
- void CancelGlobalCooldown(SpellInfo const* spellInfo);
-
-private:
- GlobalCooldownList m_GlobalCooldowns;
-};
-
enum ActiveStates
{
ACT_PASSIVE = 0x01, // 0x01 - passive
@@ -1246,8 +1223,6 @@ struct CharmInfo
CharmSpellInfo* GetCharmSpell(uint8 index) { return &(_charmspells[index]); }
- GlobalCooldownMgr& GetGlobalCooldownMgr() { return m_GlobalCooldownMgr; }
-
void SetIsCommandAttack(bool val);
bool IsCommandAttack();
void SetIsCommandFollow(bool val);
@@ -1280,8 +1255,6 @@ struct CharmInfo
float _stayX;
float _stayY;
float _stayZ;
-
- GlobalCooldownMgr m_GlobalCooldownMgr;
};
// for clearing special attacks
@@ -1312,16 +1285,6 @@ enum PlayerTotemType
SUMMON_TYPE_TOTEM_AIR = 83
};
-/// Spell cooldown flags sent in SMSG_SPELL_COOLDOWN
-enum SpellCooldownFlags
-{
- SPELL_COOLDOWN_FLAG_NONE = 0x0,
- SPELL_COOLDOWN_FLAG_INCLUDE_GCD = 0x1, ///< Starts GCD in addition to normal cooldown specified in the packet
- SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS = 0x2 ///< Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUDE_GCD set
-};
-
-typedef std::unordered_map<uint32, uint32> PacketCooldowns;
-
// delay time next attack to prevent client attack animation problems
#define ATTACK_DISPLAY_DELAY 200
#define MAX_PLAYER_STEALTH_DETECT_RANGE 30.0f // max distance for detection targets by player
@@ -1658,8 +1621,6 @@ class Unit : public WorldObject
Aura* AddAura(SpellInfo const* spellInfo, uint32 effMask, Unit* target);
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
void SendPlaySpellVisualKit(uint32 id, uint32 unkParam);
- void BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown);
- void BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns);
void DeMorph();
@@ -1920,7 +1881,6 @@ class Unit : public WorldObject
void SetChannelObjectGuid(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_CHANNEL_OBJECT, guid); }
void SetCurrentCastSpell(Spell* pSpell);
- virtual void ProhibitSpellSchool(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/) { }
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed = true, bool withInstant = true);
void FinishSpell(CurrentSpellTypes spellType, bool ok = true);
@@ -1939,6 +1899,9 @@ class Unit : public WorldObject
int32 GetCurrentSpellCastTime(uint32 spell_id) const;
virtual SpellInfo const* GetCastSpellInfo(SpellInfo const* spellInfo) const;
+ SpellHistory* GetSpellHistory() { return _spellHistory; }
+ SpellHistory const* GetSpellHistory() const { return _spellHistory; }
+
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT];
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT];
@@ -2374,6 +2337,8 @@ class Unit : public WorldObject
uint16 _aiAnimKitId;
uint16 _movementAnimKitId;
uint16 _meleeAnimKitId;
+
+ SpellHistory* _spellHistory;
};
namespace Trinity
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 444aa00a8e6..77484f372a3 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -35,56 +35,6 @@
#define MAX_GUILD_BANK_TAB_TEXT_LEN 500
#define EMBLEM_PRICE 10 * GOLD
-std::string _GetGuildEventString(GuildEvents event)
-{
- switch (event)
- {
- case GE_PROMOTION:
- return "Member promotion";
- case GE_DEMOTION:
- return "Member demotion";
- case GE_MOTD:
- return "Guild MOTD";
- case GE_JOINED:
- return "Member joined";
- case GE_LEFT:
- return "Member left";
- case GE_REMOVED:
- return "Member removed";
- case GE_LEADER_IS:
- return "Leader is";
- case GE_LEADER_CHANGED:
- return "Leader changed";
- case GE_DISBANDED:
- return "Guild disbanded";
- case GE_TABARDCHANGE:
- return "Tabard change";
- case GE_RANK_UPDATED:
- return "Rank updated";
- case GE_RANK_DELETED:
- return "Rank deleted";
- case GE_SIGNED_ON:
- return "Member signed on";
- case GE_SIGNED_OFF:
- return "Member signed off";
- case GE_GUILDBANKBAGSLOTS_CHANGED:
- return "Bank bag slots changed";
- case GE_BANK_TAB_PURCHASED:
- return "Bank tab purchased";
- case GE_BANK_TAB_UPDATED:
- return "Bank tab updated";
- case GE_BANK_MONEY_SET:
- return "Bank money set";
- case GE_BANK_TAB_AND_MONEY_UPDATED:
- return "Bank money changed";
- case GE_BANK_TEXT_CHANGED:
- return "Bank tab text changed";
- default:
- break;
- }
- return "<None>";
-}
-
inline uint32 _GetGuildBankTabPrice(uint8 tabId)
{
switch (tabId)
@@ -101,14 +51,11 @@ inline uint32 _GetGuildBankTabPrice(uint8 tabId)
void Guild::SendCommandResult(WorldSession* session, GuildCommandType type, GuildCommandError errCode, std::string const& param)
{
- // Note: SMSG_GUILD_COMMAND_RESULT and SMSG_GUILD_COMMAND_RESULT_2 do exactly the same in the client, they just have different structures.
- // There's no particular reason why we use SMSG_GUILD_COMMAND_RESULT_2, this one is processed inmediately as it is read from the client.
- // SMSG_GUILD_COMMAND_RESULT is a JAM opcode
- WorldPacket data(SMSG_GUILD_COMMAND_RESULT_2, 8 + param.size() + 1);
- data << uint32(type);
- data << param;
- data << uint32(errCode);
- session->SendPacket(&data);
+ WorldPackets::Guild::GuildCommandResult resultPacket;
+ resultPacket.Command = type;
+ resultPacket.Result = errCode;
+ resultPacket.Name = param;
+ session->SendPacket(resultPacket.Write());
TC_LOG_DEBUG("guild", "SMSG_GUILD_COMMAND_RESULT [%s]: Type: %u, code: %u, param: %s"
, session->GetPlayerInfo().c_str(), type, errCode, param.c_str());
@@ -116,11 +63,11 @@ void Guild::SendCommandResult(WorldSession* session, GuildCommandType type, Guil
void Guild::SendSaveEmblemResult(WorldSession* session, GuildEmblemError errCode)
{
- WorldPacket data(SMSG_SAVE_GUILD_EMBLEM, 4);
- data << uint32(errCode);
- session->SendPacket(&data);
+ WorldPackets::Guild::PlayerSaveGuildEmblem saveResponse;
+ saveResponse.Error = int32(errCode);
+ session->SendPacket(saveResponse.Write());
- TC_LOG_DEBUG("guild", "SMSG_SAVE_GUILD_EMBLEM [%s] Code: %u", session->GetPlayerInfo().c_str(), errCode);
+ TC_LOG_DEBUG("guild", "Sent SMSG_SAVE_GUILD_EMBLEM [%s] Code: %u", session->GetPlayerInfo().c_str(), errCode);
}
// LogHolder
@@ -156,18 +103,6 @@ inline void Guild::LogHolder::AddEvent(SQLTransaction& trans, LogEntry* entry)
entry->SaveToDB(trans);
}
-// Writes information about all events into packet.
-inline void Guild::LogHolder::WritePacket(WorldPacket& data) const
-{
- ByteBuffer buffer;
- data.WriteBits(m_log.size(), 23);
- for (GuildLog::const_iterator itr = m_log.begin(); itr != m_log.end(); ++itr)
- (*itr)->WritePacket(data, buffer);
-
- data.FlushBits();
- data.append(buffer);
-}
-
inline uint32 Guild::LogHolder::GetNextGUID()
{
// Next guid was not initialized. It means there are no records for this holder in DB yet.
@@ -199,56 +134,18 @@ void Guild::EventLogEntry::SaveToDB(SQLTransaction& trans) const
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
-void Guild::EventLogEntry::WritePacket(WorldPacket& data, ByteBuffer& content) const
+void Guild::EventLogEntry::WritePacket(WorldPackets::Guild::GuildEventLogQueryResults& packet) const
{
- ObjectGuid guid1 = ObjectGuid::Create<HighGuid::Player>(m_playerGuid1);
- ObjectGuid guid2 = ObjectGuid::Create<HighGuid::Player>(m_playerGuid2);
+ ObjectGuid playerGUID = ObjectGuid::Create<HighGuid::Player>(m_playerGuid1);
+ ObjectGuid otherGUID = ObjectGuid::Create<HighGuid::Player>(m_playerGuid2);
- data.WriteBit(guid1[2]);
- data.WriteBit(guid1[4]);
- data.WriteBit(guid2[7]);
- data.WriteBit(guid2[6]);
- data.WriteBit(guid1[3]);
- data.WriteBit(guid2[3]);
- data.WriteBit(guid2[5]);
- data.WriteBit(guid1[7]);
- data.WriteBit(guid1[5]);
- data.WriteBit(guid1[0]);
- data.WriteBit(guid2[4]);
- data.WriteBit(guid2[2]);
- data.WriteBit(guid2[0]);
- data.WriteBit(guid2[1]);
- data.WriteBit(guid1[1]);
- data.WriteBit(guid1[6]);
-
- content.WriteByteSeq(guid2[3]);
- content.WriteByteSeq(guid2[2]);
- content.WriteByteSeq(guid2[5]);
-
- // New Rank
- content << uint8(m_newRank);
-
- content.WriteByteSeq(guid2[4]);
- content.WriteByteSeq(guid1[0]);
- content.WriteByteSeq(guid1[4]);
-
- // Event timestamp
- content << uint32(::time(NULL) - m_timestamp);
-
- content.WriteByteSeq(guid1[7]);
- content.WriteByteSeq(guid1[3]);
- content.WriteByteSeq(guid2[0]);
- content.WriteByteSeq(guid2[6]);
- content.WriteByteSeq(guid2[7]);
- content.WriteByteSeq(guid1[5]);
-
- // Event type
- content << uint8(m_eventType);
-
- content.WriteByteSeq(guid2[1]);
- content.WriteByteSeq(guid1[2]);
- content.WriteByteSeq(guid1[6]);
- content.WriteByteSeq(guid1[1]);
+ WorldPackets::Guild::GuildEventEntry eventEntry;
+ eventEntry.PlayerGUID = playerGUID;
+ eventEntry.OtherGUID = otherGUID;
+ eventEntry.TransactionType = uint8(m_eventType);
+ eventEntry.TransactionDate = uint32(::time(NULL) - m_timestamp);
+ eventEntry.RankID = uint8(m_newRank);
+ packet.Entry.push_back(eventEntry);
}
// BankEventLogEntry
@@ -276,7 +173,7 @@ void Guild::BankEventLogEntry::SaveToDB(SQLTransaction& trans) const
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
-void Guild::BankEventLogEntry::WritePacket(WorldPacket& data, ByteBuffer& content) const
+void Guild::BankEventLogEntry::WritePacket(WorldPackets::Guild:: GuildBankLogQueryResults& packet) const
{
ObjectGuid logGuid = ObjectGuid::Create<HighGuid::Player>(m_playerGuid);
@@ -287,41 +184,24 @@ void Guild::BankEventLogEntry::WritePacket(WorldPacket& data, ByteBuffer& conten
bool hasStack = (hasItem && m_itemStackCount > 1) || itemMoved;
- data.WriteBit(IsMoneyEvent());
- data.WriteBit(logGuid[4]);
- data.WriteBit(logGuid[1]);
- data.WriteBit(hasItem);
- data.WriteBit(hasStack);
- data.WriteBit(logGuid[2]);
- data.WriteBit(logGuid[5]);
- data.WriteBit(logGuid[3]);
- data.WriteBit(logGuid[6]);
- data.WriteBit(logGuid[0]);
- data.WriteBit(itemMoved);
- data.WriteBit(logGuid[7]);
-
- content.WriteByteSeq(logGuid[6]);
- content.WriteByteSeq(logGuid[1]);
- content.WriteByteSeq(logGuid[5]);
- if (hasStack)
- content << uint32(m_itemStackCount);
-
- content << uint8(m_eventType);
- content.WriteByteSeq(logGuid[2]);
- content.WriteByteSeq(logGuid[4]);
- content.WriteByteSeq(logGuid[0]);
- content.WriteByteSeq(logGuid[7]);
- content.WriteByteSeq(logGuid[3]);
- if (hasItem)
- content << uint32(m_itemOrMoney);
+ WorldPackets::Guild::GuildBankLogEntry bankLogEntry;
+ bankLogEntry.PlayerGUID = logGuid;
+ bankLogEntry.TimeOffset = int32(time(NULL) - m_timestamp);
+ bankLogEntry.EntryType = int8(m_eventType);
- content << uint32(time(NULL) - m_timestamp);
+ if (hasStack)
+ bankLogEntry.Count.Set(int32(m_itemStackCount));
if (IsMoneyEvent())
- content << uint64(m_itemOrMoney);
+ bankLogEntry.Money.Set(uint64(m_itemOrMoney));
+
+ if (hasItem)
+ bankLogEntry.ItemID.Set(int32(m_itemOrMoney));
if (itemMoved)
- content << uint8(m_destTabId);
+ bankLogEntry.OtherTab.Set(int8(m_destTabId));
+
+ packet.Entry.push_back(bankLogEntry);
}
void Guild::NewsLogEntry::SaveToDB(SQLTransaction& trans) const
@@ -338,39 +218,28 @@ void Guild::NewsLogEntry::SaveToDB(SQLTransaction& trans) const
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
-void Guild::NewsLogEntry::WritePacket(WorldPacket& data, ByteBuffer& /*content*/) const
+void Guild::NewsLogEntry::WritePacket(WorldPackets::Guild::GuildNews& newsPacket) const
{
- data.WriteBits(0, 26); // Not yet implemented used for guild achievements
- ObjectGuid guid = GetPlayerGuid();
-
- data.WriteBit(guid[7]);
- data.WriteBit(guid[0]);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[4]);
- data.WriteBit(guid[3]);
- data.WriteBit(guid[1]);
- data.WriteBit(guid[2]);
+ WorldPackets::Guild::GuildNewsEvent newsEvent;
+ newsEvent.Id = int32(GetGUID());
+ newsEvent.MemberGuid = GetPlayerGuid();
+ newsEvent.CompletedDate = uint32(GetTimestamp());
+ newsEvent.Flags = int32(GetFlags());
+ newsEvent.Type = int32(GetType());
- data.FlushBits();
-
- data.WriteByteSeq(guid[5]);
+ //for (uint8 i = 0; i < 2; i++)
+ // newsEvent.Data[i] =
- data << uint32(GetFlags()); // 1 sticky
- data << uint32(GetValue());
- data << uint32(0); // always 0
+ //newsEvent.MemberList.push_back(MemberGuid);
- data.WriteByteSeq(guid[7]);
- data.WriteByteSeq(guid[6]);
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[0]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[1]);
+ if (GetType() == GUILD_NEWS_ITEM_LOOTED || GetType() == GUILD_NEWS_ITEM_CRAFTED || GetType() == GUILD_NEWS_ITEM_PURCHASED)
+ {
+ WorldPackets::Item::ItemInstance itemInstance;
+ itemInstance.ItemID = GetValue();
+ newsEvent.Item.Set(itemInstance);
+ }
- data << uint32(GetGUID());
- data << uint32(GetType());
- data.AppendPackedTime(GetTimestamp());
+ newsPacket.NewsEvents.push_back(newsEvent);
}
// RankInfo
@@ -414,8 +283,8 @@ void Guild::RankInfo::CreateMissingTabsIfNeeded(uint8 tabs, SQLTransaction& tran
stmt->setUInt64(0, m_guildId);
stmt->setUInt8(1, i);
stmt->setUInt8(2, m_rankId);
- stmt->setUInt8(3, rightsAndSlots.GetRights());
- stmt->setUInt32(4, rightsAndSlots.GetSlots());
+ stmt->setInt8(3, rightsAndSlots.GetRights());
+ stmt->setInt32(4, rightsAndSlots.GetSlots());
trans->Append(stmt);
}
}
@@ -482,8 +351,8 @@ void Guild::RankInfo::SetBankTabSlotsAndRights(GuildBankRightsAndSlots rightsAnd
stmt->setUInt64(0, m_guildId);
stmt->setUInt8 (1, guildBR.GetTabId());
stmt->setUInt8 (2, m_rankId);
- stmt->setUInt8 (3, guildBR.GetRights());
- stmt->setUInt32(4, guildBR.GetSlots());
+ stmt->setInt8 (3, guildBR.GetRights());
+ stmt->setInt32 (4, guildBR.GetSlots());
CharacterDatabase.Execute(stmt);
}
}
@@ -613,21 +482,20 @@ bool Guild::BankTab::SetItem(SQLTransaction& trans, uint8 slotId, Item* item)
void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const
{
- WorldPacket data(SMSG_GUILD_BANK_QUERY_TEXT_RESULT, 1 + m_text.size() + 1);
- data.WriteBits(m_text.length(), 14);
- data << uint32(m_tabId);
- data.WriteString(m_text);
+ WorldPackets::Guild::GuildBankTextQueryResult textQuery;
+ textQuery.Tab = m_tabId;
+ textQuery.Text = m_text;
if (session)
{
TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_QUERY_TEXT_RESULT [%s]: Tabid: %u, Text: %s"
, session->GetPlayerInfo().c_str(), m_tabId, m_text.c_str());
- session->SendPacket(&data);
+ session->SendPacket(textQuery.Write());
}
else
{
TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_QUERY_TEXT_RESULT [Broadcast]: Tabid: %u, Text: %s", m_tabId, m_text.c_str());
- guild->BroadcastPacket(&data);
+ guild->BroadcastPacket(textQuery.Write());
}
}
@@ -637,16 +505,18 @@ void Guild::Member::SetStats(Player* player)
m_name = player->GetName();
m_level = player->getLevel();
m_class = player->getClass();
+ _gender = player->getGender();
m_zoneId = player->GetZoneId();
m_accountId = player->GetSession()->GetAccountId();
m_achievementPoints = player->GetAchievementPoints();
}
-void Guild::Member::SetStats(std::string const& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId, uint32 reputation)
+void Guild::Member::SetStats(std::string const& name, uint8 level, uint8 _class, uint8 gender, uint32 zoneId, uint32 accountId, uint32 reputation)
{
m_name = name;
m_level = level;
m_class = _class;
+ _gender = gender;
m_zoneId = zoneId;
m_accountId = accountId;
m_totalReputation = reputation;
@@ -717,10 +587,11 @@ bool Guild::Member::LoadFromDB(Field* fields)
SetStats(fields[14].GetString(),
fields[15].GetUInt8(), // characters.level
fields[16].GetUInt8(), // characters.class
- fields[17].GetUInt16(), // characters.zone
- fields[18].GetUInt32(), // characters.account
+ fields[17].GetUInt8(), // characters.gender
+ fields[18].GetUInt16(), // characters.zone
+ fields[19].GetUInt32(), // characters.account
0);
- m_logoutTime = fields[19].GetUInt32(); // characters.logout_time
+ m_logoutTime = fields[20].GetUInt32(); // characters.logout_time
m_totalActivity = 0;
m_weekActivity = 0;
m_weekReputation = 0;
@@ -798,9 +669,13 @@ int32 Guild::Member::GetBankWithdrawValue(uint8 tabId) const
}
// EmblemInfo
-void EmblemInfo::ReadPacket(WorldPacket& recv)
+void EmblemInfo::ReadPacket(WorldPackets::Guild::SaveGuildEmblem& packet)
{
- recv >> m_style >> m_color >> m_borderStyle >> m_borderColor >> m_backgroundColor;
+ m_style = packet.EStyle;
+ m_color = packet.EColor;
+ m_borderStyle = packet.BStyle;
+ m_borderColor = packet.BColor;
+ m_backgroundColor = packet.Bg;
}
void EmblemInfo::LoadFromDB(Field* fields)
@@ -1159,9 +1034,7 @@ Guild::Guild():
m_eventLog(NULL),
m_newsLog(NULL),
m_achievementMgr(this),
- _level(1),
- _experience(0),
- _todayExperience(0)
+ _level(1)
{
memset(&m_bankEventLog, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(LogHolder*));
}
@@ -1209,8 +1082,6 @@ bool Guild::Create(Player* pLeader, std::string const& name)
m_bankMoney = 0;
m_createdDate = ::time(NULL);
_level = 1;
- _experience = 0;
- _todayExperience = 0;
_CreateLogHolders();
TC_LOG_DEBUG("guild", "GUILD: creating guild [%s] for leader %s (%s)",
@@ -1244,7 +1115,10 @@ bool Guild::Create(Player* pLeader, std::string const& name)
if (ret)
{
- _BroadcastEvent(GE_FOUNDER, ObjectGuid::Empty);
+ Member* leader = GetMember(m_leaderGuid);
+ if (leader)
+ SendEventNewLeader(leader, NULL);
+
sScriptMgr->OnGuildCreate(this, pLeader, name);
}
@@ -1257,7 +1131,9 @@ void Guild::Disband()
// Call scripts before guild data removed from database
sScriptMgr->OnGuildDisband(this);
- _BroadcastEvent(GE_DISBANDED, ObjectGuid::Empty);
+ WorldPackets::Guild::GuildEventDisbanded packet;
+ BroadcastPacket(packet.Write());
+
// Remove all members
while (!m_members.empty())
{
@@ -1309,13 +1185,6 @@ void Guild::SaveToDB()
{
SQLTransaction trans = CharacterDatabase.BeginTransaction();
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_EXPERIENCE);
- stmt->setUInt32(0, GetLevel());
- stmt->setUInt64(1, GetExperience());
- stmt->setUInt64(2, GetTodayExperience());
- stmt->setUInt64(3, GetId());
- trans->Append(stmt);
-
m_achievementMgr.SaveToDB(trans);
CharacterDatabase.CommitTransaction(trans);
@@ -1365,6 +1234,7 @@ bool Guild::SetName(std::string const& name)
stmt->setUInt64(1, GetId());
CharacterDatabase.Execute(stmt);
+ /* TODO 6.x update me
ObjectGuid guid = GetGUID();
WorldPacket data(SMSG_GUILD_NAME_CHANGED, 24 + 8 + 1);
data.WriteBit(guid[5]);
@@ -1387,93 +1257,56 @@ bool Guild::SetName(std::string const& name)
data.WriteByteSeq(guid[4]);
data.WriteByteSeq(guid[5]);
- BroadcastPacket(&data);
+ BroadcastPacket(&data); */
return true;
}
void Guild::HandleRoster(WorldSession* session)
{
- ByteBuffer memberData(100);
- // Guess size
- WorldPacket data(SMSG_GUILD_ROSTER, 100);
- data.WriteBits(m_motd.length(), 11);
- data.WriteBits(m_members.size(), 18);
+ WorldPackets::Guild::GuildRoster roster;
- for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
+ roster.NumAccounts = int32(m_accountsNumber);
+ roster.CreateDate = uint32(m_createdDate);
+ roster.GuildFlags = 0;
+
+ roster.MemberData.reserve(m_members.size());
+
+ for (auto itr : m_members)
{
- Member* member = itr->second;
- size_t pubNoteLength = member->GetPublicNote().length();
- size_t offNoteLength = member->GetOfficerNote().length();
-
- ObjectGuid guid = member->GetGUID();
- data.WriteBit(guid[3]);
- data.WriteBit(guid[4]);
- data.WriteBit(0); // Has Authenticator
- data.WriteBit(0); // Can Scroll of Ressurect
- data.WriteBits(pubNoteLength, 8);
- data.WriteBits(offNoteLength, 8);
- data.WriteBit(guid[0]);
- data.WriteBits(member->GetName().length(), 7);
- data.WriteBit(guid[1]);
- data.WriteBit(guid[2]);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[7]);
-
- memberData << uint8(member->GetClass());
- memberData << uint32(member->GetTotalReputation());
- memberData.WriteByteSeq(guid[0]);
- memberData << uint64(member->GetWeekActivity());
- memberData << uint32(member->GetRankId());
- memberData << uint32(member->GetAchievementPoints());
-
- // for (2 professions)
- memberData << uint32(0) << uint32(0) << uint32(0);
- memberData << uint32(0) << uint32(0) << uint32(0);
-
- memberData.WriteByteSeq(guid[2]);
- memberData << uint8(member->GetFlags());
- memberData << uint32(member->GetZoneId());
- memberData << uint64(member->GetTotalActivity());
- memberData.WriteByteSeq(guid[7]);
- memberData << uint32(sWorld->getIntConfig(CONFIG_GUILD_WEEKLY_REP_CAP) - member->GetWeekReputation());
-
- if (pubNoteLength)
- memberData.WriteString(member->GetPublicNote());
-
- memberData.WriteByteSeq(guid[3]);
- memberData << uint8(member->GetLevel());
- memberData << int32(0); // unk
- memberData.WriteByteSeq(guid[5]);
- memberData.WriteByteSeq(guid[4]);
- memberData << uint8(0); // unk
- memberData.WriteByteSeq(guid[1]);
- memberData << float(member->IsOnline() ? 0.0f : float(::time(NULL) - member->GetLogoutTime()) / DAY);
-
- if (offNoteLength)
- memberData.WriteString(member->GetOfficerNote());
-
- memberData.WriteByteSeq(guid[6]);
- memberData.WriteString(member->GetName());
- }
-
- size_t infoLength = m_info.length();
- data.WriteBits(infoLength, 12);
-
- data.FlushBits();
- data.append(memberData);
-
- if (infoLength)
- data.WriteString(m_info);
-
- data.WriteString(m_motd);
- data << uint32(m_accountsNumber);
- data << uint32(sWorld->getIntConfig(CONFIG_GUILD_WEEKLY_REP_CAP));
- data.AppendPackedTime(m_createdDate);
- data << uint32(0);
+ Member* member = itr.second;
+
+ WorldPackets::Guild::GuildRosterMemberData memberData;
+
+ memberData.Guid = member->GetGUID();
+ memberData.RankID = int32(member->GetRankId());
+ memberData.AreaID = int32(member->GetZoneId());
+ memberData.PersonalAchievementPoints = int32(member->GetAchievementPoints());
+ memberData.GuildReputation = int32(member->GetTotalReputation());
+ memberData.LastSave = float(member->IsOnline() ? 0.0f : float(::time(NULL) - member->GetLogoutTime()) / DAY);
+
+ //GuildRosterProfessionData
+
+ memberData.VirtualRealmAddress = GetVirtualRealmAddress();
+ memberData.Status = member->GetFlags();
+ memberData.Level = member->GetLevel();
+ memberData.ClassID = member->GetClass();
+ memberData.Gender = member->GetGender();
+
+ memberData.Authenticated = false;
+ memberData.SorEligible = false;
+
+ memberData.Name = member->GetName();
+ memberData.Note = member->GetPublicNote();
+ memberData.OfficerNote = member->GetOfficerNote();
+
+ roster.MemberData.push_back(memberData);
+ }
+
+ roster.WelcomeText = m_motd;
+ roster.InfoText = m_info;
TC_LOG_DEBUG("guild", "SMSG_GUILD_ROSTER [%s]", session->GetPlayerInfo().c_str());
- session->SendPacket(&data);
+ session->SendPacket(roster.Write());
}
void Guild::SendQueryResponse(WorldSession* session)
@@ -1506,10 +1339,9 @@ void Guild::SendQueryResponse(WorldSession* session)
void Guild::SendGuildRankInfo(WorldSession* session) const
{
- ByteBuffer rankData(100);
- WorldPacket data(SMSG_GUILD_RANKS, 100);
+ WorldPackets::Guild::GuildRanks ranks;
- data.WriteBits(_GetRanksSize(), 18);
+ ranks.Ranks.reserve(_GetRanksSize());
for (uint8 i = 0; i < _GetRanksSize(); i++)
{
@@ -1517,28 +1349,24 @@ void Guild::SendGuildRankInfo(WorldSession* session) const
if (!rankInfo)
continue;
- data.WriteBits(rankInfo->GetName().length(), 7);
+ WorldPackets::Guild::GuildRankData rankData;
- rankData << uint32(rankInfo->GetId());
+ rankData.RankID = uint32(rankInfo->GetId());
+ rankData.RankOrder = uint32(i);
+ rankData.Flags = rankInfo->GetRights();
+ rankData.WithdrawGoldLimit = uint32(rankInfo->GetBankMoneyPerDay());
+ rankData.RankName = rankInfo->GetName();
for (uint8 j = 0; j < GUILD_BANK_MAX_TABS; ++j)
{
- rankData << uint32(rankInfo->GetBankTabSlotsPerDay(j));
- rankData << uint32(rankInfo->GetBankTabRights(j));
+ rankData.TabFlags[j] = uint32(rankInfo->GetBankTabRights(j));
+ rankData.TabWithdrawItemLimit[j] = uint32(rankInfo->GetBankTabSlotsPerDay(j));
}
- rankData << uint32(rankInfo->GetBankMoneyPerDay());
- rankData << uint32(rankInfo->GetRights());
-
- if (rankInfo->GetName().length())
- rankData.WriteString(rankInfo->GetName());
-
- rankData << uint32(i);
+ ranks.Ranks.push_back(rankData);
}
- data.FlushBits();
- data.append(rankData);
- session->SendPacket(&data);
+ session->SendPacket(ranks.Write());
TC_LOG_DEBUG("guild", "SMSG_GUILD_RANK [%s]", session->GetPlayerInfo().c_str());
}
@@ -1589,7 +1417,7 @@ void Guild::HandleSetMOTD(WorldSession* session, std::string const& motd)
stmt->setUInt64(1, m_id);
CharacterDatabase.Execute(stmt);
- _BroadcastEvent(GE_MOTD, ObjectGuid::Empty, motd.c_str());
+ SendEventMOTD(session, true);
}
}
@@ -1646,7 +1474,8 @@ void Guild::HandleSetNewGuildMaster(WorldSession* session, std::string const& na
{
_SetLeaderGUID(newGuildMaster);
oldGuildMaster->ChangeRank(GR_INITIATE);
- _BroadcastEvent(GE_LEADER_CHANGED, ObjectGuid::Empty, player->GetName().c_str(), name.c_str());
+
+ SendEventNewLeader(newGuildMaster, oldGuildMaster);
}
}
}
@@ -1661,18 +1490,20 @@ void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string
return;
}
- char aux[2];
- sprintf(aux, "%u", tabId);
-
tab->SetInfo(name, icon);
- _BroadcastEvent(GE_BANK_TAB_UPDATED, ObjectGuid::Empty, aux, name.c_str(), icon.c_str());
+
+ WorldPackets::Guild::GuildEventTabModified packet;
+ packet.Tab = tabId;
+ packet.Name = name;
+ packet.Icon = icon;
+ BroadcastPacket(packet.Write());
}
void Guild::HandleSetMemberNote(WorldSession* session, std::string const& note, ObjectGuid guid, bool isPublic)
{
// Player must have rights to set public/officer note
- if (!_HasRankRight(session->GetPlayer(), isPublic ? GR_RIGHT_EPNOTE : GR_RIGHT_EOFFNOTE))
- SendCommandResult(session, GUILD_COMMAND_PUBLIC_NOTE, ERR_GUILD_PERMISSIONS);
+ if (!_HasRankRight(session->GetPlayer(), isPublic ? GR_RIGHT_EDIT_PUBLIC_NOTE : GR_RIGHT_EOFFNOTE))
+ SendCommandResult(session, GUILD_COMMAND_EDIT_PUBLIC_NOTE, ERR_GUILD_PERMISSIONS);
else if (Member* member = GetMember(guid))
{
if (isPublic)
@@ -1681,6 +1512,12 @@ void Guild::HandleSetMemberNote(WorldSession* session, std::string const& note,
member->SetOfficerNote(note);
HandleRoster(session); // FIXME - We should send SMSG_GUILD_MEMBER_UPDATE_NOTE
+
+ WorldPackets::Guild::GuildMemberUpdateNote updateNote;
+ updateNote.Member = guid;
+ updateNote.IsPublic = isPublic;
+ updateNote.Note = note;
+ session->SendPacket(updateNote.Write()); // @todo - Verify receiver of this packet...
}
}
@@ -1700,9 +1537,9 @@ void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string c
for (GuildBankRightsAndSlotsVec::const_iterator itr = rightsAndSlots.begin(); itr != rightsAndSlots.end(); ++itr)
_SetRankBankTabRightsAndSlots(rankId, *itr);
- char aux[2];
- sprintf(aux, "%u", rankId);
- _BroadcastEvent(GE_RANK_UPDATED, ObjectGuid::Empty, aux);
+ WorldPackets::Guild::GuildEventRankChanged packet;
+ packet.RankID = rankId;
+ BroadcastPacket(packet.Write());
}
}
@@ -1737,7 +1574,10 @@ void Guild::HandleBuyBankTab(WorldSession* session, uint8 tabId)
}
_CreateNewBankTab();
- _BroadcastEvent(GE_BANK_TAB_PURCHASED, ObjectGuid::Empty);
+
+ WorldPackets::Guild::GuildEventTabAdded packet;
+ BroadcastPacket(packet.Write());
+
SendPermissions(session); /// Hack to force client to update permissions
}
@@ -1746,7 +1586,7 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name)
Player* pInvitee = ObjectAccessor::FindPlayerByName(name);
if (!pInvitee)
{
- SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_PLAYER_NOT_FOUND_S, name);
+ SendCommandResult(session, GUILD_COMMAND_INVITE_PLAYER, ERR_GUILD_PLAYER_NOT_FOUND_S, name);
return;
}
@@ -1757,100 +1597,62 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name)
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && pInvitee->GetTeam() != player->GetTeam())
{
- SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_NOT_ALLIED, name);
+ SendCommandResult(session, GUILD_COMMAND_INVITE_PLAYER, ERR_GUILD_NOT_ALLIED, name);
return;
}
// Invited player cannot be in another guild
/*if (pInvitee->GetGuildId())
{
- SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, name);
+ SendCommandResult(session, GUILD_COMMAND_INVITE_PLAYER, ERR_ALREADY_IN_GUILD_S, name);
return;
}*/
// Invited player cannot be invited
if (pInvitee->GetGuildIdInvited())
{
- SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, name);
+ SendCommandResult(session, GUILD_COMMAND_INVITE_PLAYER, ERR_ALREADY_INVITED_TO_GUILD_S, name);
return;
}
+
// Inviting player must have rights to invite
if (!_HasRankRight(player, GR_RIGHT_INVITE))
{
- SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_PERMISSIONS);
+ SendCommandResult(session, GUILD_COMMAND_INVITE_PLAYER, ERR_GUILD_PERMISSIONS);
return;
}
- SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_COMMAND_SUCCESS, name);
+ SendCommandResult(session, GUILD_COMMAND_INVITE_PLAYER, ERR_GUILD_COMMAND_SUCCESS, name);
TC_LOG_DEBUG("guild", "Player %s invited %s to join his Guild", player->GetName().c_str(), name.c_str());
pInvitee->SetGuildIdInvited(m_id);
_LogEvent(GUILD_EVENT_LOG_INVITE_PLAYER, player->GetGUID().GetCounter(), pInvitee->GetGUID().GetCounter());
- WorldPacket data(SMSG_GUILD_INVITE, 100);
- data << uint32(GetLevel());
- data << uint32(m_emblemInfo.GetBorderStyle());
- data << uint32(m_emblemInfo.GetBorderColor());
- data << uint32(m_emblemInfo.GetStyle());
- data << uint32(m_emblemInfo.GetBackgroundColor());
- data << uint32(m_emblemInfo.GetColor());
-
- ObjectGuid oldGuildGuid;
- if (ObjectGuid::LowType oldId = pInvitee->GetGuildId())
- oldGuildGuid = ObjectGuid::Create<HighGuid::Guild>(oldId);
-
- ObjectGuid newGuildGuid = GetGUID();
-
- data.WriteBit(newGuildGuid[3]);
- data.WriteBit(newGuildGuid[2]);
- data.WriteBits(pInvitee->GetGuildName().length(), 8);
- data.WriteBit(newGuildGuid[1]);
- data.WriteBit(oldGuildGuid[6]);
- data.WriteBit(oldGuildGuid[4]);
- data.WriteBit(oldGuildGuid[1]);
- data.WriteBit(oldGuildGuid[5]);
- data.WriteBit(oldGuildGuid[7]);
- data.WriteBit(oldGuildGuid[2]);
- data.WriteBit(newGuildGuid[7]);
- data.WriteBit(newGuildGuid[0]);
- data.WriteBit(newGuildGuid[6]);
- data.WriteBits(m_name.length(), 8);
- data.WriteBit(oldGuildGuid[3]);
- data.WriteBit(oldGuildGuid[0]);
- data.WriteBit(newGuildGuid[5]);
- data.WriteBits(player->GetName().size(), 7);
- data.WriteBit(newGuildGuid[4]);
-
- data.FlushBits();
-
- data.WriteByteSeq(newGuildGuid[1]);
- data.WriteByteSeq(oldGuildGuid[3]);
- data.WriteByteSeq(newGuildGuid[6]);
- data.WriteByteSeq(oldGuildGuid[2]);
- data.WriteByteSeq(oldGuildGuid[1]);
- data.WriteByteSeq(newGuildGuid[0]);
-
- if (!pInvitee->GetGuildName().empty())
- data.WriteString(pInvitee->GetGuildName());
-
- data.WriteByteSeq(newGuildGuid[7]);
- data.WriteByteSeq(newGuildGuid[2]);
-
- data.WriteString(player->GetName());
-
- data.WriteByteSeq(oldGuildGuid[7]);
- data.WriteByteSeq(oldGuildGuid[6]);
- data.WriteByteSeq(oldGuildGuid[5]);
- data.WriteByteSeq(oldGuildGuid[0]);
- data.WriteByteSeq(newGuildGuid[4]);
-
- data.WriteString(m_name);
-
- data.WriteByteSeq(newGuildGuid[5]);
- data.WriteByteSeq(newGuildGuid[3]);
- data.WriteByteSeq(oldGuildGuid[4]);
- pInvitee->GetSession()->SendPacket(&data);
+ WorldPackets::Guild::GuildInvite invite;
+
+ invite.InviterVirtualRealmAddress = GetVirtualRealmAddress();
+ invite.GuildVirtualRealmAddress = GetVirtualRealmAddress();
+ invite.GuildGUID = GetGUID();
+
+ invite.EmblemStyle = uint32(m_emblemInfo.GetStyle());
+ invite.EmblemColor = uint32(m_emblemInfo.GetColor());
+ invite.BorderStyle = uint32(m_emblemInfo.GetBorderStyle());
+ invite.BorderColor = uint32(m_emblemInfo.GetBorderColor());
+ invite.Background = uint32(m_emblemInfo.GetBackgroundColor());
+ invite.Level = int32(GetLevel());
+
+ invite.InviterName = player->GetName();
+ invite.GuildName = GetName();
+
+ if (Guild* oldGuild = pInvitee->GetGuild())
+ {
+ invite.OldGuildGUID = oldGuild->GetGUID();
+ invite.OldGuildName = oldGuild->GetName();
+ invite.OldGuildVirtualRealmAddress = GetVirtualRealmAddress();
+ }
+
+ pInvitee->GetSession()->SendPacket(invite.Write());
TC_LOG_DEBUG("guild", "SMSG_GUILD_INVITE [%s]", pInvitee->GetName().c_str());
}
@@ -1874,9 +1676,9 @@ void Guild::HandleLeaveMember(WorldSession* session)
{
if (m_members.size() > 1)
// Leader cannot leave if he is not the last member
- SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_LEADER_LEAVE);
+ SendCommandResult(session, GUILD_COMMAND_LEAVE_GUILD, ERR_GUILD_LEADER_LEAVE);
else if (GetLevel() >= sWorld->getIntConfig(CONFIG_GUILD_UNDELETABLE_LEVEL))
- SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL);
+ SendCommandResult(session, GUILD_COMMAND_LEAVE_GUILD, ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL);
else
{
// Guild is disbanded if leader leaves.
@@ -1889,9 +1691,9 @@ void Guild::HandleLeaveMember(WorldSession* session)
DeleteMember(player->GetGUID(), false, false);
_LogEvent(GUILD_EVENT_LOG_LEAVE_GUILD, player->GetGUID().GetCounter());
- _BroadcastEvent(GE_LEFT, player->GetGUID(), player->GetName().c_str());
+ SendEventPlayerLeft(player);
- SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_COMMAND_SUCCESS, m_name);
+ SendCommandResult(session, GUILD_COMMAND_LEAVE_GUILD, ERR_GUILD_COMMAND_SUCCESS, m_name);
}
sCalendarMgr->RemovePlayerGuildEventsAndSignups(player->GetGUID(), GetId());
@@ -1906,27 +1708,30 @@ void Guild::HandleRemoveMember(WorldSession* session, ObjectGuid guid)
// Player must have rights to remove members
if (!_HasRankRight(player, GR_RIGHT_REMOVE))
- SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_PERMISSIONS);
+ SendCommandResult(session, GUILD_COMMAND_REMOVE_PLAYER, ERR_GUILD_PERMISSIONS);
else if (Member* member = GetMember(guid))
{
std::string name = member->GetName();
// Guild masters cannot be removed
if (member->IsRank(GR_GUILDMASTER))
- SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_LEADER_LEAVE);
+ SendCommandResult(session, GUILD_COMMAND_REMOVE_PLAYER, ERR_GUILD_LEADER_LEAVE);
// Do not allow to remove player with the same rank or higher
else
{
- Member const* memberMe = GetMember(player->GetGUID());
+ Member* memberMe = GetMember(player->GetGUID());
if (!memberMe || member->IsRankNotLower(memberMe->GetRankId()))
- SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_RANK_TOO_HIGH_S, name);
+ SendCommandResult(session, GUILD_COMMAND_REMOVE_PLAYER, ERR_GUILD_RANK_TOO_HIGH_S, name);
else
{
// After call to DeleteMember pointer to member becomes invalid
DeleteMember(guid, false, true);
_LogEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, player->GetGUID().GetCounter(), guid.GetCounter());
- _BroadcastEvent(GE_REMOVED, ObjectGuid::Empty, name.c_str(), player->GetName().c_str());
- SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_COMMAND_SUCCESS, name);
+
+ Player* pMember = ObjectAccessor::FindConnectedPlayer(guid);
+ SendEventPlayerLeft(pMember, player, true);
+
+ SendCommandResult(session, GUILD_COMMAND_REMOVE_PLAYER, ERR_GUILD_COMMAND_SUCCESS, name);
}
}
}
@@ -1935,7 +1740,7 @@ void Guild::HandleRemoveMember(WorldSession* session, ObjectGuid guid)
void Guild::HandleUpdateMemberRank(WorldSession* session, ObjectGuid guid, bool demote)
{
Player* player = session->GetPlayer();
- GuildCommandType type = demote ? GUILD_COMMAND_DEMOTE : GUILD_COMMAND_PROMOTE;
+ GuildCommandType type = demote ? GUILD_COMMAND_DEMOTE_PLAYER : GUILD_COMMAND_PROMOTE_PLAYER;
// Player must have rights to promote
if (!_HasRankRight(player, demote ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE))
SendCommandResult(session, type, ERR_GUILD_PERMISSIONS);
@@ -1982,7 +1787,7 @@ void Guild::HandleUpdateMemberRank(WorldSession* session, ObjectGuid guid, bool
uint32 newRankId = member->GetRankId() + (demote ? 1 : -1);
member->ChangeRank(newRankId);
_LogEvent(demote ? GUILD_EVENT_LOG_DEMOTE_PLAYER : GUILD_EVENT_LOG_PROMOTE_PLAYER, player->GetGUID().GetCounter(), member->GetGUID().GetCounter(), newRankId);
- _BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, ObjectGuid::Empty, player->GetName().c_str(), name.c_str(), _GetRankName(newRankId).c_str());
+ //_BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, ObjectGuid::Empty, player->GetName().c_str(), name.c_str(), _GetRankName(newRankId).c_str());
}
}
@@ -1993,12 +1798,12 @@ void Guild::HandleSetMemberRank(WorldSession* session, ObjectGuid targetGuid, Ob
if (!member)
return;
GuildRankRights rights = GR_RIGHT_PROMOTE;
- GuildCommandType type = GUILD_COMMAND_PROMOTE;
+ GuildCommandType type = GUILD_COMMAND_PROMOTE_PLAYER;
if (rank > member->GetRankId())
{
rights = GR_RIGHT_DEMOTE;
- type = GUILD_COMMAND_DEMOTE;
+ type = GUILD_COMMAND_DEMOTE_PLAYER;
}
// Promoted player must be a member of guild
@@ -2026,8 +1831,13 @@ void Guild::HandleAddNewRank(WorldSession* session, std::string const& name)
// Only leader can add new rank
if (_IsLeader(session->GetPlayer()))
+ {
if (_CreateRank(name, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK))
- _BroadcastEvent(GE_RANK_CREATED, ObjectGuid::Empty);
+ {
+ WorldPackets::Guild::GuildEventRanksUpdated eventPacket;
+ BroadcastPacket(eventPacket.Write());
+ }
+ }
}
void Guild::HandleRemoveRank(WorldSession* session, uint8 rankId)
@@ -2041,6 +1851,7 @@ void Guild::HandleRemoveRank(WorldSession* session, uint8 rankId)
stmt->setUInt64(0, m_id);
stmt->setUInt8(1, rankId);
CharacterDatabase.Execute(stmt);
+
// Delete rank
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANK);
stmt->setUInt64(0, m_id);
@@ -2049,7 +1860,8 @@ void Guild::HandleRemoveRank(WorldSession* session, uint8 rankId)
m_ranks.erase(m_ranks.begin() + rankId);
- _BroadcastEvent(GE_RANK_DELETED, ObjectGuid::Empty, std::to_string(rankId).c_str());
+ WorldPackets::Guild::GuildEventRanksUpdated eventPacket;
+ BroadcastPacket(eventPacket.Write());
}
void Guild::HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool cashFlow /*=false*/)
@@ -2070,8 +1882,7 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool
_LogBankEvent(trans, cashFlow ? GUILD_BANK_LOG_CASH_FLOW_DEPOSIT : GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), player->GetGUID().GetCounter(), amount);
CharacterDatabase.CommitTransaction(trans);
- std::string aux = ByteArrayToHexStr(reinterpret_cast<uint8*>(&m_bankMoney), 8, true);
- _BroadcastEvent(GE_BANK_MONEY_SET, ObjectGuid::Empty, aux.c_str());
+ SendEventBankMoneyChanged();
if (player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
{
@@ -2120,8 +1931,7 @@ bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint64 amount, bool
_LogBankEvent(trans, repair ? GUILD_BANK_LOG_REPAIR_MONEY : GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), player->GetGUID().GetCounter(), amount);
CharacterDatabase.CommitTransaction(trans);
- std::string aux = ByteArrayToHexStr(reinterpret_cast<uint8*>(&m_bankMoney), 8, true);
- _BroadcastEvent(GE_BANK_MONEY_SET, ObjectGuid::Empty, aux.c_str());
+ SendEventBankMoneyChanged();
return true;
}
@@ -2134,18 +1944,18 @@ void Guild::HandleMemberLogout(WorldSession* session)
member->UpdateLogoutTime();
member->ResetFlags();
}
- _BroadcastEvent(GE_SIGNED_OFF, player->GetGUID(), player->GetName().c_str());
+ SendEventPresenceChanged(session, false, true);
SaveToDB();
}
-void Guild::HandleDisband(WorldSession* session)
+void Guild::HandleDelete(WorldSession* session)
{
// Only leader can disband guild
if (_IsLeader(session->GetPlayer()))
{
Disband();
- TC_LOG_DEBUG("guild", "Guild Successfully Disbanded");
+ TC_LOG_DEBUG("guild", "%s successfully deleted", GetGUID().ToString().c_str());
delete this;
}
}
@@ -2159,99 +1969,74 @@ void Guild::HandleGuildPartyRequest(WorldSession* session)
if (!IsMember(player->GetGUID()) || !group)
return;
- WorldPacket data(SMSG_GUILD_PARTY_STATE_RESPONSE, 13);
- data.WriteBit(player->GetMap()->GetOwnerGuildId(player->GetTeam()) == GetId()); // Is guild group
- data.FlushBits();
- data << float(0.f); // Guild XP multiplier
- data << uint32(0); // Current guild members
- data << uint32(0); // Needed guild members
+ WorldPackets::Guild::GuildPartyState partyStateResponse;
+ partyStateResponse.InGuildParty = (player->GetMap()->GetOwnerGuildId(player->GetTeam()) == GetId());
+ partyStateResponse.NumMembers = 0;
+ partyStateResponse.NumRequired = 0;
+ partyStateResponse.GuildXPEarnedMult = 0.0f;
+ session->SendPacket(partyStateResponse.Write());
- session->SendPacket(&data);
TC_LOG_DEBUG("guild", "SMSG_GUILD_PARTY_STATE_RESPONSE [%s]", session->GetPlayerInfo().c_str());
}
void Guild::HandleGuildRequestChallengeUpdate(WorldSession* session)
{
- WorldPacket data(SMSG_GUILD_CHALLENGE_UPDATED, 4 * GUILD_CHALLENGES_TYPES * 5);
+ WorldPackets::Guild::GuildChallengeUpdate updatePacket;
for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
- data << uint32(GuildChallengeXPReward[i]);
+ updatePacket.CurrentCount[i] = int32(0); /// @todo current count
for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
- data << uint32(GuildChallengeGoldReward[i]);
+ updatePacket.MaxCount[i] = int32(GuildChallengesMaxCount[i]);
for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
- data << uint32(GuildChallengesPerWeek[i]);
+ updatePacket.MaxLevelGold[i] = int32(GuildChallengeMaxLevelGoldReward[i]);
for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
- data << uint32(GuildChallengeMaxLevelGoldReward[i]);
+ updatePacket.Gold[i] = int32(GuildChallengeGoldReward[i]);
- for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
- data << uint32(0); /// @todo current count
-
- session->SendPacket(&data);
+ session->SendPacket(updatePacket.Write());
}
void Guild::SendEventLog(WorldSession* session) const
{
- WorldPacket data(SMSG_GUILD_EVENT_LOG_QUERY_RESULTS, 1 + m_eventLog->GetSize() * (1 + 8 + 4));
- m_eventLog->WritePacket(data);
- session->SendPacket(&data);
- TC_LOG_DEBUG("guild", "SMSG_GUILD_EVENT_LOG_QUERY_RESULT [%s]", session->GetPlayerInfo().c_str());
-}
-
-void Guild::SendNewsUpdate(WorldSession* session)
-{
- uint32 size = m_newsLog->GetSize();
- GuildLog* logs = m_newsLog->GetGuildLog();
+ GuildLog* logs = m_eventLog->GetGuildLog();
if (!logs)
return;
- WorldPacket data(SMSG_GUILD_NEWS_UPDATE, (21 + size * (26 + 8)) / 8 + (8 + 6 * 4) * size);
- data.WriteBits(size, 21);
+ WorldPackets::Guild::GuildEventLogQueryResults packet;
+ packet.Entry.reserve(m_eventLog->GetSize());
for (GuildLog::const_iterator itr = logs->begin(); itr != logs->end(); ++itr)
{
- data.WriteBits(0, 26); // Not yet implemented used for guild achievements
- ObjectGuid guid = ((NewsLogEntry*)(*itr))->GetPlayerGuid();
-
- data.WriteBit(guid[7]);
- data.WriteBit(guid[0]);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[4]);
- data.WriteBit(guid[3]);
- data.WriteBit(guid[1]);
- data.WriteBit(guid[2]);
+ EventLogEntry* eventLog = (EventLogEntry*)(*itr);
+ eventLog->WritePacket(packet);
}
- data.FlushBits();
+ session->SendPacket(packet.Write());
- for (GuildLog::const_iterator itr = logs->begin(); itr != logs->end(); ++itr)
- {
- NewsLogEntry* news = (NewsLogEntry*)(*itr);
- ObjectGuid guid = news->GetPlayerGuid();
- data.WriteByteSeq(guid[5]);
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_EVENT_LOG_QUERY_RESULTS [%s]", session->GetPlayerInfo().c_str());
+}
+
+void Guild::SendNewsUpdate(WorldSession* session)
+{
+ GuildLog* logs = m_newsLog->GetGuildLog();
- data << uint32(news->GetFlags()); // 1 sticky
- data << uint32(news->GetValue());
- data << uint32(0);
+ if (!logs)
+ return;
- data.WriteByteSeq(guid[7]);
- data.WriteByteSeq(guid[6]);
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[0]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[1]);
+ WorldPackets::Guild::GuildNews packet;
+ packet.NewsEvents.reserve(m_newsLog->GetSize());
- data << uint32(news->GetGUID());
- data << uint32(news->GetType());
- data.AppendPackedTime(news->GetTimestamp());
+ for (GuildLog::const_iterator itr = logs->begin(); itr != logs->end(); ++itr)
+ {
+ NewsLogEntry* eventLog = (NewsLogEntry*)(*itr);
+ eventLog->WritePacket(packet);
}
- session->SendPacket(&data);
+ session->SendPacket(packet.Write());
+
TC_LOG_DEBUG("guild", "SMSG_GUILD_NEWS_UPDATE [%s]", session->GetPlayerInfo().c_str());
}
@@ -2260,14 +2045,26 @@ void Guild::SendBankLog(WorldSession* session, uint8 tabId) const
// GUILD_BANK_MAX_TABS send by client for money log
if (tabId < _GetPurchasedTabsSize() || tabId == GUILD_BANK_MAX_TABS)
{
- LogHolder const* log = m_bankEventLog[tabId];
- WorldPacket data(SMSG_GUILD_BANK_LOG_QUERY_RESULT, log->GetSize() * (4 * 4 + 1) + 1 + 1);
- data.WriteBit(GetLevel() >= 5 && tabId == GUILD_BANK_MAX_TABS); // has Cash Flow perk
- log->WritePacket(data);
- data << uint32(tabId);
+ GuildLog* logs = m_bankEventLog[tabId]->GetGuildLog();
+
+ if (!logs)
+ return;
+
+ WorldPackets::Guild::GuildBankLogQueryResults packet;
+ packet.Tab = int32(tabId);
+
//if (tabId == GUILD_BANK_MAX_TABS && hasCashFlow)
- // data << uint64(cashFlowContribution);
- session->SendPacket(&data);
+ // packet.WeeklyBonusMoney.Set(uint64(weeklyBonusMoney));
+
+ packet.Entry.reserve(m_bankEventLog[tabId]->GetSize());
+ for (GuildLog::const_iterator itr = logs->begin(); itr != logs->end(); ++itr)
+ {
+ BankEventLogEntry* bankEventLog = (BankEventLogEntry*)(*itr);
+ bankEventLog->WritePacket(packet);
+ }
+
+ session->SendPacket(packet.Write());
+
TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_LOG_QUERY_RESULT [%s] TabId: %u", session->GetPlayerInfo().c_str(), tabId);
}
}
@@ -2286,19 +2083,22 @@ void Guild::SendPermissions(WorldSession* session) const
uint8 rankId = member->GetRankId();
- WorldPacket data(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, 4 * 15 + 1);
- data << uint32(rankId);
- data << uint32(_GetPurchasedTabsSize());
- data << uint32(_GetRankRights(rankId));
- data << uint32(_GetMemberRemainingMoney(member));
- data.WriteBits(GUILD_BANK_MAX_TABS, 23);
+ WorldPackets::Guild::GuildPermissionsQueryResults queryResult;
+ queryResult.RankID = rankId;
+ queryResult.WithdrawGoldLimit = _GetMemberRemainingMoney(member);
+ queryResult.Flags = _GetRankRights(rankId);
+ queryResult.NumTabs = _GetPurchasedTabsSize();
+ queryResult.Tab.reserve(GUILD_BANK_MAX_TABS);
+
for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId)
{
- data << uint32(_GetRankBankTabRights(rankId, tabId));
- data << uint32(_GetMemberRemainingSlots(member, tabId));
+ WorldPackets::Guild::GuildPermissionsQueryResults::GuildRankTabPermissions tabPerm;
+ tabPerm.Flags = _GetRankBankTabRights(rankId, tabId);
+ tabPerm.WithdrawItemLimit = _GetMemberRemainingSlots(member, tabId);
+ queryResult.Tab.push_back(tabPerm);
}
- session->SendPacket(&data);
+ session->SendPacket(queryResult.Write());
TC_LOG_DEBUG("guild", "SMSG_GUILD_PERMISSIONS_QUERY_RESULTS [%s] Rank: %u", session->GetPlayerInfo().c_str(), rankId);
}
@@ -2309,9 +2109,11 @@ void Guild::SendMoneyInfo(WorldSession* session) const
return;
int32 amount = _GetMemberRemainingMoney(member);
- WorldPacket data(SMSG_GUILD_BANK_MONEY_WITHDRAWN, 8);
- data << int64(amount);
- session->SendPacket(&data);
+
+ WorldPackets::Guild::GuildBankRemainingWithdrawMoney packet;
+ packet.RemainingWithdrawMoney = int64(amount);
+ session->SendPacket(packet.Write());
+
TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_MONEY_WITHDRAWN [%s] Money: %u", session->GetPlayerInfo().c_str(), amount);
}
@@ -2324,53 +2126,119 @@ void Guild::SendLoginInfo(WorldSession* session)
/*
Login sequence:
- SMSG_GUILD_EVENT - GE_MOTD
+ SMSG_GUILD_EVENT_MOTD
SMSG_GUILD_RANK
- SMSG_GUILD_EVENT - GE_SIGNED_ON
+ SMSG_GUILD_EVENT_PRESENCE_CHANGE - LoggedOn: True
-- learn perks
- SMSG_GUILD_REPUTATION_WEEKLY_CAP
- SMSG_GUILD_ACHIEVEMENT_DATA
+ SMSG_ALL_GUILD_ACHIEVEMENTS
SMSG_GUILD_MEMBER_DAILY_RESET // bank withdrawal reset
*/
- WorldPacket data(SMSG_GUILD_EVENT, 1 + 1 + m_motd.size() + 1);
- data << uint8(GE_MOTD);
- data << uint8(1);
- data << m_motd;
- session->SendPacket(&data);
-
- TC_LOG_DEBUG("guild", "SMSG_GUILD_EVENT [%s] MOTD", session->GetPlayerInfo().c_str());
-
+ SendEventMOTD(session);
SendGuildRankInfo(session);
- _BroadcastEvent(GE_SIGNED_ON, player->GetGUID(), player->GetName().c_str());
+ SendEventPresenceChanged(session, true, true); // Broadcast
// Send to self separately, player is not in world yet and is not found by _BroadcastEvent
- data.Initialize(SMSG_GUILD_EVENT, 1 + 1 + player->GetName().size() + 8);
- data << uint8(GE_SIGNED_ON);
- data << uint8(1);
- data << player->GetName();
- data << player->GetGUID();
- session->SendPacket(&data);
-
- data.Initialize(SMSG_GUILD_MEMBER_DAILY_RESET, 0); // tells the client to request bank withdrawal limit
- session->SendPacket(&data);
+ SendEventPresenceChanged(session, true);
- if (!sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED))
- return;
+ if (member->GetGUID() == GetLeaderGUID())
+ {
+ WorldPackets::Guild::GuildFlaggedForRename renameFlag;
+ renameFlag.FlagSet = false;
+ player->GetSession()->SendPacket(renameFlag.Write());
+ }
for (uint32 i = 0; i < sGuildPerkSpellsStore.GetNumRows(); ++i)
if (GuildPerkSpellsEntry const* entry = sGuildPerkSpellsStore.LookupEntry(i))
if (entry->GuildLevel <= GetLevel())
player->LearnSpell(entry->SpellID, true);
- SendGuildReputationWeeklyCap(session, member->GetWeekReputation());
-
m_achievementMgr.SendAllAchievementData(player);
+ WorldPackets::Guild::GuildMemberDailyReset packet; // tells the client to request bank withdrawal limit
+ player->GetSession()->SendPacket(packet.Write());
+
member->SetStats(player);
member->AddFlag(GUILDMEMBER_STATUS_ONLINE);
}
+void Guild::SendEventBankMoneyChanged()
+{
+ WorldPackets::Guild::GuildEventBankMoneyChanged eventPacket;
+ eventPacket.Money = GetBankMoney();
+ BroadcastPacket(eventPacket.Write());
+}
+
+void Guild::SendEventMOTD(WorldSession* session, bool broadcast)
+{
+ WorldPackets::Guild::GuildEventMotd eventPacket;
+ eventPacket.MotdText = GetMOTD();
+
+ if (broadcast)
+ BroadcastPacket(eventPacket.Write());
+ else
+ {
+ session->SendPacket(eventPacket.Write());
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_EVENT_MOTD [%s] ", session->GetPlayerInfo().c_str());
+ }
+}
+
+void Guild::SendEventNewLeader(Member* newLeader, Member* oldLeader, bool isSelfPromoted)
+{
+ WorldPackets::Guild::GuildEventNewLeader eventPacket;
+ eventPacket.SelfPromoted = isSelfPromoted;
+ if (newLeader)
+ {
+ eventPacket.NewLeaderGUID = newLeader->GetGUID();
+ eventPacket.NewLeaderName = newLeader->GetName();
+ eventPacket.NewLeaderVirtualRealmAddress = GetVirtualRealmAddress();
+ }
+
+ if (oldLeader)
+ {
+ eventPacket.OldLeaderGUID = oldLeader->GetGUID();
+ eventPacket.OldLeaderName = oldLeader->GetName();
+ eventPacket.OldLeaderVirtualRealmAddress = GetVirtualRealmAddress();
+ }
+
+ BroadcastPacket(eventPacket.Write());
+}
+
+void Guild::SendEventPlayerLeft(Player* leaver, Player* remover, bool isRemoved)
+{
+ WorldPackets::Guild::GuildEventPlayerLeft eventPacket;
+ eventPacket.Removed = isRemoved;
+ eventPacket.LeaverGUID = leaver->GetGUID();
+ eventPacket.LeaverName = leaver->GetName();
+ eventPacket.LeaverVirtualRealmAddress = GetVirtualRealmAddress();
+
+ if (isRemoved && remover != nullptr)
+ {
+ eventPacket.RemoverGUID = remover->GetGUID();
+ eventPacket.RemoverName = remover->GetName();
+ eventPacket.RemoverVirtualRealmAddress = GetVirtualRealmAddress();
+ }
+
+ BroadcastPacket(eventPacket.Write());
+}
+
+void Guild::SendEventPresenceChanged(WorldSession* session, bool loggedOn, bool broadcast)
+{
+ Player* player = session->GetPlayer();
+
+ WorldPackets::Guild::GuildEventPresenceChange eventPacket;
+ eventPacket.Guid = player->GetGUID();
+ eventPacket.Name = player->GetName();
+ eventPacket.VirtualRealmAddress = GetVirtualRealmAddress();
+ eventPacket.LoggedOn = loggedOn;
+ eventPacket.Mobile = false;
+
+ if (broadcast)
+ BroadcastPacket(eventPacket.Write());
+ else
+ session->SendPacket(eventPacket.Write());
+}
+
// Loading methods
bool Guild::LoadFromDB(Field* fields)
{
@@ -2383,10 +2251,8 @@ bool Guild::LoadFromDB(Field* fields)
m_createdDate = time_t(fields[10].GetUInt32());
m_bankMoney = fields[11].GetUInt64();
_level = fields[12].GetUInt32();
- _experience = fields[13].GetUInt64();
- _todayExperience = fields[14].GetUInt64();
- uint8 purchasedTabs = uint8(fields[15].GetUInt64());
+ uint8 purchasedTabs = uint8(fields[13].GetUInt64());
if (purchasedTabs > GUILD_BANK_MAX_TABS)
purchasedTabs = GUILD_BANK_MAX_TABS;
@@ -2424,8 +2290,8 @@ bool Guild::LoadMemberFromDB(Field* fields)
void Guild::LoadBankRightFromDB(Field* fields)
{
- // tabId rights slots
- GuildBankRightsAndSlots rightsAndSlots(fields[1].GetUInt8(), fields[3].GetUInt8(), fields[4].GetUInt32());
+ // tabId rights slots
+ GuildBankRightsAndSlots rightsAndSlots(fields[1].GetUInt8(), fields[3].GetInt8(), fields[4].GetInt32());
// rankId
_SetRankBankTabRightsAndSlots(fields[2].GetUInt8(), rightsAndSlots, false);
}
@@ -2698,7 +2564,7 @@ bool Guild::AddMember(ObjectGuid guid, uint8 rankId)
// Remove all player signs from another petitions
// This will be prevent attempt to join many guilds and corrupt guild data integrity
- Player::RemovePetitionsAndSigns(guid, GUILD_CHARTER_TYPE);
+ Player::RemovePetitionsAndSigns(guid);
ObjectGuid::LowType lowguid = guid.GetCounter();
@@ -2734,8 +2600,9 @@ bool Guild::AddMember(ObjectGuid guid, uint8 rankId)
name,
fields[1].GetUInt8(),
fields[2].GetUInt8(),
- fields[3].GetUInt16(),
- fields[4].GetUInt32(),
+ fields[3].GetUInt8(),
+ fields[4].GetUInt16(),
+ fields[5].GetUInt32(),
0);
ok = member->CheckStats();
@@ -2754,7 +2621,13 @@ bool Guild::AddMember(ObjectGuid guid, uint8 rankId)
_UpdateAccountsNumber();
_LogEvent(GUILD_EVENT_LOG_JOIN_GUILD, lowguid);
- _BroadcastEvent(GE_JOINED, guid, name.c_str());
+
+ WorldPackets::Guild::GuildEventPlayerJoined joinNotificationPacket;
+ joinNotificationPacket.Guid = guid;
+ joinNotificationPacket.Name = name;
+ joinNotificationPacket.VirtualRealmAddress = GetVirtualRealmAddress();
+ BroadcastPacket(joinNotificationPacket.Write());
+
sGuildFinderMgr->RemoveAllMembershipRequestsFromPlayer(guid);
// Call scripts if member was succesfully added (and stored to database)
@@ -2798,8 +2671,8 @@ void Guild::DeleteMember(ObjectGuid guid, bool isDisbanding, bool isKicked, bool
// If leader does not exist (at guild loading with deleted leader) do not send broadcasts
if (oldLeader)
{
- _BroadcastEvent(GE_LEADER_CHANGED, ObjectGuid::Empty, oldLeader->GetName().c_str(), newLeader->GetName().c_str());
- _BroadcastEvent(GE_LEFT, guid, oldLeader->GetName().c_str());
+ SendEventNewLeader(newLeader, oldLeader, true);
+ SendEventPlayerLeft(player);
}
}
// Call script on remove before member is actually removed from guild (and database)
@@ -2879,6 +2752,10 @@ void Guild::SetBankTabText(uint8 tabId, std::string const& text)
{
pTab->SetText(text);
pTab->SendText(this, NULL);
+
+ WorldPackets::Guild::GuildEventTabTextChanged eventPacket;
+ eventPacket.Tab = tabId;
+ BroadcastPacket(eventPacket.Write());
}
}
@@ -3115,7 +2992,7 @@ inline void Guild::_UpdateMemberWithdrawSlots(SQLTransaction& trans, ObjectGuid
}
}
-inline bool Guild::_MemberHasTabRights(ObjectGuid guid, uint8 tabId, uint32 rights) const
+inline bool Guild::_MemberHasTabRights(ObjectGuid guid, uint8 tabId, int32 rights) const
{
if (const Member* member = GetMember(guid))
{
@@ -3313,111 +3190,98 @@ void Guild::_SendBankContentUpdate(uint8 tabId, SlotIds slots) const
{
if (BankTab const* tab = GetBankTab(tabId))
{
- ByteBuffer tabData;
- WorldPacket data(SMSG_GUILD_BANK_LIST, 1200);
- data.WriteBit(0);
- data.WriteBits(slots.size(), 20); // Item count
- data.WriteBits(0, 22); // Tab count
+ WorldPackets::Guild::GuildBankQueryResults packet;
+ packet.FullUpdate = true; // @todo
+ packet.Tab = int32(tabId);
+ packet.Money = m_bankMoney;
for (SlotIds::const_iterator itr = slots.begin(); itr != slots.end(); ++itr)
{
- data.WriteBit(0);
-
Item const* tabItem = tab->GetItem(*itr);
- uint32 enchantCount = 0;
+
+ WorldPackets::Guild::GuildBankItemInfo itemInfo;
+
+ itemInfo.Slot = int32(*itr);
+ itemInfo.Item.ItemID = int32(tabItem ? tabItem->GetEntry() : 0);
+ itemInfo.Count = int32(tabItem ? tabItem->GetCount() : 0);
+ itemInfo.Charges = int32(tabItem ? abs(tabItem->GetSpellCharges()) : 0);
+ itemInfo.OnUseEnchantmentID = 0/*int32(tabItem->GetItemSuffixFactor())*/;
+ itemInfo.Flags = 0;
+ itemInfo.Locked = false;
+
if (tabItem)
{
- for (uint32 enchSlot = 0; enchSlot < MAX_ENCHANTMENT_SLOT; ++enchSlot)
+ uint32 enchants = 0;
+ for (uint32 ench = 0; ench < MAX_ENCHANTMENT_SLOT; ++ench)
+ if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(ench)))
+ ++enchants;
+
+ itemInfo.SocketEnchant.reserve(enchants);
+ for (uint32 ench = 0; ench < MAX_ENCHANTMENT_SLOT; ++ench)
{
- if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(enchSlot)))
+ if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(ench)))
{
- tabData << uint32(enchantId);
- tabData << uint32(enchSlot);
- ++enchantCount;
+ WorldPackets::Guild::GuildBankItemInfo::GuildBankSocketEnchant socketEnchant;
+ socketEnchant.SocketEnchantID = int32(enchantId);
+ socketEnchant.SocketIndex = int32(ench);
+ itemInfo.SocketEnchant.push_back(socketEnchant);
}
}
}
- data.WriteBits(enchantCount, 23); // enchantment count
-
- tabData << uint32(0);
- tabData << uint32(0);
- tabData << uint32(0);
- tabData << uint32(tabItem ? tabItem->GetCount() : 0); // ITEM_FIELD_STACK_COUNT
- tabData << uint32(*itr);
- tabData << uint32(0);
- tabData << uint32(tabItem ? tabItem->GetEntry() : 0);
- tabData << uint32(tabItem ? tabItem->GetItemRandomPropertyId() : 0);
- tabData << uint32(tabItem ? abs(tabItem->GetSpellCharges()) : 0); // Spell charges
- tabData << uint32(tabItem ? tabItem->GetItemSuffixFactor() : 0); // SuffixFactor
+ packet.ItemInfo.push_back(itemInfo);
}
- data.FlushBits();
-
- data << uint64(m_bankMoney);
- if (!tabData.empty())
- data.append(tabData);
-
- data << uint32(tabId);
-
- size_t rempos = data.wpos();
- data << uint32(0); // Item withdraw amount, will be filled later
-
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if (_MemberHasTabRights(itr->second->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
if (Player* player = itr->second->FindPlayer())
{
- data.put<uint32>(rempos, uint32(_GetMemberRemainingSlots(itr->second, tabId)));
- player->GetSession()->SendPacket(&data);
+ packet.WithdrawalsRemaining = int32(_GetMemberRemainingSlots(itr->second, tabId));
+ player->GetSession()->SendPacket(packet.Write());
}
- TC_LOG_DEBUG("guild", "WORLD: Sent (SMSG_GUILD_BANK_LIST)");
+ TC_LOG_DEBUG("guild", "WORLD: Sent SMSG_GUILD_BANK_QUERY_RESULTS");
}
}
-void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid, const char* param1, const char* param2, const char* param3) const
-{
- uint8 count = !param3 ? (!param2 ? (!param1 ? 0 : 1) : 2) : 3;
-
- WorldPacket data(SMSG_GUILD_EVENT, 1 + 1 + count + 8);
- data << uint8(guildEvent);
- data << uint8(count);
-
- if (param3)
- data << param1 << param2 << param3;
- else if (param2)
- data << param1 << param2;
- else if (param1)
- data << param1;
-
- if (!guid.IsEmpty())
- data << guid;
-
- BroadcastPacket(&data);
-
- if (sLog->ShouldLog("guild", LOG_LEVEL_DEBUG))
- TC_LOG_DEBUG("guild", "SMSG_GUILD_EVENT [Broadcast] Event: %s (%u)", _GetGuildEventString(guildEvent).c_str(), guildEvent);
-}
-
-void Guild::SendBankList(WorldSession* session, uint8 tabId, bool withContent, bool withTabInfo) const
+void Guild::SendBankList(WorldSession* session, uint8 tabId, bool fullUpdate) const
{
Member const* member = GetMember(session->GetPlayer()->GetGUID());
if (!member) // Shouldn't happen, just in case
return;
- ByteBuffer tabData;
- WorldPacket data(SMSG_GUILD_BANK_LIST, 500);
- data.WriteBit(0);
+ WorldPackets::Guild::GuildBankQueryResults packet;
+
+ packet.Money = uint64(m_bankMoney);
+ packet.WithdrawalsRemaining = int32(_GetMemberRemainingSlots(member, tabId));
+ packet.Tab = int32(tabId);
+ packet.FullUpdate = fullUpdate;
+
+ // TabInfo
+ if (fullUpdate)
+ {
+ packet.TabInfo.reserve(_GetPurchasedTabsSize());
+ for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i)
+ {
+ WorldPackets::Guild::GuildBankTabInfo tabInfo;
+ tabInfo.TabIndex = i;
+ tabInfo.Name = m_bankTabs[i]->GetName();
+ tabInfo.Icon = m_bankTabs[i]->GetIcon();
+ packet.TabInfo.push_back(tabInfo);
+ }
+ }
+
+ // ItemInfo
uint32 itemCount = 0;
- if (withContent && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
+ if (fullUpdate && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
if (BankTab const* tab = GetBankTab(tabId))
for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId)
if (tab->GetItem(slotId))
++itemCount;
- data.WriteBits(itemCount, 20);
- data.WriteBits(withTabInfo ? _GetPurchasedTabsSize() : 0, 22);
- if (withContent && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
+ packet.ItemInfo.reserve(itemCount);
+
+ if (fullUpdate && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
{
if (BankTab const* tab = GetBankTab(tabId))
{
@@ -3425,67 +3289,44 @@ void Guild::SendBankList(WorldSession* session, uint8 tabId, bool withContent, b
{
if (Item* tabItem = tab->GetItem(slotId))
{
- data.WriteBit(0);
+ WorldPackets::Guild::GuildBankItemInfo itemInfo;
+
+ itemInfo.Slot = int32(slotId);
+ itemInfo.Item.ItemID = tabItem->GetEntry();
+ itemInfo.Count = int32(tabItem->GetCount());
+ itemInfo.Charges = int32(abs(tabItem->GetSpellCharges()));
+ itemInfo.EnchantmentID = int32(tabItem->GetItemRandomPropertyId()); // verify that...
+ itemInfo.OnUseEnchantmentID = 0/*int32(tabItem->GetItemSuffixFactor())*/;
+ itemInfo.Flags = 0;
uint32 enchants = 0;
for (uint32 ench = 0; ench < MAX_ENCHANTMENT_SLOT; ++ench)
+ if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(ench)))
+ ++enchants;
+
+ itemInfo.SocketEnchant.reserve(enchants);
+ for (uint32 ench = 0; ench < MAX_ENCHANTMENT_SLOT; ++ench)
{
if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(ench)))
{
- tabData << uint32(enchantId);
- tabData << uint32(ench);
- ++enchants;
+ WorldPackets::Guild::GuildBankItemInfo::GuildBankSocketEnchant socketEnchant;
+ socketEnchant.SocketEnchantID = int32(enchantId);
+ socketEnchant.SocketIndex = int32(ench);
+ itemInfo.SocketEnchant.push_back(socketEnchant);
}
}
- data.WriteBits(enchants, 23);
-
- tabData << uint32(0);
- tabData << uint32(0);
- tabData << uint32(0);
- tabData << uint32(tabItem->GetCount()); // ITEM_FIELD_STACK_COUNT
- tabData << uint32(slotId);
- tabData << uint32(0);
- tabData << uint32(tabItem->GetEntry());
- tabData << uint32(tabItem->GetItemRandomPropertyId());
- tabData << uint32(abs(tabItem->GetSpellCharges())); // Spell charges
- tabData << uint32(tabItem->GetItemSuffixFactor()); // SuffixFactor
+ itemInfo.Locked = false;
+
+ packet.ItemInfo.push_back(itemInfo);
}
}
}
}
- if (withTabInfo)
- {
- for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i)
- {
- data.WriteBits(m_bankTabs[i]->GetIcon().length(), 9);
- data.WriteBits(m_bankTabs[i]->GetName().length(), 7);
- }
- }
-
- data.FlushBits();
-
- if (withTabInfo)
- {
- for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i)
- {
- data.WriteString(m_bankTabs[i]->GetIcon());
- data << uint32(i);
- data.WriteString(m_bankTabs[i]->GetName());
- }
- }
-
- data << uint64(m_bankMoney);
- if (!tabData.empty())
- data.append(tabData);
-
- data << uint32(tabId);
- data << uint32(_GetMemberRemainingSlots(member, tabId));
-
- session->SendPacket(&data);
+ session->SendPacket(packet.Write());
- TC_LOG_DEBUG("guild", "WORLD: Sent (SMSG_GUILD_BANK_LIST)");
+ TC_LOG_DEBUG("guild", "WORLD: Sent SMSG_GUILD_BANK_QUERY_RESULTS");
}
void Guild::SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, uint32 rank)
@@ -3493,45 +3334,12 @@ void Guild::SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, u
Member* member = GetMember(targetGuid);
ASSERT(member);
- WorldPacket data(SMSG_GUILD_SEND_RANK_CHANGE, 100);
- data.WriteBit(setterGuid[7]);
- data.WriteBit(setterGuid[2]);
- data.WriteBit(targetGuid[2]);
- data.WriteBit(setterGuid[1]);
- data.WriteBit(targetGuid[1]);
- data.WriteBit(targetGuid[7]);
- data.WriteBit(targetGuid[0]);
- data.WriteBit(targetGuid[5]);
- data.WriteBit(targetGuid[4]);
- data.WriteBit(rank < member->GetRankId()); // 1 == higher, 0 = lower?
- data.WriteBit(setterGuid[5]);
- data.WriteBit(setterGuid[0]);
- data.WriteBit(targetGuid[6]);
- data.WriteBit(setterGuid[3]);
- data.WriteBit(setterGuid[6]);
- data.WriteBit(targetGuid[3]);
- data.WriteBit(setterGuid[4]);
-
- data.FlushBits();
-
- data << uint32(rank);
- data.WriteByteSeq(setterGuid[3]);
- data.WriteByteSeq(targetGuid[7]);
- data.WriteByteSeq(setterGuid[6]);
- data.WriteByteSeq(setterGuid[2]);
- data.WriteByteSeq(targetGuid[5]);
- data.WriteByteSeq(targetGuid[0]);
- data.WriteByteSeq(setterGuid[7]);
- data.WriteByteSeq(setterGuid[5]);
- data.WriteByteSeq(targetGuid[2]);
- data.WriteByteSeq(targetGuid[1]);
- data.WriteByteSeq(setterGuid[0]);
- data.WriteByteSeq(setterGuid[4]);
- data.WriteByteSeq(setterGuid[1]);
- data.WriteByteSeq(targetGuid[3]);
- data.WriteByteSeq(targetGuid[6]);
- data.WriteByteSeq(targetGuid[4]);
- BroadcastPacket(&data);
+ WorldPackets::Guild::GuildSendRankChange rankChange;
+ rankChange.Officer = setterGuid;
+ rankChange.Other = targetGuid;
+ rankChange.RankID = rank;
+ rankChange.Promote = (rank < member->GetRankId());
+ BroadcastPacket(rankChange.Write());
member->ChangeRank(rank);
@@ -3539,96 +3347,15 @@ void Guild::SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, u
targetGuid.ToString().c_str(), setterGuid.ToString().c_str(), rank);
}
-void Guild::GiveXP(uint32 xp, Player* source)
-{
- if (!sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED))
- return;
-
- /// @todo: Award reputation and count activity for player
-
- if (GetLevel() >= sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL))
- xp = 0; // SMSG_GUILD_XP_GAIN is always sent, even for no gains
-
- if (GetLevel() < GUILD_EXPERIENCE_UNCAPPED_LEVEL)
- xp = std::min(xp, sWorld->getIntConfig(CONFIG_GUILD_DAILY_XP_CAP) - uint32(_todayExperience));
-
- WorldPacket data(SMSG_GUILD_XP_GAIN, 8);
- data << uint64(xp);
- source->GetSession()->SendPacket(&data);
-
- _experience += xp;
- _todayExperience += xp;
-
- if (!xp)
- return;
-
- uint32 oldLevel = GetLevel();
-
- // Ding, mon!
- while (GetExperience() >= sGuildMgr->GetXPForGuildLevel(GetLevel()) && GetLevel() < sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL))
- {
- _experience -= sGuildMgr->GetXPForGuildLevel(GetLevel());
- ++_level;
-
- // Find all guild perks to learn
- std::vector<uint32> perksToLearn;
- for (uint32 i = 0; i < sGuildPerkSpellsStore.GetNumRows(); ++i)
- if (GuildPerkSpellsEntry const* entry = sGuildPerkSpellsStore.LookupEntry(i))
- if (entry->GuildLevel > oldLevel && entry->GuildLevel <= GetLevel())
- perksToLearn.push_back(entry->SpellID);
-
- // Notify all online players that guild level changed and learn perks
- for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
- {
- if (Player* player = itr->second->FindPlayer())
- {
- player->SetGuildLevel(GetLevel());
- for (size_t i = 0; i < perksToLearn.size(); ++i)
- player->LearnSpell(perksToLearn[i], true);
- }
- }
-
- AddGuildNews(GUILD_NEWS_LEVEL_UP, ObjectGuid::Empty, 0, _level);
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL, GetLevel(), 0, 0, NULL, source);
-
- ++oldLevel;
- }
-}
-
-void Guild::SendGuildXP(WorldSession* session /* = NULL */) const
-{
- //Member const* member = GetMember(session->GetGuidLow());
-
- WorldPacket data(SMSG_GUILD_XP, 40);
- data << uint64(/*member ? member->GetTotalActivity() :*/ 0);
- data << uint64(sGuildMgr->GetXPForGuildLevel(GetLevel()) - GetExperience()); // XP missing for next level
- data << uint64(GetTodayExperience());
- data << uint64(/*member ? member->GetWeeklyActivity() :*/ 0);
- data << uint64(GetExperience());
- session->SendPacket(&data);
-}
-
-void Guild::SendGuildReputationWeeklyCap(WorldSession* session, uint32 reputation) const
-{
- uint32 cap = sWorld->getIntConfig(CONFIG_GUILD_WEEKLY_REP_CAP) - reputation;
- WorldPacket data(SMSG_GUILD_REPUTATION_WEEKLY_CAP, 4);
- data << uint32(cap);
- session->SendPacket(&data);
- TC_LOG_DEBUG("guild", "SMSG_GUILD_REPUTATION_WEEKLY_CAP [%s]: Left: %u",
- session->GetPlayerInfo().c_str(), cap);
-}
-
void Guild::ResetTimes(bool weekly)
{
- _todayExperience = 0;
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
itr->second->ResetValues(weekly);
if (Player* player = itr->second->FindPlayer())
{
- //SendGuildXP(player->GetSession());
- WorldPacket data(SMSG_GUILD_MEMBER_DAILY_RESET, 0); // tells the client to request bank withdrawal limit
- player->GetSession()->SendPacket(&data);
+ WorldPackets::Guild::GuildMemberDailyReset packet; // tells the client to request bank withdrawal limit
+ player->GetSession()->SendPacket(packet.Write());
}
}
}
@@ -3641,12 +3368,10 @@ void Guild::AddGuildNews(uint8 type, ObjectGuid guid, uint32 flags, uint32 value
m_newsLog->AddEvent(trans, news);
CharacterDatabase.CommitTransaction(trans);
- WorldPacket data(SMSG_GUILD_NEWS_UPDATE, 7 + 32);
- data.WriteBits(1, 21); // size, we are only sending 1 news here
- ByteBuffer buffer;
- news->WritePacket(data, buffer);
-
- BroadcastPacket(&data);
+ WorldPackets::Guild::GuildNews newsPacket;
+ newsPacket.NewsEvents.reserve(1);
+ news->WritePacket(newsPacket);
+ BroadcastPacket(newsPacket.Write());
}
bool Guild::HasAchieved(uint32 achievementId) const
@@ -3676,12 +3401,11 @@ void Guild::HandleNewsSetSticky(WorldSession* session, uint32 newsId, bool stick
NewsLogEntry* news = (NewsLogEntry*)(*itr);
news->SetSticky(sticky);
- TC_LOG_DEBUG("guild", "HandleNewsSetSticky: [%s] chenged newsId %u sticky to %u",
+ TC_LOG_DEBUG("guild", "HandleNewsSetSticky: [%s] changed newsId %u sticky to %u",
session->GetPlayerInfo().c_str(), newsId, sticky);
- WorldPacket data(SMSG_GUILD_NEWS_UPDATE, 7 + 32);
- data.WriteBits(1, 21);
- ByteBuffer buffer;
- news->WritePacket(data, buffer);
- session->SendPacket(&data);
+ WorldPackets::Guild::GuildNews newsPacket;
+ newsPacket.NewsEvents.reserve(1);
+ news->WritePacket(newsPacket);
+ session->SendPacket(newsPacket.Write());
}
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index c20146d7bd1..55b740eb8ed 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -29,6 +29,16 @@
class Item;
+namespace WorldPackets
+{
+ namespace Guild
+ {
+ class GuildBankLogQueryResults;
+ class GuildEventLogQueryResults;
+ class GuildNews;
+ }
+}
+
enum GuildMisc
{
GUILD_BANK_MAX_TABS = 8, // send by client for money log also
@@ -40,7 +50,6 @@ enum GuildMisc
GUILD_WITHDRAW_MONEY_UNLIMITED = 0xFFFFFFFF,
GUILD_WITHDRAW_SLOT_UNLIMITED = 0xFFFFFFFF,
GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF,
- GUILD_EXPERIENCE_UNCAPPED_LEVEL = 20, ///> Hardcoded in client, starting from this level, guild daily experience gain is unlimited.
TAB_UNDEFINED = 0xFF,
};
@@ -65,20 +74,24 @@ enum GuildDefaultRanks
enum GuildRankRights
{
- GR_RIGHT_EMPTY = 0x00000040,
- GR_RIGHT_GCHATLISTEN = GR_RIGHT_EMPTY | 0x00000001,
- GR_RIGHT_GCHATSPEAK = GR_RIGHT_EMPTY | 0x00000002,
- GR_RIGHT_OFFCHATLISTEN = GR_RIGHT_EMPTY | 0x00000004,
- GR_RIGHT_OFFCHATSPEAK = GR_RIGHT_EMPTY | 0x00000008,
- GR_RIGHT_INVITE = GR_RIGHT_EMPTY | 0x00000010,
- GR_RIGHT_REMOVE = GR_RIGHT_EMPTY | 0x00000020,
- GR_RIGHT_PROMOTE = GR_RIGHT_EMPTY | 0x00000080,
- GR_RIGHT_DEMOTE = GR_RIGHT_EMPTY | 0x00000100,
- GR_RIGHT_SETMOTD = GR_RIGHT_EMPTY | 0x00001000,
- GR_RIGHT_EPNOTE = GR_RIGHT_EMPTY | 0x00002000,
- GR_RIGHT_VIEWOFFNOTE = GR_RIGHT_EMPTY | 0x00004000,
- GR_RIGHT_EOFFNOTE = GR_RIGHT_EMPTY | 0x00008000,
- GR_RIGHT_MODIFY_GUILD_INFO = GR_RIGHT_EMPTY | 0x00010000,
+ GR_RIGHT_NONE = 0x00000000,
+ GR_RIGHT_GCHATLISTEN = 0x00000001,
+ GR_RIGHT_GCHATSPEAK = 0x00000002,
+ GR_RIGHT_OFFCHATLISTEN = 0x00000004,
+ GR_RIGHT_OFFCHATSPEAK = 0x00000008,
+ GR_RIGHT_INVITE = 0x00000010,
+ GR_RIGHT_REMOVE = 0x00000020,
+ GR_RIGHT_ROSTER = 0x00000040,
+ GR_RIGHT_PROMOTE = 0x00000080,
+ GR_RIGHT_DEMOTE = 0x00000100,
+ GR_RIGHT_UNK_200 = 0x00000200,
+ GR_RIGHT_UNK_400 = 0x00000400,
+ GR_RIGHT_UNK_800 = 0x00000800,
+ GR_RIGHT_SETMOTD = 0x00001000,
+ GR_RIGHT_EDIT_PUBLIC_NOTE = 0x00002000,
+ GR_RIGHT_VIEWOFFNOTE = 0x00004000,
+ GR_RIGHT_EOFFNOTE = 0x00008000,
+ GR_RIGHT_MODIFY_GUILD_INFO = 0x00010000,
GR_RIGHT_WITHDRAW_GOLD_LOCK = 0x00020000, // remove money withdraw capacity
GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair
GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold
@@ -88,19 +101,19 @@ enum GuildRankRights
enum GuildCommandType
{
- GUILD_COMMAND_CREATE = 0,
- GUILD_COMMAND_INVITE = 1,
- GUILD_COMMAND_QUIT = 3,
- GUILD_COMMAND_ROSTER = 5,
- GUILD_COMMAND_PROMOTE = 6,
- GUILD_COMMAND_DEMOTE = 7,
- GUILD_COMMAND_REMOVE = 8,
+ GUILD_COMMAND_CREATE_GUILD = 0,
+ GUILD_COMMAND_INVITE_PLAYER = 1,
+ GUILD_COMMAND_LEAVE_GUILD = 3,
+ GUILD_COMMAND_GET_ROSTER = 5,
+ GUILD_COMMAND_PROMOTE_PLAYER = 6,
+ GUILD_COMMAND_DEMOTE_PLAYER = 7,
+ GUILD_COMMAND_REMOVE_PLAYER = 8,
GUILD_COMMAND_CHANGE_LEADER = 10,
GUILD_COMMAND_EDIT_MOTD = 11,
GUILD_COMMAND_GUILD_CHAT = 13,
GUILD_COMMAND_FOUNDER = 14,
GUILD_COMMAND_CHANGE_RANK = 16,
- GUILD_COMMAND_PUBLIC_NOTE = 19,
+ GUILD_COMMAND_EDIT_PUBLIC_NOTE = 19,
GUILD_COMMAND_VIEW_TAB = 21,
GUILD_COMMAND_MOVE_ITEM = 22,
GUILD_COMMAND_REPAIR = 25,
@@ -142,36 +155,6 @@ enum GuildCommandError
ERR_GUILD_REP_TOO_LOW = 39
};
-enum GuildEvents
-{
- GE_PROMOTION = 1,
- GE_DEMOTION = 2,
- GE_MOTD = 3,
- GE_JOINED = 4,
- GE_LEFT = 5,
- GE_REMOVED = 6,
- GE_LEADER_IS = 7,
- GE_LEADER_CHANGED = 8,
- GE_DISBANDED = 9,
- GE_TABARDCHANGE = 10,
- GE_RANK_UPDATED = 11,
- GE_RANK_CREATED = 12,
- GE_RANK_DELETED = 13,
- GE_RANK_ORDER_CHANGED = 14,
- GE_FOUNDER = 15,
- GE_SIGNED_ON = 16,
- GE_SIGNED_OFF = 17,
- GE_GUILDBANKBAGSLOTS_CHANGED = 18,
- GE_BANK_TAB_PURCHASED = 19,
- GE_BANK_TAB_UPDATED = 20,
- GE_BANK_MONEY_SET = 21,
- GE_BANK_TAB_AND_MONEY_UPDATED = 22,
- GE_BANK_TEXT_CHANGED = 23,
- // 24 - error 795
- GE_SIGNED_ON_MOBILE = 25,
- GE_SIGNED_Off_MOBILE = 26,
-};
-
enum PetitionTurns
{
PETITION_TURN_OK = 0,
@@ -200,7 +183,7 @@ enum GuildBankRights
GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04,
GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM,
- GUILD_BANK_RIGHT_FULL = 0xFF
+ GUILD_BANK_RIGHT_FULL = -1
};
enum GuildBankEventLogTypes
@@ -255,26 +238,27 @@ enum GuildNews
GUILD_NEWS_ITEM_CRAFTED = 4,
GUILD_NEWS_ITEM_PURCHASED = 5,
GUILD_NEWS_LEVEL_UP = 6,
+ GUILD_NEWS_CREATE = 7, // @todo Implement
+ GUILD_NEWS_EVENT = 8 // @todo Implement
};
struct GuildReward
{
- uint32 Entry;
- int32 Racemask;
- uint64 Price;
- uint32 AchievementId;
- uint8 Standing;
+ uint32 ItemID;
+ uint8 MinGuildRep;
+ int32 RaceMask;
+ uint64 Cost;
+ std::vector<uint32> AchievementsRequired;
};
uint32 const MinNewsItemLevel[MAX_CONTENT] = { 61, 90, 200, 353 };
// Guild Challenge
-#define GUILD_CHALLENGES_TYPES 4
+#define GUILD_CHALLENGES_TYPES 6
-const uint32 GuildChallengeGoldReward[GUILD_CHALLENGES_TYPES] = { 0, 250, 1000, 500 };
-const uint32 GuildChallengeMaxLevelGoldReward[GUILD_CHALLENGES_TYPES] = { 0, 125, 500, 250 };
-const uint32 GuildChallengeXPReward[GUILD_CHALLENGES_TYPES] = { 0, 300000, 3000000, 1500000 };
-const uint32 GuildChallengesPerWeek[GUILD_CHALLENGES_TYPES] = { 0, 7, 1, 3 };
+const uint32 GuildChallengeGoldReward[GUILD_CHALLENGES_TYPES] = { 0, 250, 1000, 500, 250, 500 };
+const uint32 GuildChallengeMaxLevelGoldReward[GUILD_CHALLENGES_TYPES] = { 0, 125, 500, 250, 125, 250 };
+const uint32 GuildChallengesMaxCount[GUILD_CHALLENGES_TYPES] = { 0, 7, 1, 3, 0, 3 };
// Emblem info
class EmblemInfo
@@ -284,7 +268,7 @@ public:
void LoadFromDB(Field* fields);
void SaveToDB(ObjectGuid::LowType guildId) const;
- void ReadPacket(WorldPacket& recv);
+ void ReadPacket(WorldPackets::Guild::SaveGuildEmblem& packet);
uint32 GetStyle() const { return m_style; }
uint32 GetColor() const { return m_color; }
@@ -306,26 +290,26 @@ class GuildBankRightsAndSlots
public:
GuildBankRightsAndSlots() : tabId(TAB_UNDEFINED), rights(0), slots(0) { }
GuildBankRightsAndSlots(uint8 _tabId) : tabId(_tabId), rights(0), slots(0) { }
- GuildBankRightsAndSlots(uint8 _tabId, uint8 _rights, uint32 _slots) : tabId(_tabId), rights(_rights), slots(_slots) { }
+ GuildBankRightsAndSlots(uint8 _tabId, int8 _rights, int32 _slots) : tabId(_tabId), rights(_rights), slots(_slots) { }
void SetGuildMasterValues()
{
rights = GUILD_BANK_RIGHT_FULL;
- slots = uint32(GUILD_WITHDRAW_SLOT_UNLIMITED);
+ slots = int32(GUILD_WITHDRAW_SLOT_UNLIMITED);
}
void SetTabId(uint8 _tabId) { tabId = _tabId; }
- void SetSlots(uint32 _slots) { slots = _slots; }
- void SetRights(uint8 _rights) { rights = _rights; }
+ void SetSlots(int32 _slots) { slots = _slots; }
+ void SetRights(int8 _rights) { rights = _rights; }
int8 GetTabId() const { return tabId; }
int32 GetSlots() const { return slots; }
int8 GetRights() const { return rights; }
private:
- uint8 tabId;
- uint8 rights;
- uint32 slots;
+ uint8 tabId;
+ int8 rights;
+ int32 slots;
};
typedef std::vector <GuildBankRightsAndSlots> GuildBankRightsAndSlotsVec;
@@ -345,6 +329,7 @@ private:
m_zoneId(0),
m_level(0),
m_class(0),
+ _gender(0),
m_flags(GUILDMEMBER_STATUS_NONE),
m_logoutTime(::time(NULL)),
m_accountId(0),
@@ -359,7 +344,7 @@ private:
}
void SetStats(Player* player);
- void SetStats(std::string const& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId, uint32 reputation);
+ void SetStats(std::string const& name, uint8 level, uint8 _class, uint8 gender, uint32 zoneId, uint32 accountId, uint32 reputation);
bool CheckStats() const;
void SetPublicNote(std::string const& publicNote);
@@ -385,6 +370,7 @@ private:
std::string GetPublicNote() const { return m_publicNote; }
std::string GetOfficerNote() const { return m_officerNote; }
uint8 GetClass() const { return m_class; }
+ uint8 GetGender() const { return _gender; }
uint8 GetLevel() const { return m_level; }
uint8 GetFlags() const { return m_flags; }
uint32 GetZoneId() const { return m_zoneId; }
@@ -422,6 +408,7 @@ private:
uint32 m_zoneId;
uint8 m_level;
uint8 m_class;
+ uint8 _gender;
uint8 m_flags;
uint64 m_logoutTime;
uint32 m_accountId;
@@ -452,7 +439,6 @@ private:
uint64 GetTimestamp() const { return m_timestamp; }
virtual void SaveToDB(SQLTransaction& trans) const = 0;
- virtual void WritePacket(WorldPacket& data, ByteBuffer& content) const = 0;
protected:
ObjectGuid::LowType m_guildId;
@@ -473,7 +459,7 @@ private:
~EventLogEntry() { }
void SaveToDB(SQLTransaction& trans) const override;
- void WritePacket(WorldPacket& data, ByteBuffer& content) const override;
+ void WritePacket(WorldPackets::Guild::GuildEventLogQueryResults& packet) const;
private:
GuildEventLogTypes m_eventType;
@@ -511,7 +497,7 @@ private:
~BankEventLogEntry() { }
void SaveToDB(SQLTransaction& trans) const override;
- void WritePacket(WorldPacket& data, ByteBuffer& content) const override;
+ void WritePacket(WorldPackets::Guild::GuildBankLogQueryResults& packet) const;
private:
GuildBankEventLogTypes m_eventType;
@@ -547,7 +533,7 @@ private:
}
void SaveToDB(SQLTransaction& trans) const;
- void WritePacket(WorldPacket& data, ByteBuffer& content) const;
+ void WritePacket(WorldPackets::Guild::GuildNews& newsPacket) const;
private:
GuildNews m_type;
@@ -572,10 +558,8 @@ private:
void LoadEvent(LogEntry* entry);
// Adds new event to collection and saves it to DB
void AddEvent(SQLTransaction& trans, LogEntry* entry);
- // Writes information about all events to packet
- void WritePacket(WorldPacket& data) const;
uint32 GetNextGUID();
- GuildLog* GetGuildLog() { return &m_log; } // Hack needed for news as WritePacket can't be used
+ GuildLog* GetGuildLog() { return &m_log; }
private:
GuildLog m_log;
@@ -587,8 +571,8 @@ private:
class RankInfo
{
public:
- RankInfo(): m_guildId(UI64LIT(0)), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { }
- RankInfo(ObjectGuid::LowType guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { }
+ RankInfo(): m_guildId(UI64LIT(0)), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_NONE), m_bankMoneyPerDay(0) { }
+ RankInfo(ObjectGuid::LowType guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_NONE), m_bankMoneyPerDay(0) { }
RankInfo(ObjectGuid::LowType guildId, uint8 rankId, std::string const& name, uint32 rights, uint32 money) :
m_guildId(guildId), m_rankId(rankId), m_name(name), m_rights(rights),
m_bankMoneyPerDay(rankId != GR_GUILDMASTER ? money : GUILD_WITHDRAW_MONEY_UNLIMITED) { }
@@ -810,7 +794,7 @@ public:
void HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool cashFlow = false);
bool HandleMemberWithdrawMoney(WorldSession* session, uint64 amount, bool repair = false);
void HandleMemberLogout(WorldSession* session);
- void HandleDisband(WorldSession* session);
+ void HandleDelete(WorldSession* session);
void HandleGuildPartyRequest(WorldSession* session);
void HandleNewsSetSticky(WorldSession* session, uint32 newsId, bool sticky);
void HandleGuildRequestChallengeUpdate(WorldSession* session);
@@ -822,14 +806,20 @@ public:
void SendGuildRankInfo(WorldSession* session) const;
void SendEventLog(WorldSession* session) const;
void SendBankLog(WorldSession* session, uint8 tabId) const;
- void SendBankList(WorldSession* session, uint8 tabId, bool withContent, bool withTabInfo) const;
- void SendGuildXP(WorldSession* session = NULL) const;
+ void SendBankList(WorldSession* session, uint8 tabId, bool fullUpdate) const;
void SendBankTabText(WorldSession* session, uint8 tabId) const;
void SendPermissions(WorldSession* session) const;
void SendMoneyInfo(WorldSession* session) const;
void SendLoginInfo(WorldSession* session);
void SendNewsUpdate(WorldSession* session);
+ // Send events
+ void SendEventBankMoneyChanged();
+ void SendEventMOTD(WorldSession* session, bool broadcast = false);
+ void SendEventNewLeader(Member* newLeader, Member* oldLeader, bool isSelfPromoted = false);
+ void SendEventPlayerLeft(Player* leaver, Player* remover = nullptr, bool isRemoved = false);
+ void SendEventPresenceChanged(WorldSession* session, bool loggedOn, bool broadcast = false);
+
// Load from DB
bool LoadFromDB(Field* fields);
void LoadGuildNewsLogFromDB(Field* fields);
@@ -880,9 +870,6 @@ public:
// Guild leveling
uint8 GetLevel() const { return _level; }
- void GiveXP(uint32 xp, Player* source);
- uint64 GetExperience() const { return _experience; }
- uint64 GetTodayExperience() const { return _todayExperience; }
void AddGuildNews(uint8 type, ObjectGuid guid, uint32 flags, uint32 value);
@@ -915,8 +902,6 @@ protected:
AchievementMgr<Guild> m_achievementMgr;
uint8 _level;
- uint64 _experience;
- uint64 _todayExperience;
private:
inline uint8 _GetRanksSize() const { return uint8(m_ranks.size()); }
@@ -926,7 +911,7 @@ private:
{
if (player)
if (Member const* member = GetMember(player->GetGUID()))
- return (_GetRankRights(member->GetRankId()) & right) != GR_RIGHT_EMPTY;
+ return (_GetRankRights(member->GetRankId()) & right) != GR_RIGHT_NONE;
return false;
}
@@ -990,7 +975,7 @@ private:
int32 _GetMemberRemainingSlots(Member const* member, uint8 tabId) const;
int32 _GetMemberRemainingMoney(Member const* member) const;
void _UpdateMemberWithdrawSlots(SQLTransaction& trans, ObjectGuid guid, uint8 tabId);
- bool _MemberHasTabRights(ObjectGuid guid, uint8 tabId, uint32 rights) const;
+ bool _MemberHasTabRights(ObjectGuid guid, uint8 tabId, int32 rights) const;
void _LogEvent(GuildEventLogTypes eventType, ObjectGuid::LowType playerGuid1, ObjectGuid::LowType playerGuid2 = UI64LIT(0), uint8 newRank = 0);
void _LogBankEvent(SQLTransaction& trans, GuildBankEventLogTypes eventType, uint8 tabId, ObjectGuid::LowType playerGuid, uint64 itemOrMoney, uint16 itemStackCount = 0, uint8 destTabId = 0);
@@ -1002,9 +987,6 @@ private:
void _SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) const;
void _SendBankContentUpdate(uint8 tabId, SlotIds slots) const;
- void SendGuildReputationWeeklyCap(WorldSession* session, uint32 reputation) const;
void SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, uint32 rank);
-
- void _BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid, const char* param1 = NULL, const char* param2 = NULL, const char* param3 = NULL) const;
};
#endif
diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp
index f207cae7456..8f90b0268aa 100644
--- a/src/server/game/Guilds/GuildMgr.cpp
+++ b/src/server/game/Guilds/GuildMgr.cpp
@@ -105,13 +105,6 @@ Guild* GuildMgr::GetGuildByLeader(ObjectGuid guid) const
return NULL;
}
-uint64 GuildMgr::GetXPForGuildLevel(uint8 level) const
-{
- if (level < GuildXPperLevel.size())
- return GuildXPperLevel[level];
- return 0;
-}
-
void GuildMgr::LoadGuilds()
{
// 1. Load all guilds
@@ -119,11 +112,11 @@ void GuildMgr::LoadGuilds()
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6
+ // 0 1 2 3 4 5 6
QueryResult result = CharacterDatabase.Query("SELECT g.guildid, g.name, g.leaderguid, g.EmblemStyle, g.EmblemColor, g.BorderStyle, g.BorderColor, "
- // 7 8 9 10 11 12 13 14 15
- "g.BackgroundColor, g.info, g.motd, g.createdate, g.BankMoney, g.level, g.experience, g.todayExperience, COUNT(gbt.guildid) "
- "FROM guild g LEFT JOIN guild_bank_tab gbt ON g.guildid = gbt.guildid GROUP BY g.guildid ORDER BY g.guildid ASC");
+ // 7 8 9 10 11 12 13
+ "g.BackgroundColor, g.info, g.motd, g.createdate, g.BankMoney, g.level, COUNT(gbt.guildid) "
+ "FROM guild g LEFT JOIN guild_bank_tab gbt ON g.guildid = gbt.guildid GROUP BY g.guildid ORDER BY g.guildid ASC");
if (!result)
{
@@ -199,8 +192,8 @@ void GuildMgr::LoadGuilds()
// 0 1 2 3 4 5 6 7 8 9 10
QueryResult result = CharacterDatabase.Query("SELECT gm.guildid, gm.guid, rank, pnote, offnote, w.tab0, w.tab1, w.tab2, w.tab3, w.tab4, w.tab5, "
- // 11 12 13 14 15 16 17 18 19
- "w.tab6, w.tab7, w.money, c.name, c.level, c.class, c.zone, c.account, c.logout_time "
+ // 11 12 13 14 15 16 17 18 19 20
+ "w.tab6, w.tab7, w.money, c.name, c.level, c.class, c.gender, c.zone, c.account, c.logout_time "
"FROM guild_member gm "
"LEFT JOIN guild_member_withdraw w ON gm.guid = w.guid "
"LEFT JOIN characters c ON c.guid = gm.guid ORDER BY gm.guildid ASC");
@@ -404,7 +397,7 @@ void GuildMgr::LoadGuilds()
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, transmogrification, upgradeId, enchantIllusion, bonusListIDs,
- // 17 18 19
+ // 17 18 19
// guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid
PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEMS));
@@ -465,62 +458,12 @@ void GuildMgr::LoadGuilds()
}
}
-void GuildMgr::LoadGuildXpForLevel()
-{
- uint32 oldMSTime = getMSTime();
-
- GuildXPperLevel.resize(sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL));
- for (uint8 level = 0; level < sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL); ++level)
- GuildXPperLevel[level] = 0;
-
- // 0 1
- QueryResult result = WorldDatabase.Query("SELECT lvl, xp_for_next_level FROM guild_xp_for_level");
-
- if (!result)
- {
- TC_LOG_ERROR("server.loading", ">> Loaded 0 xp for guild level definitions. DB table `guild_xp_for_level` is empty.");
- return;
- }
-
- uint32 count = 0;
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 level = fields[0].GetUInt8();
- uint32 requiredXP = fields[1].GetUInt32();
-
- if (level >= sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL))
- {
- TC_LOG_INFO("misc", "Unused (> Guild.MaxLevel in worldserver.conf) level %u in `guild_xp_for_level` table, ignoring.", uint32(level));
- continue;
- }
-
- GuildXPperLevel[level] = requiredXP;
- ++count;
-
- } while (result->NextRow());
-
- // fill level gaps
- for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL); ++level)
- {
- if (!GuildXPperLevel[level])
- {
- TC_LOG_ERROR("sql.sql", "Level %i does not have XP for guild level data. Using data of level [%i] + 1660000.", level+1, level);
- GuildXPperLevel[level] = GuildXPperLevel[level - 1] + 1660000;
- }
- }
-
- TC_LOG_INFO("server.loading", ">> Loaded %u xp for guild level definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
-}
-
void GuildMgr::LoadGuildRewards()
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4
- QueryResult result = WorldDatabase.Query("SELECT entry, standing, racemask, price, achievement FROM guild_rewards");
+ // 0 1 2 3
+ QueryResult result = WorldDatabase.Query("SELECT ItemID, MinGuildRep, RaceMask, Cost FROM guild_rewards");
if (!result)
{
@@ -534,28 +477,42 @@ void GuildMgr::LoadGuildRewards()
{
GuildReward reward;
Field* fields = result->Fetch();
- reward.Entry = fields[0].GetUInt32();
- reward.Standing = fields[1].GetUInt8();
- reward.Racemask = fields[2].GetInt32();
- reward.Price = fields[3].GetUInt64();
- reward.AchievementId = fields[4].GetUInt32();
+ reward.ItemID = fields[0].GetUInt32();
+ reward.MinGuildRep = fields[1].GetUInt8();
+ reward.RaceMask = fields[2].GetInt32();
+ reward.Cost = fields[3].GetUInt64();
- if (!sObjectMgr->GetItemTemplate(reward.Entry))
+ if (!sObjectMgr->GetItemTemplate(reward.ItemID))
{
- TC_LOG_ERROR("server.loading", "Guild rewards constains not existing item entry %u", reward.Entry);
+ TC_LOG_ERROR("server.loading", "Guild rewards constains not existing item entry %u", reward.ItemID);
continue;
}
- if (reward.AchievementId != 0 && (!sAchievementMgr->GetAchievement(reward.AchievementId)))
+ if (reward.MinGuildRep >= MAX_REPUTATION_RANK)
{
- TC_LOG_ERROR("server.loading", "Guild rewards constains not existing achievement entry %u", reward.AchievementId);
+ TC_LOG_ERROR("server.loading", "Guild rewards contains wrong reputation standing %u, max is %u", uint32(reward.MinGuildRep), MAX_REPUTATION_RANK - 1);
continue;
}
- if (reward.Standing >= MAX_REPUTATION_RANK)
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_GUILD_REWARDS_REQ_ACHIEVEMENTS);
+ stmt->setUInt32(0, reward.ItemID);
+ PreparedQueryResult reqAchievementResult = WorldDatabase.Query(stmt);
+ if (reqAchievementResult)
{
- TC_LOG_ERROR("server.loading", "Guild rewards contains wrong reputation standing %u, max is %u", uint32(reward.Standing), MAX_REPUTATION_RANK - 1);
- continue;
+ do
+ {
+ Field* fields = reqAchievementResult->Fetch();
+
+ uint32 requiredAchievementId = fields[0].GetUInt32();
+
+ if (!sAchievementMgr->GetAchievement(requiredAchievementId))
+ {
+ TC_LOG_ERROR("server.loading", "Guild rewards constains not existing achievement entry %u", requiredAchievementId);
+ continue;
+ }
+
+ reward.AchievementsRequired.push_back(requiredAchievementId);
+ } while (reqAchievementResult->NextRow());
}
GuildRewards.push_back(reward);
@@ -567,7 +524,6 @@ void GuildMgr::LoadGuildRewards()
void GuildMgr::ResetTimes(bool week)
{
- CharacterDatabase.Execute(CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE));
CharacterDatabase.Execute(CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBER_WITHDRAW));
for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr)
diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h
index 4753194546c..c5f1dbf49a6 100644
--- a/src/server/game/Guilds/GuildMgr.h
+++ b/src/server/game/Guilds/GuildMgr.h
@@ -39,7 +39,6 @@ public:
Guild* GetGuildByName(std::string const& guildName) const;
std::string GetGuildNameById(ObjectGuid::LowType guildId) const;
- void LoadGuildXpForLevel();
void LoadGuildRewards();
void LoadGuilds();
@@ -53,7 +52,6 @@ public:
ObjectGuid::LowType GenerateGuildId();
void SetNextGuildId(ObjectGuid::LowType Id) { NextGuildId = Id; }
- uint64 GetXPForGuildLevel(uint8 level) const;
std::vector<GuildReward> const& GetGuildRewards() const { return GuildRewards; }
void ResetTimes(bool week);
@@ -61,7 +59,6 @@ protected:
typedef std::unordered_map<ObjectGuid::LowType, Guild*> GuildContainer;
ObjectGuid::LowType NextGuildId;
GuildContainer GuildStore;
- std::vector<uint64> GuildXPperLevel;
std::vector<GuildReward> GuildRewards;
};
diff --git a/src/server/game/Handlers/BattlefieldHandler.cpp b/src/server/game/Handlers/BattlefieldHandler.cpp
index 1503e1fb091..e95e9ee9104 100644
--- a/src/server/game/Handlers/BattlefieldHandler.cpp
+++ b/src/server/game/Handlers/BattlefieldHandler.cpp
@@ -167,7 +167,7 @@ void WorldSession::SendBfEntered(ObjectGuid guid)
{
uint8 isAFK = _player->isAFK() ? 1 : 0;
- WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTERED, 11);
+ WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTERING, 11);
data.WriteBit(0); // unk
data.WriteBit(isAFK); // Clear AFK
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 255eea8fbe6..0385b8f1a39 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -162,6 +162,10 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS, stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SPELL_CHARGES);
+ stmt->setUInt64(0, lowGuid);
+ res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_SPELL_CHARGES, stmt);
+
if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_DECLINEDNAMES);
diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp
index 13115da3df3..9b9a32b2c2a 100644
--- a/src/server/game/Handlers/CombatHandler.cpp
+++ b/src/server/game/Handlers/CombatHandler.cpp
@@ -31,21 +31,19 @@
void WorldSession::HandleAttackSwingOpcode(WorldPackets::Combat::AttackSwing& packet)
{
- TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_ATTACKSWING Message %s", packet.Victim.ToString().c_str());
+ Unit* enemy = ObjectAccessor::GetUnit(*_player, packet.Victim);
- Unit* pEnemy = ObjectAccessor::GetUnit(*_player, packet.Victim);
-
- if (!pEnemy)
+ if (!enemy)
{
// stop attack state at client
- SendAttackStop(NULL);
+ SendAttackStop(nullptr);
return;
}
- if (!_player->IsValidAttackTarget(pEnemy))
+ if (!_player->IsValidAttackTarget(enemy))
{
// stop attack state at client
- SendAttackStop(pEnemy);
+ SendAttackStop(enemy);
return;
}
@@ -58,12 +56,12 @@ void WorldSession::HandleAttackSwingOpcode(WorldPackets::Combat::AttackSwing& pa
ASSERT(seat);
if (!(seat->Flags & VEHICLE_SEAT_FLAG_CAN_ATTACK))
{
- SendAttackStop(pEnemy);
+ SendAttackStop(enemy);
return;
}
}
- _player->Attack(pEnemy, true);
+ _player->Attack(enemy, true);
}
void WorldSession::HandleAttackStopOpcode(WorldPackets::Combat::AttackStop& /*recvData*/)
@@ -71,31 +69,18 @@ void WorldSession::HandleAttackStopOpcode(WorldPackets::Combat::AttackStop& /*re
GetPlayer()->AttackStop();
}
-void WorldSession::HandleSetSheathedOpcode(WorldPacket& recvData)
+void WorldSession::HandleSetSheathedOpcode(WorldPackets::Combat::SetSheathed& packet)
{
- uint32 sheathed;
- recvData >> sheathed;
-
- //TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_SETSHEATHED Message guidlow:%u value1:%u", GetPlayer()->GetGUIDLow(), sheathed);
-
- if (sheathed >= MAX_SHEATH_STATE)
+ if (packet.CurrentSheathState >= MAX_SHEATH_STATE)
{
- TC_LOG_ERROR("network", "Unknown sheath state %u ??", sheathed);
+ TC_LOG_ERROR("network", "Unknown sheath state %u ??", packet.CurrentSheathState);
return;
}
- GetPlayer()->SetSheath(SheathState(sheathed));
+ GetPlayer()->SetSheath(SheathState(packet.CurrentSheathState));
}
void WorldSession::SendAttackStop(Unit const* enemy)
{
- WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); // we guess size
- data << GetPlayer()->GetPackGUID();
- if (enemy)
- data << enemy->GetPackGUID();
- else
- data << uint8(0);
-
- data << uint32(0); // unk, can be 1 also
- SendPacket(&data);
+ SendPacket(WorldPackets::Combat::SAttackStop(GetPlayer(), enemy).Write());
}
diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp
index 103334db568..2f5c1602a9f 100644
--- a/src/server/game/Handlers/GuildHandler.cpp
+++ b/src/server/game/Handlers/GuildHandler.cpp
@@ -48,179 +48,77 @@ void WorldSession::HandleGuildQueryOpcode(WorldPackets::Guild::QueryGuildInfo& q
TC_LOG_DEBUG("guild", "SMSG_GUILD_QUERY_RESPONSE [%s]", GetPlayerInfo().c_str());
}
-void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildInviteByName(WorldPackets::Guild::GuildInviteByName& packet)
{
- uint32 nameLength = recvPacket.ReadBits(7);
- std::string invitedName = recvPacket.ReadString(nameLength);
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_INVITE [%s]: Invited: %s", GetPlayerInfo().c_str(), invitedName.c_str());
- if (normalizePlayerName(invitedName))
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_INVITE [%s]: Invited: %s", GetPlayerInfo().c_str(), packet.Name.c_str());
+ if (normalizePlayerName(packet.Name))
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleInviteMember(this, invitedName);
+ guild->HandleInviteMember(this, packet.Name);
}
-void WorldSession::HandleGuildOfficerRemoveMemberOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildOfficerRemoveMember(WorldPackets::Guild::GuildOfficerRemoveMember& packet)
{
- ObjectGuid playerGuid;
-
- playerGuid[6] = recvPacket.ReadBit();
- playerGuid[5] = recvPacket.ReadBit();
- playerGuid[4] = recvPacket.ReadBit();
- playerGuid[0] = recvPacket.ReadBit();
- playerGuid[1] = recvPacket.ReadBit();
- playerGuid[3] = recvPacket.ReadBit();
- playerGuid[7] = recvPacket.ReadBit();
- playerGuid[2] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(playerGuid[2]);
- recvPacket.ReadByteSeq(playerGuid[6]);
- recvPacket.ReadByteSeq(playerGuid[5]);
- recvPacket.ReadByteSeq(playerGuid[7]);
- recvPacket.ReadByteSeq(playerGuid[1]);
- recvPacket.ReadByteSeq(playerGuid[4]);
- recvPacket.ReadByteSeq(playerGuid[3]);
- recvPacket.ReadByteSeq(playerGuid[0]);
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_OFFICER_REMOVE_MEMBER [%s]: Target: %s", GetPlayerInfo().c_str(), playerGuid.ToString().c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_REMOVE [%s]: Target: %s", GetPlayerInfo().c_str(), packet.Removee.ToString().c_str());
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleRemoveMember(this, playerGuid);
+ guild->HandleRemoveMember(this, packet.Removee);
}
-void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleGuildAcceptInvite(WorldPackets::Guild::AcceptGuildInvite& /*invite*/)
{
- TC_LOG_DEBUG("guild", "CMSG_GUILD_ACCEPT [%s]", GetPlayerInfo().c_str());
+ TC_LOG_DEBUG("guild", "CMSG_ACCEPT_GUILD_INVITE [%s]", GetPlayerInfo().c_str());
if (!GetPlayer()->GetGuildId())
if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildIdInvited()))
guild->HandleAcceptMember(this);
}
-void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleGuildDeclineInvitation(WorldPackets::Guild::GuildDeclineInvitation& /*decline*/)
{
- TC_LOG_DEBUG("guild", "CMSG_GUILD_DECLINE [%s]", GetPlayerInfo().c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_DECLINE_INVITATION [%s]", GetPlayerInfo().c_str());
GetPlayer()->SetGuildIdInvited(UI64LIT(0));
GetPlayer()->SetInGuild(UI64LIT(0));
}
-void WorldSession::HandleGuildRosterOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildGetRoster(WorldPackets::Guild::GuildGetRoster& /*packet*/)
{
TC_LOG_DEBUG("guild", "CMSG_GUILD_ROSTER [%s]", GetPlayerInfo().c_str());
- recvPacket.rfinish();
if (Guild* guild = GetPlayer()->GetGuild())
guild->HandleRoster(this);
else
- Guild::SendCommandResult(this, GUILD_COMMAND_ROSTER, ERR_GUILD_PLAYER_NOT_IN_GUILD);
+ Guild::SendCommandResult(this, GUILD_COMMAND_GET_ROSTER, ERR_GUILD_PLAYER_NOT_IN_GUILD);
}
-void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildPromoteMember(WorldPackets::Guild::GuildPromoteMember& promote)
{
- ObjectGuid targetGuid;
-
- targetGuid[7] = recvPacket.ReadBit();
- targetGuid[2] = recvPacket.ReadBit();
- targetGuid[5] = recvPacket.ReadBit();
- targetGuid[6] = recvPacket.ReadBit();
- targetGuid[1] = recvPacket.ReadBit();
- targetGuid[0] = recvPacket.ReadBit();
- targetGuid[3] = recvPacket.ReadBit();
- targetGuid[4] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(targetGuid[0]);
- recvPacket.ReadByteSeq(targetGuid[5]);
- recvPacket.ReadByteSeq(targetGuid[2]);
- recvPacket.ReadByteSeq(targetGuid[3]);
- recvPacket.ReadByteSeq(targetGuid[6]);
- recvPacket.ReadByteSeq(targetGuid[4]);
- recvPacket.ReadByteSeq(targetGuid[1]);
- recvPacket.ReadByteSeq(targetGuid[7]);
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_PROMOTE [%s]: Target: %s", GetPlayerInfo().c_str(), targetGuid.ToString().c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_PROMOTE [%s]: Target: %s", GetPlayerInfo().c_str(), promote.Promotee.ToString().c_str());
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleUpdateMemberRank(this, targetGuid, false);
+ guild->HandleUpdateMemberRank(this, promote.Promotee, false);
}
-void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildDemoteMember(WorldPackets::Guild::GuildDemoteMember& demote)
{
- ObjectGuid targetGuid;
-
- targetGuid[7] = recvPacket.ReadBit();
- targetGuid[1] = recvPacket.ReadBit();
- targetGuid[5] = recvPacket.ReadBit();
- targetGuid[6] = recvPacket.ReadBit();
- targetGuid[2] = recvPacket.ReadBit();
- targetGuid[3] = recvPacket.ReadBit();
- targetGuid[0] = recvPacket.ReadBit();
- targetGuid[4] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(targetGuid[1]);
- recvPacket.ReadByteSeq(targetGuid[2]);
- recvPacket.ReadByteSeq(targetGuid[7]);
- recvPacket.ReadByteSeq(targetGuid[5]);
- recvPacket.ReadByteSeq(targetGuid[6]);
- recvPacket.ReadByteSeq(targetGuid[0]);
- recvPacket.ReadByteSeq(targetGuid[4]);
- recvPacket.ReadByteSeq(targetGuid[3]);
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_DEMOTE [%s]: Target: %s", GetPlayerInfo().c_str(), targetGuid.ToString().c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_DEMOTE [%s]: Target: %s", GetPlayerInfo().c_str(), demote.Demotee.ToString().c_str());
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleUpdateMemberRank(this, targetGuid, true);
-}
-
-void WorldSession::HandleGuildAssignRankOpcode(WorldPacket& recvPacket)
-{
- ObjectGuid targetGuid;
- ObjectGuid setterGuid;
-
- uint32 rankId;
- recvPacket >> rankId;
-
- targetGuid[1] = recvPacket.ReadBit();
- targetGuid[7] = recvPacket.ReadBit();
- setterGuid[4] = recvPacket.ReadBit();
- setterGuid[2] = recvPacket.ReadBit();
- targetGuid[4] = recvPacket.ReadBit();
- targetGuid[5] = recvPacket.ReadBit();
- targetGuid[6] = recvPacket.ReadBit();
- setterGuid[1] = recvPacket.ReadBit();
- setterGuid[7] = recvPacket.ReadBit();
- targetGuid[2] = recvPacket.ReadBit();
- targetGuid[3] = recvPacket.ReadBit();
- targetGuid[0] = recvPacket.ReadBit();
- setterGuid[6] = recvPacket.ReadBit();
- setterGuid[3] = recvPacket.ReadBit();
- setterGuid[0] = recvPacket.ReadBit();
- setterGuid[5] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(targetGuid[0]);
- recvPacket.ReadByteSeq(setterGuid[1]);
- recvPacket.ReadByteSeq(setterGuid[3]);
- recvPacket.ReadByteSeq(setterGuid[5]);
- recvPacket.ReadByteSeq(targetGuid[7]);
- recvPacket.ReadByteSeq(targetGuid[3]);
- recvPacket.ReadByteSeq(setterGuid[0]);
- recvPacket.ReadByteSeq(targetGuid[1]);
- recvPacket.ReadByteSeq(setterGuid[6]);
- recvPacket.ReadByteSeq(targetGuid[2]);
- recvPacket.ReadByteSeq(targetGuid[5]);
- recvPacket.ReadByteSeq(targetGuid[4]);
- recvPacket.ReadByteSeq(setterGuid[2]);
- recvPacket.ReadByteSeq(setterGuid[4]);
- recvPacket.ReadByteSeq(targetGuid[6]);
- recvPacket.ReadByteSeq(setterGuid[7]);
+ guild->HandleUpdateMemberRank(this, demote.Demotee, true);
+}
+
+void WorldSession::HandleGuildAssignRank(WorldPackets::Guild::GuildAssignMemberRank& packet)
+{
+ ObjectGuid setterGuid = GetPlayer()->GetGUID();
TC_LOG_DEBUG("guild", "CMSG_GUILD_ASSIGN_MEMBER_RANK [%s]: Target: %s Rank: %u, Issuer: %s",
- GetPlayerInfo().c_str(), targetGuid.ToString().c_str(), rankId, setterGuid.ToString().c_str());
+ GetPlayerInfo().c_str(), packet.Member.ToString().c_str(), packet.RankOrder, setterGuid.ToString().c_str());
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleSetMemberRank(this, targetGuid, setterGuid, rankId);
+ guild->HandleSetMemberRank(this, packet.Member, setterGuid, packet.RankOrder);
}
-void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleGuildLeave(WorldPackets::Guild::GuildLeave& /*leave*/)
{
TC_LOG_DEBUG("guild", "CMSG_GUILD_LEAVE [%s]", GetPlayerInfo().c_str());
@@ -228,136 +126,76 @@ void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/)
guild->HandleLeaveMember(this);
}
-void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleGuildDelete(WorldPackets::Guild::GuildDelete& /*packet*/)
{
- TC_LOG_DEBUG("guild", "CMSG_GUILD_DISBAND [%s]", GetPlayerInfo().c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_DELETE [%s]", GetPlayerInfo().c_str());
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleDisband(this);
+ guild->HandleDelete(this);
}
-void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildUpdateMotdText(WorldPackets::Guild::GuildUpdateMotdText& packet)
{
- uint32 motdLength = recvPacket.ReadBits(11);
- std::string motd = recvPacket.ReadString(motdLength);
- TC_LOG_DEBUG("guild", "CMSG_GUILD_MOTD [%s]: MOTD: %s", GetPlayerInfo().c_str(), motd.c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_UPDATE_MOTD_TEXT [%s]: MOTD: %s", GetPlayerInfo().c_str(), packet.MotdText.c_str());
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleSetMOTD(this, motd);
-}
-
-void WorldSession::HandleGuildSetNoteOpcode(WorldPacket& recvPacket)
-{
- ObjectGuid playerGuid;
-
- playerGuid[1] = recvPacket.ReadBit();
- playerGuid[4] = recvPacket.ReadBit();
- playerGuid[5] = recvPacket.ReadBit();
- playerGuid[3] = recvPacket.ReadBit();
- playerGuid[0] = recvPacket.ReadBit();
- playerGuid[7] = recvPacket.ReadBit();
- bool ispublic = recvPacket.ReadBit(); // 0 == Officer, 1 == Public
- playerGuid[6] = recvPacket.ReadBit();
- uint32 noteLength = recvPacket.ReadBits(8);
- playerGuid[2] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(playerGuid[4]);
- recvPacket.ReadByteSeq(playerGuid[5]);
- recvPacket.ReadByteSeq(playerGuid[0]);
- recvPacket.ReadByteSeq(playerGuid[3]);
- recvPacket.ReadByteSeq(playerGuid[1]);
- recvPacket.ReadByteSeq(playerGuid[6]);
- recvPacket.ReadByteSeq(playerGuid[7]);
- std::string note = recvPacket.ReadString(noteLength);
- recvPacket.ReadByteSeq(playerGuid[2]);
+ guild->HandleSetMOTD(this, packet.MotdText);
+}
+void WorldSession::HandleGuildSetMemberNote(WorldPackets::Guild::GuildSetMemberNote& packet)
+{
TC_LOG_DEBUG("guild", "CMSG_GUILD_SET_NOTE [%s]: Target: %s, Note: %s, Public: %u",
- GetPlayerInfo().c_str(), playerGuid.ToString().c_str(), note.c_str(), ispublic);
+ GetPlayerInfo().c_str(), packet.NoteeGUID.ToString().c_str(), packet.Note.c_str(), packet.IsPublic);
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleSetMemberNote(this, note, playerGuid, ispublic);
+ guild->HandleSetMemberNote(this, packet.Note, packet.NoteeGUID, packet.IsPublic);
}
-void WorldSession::HandleGuildGetRanksOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildGetRanks(WorldPackets::Guild::GuildGetRanks& packet)
{
- ObjectGuid guildGuid;
-
- guildGuid[2] = recvPacket.ReadBit();
- guildGuid[3] = recvPacket.ReadBit();
- guildGuid[0] = recvPacket.ReadBit();
- guildGuid[6] = recvPacket.ReadBit();
- guildGuid[4] = recvPacket.ReadBit();
- guildGuid[7] = recvPacket.ReadBit();
- guildGuid[5] = recvPacket.ReadBit();
- guildGuid[1] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(guildGuid[3]);
- recvPacket.ReadByteSeq(guildGuid[4]);
- recvPacket.ReadByteSeq(guildGuid[5]);
- recvPacket.ReadByteSeq(guildGuid[7]);
- recvPacket.ReadByteSeq(guildGuid[1]);
- recvPacket.ReadByteSeq(guildGuid[0]);
- recvPacket.ReadByteSeq(guildGuid[6]);
- recvPacket.ReadByteSeq(guildGuid[2]);
-
TC_LOG_DEBUG("guild", "CMSG_GUILD_GET_RANKS [%s]: Guild: %s",
- GetPlayerInfo().c_str(), guildGuid.ToString().c_str());
+ GetPlayerInfo().c_str(), packet.GuildGUID.ToString().c_str());
- if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid))
+ if (Guild* guild = sGuildMgr->GetGuildByGuid(packet.GuildGUID))
if (guild->IsMember(_player->GetGUID()))
guild->SendGuildRankInfo(this);
}
-void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildAddRank(WorldPackets::Guild::GuildAddRank& packet)
{
- uint32 rankId;
- recvPacket >> rankId;
-
- uint32 length = recvPacket.ReadBits(7);
- std::string rankName = recvPacket.ReadString(length);
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_ADD_RANK [%s]: Rank: %s", GetPlayerInfo().c_str(), rankName.c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_ADD_RANK [%s]: Rank: %s", GetPlayerInfo().c_str(), packet.Name.c_str());
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleAddNewRank(this, rankName);
+ guild->HandleAddNewRank(this, packet.Name);
}
-void WorldSession::HandleGuildDeleteRankOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildDeleteRank(WorldPackets::Guild::GuildDeleteRank& packet)
{
- uint32 rankId;
- recvPacket >> rankId;
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_DELETE_RANK [%s]: Rank: %u", GetPlayerInfo().c_str(), rankId);
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_DELETE_RANK [%s]: Rank: %u", GetPlayerInfo().c_str(), packet.RankOrder);
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleRemoveRank(this, rankId);
+ guild->HandleRemoveRank(this, packet.RankOrder);
}
-void WorldSession::HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildUpdateInfoText(WorldPackets::Guild::GuildUpdateInfoText& packet)
{
- uint32 length = recvPacket.ReadBits(12);
- std::string info = recvPacket.ReadString(length);
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_INFO_TEXT [%s]: %s", GetPlayerInfo().c_str(), info.c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_UPDATE_INFO_TEXT [%s]: %s", GetPlayerInfo().c_str(), packet.InfoText.c_str());
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleSetInfo(this, info);
+ guild->HandleSetInfo(this, packet.InfoText);
}
-void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleSaveGuildEmblem(WorldPackets::Guild::SaveGuildEmblem& packet)
{
- ObjectGuid vendorGuid;
- recvPacket >> vendorGuid;
-
EmblemInfo emblemInfo;
- emblemInfo.ReadPacket(recvPacket);
+ emblemInfo.ReadPacket(packet);
TC_LOG_DEBUG("guild", "CMSG_SAVE_GUILD_EMBLEM [%s]: Guid: [%s] Style: %d, Color: %d, BorderStyle: %d, BorderColor: %d, BackgroundColor: %d"
- , GetPlayerInfo().c_str(), vendorGuid.ToString().c_str(), emblemInfo.GetStyle()
+ , GetPlayerInfo().c_str(), packet.Vendor.ToString().c_str(), emblemInfo.GetStyle()
, emblemInfo.GetColor(), emblemInfo.GetBorderStyle()
, emblemInfo.GetBorderColor(), emblemInfo.GetBackgroundColor());
- if (GetPlayer()->GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_TABARDDESIGNER))
+ if (GetPlayer()->GetNPCIfCanInteractWith(packet.Vendor, UNIT_NPC_FLAG_TABARDDESIGNER))
{
// Remove fake death
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
@@ -372,7 +210,7 @@ void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket)
Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_INVALIDVENDOR); // "That's not an emblem vendor!"
}
-void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */)
+void WorldSession::HandleGuildEventLogQuery(WorldPackets::Guild::GuildEventLogQuery& /*packet*/)
{
TC_LOG_DEBUG("guild", "MSG_GUILD_EVENT_LOG_QUERY [%s]", GetPlayerInfo().c_str());
@@ -380,7 +218,7 @@ void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */)
guild->SendEventLog(this);
}
-void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPacket& /* recvPacket */)
+void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery& /*packet*/)
{
TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_MONEY_WITHDRAWN [%s]", GetPlayerInfo().c_str());
@@ -388,25 +226,21 @@ void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPacket& /* recvPacket */)
guild->SendMoneyInfo(this);
}
-void WorldSession::HandleGuildPermissions(WorldPacket& /* recvPacket */)
+void WorldSession::HandleGuildPermissionsQuery(WorldPackets::Guild::GuildPermissionsQuery& /* packet */)
{
- TC_LOG_DEBUG("guild", "CMSG_GUILD_PERMISSIONS [%s]", GetPlayerInfo().c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_PERMISSIONS_QUERY [%s]", GetPlayerInfo().c_str());
if (Guild* guild = GetPlayer()->GetGuild())
guild->SendPermissions(this);
}
// Called when clicking on Guild bank gameobject
-void WorldSession::HandleGuildBankerActivate(WorldPacket& recvPacket)
+void WorldSession::HandleGuildBankActivate(WorldPackets::Guild::GuildBankActivate& packet)
{
- ObjectGuid guid;
- bool sendAllSlots;
- recvPacket >> guid >> sendAllSlots;
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_BANKER_ACTIVATE [%s]: [%s] AllSlots: %u"
- , GetPlayerInfo().c_str(), guid.ToString().c_str(), sendAllSlots);
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_ACTIVATE [%s]: [%s] AllSlots: %u"
+ , GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.FullUpdate);
- GameObject const* const go = GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK);
+ GameObject const* const go = GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK);
if (!go)
return;
@@ -417,423 +251,189 @@ void WorldSession::HandleGuildBankerActivate(WorldPacket& recvPacket)
return;
}
- guild->SendBankList(this, 0, true, true);
+ guild->SendBankList(this, 0, packet.FullUpdate);
}
// Called when opening guild bank tab only (first one)
-void WorldSession::HandleGuildBankQueryTab(WorldPacket& recvPacket)
+void WorldSession::HandleGuildBankQueryTab(WorldPackets::Guild::GuildBankQueryTab& packet)
{
- ObjectGuid guid;
- uint8 tabId;
- bool full;
-
- recvPacket >> guid >> tabId >> full;
-
TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_QUERY_TAB [%s]: %s, TabId: %u, ShowTabs: %u"
- , GetPlayerInfo().c_str(), guid.ToString().c_str(), tabId, full);
+ , GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.Tab, packet.FullUpdate);
- if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
+ if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
if (Guild* guild = GetPlayer()->GetGuild())
- guild->SendBankList(this, tabId, true, false);
+ guild->SendBankList(this, packet.Tab, packet.FullUpdate);
}
-void WorldSession::HandleGuildBankDepositMoney(WorldPacket& recvPacket)
+void WorldSession::HandleGuildBankDepositMoney(WorldPackets::Guild::GuildBankDepositMoney& packet)
{
- ObjectGuid guid;
- uint64 money;
- recvPacket >> guid >> money;
-
TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_DEPOSIT_MONEY [%s]: [%s], money: " UI64FMTD,
- GetPlayerInfo().c_str(), guid.ToString().c_str(), money);
+ GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.Money);
- if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
- if (money && GetPlayer()->HasEnoughMoney(money))
+ if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
+ if (packet.Money && GetPlayer()->HasEnoughMoney(packet.Money))
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleMemberDepositMoney(this, money);
+ guild->HandleMemberDepositMoney(this, packet.Money);
}
-void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket& recvPacket)
+void WorldSession::HandleGuildBankWithdrawMoney(WorldPackets::Guild::GuildBankWithdrawMoney& packet)
{
- ObjectGuid guid;
- uint64 money;
- recvPacket >> guid >> money;
-
TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_WITHDRAW_MONEY [%s]: [%s], money: " UI64FMTD,
- GetPlayerInfo().c_str(), guid.ToString().c_str(), money);
+ GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.Money);
- if (money && GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
+ if (packet.Money && GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleMemberWithdrawMoney(this, money);
+ guild->HandleMemberWithdrawMoney(this, packet.Money);
}
-void WorldSession::HandleGuildBankSwapItems(WorldPacket& recvPacket)
+void WorldSession::HandleGuildBankSwapItems(WorldPackets::Guild::GuildBankSwapItems& packet)
{
TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_SWAP_ITEMS [%s]", GetPlayerInfo().c_str());
- ObjectGuid GoGuid;
- recvPacket >> GoGuid;
-
- if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
- {
- recvPacket.rfinish(); // Prevent additional spam at rejected packet
+ if (!GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
return;
- }
Guild* guild = GetPlayer()->GetGuild();
if (!guild)
- {
- recvPacket.rfinish(); // Prevent additional spam at rejected packet
return;
- }
- uint8 bankToBank;
- recvPacket >> bankToBank;
-
- uint8 tabId;
- uint8 slotId;
- uint32 itemEntry;
- uint32 splitedAmount = 0;
-
- if (bankToBank)
+ if (packet.BankOnly)
{
- uint8 destTabId;
- recvPacket >> destTabId;
-
- uint8 destSlotId;
- recvPacket >> destSlotId;
-
- uint32 destItemEntry;
- recvPacket >> destItemEntry;
-
- recvPacket >> tabId;
- recvPacket >> slotId;
- recvPacket >> itemEntry;
- recvPacket.read_skip<uint8>(); // Always 0
- recvPacket >> splitedAmount;
-
- guild->SwapItems(GetPlayer(), tabId, slotId, destTabId, destSlotId, splitedAmount);
+ guild->SwapItems(GetPlayer(), packet.BankTab1, packet.BankSlot1, packet.BankTab, packet.BankSlot, packet.StackCount);
}
else
{
- uint8 playerBag = NULL_BAG;
- uint8 playerSlotId = NULL_SLOT;
- uint8 toChar = 1;
-
- recvPacket >> tabId;
- recvPacket >> slotId;
- recvPacket >> itemEntry;
-
- uint8 autoStore;
- recvPacket >> autoStore;
- if (autoStore)
- {
- recvPacket.read_skip<uint32>(); // autoStoreCount
- recvPacket.read_skip<uint8>(); // ToChar (?), always and expected to be 1 (autostore only triggered in Bank -> Char)
- recvPacket.read_skip<uint32>(); // Always 0
- }
- else
- {
- recvPacket >> playerBag;
- recvPacket >> playerSlotId;
- recvPacket >> toChar;
- recvPacket >> splitedAmount;
- }
-
// Player <-> Bank
// Allow to work with inventory only
- if (!Player::IsInventoryPos(playerBag, playerSlotId) && !(playerBag == NULL_BAG && playerSlotId == NULL_SLOT))
+ if (!Player::IsInventoryPos(packet.ContainerSlot, packet.ContainerItemSlot) && !packet.AutoStore)
GetPlayer()->SendEquipError(EQUIP_ERR_INTERNAL_BAG_ERROR, NULL);
else
- guild->SwapItemsWithInventory(GetPlayer(), toChar != 0, tabId, slotId, playerBag, playerSlotId, splitedAmount);
+ guild->SwapItemsWithInventory(GetPlayer(), packet.ToSlot != 0, packet.BankTab, packet.BankSlot, packet.ContainerSlot, packet.ContainerItemSlot, packet.StackCount);
}
}
-void WorldSession::HandleGuildBankBuyTab(WorldPacket& recvPacket)
+void WorldSession::HandleGuildBankBuyTab(WorldPackets::Guild::GuildBankBuyTab& packet)
{
- ObjectGuid guid;
- recvPacket >> guid;
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_BUY_TAB [%s]: [%s[, TabId: %u", GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.BankTab);
- uint8 tabId;
- recvPacket >> tabId;
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_BUY_TAB [%s]: [%s[, TabId: %u", GetPlayerInfo().c_str(), guid.ToString().c_str(), tabId);
-
- if (!guid || GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
+ if (!packet.Banker || GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleBuyBankTab(this, tabId);
+ guild->HandleBuyBankTab(this, packet.BankTab);
}
-void WorldSession::HandleGuildBankUpdateTab(WorldPacket& recvPacket)
+void WorldSession::HandleGuildBankUpdateTab(WorldPackets::Guild::GuildBankUpdateTab& packet)
{
- ObjectGuid guid;
- uint8 tabId;
- std::string name, icon;
-
- recvPacket >> guid >> tabId >> name >> icon;
-
TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_UPDATE_TAB [%s]: [%s], TabId: %u, Name: %s, Icon: %s"
- , GetPlayerInfo().c_str(), guid.ToString().c_str(), tabId, name.c_str(), icon.c_str());
- if (!name.empty() && !icon.empty())
- if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
+ , GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.BankTab, packet.Name.c_str(), packet.Icon.c_str());
+
+ if (!packet.Name.empty() && !packet.Icon.empty())
+ if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleSetBankTabInfo(this, tabId, name, icon);
+ guild->HandleSetBankTabInfo(this, packet.BankTab, packet.Name, packet.Icon);
}
-void WorldSession::HandleGuildBankLogQuery(WorldPacket& recvPacket)
+void WorldSession::HandleGuildBankLogQuery(WorldPackets::Guild::GuildBankLogQuery& packet)
{
- uint32 tabId;
- recvPacket >> tabId;
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_LOG_QUERY [%s]: TabId: %u", GetPlayerInfo().c_str(), tabId);
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_LOG_QUERY [%s]: TabId: %u", GetPlayerInfo().c_str(), packet.Tab);
if (Guild* guild = GetPlayer()->GetGuild())
- guild->SendBankLog(this, tabId);
+ guild->SendBankLog(this, packet.Tab);
}
-void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recvPacket)
+void WorldSession::HandleGuildBankTextQuery(WorldPackets::Guild::GuildBankTextQuery& packet)
{
- uint8 tabId;
- recvPacket >> tabId;
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_QUERY_TEXT [%s]: TabId: %u", GetPlayerInfo().c_str(), tabId);
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_QUERY_TEXT [%s]: TabId: %u", GetPlayerInfo().c_str(), packet.Tab);
if (Guild* guild = GetPlayer()->GetGuild())
- guild->SendBankTabText(this, tabId);
+ guild->SendBankTabText(this, packet.Tab);
}
-void WorldSession::HandleSetGuildBankTabText(WorldPacket& recvPacket)
+void WorldSession::HandleGuildBankSetTabText(WorldPackets::Guild::GuildBankSetTabText& packet)
{
- uint32 tabId;
- recvPacket >> tabId;
-
- uint32 textLen = recvPacket.ReadBits(14);
- std::string text = recvPacket.ReadString(textLen);
-
- TC_LOG_DEBUG("guild", "CMSG_SET_GUILD_BANK_TEXT [%s]: TabId: %u, Text: %s", GetPlayerInfo().c_str(), tabId, text.c_str());
+ TC_LOG_DEBUG("guild", "CMSG_SET_GUILD_BANK_TEXT [%s]: TabId: %u, Text: %s", GetPlayerInfo().c_str(), packet.Tab, packet.TabText.c_str());
if (Guild* guild = GetPlayer()->GetGuild())
- guild->SetBankTabText(tabId, text);
+ guild->SetBankTabText(packet.Tab, packet.TabText);
}
-void WorldSession::HandleGuildQueryXPOpcode(WorldPacket& recvPacket)
-{
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUERY_GUILD_XP");
-
- ObjectGuid guildGuid;
-
- guildGuid[2] = recvPacket.ReadBit();
- guildGuid[1] = recvPacket.ReadBit();
- guildGuid[0] = recvPacket.ReadBit();
- guildGuid[5] = recvPacket.ReadBit();
- guildGuid[4] = recvPacket.ReadBit();
- guildGuid[7] = recvPacket.ReadBit();
- guildGuid[6] = recvPacket.ReadBit();
- guildGuid[3] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(guildGuid[7]);
- recvPacket.ReadByteSeq(guildGuid[2]);
- recvPacket.ReadByteSeq(guildGuid[3]);
- recvPacket.ReadByteSeq(guildGuid[6]);
- recvPacket.ReadByteSeq(guildGuid[1]);
- recvPacket.ReadByteSeq(guildGuid[5]);
- recvPacket.ReadByteSeq(guildGuid[0]);
- recvPacket.ReadByteSeq(guildGuid[4]);
-
- TC_LOG_DEBUG("guild", "CMSG_QUERY_GUILD_XP [%s]: Guild: %s", GetPlayerInfo().c_str(), guildGuid.ToString().c_str());
-
- if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid))
- if (guild->IsMember(_player->GetGUID()))
- guild->SendGuildXP(this);
-}
-
-void WorldSession::HandleGuildSetRankPermissionsOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildSetRankPermissions(WorldPackets::Guild::GuildSetRankPermissions& packet)
{
Guild* guild = GetPlayer()->GetGuild();
if (!guild)
- {
- recvPacket.rfinish();
return;
- }
-
- uint32 oldRankId;
- uint32 newRankId;
- uint32 oldRights;
- uint32 newRights;
- uint32 moneyPerDay;
-
- recvPacket >> oldRankId;
- recvPacket >> oldRights;
- recvPacket >> newRights;
GuildBankRightsAndSlotsVec rightsAndSlots(GUILD_BANK_MAX_TABS);
for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId)
- {
- uint32 bankRights;
- uint32 slots;
-
- recvPacket >> bankRights;
- recvPacket >> slots;
+ rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, uint8(packet.TabFlags[tabId]), uint32(packet.TabWithdrawItemLimit[tabId]));
- rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, uint8(bankRights), slots);
- }
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_SET_RANK_PERMISSIONS [%s]: Rank: %s (%u)", GetPlayerInfo().c_str(), packet.RankName.c_str(), packet.RankOrder);
- recvPacket >> moneyPerDay;
- recvPacket >> newRankId;
- uint32 nameLength = recvPacket.ReadBits(7);
- std::string rankName = recvPacket.ReadString(nameLength);
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_SET_RANK_PERMISSIONS [%s]: Rank: %s (%u)", GetPlayerInfo().c_str(), rankName.c_str(), newRankId);
-
- guild->HandleSetRankInfo(this, newRankId, rankName, newRights, moneyPerDay, rightsAndSlots);
+ guild->HandleSetRankInfo(this, packet.RankOrder, packet.RankName, packet.Flags, packet.WithdrawGoldLimit, rightsAndSlots);
}
-void WorldSession::HandleGuildRequestPartyState(WorldPacket& recvPacket)
+void WorldSession::HandleGuildRequestPartyState(WorldPackets::Guild::RequestGuildPartyState& packet)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_GUILD_REQUEST_PARTY_STATE");
- ObjectGuid guildGuid;
-
- guildGuid[0] = recvPacket.ReadBit();
- guildGuid[6] = recvPacket.ReadBit();
- guildGuid[7] = recvPacket.ReadBit();
- guildGuid[3] = recvPacket.ReadBit();
- guildGuid[5] = recvPacket.ReadBit();
- guildGuid[1] = recvPacket.ReadBit();
- guildGuid[2] = recvPacket.ReadBit();
- guildGuid[4] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(guildGuid[6]);
- recvPacket.ReadByteSeq(guildGuid[3]);
- recvPacket.ReadByteSeq(guildGuid[2]);
- recvPacket.ReadByteSeq(guildGuid[1]);
- recvPacket.ReadByteSeq(guildGuid[5]);
- recvPacket.ReadByteSeq(guildGuid[0]);
- recvPacket.ReadByteSeq(guildGuid[7]);
- recvPacket.ReadByteSeq(guildGuid[4]);
-
- if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid))
+ if (Guild* guild = sGuildMgr->GetGuildByGuid(packet.GuildGUID))
guild->HandleGuildPartyRequest(this);
}
-void WorldSession::HandleGuildRequestChallengeUpdate(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleGuildChallengeUpdateRequest(WorldPackets::Guild::GuildChallengeUpdateRequest& /*packet*/)
{
if (Guild* guild = _player->GetGuild())
guild->HandleGuildRequestChallengeUpdate(this);
}
-void WorldSession::HandleGuildRequestMaxDailyXP(WorldPacket& recvPacket)
-{
- ObjectGuid guid;
- guid[0] = recvPacket.ReadBit();
- guid[3] = recvPacket.ReadBit();
- guid[5] = recvPacket.ReadBit();
- guid[1] = recvPacket.ReadBit();
- guid[4] = recvPacket.ReadBit();
- guid[6] = recvPacket.ReadBit();
- guid[7] = recvPacket.ReadBit();
- guid[2] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(guid[7]);
- recvPacket.ReadByteSeq(guid[4]);
- recvPacket.ReadByteSeq(guid[3]);
- recvPacket.ReadByteSeq(guid[5]);
- recvPacket.ReadByteSeq(guid[1]);
- recvPacket.ReadByteSeq(guid[2]);
- recvPacket.ReadByteSeq(guid[6]);
- recvPacket.ReadByteSeq(guid[0]);
-
- if (Guild* guild = sGuildMgr->GetGuildByGuid(guid))
- {
- if (guild->IsMember(_player->GetGUID()))
- {
- WorldPacket data(SMSG_GUILD_MAX_DAILY_XP, 8);
- data << uint64(sWorld->getIntConfig(CONFIG_GUILD_DAILY_XP_CAP));
- SendPacket(&data);
- }
- }
-}
-
-void WorldSession::HandleAutoDeclineGuildInvites(WorldPacket& recvPacket)
+void WorldSession::HandleDeclineGuildInvites(WorldPackets::Guild::DeclineGuildInvites& packet)
{
- uint8 enable;
- recvPacket >> enable;
-
- GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_AUTO_DECLINE_GUILD, enable != 0);
+ GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_AUTO_DECLINE_GUILD, packet.Allow);
}
-void WorldSession::HandleGuildRewardsQueryOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleRequestGuildRewardsList(WorldPackets::Guild::RequestGuildRewardsList& packet)
{
- recvPacket.read_skip<uint32>(); // Unk
-
if (sGuildMgr->GetGuildById(_player->GetGuildId()))
{
std::vector<GuildReward> const& rewards = sGuildMgr->GetGuildRewards();
- WorldPacket data(SMSG_GUILD_REWARDS_LIST, 3 + rewards.size() * (4 + 4 + 4 + 8 + 4 + 4));
- data.WriteBits(rewards.size(), 21);
- data.FlushBits();
+ WorldPackets::Guild::GuildRewardList rewardList;
+ rewardList.Version = uint32(time(NULL));
+ rewardList.RewardItems.reserve(rewards.size());
for (uint32 i = 0; i < rewards.size(); i++)
{
- data << uint32(rewards[i].Standing);
- data << int32(rewards[i].Racemask);
- data << uint32(rewards[i].Entry);
- data << uint64(rewards[i].Price);
- data << uint32(0); // Unused
- data << uint32(rewards[i].AchievementId);
+ WorldPackets::Guild::GuildRewardItem rewardItem;
+ rewardItem.ItemID = rewards[i].ItemID;
+ rewardItem.RaceMask = rewards[i].RaceMask;
+ rewardItem.MinGuildLevel = 0;
+ rewardItem.MinGuildRep = rewards[i].MinGuildRep;
+ rewardItem.AchievementsRequired = rewards[i].AchievementsRequired;
+ rewardItem.Cost = rewards[i].Cost;
+ rewardList.RewardItems.push_back(rewardItem);
}
- data << uint32(time(NULL));
- SendPacket(&data);
+
+ SendPacket(rewardList.Write());
}
}
-void WorldSession::HandleGuildQueryNewsOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildQueryNews(WorldPackets::Guild::GuildQueryNews& newsQuery)
{
- recvPacket.read_skip<uint32>();
TC_LOG_DEBUG("guild", "CMSG_GUILD_QUERY_NEWS [%s]", GetPlayerInfo().c_str());
if (Guild* guild = GetPlayer()->GetGuild())
- guild->SendNewsUpdate(this);
+ if (guild->GetGUID() == newsQuery.GuildGUID)
+ guild->SendNewsUpdate(this);
}
-void WorldSession::HandleGuildNewsUpdateStickyOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildNewsUpdateSticky(WorldPackets::Guild::GuildNewsUpdateSticky& packet)
{
- uint32 newsId;
- bool sticky;
- ObjectGuid guid;
-
- recvPacket >> newsId;
-
- guid[2] = recvPacket.ReadBit();
- guid[4] = recvPacket.ReadBit();
- guid[3] = recvPacket.ReadBit();
- guid[0] = recvPacket.ReadBit();
- sticky = recvPacket.ReadBit();
- guid[6] = recvPacket.ReadBit();
- guid[7] = recvPacket.ReadBit();
- guid[1] = recvPacket.ReadBit();
- guid[5] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(guid[6]);
- recvPacket.ReadByteSeq(guid[2]);
- recvPacket.ReadByteSeq(guid[1]);
- recvPacket.ReadByteSeq(guid[0]);
- recvPacket.ReadByteSeq(guid[5]);
- recvPacket.ReadByteSeq(guid[3]);
- recvPacket.ReadByteSeq(guid[7]);
- recvPacket.ReadByteSeq(guid[4]);
-
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleNewsSetSticky(this, newsId, sticky);
+ guild->HandleNewsSetSticky(this, packet.NewsID, packet.Sticky);
}
-void WorldSession::HandleGuildSetGuildMaster(WorldPacket& recvPacket)
+void WorldSession::HandleGuildSetGuildMaster(WorldPackets::Guild::GuildSetGuildMaster& packet)
{
- uint8 nameLength = recvPacket.ReadBits(7);
- // This is related to guild master inactivity.
- /*bool isDethrone = */recvPacket.ReadBit();
- std::string playerName = recvPacket.ReadString(nameLength);
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleSetNewGuildMaster(this, playerName);
+ guild->HandleSetNewGuildMaster(this, packet.NewMasterName);
}
void WorldSession::HandleGuildSetAchievementTracking(WorldPacket& recvPacket)
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 87f98e232bb..b3b9461e5d4 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -529,38 +529,41 @@ void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket& recvData)
GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagslot);
}
-void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData)
+void WorldSession::HandleBuyItemOpcode(WorldPackets::Item::BuyItem& packet)
{
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_BUY_ITEM");
- ObjectGuid vendorguid, bagGuid;
- uint32 item, slot, count;
- uint8 itemType; // 1 = item, 2 = currency
- uint8 bagSlot;
-
- recvData >> vendorguid >> itemType >> item >> slot >> count >> bagGuid >> bagSlot;
-
// client expects count starting at 1, and we send vendorslot+1 to client already
- if (slot > 0)
- --slot;
+ if (packet.Muid > 0)
+ --packet.Muid;
else
return; // cheating
- if (itemType == ITEM_VENDOR_TYPE_ITEM)
+ switch (packet.ItemType)
{
- Item* bagItem = _player->GetItemByGuid(bagGuid);
+ case ITEM_VENDOR_TYPE_ITEM:
+ {
+ Item* bagItem = _player->GetItemByGuid(packet.ContainerGUID);
- uint8 bag = NULL_BAG;
- if (bagItem && bagItem->IsBag())
- bag = bagItem->GetSlot();
- else if (bagGuid == GetPlayer()->GetGUID()) // The client sends the player guid when trying to store an item in the default backpack
- bag = INVENTORY_SLOT_BAG_0;
+ uint8 bag = NULL_BAG;
+ if (bagItem && bagItem->IsBag())
+ bag = bagItem->GetSlot();
+ else if (packet.ContainerGUID == GetPlayer()->GetGUID()) // The client sends the player guid when trying to store an item in the default backpack
+ bag = INVENTORY_SLOT_BAG_0;
- GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagSlot);
+ GetPlayer()->BuyItemFromVendorSlot(packet.VendorGUID, packet.Muid, packet.Item.ItemID,
+ packet.Quantity, bag, packet.Slot);
+ break;
+ }
+ case ITEM_VENDOR_TYPE_CURRENCY:
+ {
+ GetPlayer()->BuyCurrencyFromVendorSlot(packet.VendorGUID, packet.Muid, packet.Item.ItemID, packet.Quantity);
+ break;
+ }
+ default:
+ {
+ TC_LOG_DEBUG("network", "WORLD: received wrong itemType (%u) in HandleBuyItemOpcode", packet.ItemType);
+ break;
+ }
}
- else if (itemType == ITEM_VENDOR_TYPE_CURRENCY)
- GetPlayer()->BuyCurrencyFromVendorSlot(vendorguid, slot, item, count);
- else
- TC_LOG_DEBUG("network", "WORLD: received wrong itemType (%u) in HandleBuyItemOpcode", itemType);
}
void WorldSession::HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet)
@@ -1283,7 +1286,7 @@ void WorldSession::HandleItemTextQuery(WorldPacket& recvData )
TC_LOG_DEBUG("network", "CMSG_ITEM_TEXT_QUERY %s", itemGuid.ToString().c_str());
- WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, 14); // guess size
+ WorldPacket data(SMSG_QUERY_ITEM_TEXT_RESPONSE, 14); // guess size
if (Item* item = _player->GetItemByGuid(itemGuid))
{
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index 136f998b308..b8407c35be4 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -578,7 +578,7 @@ void WorldSession::HandleGetMailList(WorldPackets::Mail::MailGetList& packet)
response.TotalNumRecords = player->GetMailSize();
time_t cur_time = time(nullptr);
-
+
for (Mail* m : player->GetMails())
{
// skip deleted or not delivered (deliver delay not expired) mails
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index 154b3428022..80a2284aa7d 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -50,15 +50,12 @@ enum StableResultCode
STABLE_ERR_STABLE = 0x0C, // "Internal pet error"
};
-void WorldSession::HandleTabardVendorActivateOpcode(WorldPacket& recvData)
+void WorldSession::HandleTabardVendorActivateOpcode(WorldPackets::NPC::Hello& packet)
{
- ObjectGuid guid;
- recvData >> guid;
-
- Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TABARDDESIGNER);
+ Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_TABARDDESIGNER);
if (!unit)
{
- TC_LOG_DEBUG("network", "WORLD: HandleTabardVendorActivateOpcode - %s not found or you can not interact with him.", guid.ToString().c_str());
+ TC_LOG_DEBUG("network", "WORLD: HandleTabardVendorActivateOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str());
return;
}
@@ -66,14 +63,14 @@ void WorldSession::HandleTabardVendorActivateOpcode(WorldPacket& recvData)
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
- SendTabardVendorActivate(guid);
+ SendTabardVendorActivate(packet.Unit);
}
void WorldSession::SendTabardVendorActivate(ObjectGuid guid)
{
- WorldPacket data(SMSG_TABARD_VENDOR_ACTIVATE, 18);
- data << guid;
- SendPacket(&data);
+ WorldPackets::NPC::PlayerTabardVendorActivate packet;
+ packet.Vendor = guid;
+ SendPacket(packet.Write());
}
void WorldSession::HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet)
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index c1ac3cb18b2..193cc951a48 100644
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -30,6 +30,7 @@
#include "Pet.h"
#include "World.h"
#include "Group.h"
+#include "SpellHistory.h"
#include "SpellInfo.h"
#include "Player.h"
@@ -361,8 +362,6 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
if (result == SPELL_CAST_OK)
{
- pet->ToCreature()->AddCreatureSpellCooldown(spellid);
-
unit_target = spell->m_targets.GetUnitTarget();
//10% chance to play special pet attack talk, else growl
@@ -396,8 +395,8 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
else
spell->SendPetCastResult(result);
- if (!pet->ToCreature()->HasSpellCooldown(spellid))
- GetPlayer()->SendClearCooldown(spellid, pet);
+ if (!pet->GetSpellHistory()->HasCooldown(spellid))
+ pet->GetSpellHistory()->ResetCooldown(spellid, true);
spell->finish(false);
delete spell;
@@ -804,7 +803,6 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell&
{
if (Creature* creature = caster->ToCreature())
{
- creature->AddCreatureSpellCooldown(spellId);
if (Pet* pet = creature->ToPet())
{
// 10% chance to play special pet attack talk, else growl
@@ -822,16 +820,8 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell&
{
spell->SendPetCastResult(result);
- if (caster->GetTypeId() == TYPEID_PLAYER)
- {
- if (!caster->ToPlayer()->HasSpellCooldown(spellId))
- GetPlayer()->SendClearCooldown(spellId, caster);
- }
- else
- {
- if (!caster->ToCreature()->HasSpellCooldown(spellId))
- GetPlayer()->SendClearCooldown(spellId, caster);
- }
+ if (!caster->GetSpellHistory()->HasCooldown(spellId))
+ caster->GetSpellHistory()->ResetCooldown(spellId, true);
spell->finish(false);
delete spell;
diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp
index 45f8b6dea1d..bb658612f25 100644
--- a/src/server/game/Handlers/PetitionsHandler.cpp
+++ b/src/server/game/Handlers/PetitionsHandler.cpp
@@ -22,64 +22,28 @@
#include "WorldSession.h"
#include "World.h"
#include "ObjectMgr.h"
-#include "ArenaTeamMgr.h"
#include "GuildMgr.h"
#include "Log.h"
#include "Opcodes.h"
#include "Guild.h"
-#include "ArenaTeam.h"
#include "GossipDef.h"
#include "SocialMgr.h"
+#include "PetitionPackets.h"
#define CHARTER_DISPLAY_ID 16161
+#define GUILD_CHARTER_ITEM_ID 5863
-// Charters ID in item_template
-enum CharterItemIDs
+void WorldSession::HandlePetitionBuy(WorldPackets::Petition::PetitionBuy& packet)
{
- GUILD_CHARTER = 5863,
- ARENA_TEAM_CHARTER_2v2 = 23560,
- ARENA_TEAM_CHARTER_3v3 = 23561,
- ARENA_TEAM_CHARTER_5v5 = 23562
-};
+ TC_LOG_DEBUG("network", "Received CMSG_PETITION_BUY");
-void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
-{
- TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_BUY");
-
- ObjectGuid guidNPC;
- uint32 clientIndex; // 1 for guild and arenaslot+1 for arenas in client
- std::string name;
-
- recvData >> guidNPC; // NPC GUID
- recvData.read_skip<uint32>(); // 0
- recvData.read_skip<uint64>(); // 0
- recvData >> name; // name
- recvData.read_skip<std::string>(); // some string
- recvData.read_skip<uint32>(); // 0
- recvData.read_skip<uint32>(); // 0
- recvData.read_skip<uint32>(); // 0
- recvData.read_skip<uint32>(); // 0
- recvData.read_skip<uint32>(); // 0
- recvData.read_skip<uint32>(); // 0
- recvData.read_skip<uint32>(); // 0
- recvData.read_skip<uint16>(); // 0
- recvData.read_skip<uint32>(); // 0
- recvData.read_skip<uint32>(); // 0
- recvData.read_skip<uint32>(); // 0
-
- for (int i = 0; i < 10; ++i)
- recvData.read_skip<std::string>();
-
- recvData >> clientIndex; // index
- recvData.read_skip<uint32>(); // 0
-
- TC_LOG_DEBUG("network", "Petitioner %s tried sell petition: name %s", guidNPC.ToString().c_str(), name.c_str());
+ TC_LOG_DEBUG("network", "Petitioner %s tried sell petition: title %s", packet.Unit.ToString().c_str(), packet.Title.c_str());
// prevent cheating
- Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guidNPC, UNIT_NPC_FLAG_PETITIONER);
+ Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_PETITIONER);
if (!creature)
{
- TC_LOG_DEBUG("network", "WORLD: HandlePetitionBuyOpcode - %s not found or you can't interact with him.", guidNPC.ToString().c_str());
+ TC_LOG_DEBUG("network", "WORLD: HandlePetitionBuyOpcode - %s not found or you can't interact with him.", packet.Unit.ToString().c_str());
return;
}
@@ -87,109 +51,48 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
- uint32 charterid = 0;
- uint32 cost = 0;
- uint32 type = 0;
- if (creature->IsTabardDesigner())
- {
- // if tabard designer, then trying to buy a guild charter.
- // do not let if already in guild.
- if (_player->GetGuildId())
- return;
-
- charterid = GUILD_CHARTER;
- cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
- type = GUILD_CHARTER_TYPE;
- }
- else
- {
- /// @todo find correct opcode
- if (_player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
- {
- SendNotification(LANG_ARENA_ONE_TOOLOW, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
- return;
- }
+ uint32 charterItemID = GUILD_CHARTER_ITEM_ID;
+ uint32 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
- switch (clientIndex) // arenaSlot+1 as received from client (1 from 3 case)
- {
- case 1:
- charterid = ARENA_TEAM_CHARTER_2v2;
- cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
- type = ARENA_TEAM_CHARTER_2v2_TYPE;
- break;
- case 2:
- charterid = ARENA_TEAM_CHARTER_3v3;
- cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
- type = ARENA_TEAM_CHARTER_3v3_TYPE;
- break;
- case 3:
- charterid = ARENA_TEAM_CHARTER_5v5;
- cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
- type = ARENA_TEAM_CHARTER_5v5_TYPE;
- break;
- default:
- TC_LOG_DEBUG("network", "unknown selection at buy arena petition: %u", clientIndex);
- return;
- }
-
- if (_player->GetArenaTeamId(clientIndex - 1)) // arenaSlot+1 as received from client
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM);
- return;
- }
- }
+ // do not let if already in guild.
+ if (_player->GetGuildId())
+ return;
- if (type == GUILD_CHARTER_TYPE)
+ if (sGuildMgr->GetGuildByName(packet.Title))
{
- if (sGuildMgr->GetGuildByName(name))
- {
- Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, name);
- return;
- }
-
- if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
- {
- Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_INVALID, name);
- return;
- }
+ Guild::SendCommandResult(this, GUILD_COMMAND_CREATE_GUILD, ERR_GUILD_NAME_EXISTS_S, packet.Title);
+ return;
}
- else
+
+ if (sObjectMgr->IsReservedName(packet.Title) || !ObjectMgr::IsValidCharterName(packet.Title))
{
- if (sArenaTeamMgr->GetArenaTeamByName(name))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
- return;
- }
- if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID);
- return;
- }
+ Guild::SendCommandResult(this, GUILD_COMMAND_CREATE_GUILD, ERR_GUILD_NAME_INVALID, packet.Title);
+ return;
}
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(charterid);
+ ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(charterItemID);
if (!pProto)
{
- _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, charterid, 0);
+ _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, charterItemID, 0);
return;
}
if (!_player->HasEnoughMoney(uint64(cost)))
- { //player hasn't got enough money
- _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterid, 0);
+ {
+ _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterItemID, 0);
return;
}
ItemPosCountVec dest;
- InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->GetBuyCount());
+ InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterItemID, pProto->GetBuyCount());
if (msg != EQUIP_ERR_OK)
{
- _player->SendEquipError(msg, NULL, NULL, charterid);
+ _player->SendEquipError(msg, NULL, NULL, charterItemID);
return;
}
- _player->ModifyMoney(-(int32)cost);
- Item* charter = _player->StoreNewItem(dest, charterid, true);
+ _player->ModifyMoney(-int32(cost));
+ Item* charter = _player->StoreNewItem(dest, charterItemID, true);
if (!charter)
return;
@@ -204,7 +107,6 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
// datacorruption
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_BY_OWNER);
stmt->setUInt64(0, _player->GetGUID().GetCounter());
- stmt->setUInt8(1, type);
PreparedQueryResult result = CharacterDatabase.Query(stmt);
std::ostringstream ssInvalidPetitionGUIDs;
@@ -222,7 +124,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
ssInvalidPetitionGUIDs << '\'' << charter->GetGUID().GetCounter() << '\'';
TC_LOG_DEBUG("network", "Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str());
- CharacterDatabase.EscapeString(name);
+ CharacterDatabase.EscapeString(packet.Title);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
trans->PAppend("DELETE FROM petition WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str());
trans->PAppend("DELETE FROM petition_sign WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str());
@@ -230,244 +132,165 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION);
stmt->setUInt64(0, _player->GetGUID().GetCounter());
stmt->setUInt64(1, charter->GetGUID().GetCounter());
- stmt->setString(2, name);
- stmt->setUInt8(3, uint8(type));
+ stmt->setString(2, packet.Title);
trans->Append(stmt);
CharacterDatabase.CommitTransaction(trans);
}
-void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData)
+void WorldSession::HandlePetitionShowSignatures(WorldPackets::Petition::PetitionShowSignatures& packet)
{
TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_SHOW_SIGNATURES");
uint8 signs = 0;
- ObjectGuid petitionguid;
- recvData >> petitionguid; // petition guid
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE);
-
- stmt->setUInt64(0, petitionguid.GetCounter());
-
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (!result)
- {
- TC_LOG_DEBUG("entities.player.items", "Petition %s is not found for %s %s", petitionguid.ToString().c_str(), GetPlayer()->GetGUID().ToString().c_str(), GetPlayer()->GetName().c_str());
- return;
- }
- Field* fields = result->Fetch();
- uint32 type = fields[0].GetUInt8();
- // if guild petition and has guild => error, return;
- if (type == GUILD_CHARTER_TYPE && _player->GetGuildId())
+ // if has guild => error, return;
+ if (_player->GetGuildId())
return;
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE);
- stmt->setUInt64(0, petitionguid.GetCounter());
+ stmt->setUInt64(0, packet.Item.GetCounter());
- result = CharacterDatabase.Query(stmt);
+ PreparedQueryResult result = CharacterDatabase.Query(stmt);
// result == NULL also correct in case no sign yet
if (result)
signs = uint8(result->GetRowCount());
- TC_LOG_DEBUG("network", "CMSG_PETITION_SHOW_SIGNATURES %s", petitionguid.ToString().c_str());
+ TC_LOG_DEBUG("network", "CMSG_PETITION_SHOW_SIGNATURES %s", packet.Item.ToString().c_str());
- WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+1+signs*12));
- data << petitionguid; // petition guid
- data << _player->GetGUID(); // owner guid
- data << uint32(petitionguid.GetCounter()); // guild guid
- data << uint8(signs); // sign's count
+ WorldPackets::Petition::ServerPetitionShowSignatures signaturesPacket;
+ signaturesPacket.Item = packet.Item;
+ signaturesPacket.Owner = _player->GetGUID();
+ signaturesPacket.OwnerAccountID = ObjectGuid::Create<HighGuid::WowAccount>(ObjectMgr::GetPlayerAccountIdByGUID(_player->GetGUID()));
+ signaturesPacket.PetitionID = int32(packet.Item.GetCounter()); // @todo verify that...
+ signaturesPacket.Signatures.reserve(signs);
for (uint8 i = 1; i <= signs; ++i)
{
Field* fields2 = result->Fetch();
- data << ObjectGuid::Create<HighGuid::Player>(fields2[0].GetUInt64()); // Player GUID
- data << uint32(0); // there 0 ...
+ ObjectGuid signerGUID = ObjectGuid::Create<HighGuid::Player>(fields2[0].GetUInt64());
+
+ WorldPackets::Petition::ServerPetitionShowSignatures::PetitionSignature signature;
+ signature.Signer = signerGUID;
+ signature.Choice = 0;
+ signaturesPacket.Signatures.push_back(signature);
result->NextRow();
}
- SendPacket(&data);
+
+ SendPacket(signaturesPacket.Write());
}
-void WorldSession::HandlePetitionQueryOpcode(WorldPacket& recvData)
+void WorldSession::HandleQueryPetition(WorldPackets::Petition::QueryPetition& packet)
{
- TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_QUERY"); // ok
+ TC_LOG_DEBUG("network", "Received CMSG_QUERY_PETITION Petition %s PetitionID %u", packet.ItemGUID.ToString().c_str(), packet.PetitionID);
- uint32 guildguid;
- ObjectGuid petitionguid;
- recvData >> guildguid; // in Trinity always same as GUID_LOPART(petitionguid)
- recvData >> petitionguid; // petition guid
- TC_LOG_DEBUG("network", "CMSG_PETITION_QUERY Petition %s Guild GUID %u", petitionguid.ToString().c_str(), guildguid);
-
- SendPetitionQueryOpcode(petitionguid);
+ SendPetitionQueryOpcode(packet.ItemGUID);
}
-void WorldSession::SendPetitionQueryOpcode(ObjectGuid petitionguid)
+void WorldSession::SendPetitionQueryOpcode(ObjectGuid petitionGUID)
{
- ObjectGuid ownerguid;
- uint32 type;
- std::string name = "NO_NAME_FOR_GUID";
+ ObjectGuid ownerGUID;
+ std::string title = "NO_NAME_FOR_GUID";
+
+ WorldPackets::Petition::QueryPetitionResponse responsePacket;
+ responsePacket.PetitionID = uint32(petitionGUID.GetCounter()); // PetitionID (in Trinity always same as GUID_LOPART(petition guid))
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION);
- stmt->setUInt64(0, petitionguid.GetCounter());
+ stmt->setUInt64(0, petitionGUID.GetCounter());
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (result)
{
Field* fields = result->Fetch();
- ownerguid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64());
- name = fields[1].GetString();
- type = fields[2].GetUInt8();
+ ownerGUID = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64());
+ title = fields[1].GetString();
}
else
{
- TC_LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition (%s)", petitionguid.ToString().c_str());
- return;
- }
+ responsePacket.Allow = false;
+ SendPacket(responsePacket.Write());
- WorldPacket data(SMSG_QUERY_PETITION_RESPONSE, (4+8+name.size()+1+1+4*12+2+10));
- data << uint32(petitionguid.GetCounter()); // guild/team guid (in Trinity always same as GUID_LOPART(petition guid)
- data << ownerguid; // charter owner guid
- data << name; // name (guild/arena team)
- data << uint8(0); // some string
- if (type == GUILD_CHARTER_TYPE)
- {
- uint32 needed = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
- data << uint32(needed);
- data << uint32(needed);
- data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition
- }
- else
- {
- data << uint32(type-1);
- data << uint32(type-1);
- data << uint32(type); // bypass client - side limitation, a different value is needed here for each petition
+ TC_LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition (%s)", petitionGUID.ToString().c_str());
+ return;
}
- data << uint32(0); // 5
- data << uint32(0); // 6
- data << uint32(0); // 7
- data << uint32(0); // 8
- data << uint16(0); // 9 2 bytes field
- data << uint32(0); // 10
- data << uint32(0); // 11
- data << uint32(0); // 13 count of next strings?
- for (int i = 0; i < 10; ++i)
- data << uint8(0); // some string
+ int32 reqSignatures = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
- data << uint32(0); // 14
+ WorldPackets::Petition::PetitionInfo petitionInfo;
+ petitionInfo.PetitionID = int32(petitionGUID.GetCounter());
+ petitionInfo.Petitioner = ownerGUID;
+ petitionInfo.MinSignatures = reqSignatures;
+ petitionInfo.MaxSignatures = reqSignatures;
+ petitionInfo.Title = title;
- data << uint32(type != GUILD_CHARTER_TYPE); // 15 0 - guild, 1 - arena team
+ responsePacket.Allow = true;
+ responsePacket.Info = petitionInfo;
- SendPacket(&data);
+ SendPacket(responsePacket.Write());
}
-void WorldSession::HandlePetitionRenameGuildOpcode(WorldPacket& recvData)
+void WorldSession::HandlePetitionRenameGuild(WorldPackets::Petition::PetitionRenameGuild& packet)
{
- /// @todo: drop arena team code
+ TC_LOG_DEBUG("network", "Received CMSG_PETITION_RENAME_GUILD");
TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_RENAME_GUILD");
- ObjectGuid petitionGuid;
- uint32 type;
- std::string newName;
-
- recvData >> petitionGuid; // guid
- recvData >> newName; // new name
-
- Item* item = _player->GetItemByGuid(petitionGuid);
+ uint8 type = 0;
+ Item* item = _player->GetItemByGuid(packet.PetitionGuid);
if (!item)
return;
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE);
-
- stmt->setUInt64(0, petitionGuid.GetCounter());
-
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (result)
- {
- Field* fields = result->Fetch();
- type = fields[0].GetUInt8();
- }
- else
+ if (sGuildMgr->GetGuildByName(packet.NewGuildName))
{
- TC_LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition %s", petitionGuid.ToString().c_str());
+ Guild::SendCommandResult(this, GUILD_COMMAND_CREATE_GUILD, ERR_GUILD_NAME_EXISTS_S, packet.NewGuildName);
return;
}
- if (type == GUILD_CHARTER_TYPE)
+ if (sObjectMgr->IsReservedName(packet.NewGuildName) || !ObjectMgr::IsValidCharterName(packet.NewGuildName))
{
- if (sGuildMgr->GetGuildByName(newName))
- {
- Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, newName);
- return;
- }
- if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName))
- {
- Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_INVALID, newName);
- return;
- }
- }
- else
- {
- if (sArenaTeamMgr->GetArenaTeamByName(newName))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newName, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
- return;
- }
- if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newName, "", ERR_ARENA_TEAM_NAME_INVALID);
- return;
- }
+ Guild::SendCommandResult(this, GUILD_COMMAND_CREATE_GUILD, ERR_GUILD_NAME_INVALID, packet.NewGuildName);
+ return;
}
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME);
- stmt->setString(0, newName);
- stmt->setUInt64(1, petitionGuid.GetCounter());
+ stmt->setString(0, packet.NewGuildName);
+ stmt->setUInt64(1, packet.PetitionGuid.GetCounter());
CharacterDatabase.Execute(stmt);
- TC_LOG_DEBUG("network", "Petition %s renamed to '%s'", petitionGuid.ToString().c_str(), newName.c_str());
- WorldPacket data(SMSG_PETITION_RENAME_GUILD_RESPONSE, (8 + newName.size() + 1));
- data << petitionGuid;
- data << newName;
- SendPacket(&data);
+ WorldPackets::Petition::PetitionRenameGuildResponse renameResponse;
+ renameResponse.PetitionGuid = packet.PetitionGuid;
+ renameResponse.NewGuildName = packet.NewGuildName;
+ SendPacket(renameResponse.Write());
+
+ TC_LOG_DEBUG("network", "Petition %s renamed to '%s'", packet.PetitionGuid.ToString().c_str(), packet.NewGuildName.c_str());
}
-void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData)
+void WorldSession::HandleSignPetition(WorldPackets::Petition::SignPetition& packet)
{
- TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_SIGN"); // ok
-
- Field* fields;
- ObjectGuid petitionGuid;
- uint8 unk;
- recvData >> petitionGuid; // petition guid
- recvData >> unk;
+ TC_LOG_DEBUG("network", "Received CMSG_SIGN_PETITION");
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURES);
- stmt->setUInt64(0, petitionGuid.GetCounter());
- stmt->setUInt64(1, petitionGuid.GetCounter());
+ stmt->setUInt64(0, packet.PetitionGUID.GetCounter());
+ stmt->setUInt64(1, packet.PetitionGUID.GetCounter());
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (!result)
{
- TC_LOG_ERROR("network", "Petition %s is not found for %s %s", petitionGuid.ToString().c_str(), GetPlayer()->GetGUID().ToString().c_str(), GetPlayer()->GetName().c_str());
+ TC_LOG_ERROR("network", "Petition %s is not found for %s %s", packet.PetitionGUID.ToString().c_str(), GetPlayer()->GetGUID().ToString().c_str(), GetPlayer()->GetName().c_str());
return;
}
- fields = result->Fetch();
+ Field* fields = result->Fetch();
ObjectGuid ownerGuid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64());
uint64 signs = fields[1].GetUInt64();
- uint8 type = fields[2].GetUInt8();
if (ownerGuid == _player->GetGUID())
return;
@@ -475,93 +298,62 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData)
// not let enemies sign guild charter
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != ObjectMgr::GetPlayerTeamByGUID(ownerGuid))
{
- if (type != GUILD_CHARTER_TYPE)
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
- else
- Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED);
+ Guild::SendCommandResult(this, GUILD_COMMAND_CREATE_GUILD, ERR_GUILD_NOT_ALLIED);
return;
}
- if (type != GUILD_CHARTER_TYPE)
+ if (_player->GetGuildId())
{
- if (_player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", _player->GetName().c_str(), ERR_ARENA_TEAM_TARGET_TOO_LOW_S);
- return;
- }
-
- uint8 slot = ArenaTeam::GetSlotByType(type);
- if (slot >= MAX_ARENA_SLOT)
- return;
-
- if (_player->GetArenaTeamId(slot))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName().c_str(), ERR_ALREADY_IN_ARENA_TEAM_S);
- return;
- }
-
- if (_player->GetArenaTeamIdInvited())
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName().c_str(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
- return;
- }
+ Guild::SendCommandResult(this, GUILD_COMMAND_INVITE_PLAYER, ERR_ALREADY_IN_GUILD_S, _player->GetName());
+ return;
}
- else
+
+ if (_player->GetGuildIdInvited())
{
- if (_player->GetGuildId())
- {
- Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName());
- return;
- }
- if (_player->GetGuildIdInvited())
- {
- Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName());
- return;
- }
+ Guild::SendCommandResult(this, GUILD_COMMAND_INVITE_PLAYER, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName());
+ return;
}
- if (++signs > type) // client signs maximum
- return;
+ //if (++signs > type) // client signs maximum
+ // return;
// Client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
// not allow sign another player from already sign player account
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_ACCOUNT);
stmt->setUInt32(0, GetAccountId());
- stmt->setUInt64(1, petitionGuid.GetCounter());
+ stmt->setUInt64(1, packet.PetitionGUID.GetCounter());
result = CharacterDatabase.Query(stmt);
+ WorldPackets::Petition::PetitionSignResults signResult;
+ signResult.Player = _player->GetGUID();
+ signResult.Item = packet.PetitionGUID;
+
if (result)
{
- WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4));
- data << petitionGuid;
- data << _player->GetGUID();
- data << uint32(PETITION_SIGN_ALREADY_SIGNED);
+ signResult.Error = int32(PETITION_SIGN_ALREADY_SIGNED);
// close at signer side
- SendPacket(&data);
+ SendPacket(signResult.Write());
return;
}
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION_SIGNATURE);
stmt->setUInt64(0, ownerGuid.GetCounter());
- stmt->setUInt64(1, petitionGuid.GetCounter());
+ stmt->setUInt64(1, packet.PetitionGUID.GetCounter());
stmt->setUInt64(2, _player->GetGUID().GetCounter());
stmt->setUInt32(3, GetAccountId());
CharacterDatabase.Execute(stmt);
- TC_LOG_DEBUG("network", "PETITION SIGN: %s by player: %s (%s Account: %u)", petitionGuid.ToString().c_str(), _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), GetAccountId());
+ TC_LOG_DEBUG("network", "PETITION SIGN: %s by player: %s (%s Account: %u)", packet.PetitionGUID.ToString().c_str(), _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), GetAccountId());
- WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4));
- data << petitionGuid;
- data << _player->GetGUID();
- data << uint32(PETITION_SIGN_OK);
+ signResult.Error = int32(PETITION_SIGN_OK);
// close at signer side
- SendPacket(&data);
+ SendPacket(signResult.Write());
// update signs count on charter, required testing...
//Item* item = _player->GetItemByGuid(petitionguid));
@@ -570,21 +362,17 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData)
// update for owner if online
if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerGuid))
- owner->GetSession()->SendPacket(&data);
+ owner->GetSession()->SendPacket(signResult.Write());
}
-void WorldSession::HandlePetitionDeclineOpcode(WorldPacket& recvData)
+void WorldSession::HandleDeclinePetition(WorldPackets::Petition::DeclinePetition& packet)
{
- TC_LOG_DEBUG("network", "Received opcode MSG_PETITION_DECLINE"); // ok
+ TC_LOG_DEBUG("network", "Received CMSG_DECLINE_PETITION");
- ObjectGuid petitionguid;
- recvData >> petitionguid; // petition guid
- TC_LOG_DEBUG("network", "Petition %s declined by %s", petitionguid.ToString().c_str(), _player->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("network", "Petition %s declined by %s", packet.PetitionGUID.ToString().c_str(), _player->GetGUID().ToString().c_str());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_OWNER_BY_GUID);
-
- stmt->setUInt64(0, petitionguid.GetCounter());
-
+ stmt->setUInt64(0, packet.PetitionGUID.GetCounter());
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (!result)
@@ -596,147 +384,92 @@ void WorldSession::HandlePetitionDeclineOpcode(WorldPacket& recvData)
Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid);
if (owner) // petition owner online
{
+ // Disabled because packet isn't handled by the client in any way
/*
- WorldPacket data(SMSG_DECLINE_PETITION, 18);
- data << _player->GetGUID();
- owner->GetSession()->SendPacket(&data);
+ WorldPackets::Petition::PetitionDeclined packet;
+ packet.Decliner = _player->GetGUID();
+ owner->GetSession()->SendPacket(packet.Write());
*/
}
}
-void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData)
+void WorldSession::HandleOfferPetition(WorldPackets::Petition::OfferPetition& packet)
{
- TC_LOG_DEBUG("network", "Received opcode CMSG_OFFER_PETITION"); // ok
+ TC_LOG_DEBUG("network", "Received opcode CMSG_OFFER_PETITION");
- uint8 signs = 0;
- ObjectGuid petitionguid, plguid;
- uint32 type, junk;
- Player* player;
- recvData >> junk; // this is not petition type!
- recvData >> petitionguid; // petition guid
- recvData >> plguid; // player guid
-
- player = ObjectAccessor::FindConnectedPlayer(plguid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(packet.TargetPlayer);
if (!player)
return;
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE);
-
- stmt->setUInt64(0, petitionguid.GetCounter());
-
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (!result)
- return;
-
- Field* fields = result->Fetch();
- type = fields[0].GetUInt8();
-
- TC_LOG_DEBUG("network", "OFFER PETITION: type %u, %s, to %s", type, petitionguid.ToString().c_str(), plguid.ToString().c_str());
+ TC_LOG_DEBUG("network", "OFFER PETITION: %s, to %s", packet.ItemGUID.ToString().c_str(), packet.TargetPlayer.ToString().c_str());
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam())
{
- if (type != GUILD_CHARTER_TYPE)
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
- else
- Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED);
+ Guild::SendCommandResult(this, GUILD_COMMAND_CREATE_GUILD, ERR_GUILD_NOT_ALLIED);
return;
}
- if (type != GUILD_CHARTER_TYPE)
+ if (player->GetGuildId())
{
- if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
- {
- // player is too low level to join an arena team
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, player->GetName().c_str(), "", ERR_ARENA_TEAM_TARGET_TOO_LOW_S);
- return;
- }
-
- uint8 slot = ArenaTeam::GetSlotByType(type);
- if (slot >= MAX_ARENA_SLOT)
- return;
-
- if (player->GetArenaTeamId(slot))
- {
- // player is already in an arena team
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, player->GetName().c_str(), "", ERR_ALREADY_IN_ARENA_TEAM_S);
- return;
- }
-
- if (player->GetArenaTeamIdInvited())
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName().c_str(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
- return;
- }
+ Guild::SendCommandResult(this, GUILD_COMMAND_INVITE_PLAYER, ERR_ALREADY_IN_GUILD_S, _player->GetName());
+ return;
}
- else
- {
- if (player->GetGuildId())
- {
- Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName());
- return;
- }
- if (player->GetGuildIdInvited())
- {
- Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName());
- return;
- }
+ if (player->GetGuildIdInvited())
+ {
+ Guild::SendCommandResult(this, GUILD_COMMAND_INVITE_PLAYER, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName());
+ return;
}
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE);
+ stmt->setUInt64(0, packet.ItemGUID.GetCounter());
+ PreparedQueryResult result = CharacterDatabase.Query(stmt);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE);
-
- stmt->setUInt64(0, petitionguid.GetCounter());
-
- result = CharacterDatabase.Query(stmt);
-
+ uint8 signs = 0;
// result == NULL also correct charter without signs
if (result)
signs = uint8(result->GetRowCount());
- WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+signs+signs*12));
- data << petitionguid; // petition guid
- data << _player->GetGUID(); // owner guid
- data << uint32(petitionguid.GetCounter()); // guild guid
- data << uint8(signs); // sign's count
+ WorldPackets::Petition::ServerPetitionShowSignatures signaturesPacket;
+ signaturesPacket.Item = packet.ItemGUID;
+ signaturesPacket.Owner = _player->GetGUID();
+ signaturesPacket.OwnerAccountID = ObjectGuid::Create<HighGuid::WowAccount>(player->GetSession()->GetAccountId());
+ signaturesPacket.PetitionID = int32(packet.ItemGUID.GetCounter()); // @todo verify that...
- for (uint8 i = 1; i <= signs; ++i)
+ signaturesPacket.Signatures.reserve(signs);
+ for (uint8 i = 0; i < signs; ++i)
{
Field* fields2 = result->Fetch();
- data << ObjectGuid::Create<HighGuid::Player>(fields2[0].GetUInt64()); // Player GUID
- data << uint32(0); // there 0 ...
+ ObjectGuid signerGUID = ObjectGuid::Create<HighGuid::Player>(fields2[0].GetUInt64());
+
+ WorldPackets::Petition::ServerPetitionShowSignatures::PetitionSignature signature;
+ signature.Signer = signerGUID;
+ signature.Choice = 0;
+ signaturesPacket.Signatures.push_back(signature);
result->NextRow();
}
- player->GetSession()->SendPacket(&data);
+ player->GetSession()->SendPacket(signaturesPacket.Write());
}
-void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData)
+void WorldSession::HandleTurnInPetition(WorldPackets::Petition::TurnInPetition& packet)
{
- TC_LOG_DEBUG("network", "Received opcode CMSG_TURN_IN_PETITION");
-
- // Get petition guid from packet
- WorldPacket data;
- ObjectGuid petitionGuid;
-
- recvData >> petitionGuid;
+ TC_LOG_DEBUG("network", "Received CMSG_TURN_IN_PETITION");
// Check if player really has the required petition charter
- Item* item = _player->GetItemByGuid(petitionGuid);
+ Item* item = _player->GetItemByGuid(packet.Item);
if (!item)
return;
- TC_LOG_DEBUG("network", "Petition %s turned in by %s", petitionGuid.ToString().c_str(), _player->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("network", "Petition %s turned in by %s", packet.Item.ToString().c_str(), _player->GetGUID().ToString().c_str());
// Get petition data from db
ObjectGuid ownerguid;
- uint32 type;
std::string name;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION);
- stmt->setUInt64(0, petitionGuid.GetCounter());
+ stmt->setUInt64(0, packet.Item.GetCounter());
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (result)
@@ -744,11 +477,10 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData)
Field* fields = result->Fetch();
ownerguid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64());
name = fields[1].GetString();
- type = fields[2].GetUInt8();
}
else
{
- TC_LOG_ERROR("network", "Player %s (%s) tried to turn in petition (%s) that is not present in the database", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), petitionGuid.ToString().c_str());
+ TC_LOG_ERROR("network", "Player %s (%s) tried to turn in petition (%s) that is not present in the database", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.Item.ToString().c_str());
return;
}
@@ -756,52 +488,27 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData)
if (_player->GetGUID() != ownerguid)
return;
- // Petition type (guild/arena) specific checks
- if (type == GUILD_CHARTER_TYPE)
+ // Check if player is already in a guild
+ if (_player->GetGuildId())
{
- // Check if player is already in a guild
- if (_player->GetGuildId())
- {
- data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
- data << uint32(PETITION_TURN_ALREADY_IN_GUILD);
- _player->GetSession()->SendPacket(&data);
- return;
- }
-
- // Check if guild name is already taken
- if (sGuildMgr->GetGuildByName(name))
- {
- Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, name);
- return;
- }
+ WorldPackets::Petition::TurnInPetitionResult resultPacket;
+ resultPacket.Result = int32(PETITION_TURN_ALREADY_IN_GUILD);
+ _player->GetSession()->SendPacket(resultPacket.Write());
+ return;
}
- else
- {
- // Check for valid arena bracket (2v2, 3v3, 5v5)
- uint8 slot = ArenaTeam::GetSlotByType(type);
- if (slot >= MAX_ARENA_SLOT)
- return;
-
- // Check if player is already in an arena team
- if (_player->GetArenaTeamId(slot))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM);
- return;
- }
- // Check if arena team name is already taken
- if (sArenaTeamMgr->GetArenaTeamByName(name))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
- return;
- }
+ // Check if guild name is already taken
+ if (sGuildMgr->GetGuildByName(name))
+ {
+ Guild::SendCommandResult(this, GUILD_COMMAND_CREATE_GUILD, ERR_GUILD_NAME_EXISTS_S, name);
+ return;
}
// Get petition signatures from db
uint8 signatures;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE);
- stmt->setUInt64(0, petitionGuid.GetCounter());
+ stmt->setUInt64(0, packet.Item.GetCounter());
result = CharacterDatabase.Query(stmt);
if (result)
@@ -809,108 +516,69 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData)
else
signatures = 0;
- uint32 requiredSignatures;
- if (type == GUILD_CHARTER_TYPE)
- requiredSignatures = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
- else
- requiredSignatures = type-1;
+ uint32 requiredSignatures = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
// Notify player if signatures are missing
if (signatures < requiredSignatures)
{
- data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
- data << (uint32)PETITION_TURN_NEED_MORE_SIGNATURES;
- SendPacket(&data);
+ WorldPackets::Petition::TurnInPetitionResult resultPacket;
+ resultPacket.Result = int32(PETITION_TURN_NEED_MORE_SIGNATURES);
+ SendPacket(resultPacket.Write());
return;
}
- // Proceed with guild/arena team creation
+ // Proceed with guild creation
// Delete charter item
_player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
- if (type == GUILD_CHARTER_TYPE)
- {
- // Create guild
- Guild* guild = new Guild;
-
- if (!guild->Create(_player, name))
- {
- delete guild;
- return;
- }
-
- // Register guild and add guild master
- sGuildMgr->AddGuild(guild);
+ // Create guild
+ Guild* guild = new Guild;
- Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_COMMAND_SUCCESS, name);
-
- // Add members from signatures
- for (uint8 i = 0; i < signatures; ++i)
- {
- Field* fields = result->Fetch();
- guild->AddMember(ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64()));
- result->NextRow();
- }
- }
- else
+ if (!guild->Create(_player, name))
{
- // Receive the rest of the packet in arena team creation case
- uint32 background, icon, iconcolor, border, bordercolor;
- recvData >> background >> icon >> iconcolor >> border >> bordercolor;
-
- // Create arena team
- ArenaTeam* arenaTeam = new ArenaTeam();
+ delete guild;
+ return;
+ }
- if (!arenaTeam->Create(_player->GetGUID(), type, name, background, icon, iconcolor, border, bordercolor))
- {
- delete arenaTeam;
- return;
- }
+ // Register guild and add guild master
+ sGuildMgr->AddGuild(guild);
- // Register arena team
- sArenaTeamMgr->AddArenaTeam(arenaTeam);
- TC_LOG_DEBUG("network", "PetitonsHandler: Arena team (guid: %u) added to ObjectMgr", arenaTeam->GetId());
+ Guild::SendCommandResult(this, GUILD_COMMAND_CREATE_GUILD, ERR_GUILD_COMMAND_SUCCESS, name);
- // Add members
- for (uint8 i = 0; i < signatures; ++i)
- {
- Field* fields = result->Fetch();
- ObjectGuid memberGUID = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64());
- TC_LOG_DEBUG("network", "PetitionsHandler: Adding arena team (guid: %u) member %s", arenaTeam->GetId(), memberGUID.ToString().c_str());
- arenaTeam->AddMember(memberGUID);
- result->NextRow();
- }
+ // Add members from signatures
+ for (uint8 i = 0; i < signatures; ++i)
+ {
+ Field* fields = result->Fetch();
+ guild->AddMember(ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64()));
+ result->NextRow();
}
SQLTransaction trans = CharacterDatabase.BeginTransaction();
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_GUID);
- stmt->setUInt64(0, petitionGuid.GetCounter());
+ stmt->setUInt64(0, packet.Item.GetCounter());
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID);
- stmt->setUInt64(0, petitionGuid.GetCounter());
+ stmt->setUInt64(0, packet.Item.GetCounter());
trans->Append(stmt);
CharacterDatabase.CommitTransaction(trans);
// created
- TC_LOG_DEBUG("network", "Player %s (%s) turning in petition %s", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), petitionGuid.ToString().c_str());
+ TC_LOG_DEBUG("network", "Player %s (%s) turning in petition %s", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.Item.ToString().c_str());
- data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
- data << (uint32)PETITION_TURN_OK;
- SendPacket(&data);
+ WorldPackets::Petition::TurnInPetitionResult resultPacket;
+ resultPacket.Result = int32(PETITION_TURN_OK);
+ SendPacket(resultPacket.Write());
}
-void WorldSession::HandlePetitionShowListOpcode(WorldPacket& recvData)
+void WorldSession::HandlePetitionShowList(WorldPackets::Petition::PetitionShowList& packet)
{
- TC_LOG_DEBUG("network", "Received CMSG_PETITION_SHOWLIST");
-
- ObjectGuid guid;
- recvData >> guid;
+ TC_LOG_DEBUG("network", "Received CMSG_PETITION_SHOW_LIST");
- SendPetitionShowList(guid);
+ SendPetitionShowList(packet.PetitionUnit);
}
void WorldSession::SendPetitionShowList(ObjectGuid guid)
@@ -922,45 +590,10 @@ void WorldSession::SendPetitionShowList(ObjectGuid guid)
return;
}
- WorldPacket data(SMSG_PETITION_SHOW_LIST, 8+1+4*6);
- data << guid; // npc guid
-
- if (creature->IsTabardDesigner())
- {
- data << uint8(1); // count
- data << uint32(1); // index
- data << uint32(GUILD_CHARTER); // charter entry
- data << uint32(CHARTER_DISPLAY_ID); // charter display id
- data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD)); // charter cost
- data << uint32(0); // unknown
- data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs
- }
- else
- {
- data << uint8(3); // count
- // 2v2
- data << uint32(1); // index
- data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry
- data << uint32(CHARTER_DISPLAY_ID); // charter display id
- data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2)); // charter cost
- data << uint32(2); // unknown
- data << uint32(2); // required signs?
- // 3v3
- data << uint32(2); // index
- data << uint32(ARENA_TEAM_CHARTER_3v3); // charter entry
- data << uint32(CHARTER_DISPLAY_ID); // charter display id
- data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3)); // charter cost
- data << uint32(3); // unknown
- data << uint32(3); // required signs?
- // 5v5
- data << uint32(3); // index
- data << uint32(ARENA_TEAM_CHARTER_5v5); // charter entry
- data << uint32(CHARTER_DISPLAY_ID); // charter display id
- data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5)); // charter cost
- data << uint32(5); // unknown
- data << uint32(5); // required signs?
- }
+ WorldPackets::Petition::ServerPetitionShowList packet;
+ packet.Unit = guid;
+ packet.Price = uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD));
+ SendPacket(packet.Write());
- SendPacket(&data);
- TC_LOG_DEBUG("network", "Sent SMSG_PETITION_SHOWLIST");
+ TC_LOG_DEBUG("network", "Sent SMSG_PETITION_SHOW_LIST");
}
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index 4afb2826889..6883ec13aac 100644
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -291,7 +291,7 @@ void WorldSession::HandleQuestNPCQuery(WorldPacket& recvData)
if (!sObjectMgr->GetQuestTemplate(questId))
{
- TC_LOG_DEBUG("network", "WORLD: Unknown quest %u in CMSG_QUEST_NPC_QUERY by %s", questId, _player->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("network", "WORLD: Unknown quest %u in CMSG_QUERY_QUEST_COMPLETION_NPCS by %s", questId, _player->GetGUID().ToString().c_str());
continue;
}
@@ -304,7 +304,7 @@ void WorldSession::HandleQuestNPCQuery(WorldPacket& recvData)
quests[questId].push_back(it->second | 0x80000000); // GO mask
}
- WorldPacket data(SMSG_QUEST_NPC_QUERY_RESPONSE, 3 + quests.size() * 14);
+ WorldPacket data(SMSG_QUEST_COMPLETION_NPC_RESPONSE, 3 + quests.size() * 14);
data.WriteBits(quests.size(), 23);
for (auto it = quests.begin(); it != quests.end(); ++it)
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index 3a173e4e582..c86ff147559 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -418,8 +418,6 @@ void WorldSession::HandlePetCancelAuraOpcode(WorldPacket& recvPacket)
}
pet->RemoveOwnedAura(spellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_CANCEL);
-
- pet->AddCreatureSpellCooldown(spellId);
}
void WorldSession::HandleCancelGrowthAuraOpcode(WorldPacket& /*recvPacket*/) { }
diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h
index 75ea54a9dc5..a14bcb50107 100644
--- a/src/server/game/Loot/LootMgr.h
+++ b/src/server/game/Loot/LootMgr.h
@@ -35,11 +35,6 @@ namespace WorldPackets
{
class LootResponse;
}
-
- namespace Item
- {
- struct ItemInstance;
- }
}
enum RollType
@@ -155,8 +150,7 @@ struct LootStoreItem
{ }
bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation)
- bool IsValid(LootStore const& store, uint32 entry) const;
- // Checks correctness of values
+ bool IsValid(LootStore const& store, uint32 entry) const; // Checks correctness of values
};
struct LootItem
diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp
index 92a41e8c6a6..adc4768501c 100644
--- a/src/server/game/Reputation/ReputationMgr.cpp
+++ b/src/server/game/Reputation/ReputationMgr.cpp
@@ -49,7 +49,7 @@ bool ReputationMgr::IsAtWar(uint32 faction_id) const
if (!factionEntry)
{
TC_LOG_ERROR("misc", "ReputationMgr::IsAtWar: Can't get AtWar flag of %s for unknown faction (faction id) #%u.", _player->GetName().c_str(), faction_id);
- return 0;
+ return false;
}
return IsAtWar(factionEntry);
diff --git a/src/server/game/Server/Packets/CombatPackets.cpp b/src/server/game/Server/Packets/CombatPackets.cpp
index 53a489ebc21..69718cb932f 100644
--- a/src/server/game/Server/Packets/CombatPackets.cpp
+++ b/src/server/game/Server/Packets/CombatPackets.cpp
@@ -31,11 +31,21 @@ WorldPacket const* WorldPackets::Combat::AttackStart::Write()
return &_worldPacket;
}
+WorldPackets::Combat::SAttackStop::SAttackStop(Unit const* attacker, Unit const* victim) : ServerPacket(SMSG_ATTACKSTOP, 16 + 16 + 1)
+{
+ Attacker = attacker->GetGUID();
+ if (victim)
+ {
+ Victim = victim->GetGUID();
+ NowDead = victim->isDead();
+ }
+}
+
WorldPacket const* WorldPackets::Combat::SAttackStop::Write()
{
_worldPacket << Attacker;
_worldPacket << Victim;
- _worldPacket.WriteBit(Dead);
+ _worldPacket.WriteBit(NowDead);
_worldPacket.FlushBits();
return &_worldPacket;
@@ -147,3 +157,22 @@ WorldPacket const* WorldPackets::Combat::AttackSwingError::Write()
_worldPacket.FlushBits();
return &_worldPacket;
}
+
+WorldPacket const* WorldPackets::Combat::PowerUpdate::Write()
+{
+ _worldPacket << Guid;
+ _worldPacket << uint32(Powers.size());
+ for (PowerUpdatePower const& power : Powers)
+ {
+ _worldPacket << power.Power;
+ _worldPacket << power.PowerType;
+ }
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Combat::SetSheathed::Read()
+{
+ _worldPacket >> CurrentSheathState;
+ Animate = _worldPacket.ReadBit();
+}
diff --git a/src/server/game/Server/Packets/CombatPackets.h b/src/server/game/Server/Packets/CombatPackets.h
index 54d97e5774c..4eeb61d3523 100644
--- a/src/server/game/Server/Packets/CombatPackets.h
+++ b/src/server/game/Server/Packets/CombatPackets.h
@@ -69,13 +69,14 @@ namespace WorldPackets
class SAttackStop final : public ServerPacket
{
public:
- SAttackStop() : ServerPacket(SMSG_ATTACKSTOP, 17) { }
+ SAttackStop() : ServerPacket(SMSG_ATTACKSTOP, 16 + 16 + 1) { }
+ SAttackStop(Unit const* attacker, Unit const* victim);
WorldPacket const* Write() override;
ObjectGuid Attacker;
ObjectGuid Victim;
- bool Dead = false;
+ bool NowDead = false;
};
struct ThreatInfo
@@ -161,7 +162,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
- Optional<WorldPackets::Spells::SpellCastLogData> LogData;
+ Optional<Spells::SpellCastLogData> LogData;
uint32 HitInfo = 0; // Flags
ObjectGuid AttackerGUID;
ObjectGuid VictimGUID;
@@ -184,6 +185,36 @@ namespace WorldPackets
WorldPacket const* Write() override { return &_worldPacket; }
};
+
+ struct PowerUpdatePower
+ {
+ PowerUpdatePower(int32 power, uint8 powerType) : Power(power), PowerType(powerType) { }
+
+ int32 Power = 0;
+ uint8 PowerType = 0;
+ };
+
+ class PowerUpdate final : public ServerPacket
+ {
+ public:
+ PowerUpdate() : ServerPacket(SMSG_POWER_UPDATE, 16 + 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Guid;
+ std::vector<PowerUpdatePower> Powers;
+ };
+
+ class SetSheathed final : public ClientPacket
+ {
+ public:
+ SetSheathed(WorldPacket&& packet) : ClientPacket(CMSG_SET_SHEATHED, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 CurrentSheathState = 0;
+ bool Animate = true;
+ };
}
}
diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp
index 5ad6d9729c2..ef0c01c5cb7 100644
--- a/src/server/game/Server/Packets/GuildPackets.cpp
+++ b/src/server/game/Server/Packets/GuildPackets.cpp
@@ -58,3 +58,755 @@ WorldPacket const* WorldPackets::Guild::QueryGuildInfoResponse::Write()
return &_worldPacket;
}
+
+WorldPacket const* WorldPackets::Guild::GuildRoster::Write()
+{
+ _worldPacket << NumAccounts;
+ _worldPacket.AppendPackedTime(CreateDate);
+ _worldPacket << GuildFlags;
+ _worldPacket << uint32(MemberData.size());
+
+ for (GuildRosterMemberData const& member : MemberData)
+ _worldPacket << member;
+
+ _worldPacket.ResetBitPos();
+ _worldPacket.WriteBits(WelcomeText.length(), 10);
+ _worldPacket.WriteBits(InfoText.length(), 10);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(WelcomeText);
+ _worldPacket.WriteString(InfoText);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildRosterUpdate::Write()
+{
+ _worldPacket << uint32(MemberData.size());
+
+ for (GuildRosterMemberData const& member : MemberData)
+ _worldPacket << member;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::GuildUpdateMotdText::Read()
+{
+ uint32 textLen = _worldPacket.ReadBits(10);
+ MotdText = _worldPacket.ReadString(textLen);
+}
+
+WorldPacket const* WorldPackets::Guild::GuildCommandResult::Write()
+{
+ _worldPacket << Result;
+ _worldPacket << Command;
+
+ _worldPacket.WriteBits(Name.length(), 8);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(Name);
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::DeclineGuildInvites::Read()
+{
+ Allow = _worldPacket.ReadBit();
+}
+
+void WorldPackets::Guild::GuildInviteByName::Read()
+{
+ uint32 nameLen = _worldPacket.ReadBits(9);
+ Name = _worldPacket.ReadString(nameLen);
+}
+
+WorldPacket const* WorldPackets::Guild::GuildInvite::Write()
+{
+ _worldPacket.WriteBits(InviterName.length(), 6);
+ _worldPacket.WriteBits(GuildName.length(), 7);
+ _worldPacket.WriteBits(OldGuildName.length(), 7);
+ _worldPacket.FlushBits();
+
+ _worldPacket << InviterVirtualRealmAddress;
+ _worldPacket << GuildVirtualRealmAddress;
+ _worldPacket << GuildGUID;
+ _worldPacket << OldGuildVirtualRealmAddress;
+ _worldPacket << OldGuildGUID;
+ _worldPacket << EmblemStyle;
+ _worldPacket << EmblemColor;
+ _worldPacket << BorderStyle;
+ _worldPacket << BorderColor;
+ _worldPacket << Background;
+ _worldPacket << Level;
+
+ _worldPacket.WriteString(InviterName);
+ _worldPacket.WriteString(GuildName);
+ _worldPacket.WriteString(OldGuildName);
+
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRosterProfessionData const& rosterProfessionData)
+{
+ data << rosterProfessionData.DbID;
+ data << rosterProfessionData.Rank;
+ data << rosterProfessionData.Step;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRosterMemberData const& rosterMemberData)
+{
+ data << rosterMemberData.Guid;
+ data << rosterMemberData.RankID;
+ data << rosterMemberData.AreaID;
+ data << rosterMemberData.PersonalAchievementPoints;
+ data << rosterMemberData.GuildReputation;
+ data << rosterMemberData.LastSave;
+
+ for (uint8 i = 0; i < 2; i++)
+ data << rosterMemberData.Profession[i];
+
+ data << rosterMemberData.VirtualRealmAddress;
+ data << rosterMemberData.Status;
+ data << rosterMemberData.Level;
+ data << rosterMemberData.ClassID;
+ data << rosterMemberData.Gender;
+
+ data.WriteBits(rosterMemberData.Name.length(), 6);
+ data.WriteBits(rosterMemberData.Note.length(), 8);
+ data.WriteBits(rosterMemberData.OfficerNote.length(), 8);
+ data.WriteBit(rosterMemberData.Authenticated);
+ data.WriteBit(rosterMemberData.SorEligible);
+ data.FlushBits();
+
+ data.WriteString(rosterMemberData.Name);
+ data.WriteString(rosterMemberData.Note);
+ data.WriteString(rosterMemberData.OfficerNote);
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildEventPresenceChange::Write()
+{
+ _worldPacket << Guid;
+ _worldPacket << VirtualRealmAddress;
+
+ _worldPacket.WriteBits(Name.length(), 6);
+ _worldPacket.WriteBit(LoggedOn);
+ _worldPacket.WriteBit(Mobile);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(Name);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildEventMotd::Write()
+{
+ _worldPacket.WriteBits(MotdText.length(), 10);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(MotdText);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildEventPlayerJoined::Write()
+{
+ _worldPacket << Guid;
+ _worldPacket << VirtualRealmAddress;
+
+ _worldPacket.WriteBits(Name.length(), 6);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(Name);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildEventRankChanged::Write()
+{
+ _worldPacket << RankID;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildEventBankMoneyChanged::Write()
+{
+ _worldPacket << Money;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildEventLogQueryResults::Write()
+{
+ _worldPacket.reserve(4 + Entry.size() * 38);
+
+ _worldPacket << uint32(Entry.size());
+
+ for (GuildEventEntry const& entry : Entry)
+ {
+ _worldPacket << entry.PlayerGUID;
+ _worldPacket << entry.OtherGUID;
+ _worldPacket << entry.TransactionType;
+ _worldPacket << entry.RankID;
+ _worldPacket << entry.TransactionDate;
+ }
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildEventPlayerLeft::Write()
+{
+ _worldPacket.WriteBit(Removed);
+ _worldPacket.WriteBits(LeaverName.length(), 6);
+ _worldPacket.FlushBits();
+
+ if (Removed)
+ {
+ _worldPacket.WriteBits(RemoverName.length(), 6);
+ _worldPacket.FlushBits();
+
+ _worldPacket << RemoverGUID;
+ _worldPacket << RemoverVirtualRealmAddress;
+ _worldPacket.WriteString(RemoverName);
+ }
+
+ _worldPacket << LeaverGUID;
+ _worldPacket << LeaverVirtualRealmAddress;
+ _worldPacket.WriteString(LeaverName);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildPermissionsQueryResults::Write()
+{
+ _worldPacket << RankID;
+ _worldPacket << WithdrawGoldLimit;
+ _worldPacket << Flags;
+ _worldPacket << NumTabs;
+ _worldPacket << uint32(Tab.size());
+
+ for (GuildRankTabPermissions const& tab : Tab)
+ {
+ _worldPacket << tab.Flags;
+ _worldPacket << tab.WithdrawItemLimit;
+ }
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::GuildSetRankPermissions::Read()
+{
+ _worldPacket >> RankID;
+ _worldPacket >> RankOrder;
+ _worldPacket >> Flags;
+ _worldPacket >> OldFlags;
+ _worldPacket >> WithdrawGoldLimit;
+
+ for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; i++)
+ {
+ _worldPacket >> TabFlags[i];
+ _worldPacket >> TabWithdrawItemLimit[i];
+ }
+
+ _worldPacket.ResetBitPos();
+ uint32 rankNameLen = _worldPacket.ReadBits(7);
+
+ RankName = _worldPacket.ReadString(rankNameLen);
+}
+
+WorldPacket const* WorldPackets::Guild::GuildEventNewLeader::Write()
+{
+ _worldPacket.WriteBit(SelfPromoted);
+ _worldPacket.WriteBits(NewLeaderName.length(), 6);
+ _worldPacket.WriteBits(OldLeaderName.length(), 6);
+ _worldPacket.FlushBits();
+
+ _worldPacket << OldLeaderGUID;
+ _worldPacket << OldLeaderVirtualRealmAddress;
+ _worldPacket << NewLeaderGUID;
+ _worldPacket << NewLeaderVirtualRealmAddress;
+
+ _worldPacket.WriteString(NewLeaderName);
+ _worldPacket.WriteString(OldLeaderName);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildEventTabModified::Write()
+{
+ _worldPacket << Tab;
+
+ _worldPacket.WriteBits(Name.length(), 7);
+ _worldPacket.WriteBits(Icon.length(), 9);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(Name);
+ _worldPacket.WriteString(Icon);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildEventTabTextChanged::Write()
+{
+ _worldPacket << Tab;
+
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRankData const& rankData)
+{
+ data << rankData.RankID;
+ data << rankData.RankOrder;
+ data << rankData.Flags;
+ data << rankData.WithdrawGoldLimit;
+
+ for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; i++)
+ {
+ data << rankData.TabFlags[i];
+ data << rankData.TabWithdrawItemLimit[i];
+ }
+
+ data.WriteBits(rankData.RankName.length(), 7);
+ data.FlushBits();
+
+ data.WriteString(rankData.RankName);
+
+ return data;
+}
+
+void WorldPackets::Guild::GuildAddRank::Read()
+{
+ _worldPacket.WriteBits(Name.length(), 7);
+ _worldPacket.FlushBits();
+
+ _worldPacket >> RankOrder;
+ _worldPacket.WriteString(Name);
+}
+
+void WorldPackets::Guild::GuildAssignMemberRank::Read()
+{
+ _worldPacket >> Member;
+ _worldPacket >> RankOrder;
+}
+
+void WorldPackets::Guild::GuildDeleteRank::Read()
+{
+ _worldPacket >> RankOrder;
+}
+
+void WorldPackets::Guild::GuildGetRanks::Read()
+{
+ _worldPacket >> GuildGUID;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildRanks::Write()
+{
+ _worldPacket << uint32(Ranks.size());
+
+ for (GuildRankData const& rank : Ranks)
+ _worldPacket << rank;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildSendRankChange::Write()
+{
+ _worldPacket << Officer;
+ _worldPacket << Other;
+ _worldPacket << RankID;
+
+ _worldPacket.WriteBit(Promote);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::GuildShiftRank::Read()
+{
+ _worldPacket >> RankOrder;
+ ShiftUp = _worldPacket.ReadBit();
+}
+
+void WorldPackets::Guild::GuildUpdateInfoText::Read()
+{
+ uint32 textLen = _worldPacket.ReadBits(11);
+ InfoText = _worldPacket.ReadString(textLen);
+}
+
+void WorldPackets::Guild::GuildSetMemberNote::Read()
+{
+ _worldPacket >> NoteeGUID;
+
+ uint32 noteLen = _worldPacket.ReadBits(8);
+ IsPublic = _worldPacket.ReadBit();
+
+ Note = _worldPacket.ReadString(noteLen);
+}
+
+WorldPacket const* WorldPackets::Guild::GuildMemberUpdateNote::Write()
+{
+ _worldPacket.reserve(16 + 2 + Note.size());
+
+ _worldPacket << Member;
+
+ _worldPacket.WriteBits(Note.length(), 8);
+ _worldPacket.WriteBit(IsPublic);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(Note);
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::GuildDemoteMember::Read()
+{
+ _worldPacket >> Demotee;
+}
+
+void WorldPackets::Guild::GuildPromoteMember::Read()
+{
+ _worldPacket >> Promotee;
+}
+
+void WorldPackets::Guild::GuildOfficerRemoveMember::Read()
+{
+ _worldPacket >> Removee;
+}
+
+void WorldPackets::Guild::GuildChangeNameRequest::Read()
+{
+ uint32 nameLen = _worldPacket.ReadBits(7);
+ NewName = _worldPacket.ReadString(nameLen);
+}
+
+WorldPacket const* WorldPackets::Guild::GuildFlaggedForRename::Write()
+{
+ _worldPacket.WriteBit(FlagSet);
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::RequestGuildPartyState::Read()
+{
+ _worldPacket >> GuildGUID;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildPartyState::Write()
+{
+ _worldPacket.WriteBit(InGuildParty);
+ _worldPacket.FlushBits();
+
+ _worldPacket << NumMembers;
+ _worldPacket << NumRequired;
+ _worldPacket << GuildXPEarnedMult;
+
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRewardItem const& rewardItem)
+{
+ data << rewardItem.ItemID;
+ data << uint32(rewardItem.AchievementsRequired.size());
+ data << rewardItem.RaceMask;
+ data << rewardItem.MinGuildLevel;
+ data << rewardItem.MinGuildRep;
+ data << rewardItem.Cost;
+
+ for (uint8 i = 0; i < rewardItem.AchievementsRequired.size(); i++)
+ data << rewardItem.AchievementsRequired[i];
+
+ return data;
+}
+
+void WorldPackets::Guild::RequestGuildRewardsList::Read()
+{
+ _worldPacket >> CurrentVersion;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildRewardList::Write()
+{
+ _worldPacket << Version;
+ _worldPacket << uint32(RewardItems.size());
+
+ for (GuildRewardItem const& item : RewardItems)
+ _worldPacket << item;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::GuildBankActivate::Read()
+{
+ _worldPacket >> Banker;
+ FullUpdate = _worldPacket.ReadBit();
+}
+
+void WorldPackets::Guild::GuildBankBuyTab::Read()
+{
+ _worldPacket >> Banker;
+ _worldPacket >> BankTab;
+}
+
+void WorldPackets::Guild::GuildBankUpdateTab::Read()
+{
+ _worldPacket >> Banker;
+ _worldPacket >> BankTab;
+
+ _worldPacket.ResetBitPos();
+ uint32 nameLen = _worldPacket.ReadBits(7);
+ uint32 iconLen = _worldPacket.ReadBits(9);
+
+ Name = _worldPacket.ReadString(nameLen);
+ Icon = _worldPacket.ReadString(iconLen);
+}
+
+void WorldPackets::Guild::GuildBankDepositMoney::Read()
+{
+ _worldPacket >> Banker;
+ _worldPacket >> Money;
+}
+
+void WorldPackets::Guild::GuildBankQueryTab::Read()
+{
+ _worldPacket >> Banker;
+ _worldPacket >> Tab;
+
+ FullUpdate = _worldPacket.ReadBit();
+}
+
+WorldPacket const* WorldPackets::Guild::GuildBankRemainingWithdrawMoney::Write()
+{
+ _worldPacket << RemainingWithdrawMoney;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::GuildBankWithdrawMoney::Read()
+{
+ _worldPacket >> Banker;
+ _worldPacket >> Money;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildBankQueryResults::Write()
+{
+ _worldPacket << Money;
+ _worldPacket << Tab;
+ _worldPacket << WithdrawalsRemaining;
+ _worldPacket << uint32(TabInfo.size());
+ _worldPacket << uint32(ItemInfo.size());
+
+ for (GuildBankTabInfo const& tab : TabInfo)
+ {
+ _worldPacket << tab.TabIndex;
+ _worldPacket.WriteBits(tab.Name.length(), 7);
+ _worldPacket.WriteBits(tab.Icon.length(), 9);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(tab.Name);
+ _worldPacket.WriteString(tab.Icon);
+ }
+
+ for (GuildBankItemInfo const& item : ItemInfo)
+ {
+ _worldPacket << item.Slot;
+ _worldPacket << item.Item;
+ _worldPacket << item.Count;
+ _worldPacket << item.EnchantmentID;
+ _worldPacket << item.Charges;
+ _worldPacket << item.OnUseEnchantmentID;
+ _worldPacket << uint32(item.SocketEnchant.size());
+ _worldPacket << item.Flags;
+
+ for (GuildBankItemInfo::GuildBankSocketEnchant const& socketEnchant : item.SocketEnchant)
+ {
+ _worldPacket << socketEnchant.SocketIndex;
+ _worldPacket << socketEnchant.SocketEnchantID;
+ }
+
+ _worldPacket.WriteBit(item.Locked);
+ _worldPacket.FlushBits();
+ }
+
+ _worldPacket.WriteBit(FullUpdate);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::GuildBankSwapItems::Read()
+{
+ _worldPacket >> Banker;
+ _worldPacket >> BankTab;
+ _worldPacket >> BankSlot;
+ _worldPacket >> ItemID;
+ _worldPacket >> BankTab1;
+ _worldPacket >> BankSlot1;
+ _worldPacket >> ItemID1;
+ _worldPacket >> BankItemCount;
+ _worldPacket >> ContainerSlot;
+ _worldPacket >> ContainerItemSlot;
+ _worldPacket >> ToSlot;
+ _worldPacket >> StackCount;
+
+ _worldPacket.ResetBitPos();
+ BankOnly = _worldPacket.ReadBit();
+ AutoStore = _worldPacket.ReadBit();
+}
+
+void WorldPackets::Guild::GuildBankLogQuery::Read()
+{
+ _worldPacket >> Tab;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildBankLogQueryResults::Write()
+{
+ _worldPacket << Tab;
+ _worldPacket << uint32(Entry.size());
+
+ for (GuildBankLogEntry const& logEntry : Entry)
+ {
+ _worldPacket << logEntry.PlayerGUID;
+ _worldPacket << logEntry.TimeOffset;
+ _worldPacket << logEntry.EntryType;
+
+ _worldPacket.WriteBit(logEntry.Money.HasValue);
+ _worldPacket.WriteBit(logEntry.ItemID.HasValue);
+ _worldPacket.WriteBit(logEntry.Count.HasValue);
+ _worldPacket.WriteBit(logEntry.OtherTab.HasValue);
+ _worldPacket.FlushBits();
+
+ if (logEntry.Money.HasValue)
+ _worldPacket << logEntry.Money.Value;
+
+ if (logEntry.ItemID.HasValue)
+ _worldPacket << logEntry.ItemID.Value;
+
+ if (logEntry.Count.HasValue)
+ _worldPacket << logEntry.Count.Value;
+
+ if (logEntry.OtherTab.HasValue)
+ _worldPacket << logEntry.OtherTab.Value;
+ }
+
+ _worldPacket.WriteBit(WeeklyBonusMoney.HasValue);
+ _worldPacket.FlushBits();
+
+ if (WeeklyBonusMoney.HasValue)
+ _worldPacket << WeeklyBonusMoney.Value;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::GuildBankTextQuery::Read()
+{
+ _worldPacket >> Tab;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildBankTextQueryResult::Write()
+{
+ _worldPacket << Tab;
+
+ _worldPacket.WriteBits(Text.length(), 14);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(Text);
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::GuildBankSetTabText::Read()
+{
+ _worldPacket >> Tab;
+
+ _worldPacket.ResetBitPos();
+ uint32 tabTextLen = _worldPacket.ReadBits(14);
+
+ TabText = _worldPacket.ReadString(tabTextLen);
+}
+
+void WorldPackets::Guild::GuildQueryNews::Read()
+{
+ _worldPacket >> GuildGUID;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildNewsEvent const& newsEvent)
+{
+ data << newsEvent.Id;
+ data.AppendPackedTime(newsEvent.CompletedDate);
+ data << newsEvent.Type;
+ data << newsEvent.Flags;
+
+ for (uint8 i = 0; i < 2; i++)
+ data << newsEvent.Data[i];
+
+ data << newsEvent.MemberGuid;
+ data << uint32(newsEvent.MemberList.size());
+
+ for (ObjectGuid memberGuid : newsEvent.MemberList)
+ data << memberGuid;
+
+ data.WriteBit(newsEvent.Item.HasValue);
+ data.FlushBits();
+
+ if (newsEvent.Item.HasValue)
+ data << newsEvent.Item.Value; // WorldPackets::Item::ItemInstance
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Guild::GuildNews::Write()
+{
+ _worldPacket << NewsEvents;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::GuildNewsUpdateSticky::Read()
+{
+ _worldPacket >> GuildGUID;
+ _worldPacket >> NewsID;
+
+ NewsID = _worldPacket.ReadBit();
+}
+
+void WorldPackets::Guild::GuildSetGuildMaster::Read()
+{
+ uint32 nameLen = _worldPacket.ReadBits(9);
+ NewMasterName = _worldPacket.ReadString(nameLen);
+}
+
+WorldPacket const* WorldPackets::Guild::GuildChallengeUpdate::Write()
+{
+ for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
+ _worldPacket << int32(CurrentCount[i]);
+
+ for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
+ _worldPacket << int32(MaxCount[i]);
+
+ for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
+ _worldPacket << int32(MaxLevelGold[i]);
+
+ for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
+ _worldPacket << int32(Gold[i]);
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Guild::SaveGuildEmblem::Read()
+{
+ _worldPacket >> Vendor;
+ _worldPacket >> BStyle;
+ _worldPacket >> EStyle;
+ _worldPacket >> BColor;
+ _worldPacket >> EColor;
+ _worldPacket >> Bg;
+}
+
+WorldPacket const* WorldPackets::Guild::PlayerSaveGuildEmblem::Write()
+{
+ _worldPacket << int32(Error);
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h
index d4b1e9f12bd..9d146587c46 100644
--- a/src/server/game/Server/Packets/GuildPackets.h
+++ b/src/server/game/Server/Packets/GuildPackets.h
@@ -20,6 +20,8 @@
#include "Packet.h"
#include "ObjectGuid.h"
+#include "Guild.h"
+#include "ItemPackets.h"
namespace WorldPackets
{
@@ -78,7 +80,938 @@ namespace WorldPackets
ObjectGuid GuildGuid;
Optional<GuildInfo> Info;
};
+
+ class GuildGetRoster final : public ClientPacket
+ {
+ public:
+ GuildGetRoster(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_GET_ROSTER, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ struct GuildRosterProfessionData
+ {
+ int32 DbID = 0;
+ int32 Rank = 0;
+ int32 Step = 0;
+ };
+
+ struct GuildRosterMemberData
+ {
+ ObjectGuid Guid;
+ int64 WeeklyXP = 0;
+ int64 TotalXP = 0;
+ int32 RankID = 0;
+ int32 AreaID = 0;
+ int32 PersonalAchievementPoints = 0;
+ int32 GuildReputation = 0;
+ int32 GuildRepToCap = 0;
+ float LastSave = 0.0f;
+ std::string Name;
+ uint32 VirtualRealmAddress = 0;
+ std::string Note;
+ std::string OfficerNote;
+ uint8 Status = 0;
+ uint8 Level = 0;
+ uint8 ClassID = 0;
+ uint8 Gender = 0;
+ bool Authenticated = false;
+ bool SorEligible = false;
+ GuildRosterProfessionData Profession[2];
+ };
+
+ class GuildRoster final : public ServerPacket
+ {
+ public:
+ GuildRoster() : ServerPacket(SMSG_GUILD_ROSTER, 4 + 4 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<GuildRosterMemberData> MemberData;
+ std::string WelcomeText;
+ std::string InfoText;
+ uint32 CreateDate = 0;
+ int32 NumAccounts = 0;
+ int32 GuildFlags = 0;
+ };
+
+ class GuildRosterUpdate final : public ServerPacket
+ {
+ public:
+ GuildRosterUpdate() : ServerPacket(SMSG_GUILD_ROSTER_UPDATE, 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<GuildRosterMemberData> MemberData;
+ };
+
+ class GuildUpdateMotdText final : public ClientPacket
+ {
+ public:
+ GuildUpdateMotdText(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_UPDATE_MOTD_TEXT, std::move(packet)) { }
+
+ void Read() override;
+
+ std::string MotdText;
+ };
+
+ class GuildCommandResult final : public ServerPacket
+ {
+ public:
+ GuildCommandResult() : ServerPacket(SMSG_GUILD_COMMAND_RESULT, 9) { }
+
+ WorldPacket const* Write() override;
+
+ std::string Name;
+ int32 Result = 0;
+ int32 Command = 0;
+ };
+
+ class AcceptGuildInvite final : public ClientPacket
+ {
+ public:
+ AcceptGuildInvite(WorldPacket&& packet) : ClientPacket(CMSG_ACCEPT_GUILD_INVITE, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class GuildDeclineInvitation final : public ClientPacket
+ {
+ public:
+ GuildDeclineInvitation(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_DECLINE_INVITATION, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class DeclineGuildInvites final : public ClientPacket
+ {
+ public:
+ DeclineGuildInvites(WorldPacket&& packet) : ClientPacket(CMSG_DECLINE_GUILD_INVITES, std::move(packet)) { }
+
+ void Read() override;
+
+ bool Allow = false;
+ };
+
+ class GuildInviteByName final : public ClientPacket
+ {
+ public:
+ GuildInviteByName(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_INVITE_BY_NAME, std::move(packet)) { }
+
+ void Read() override;
+
+ std::string Name;
+ };
+
+ class GuildInvite final : public ServerPacket
+ {
+ public:
+ GuildInvite() : ServerPacket(SMSG_GUILD_INVITE, 68) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid GuildGUID;
+ ObjectGuid OldGuildGUID;
+ int32 Level = 0;
+ uint32 EmblemColor = 0;
+ uint32 EmblemStyle = 0;
+ uint32 BorderStyle = 0;
+ uint32 BorderColor = 0;
+ uint32 Background = 0;
+ uint32 GuildVirtualRealmAddress = 0;
+ uint32 OldGuildVirtualRealmAddress = 0;
+ uint32 InviterVirtualRealmAddress = 0;
+ std::string InviterName;
+ std::string GuildName;
+ std::string OldGuildName;
+ };
+
+ class GuildEventPresenceChange final : public ServerPacket
+ {
+ public:
+ GuildEventPresenceChange() : ServerPacket(SMSG_GUILD_EVENT_PRESENCE_CHANGE, 16 + 4 + 1 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Guid;
+ uint32 VirtualRealmAddress = 0;
+ std::string Name;
+ bool Mobile = false;
+ bool LoggedOn = false;
+ };
+
+ class GuildEventMotd final : public ServerPacket
+ {
+ public:
+ GuildEventMotd() : ServerPacket(SMSG_GUILD_EVENT_MOTD, 1) { }
+
+ WorldPacket const* Write() override;
+
+ std::string MotdText;
+ };
+
+ class GuildEventPlayerJoined final : public ServerPacket
+ {
+ public:
+ GuildEventPlayerJoined() : ServerPacket(SMSG_GUILD_EVENT_PLAYER_JOINED, 21) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Guid;
+ std::string Name;
+ uint32 VirtualRealmAddress = 0;
+ };
+
+ class GuildEventRankChanged final : public ServerPacket
+ {
+ public:
+ GuildEventRankChanged() : ServerPacket(SMSG_GUILD_EVENT_RANK_CHANGED, 4) { }
+
+ WorldPacket const* Write() override;
+
+ int32 RankID = 0;
+ };
+
+ class GuildEventRanksUpdated final : public ServerPacket
+ {
+ public:
+ GuildEventRanksUpdated() : ServerPacket(SMSG_GUILD_EVENT_RANKS_UPDATED, 0) { }
+
+ WorldPacket const* Write() override { return &_worldPacket; }
+ };
+
+ class GuildEventBankMoneyChanged final : public ServerPacket
+ {
+ public:
+ GuildEventBankMoneyChanged() : ServerPacket(SMSG_GUILD_EVENT_BANK_MONEY_CHANGED, 8) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 Money = 0;
+ };
+
+ class GuildEventDisbanded final : public ServerPacket
+ {
+ public:
+ GuildEventDisbanded() : ServerPacket(SMSG_GUILD_EVENT_DISBANDED, 0) { }
+
+ WorldPacket const* Write() override { return &_worldPacket; }
+ };
+
+ struct GuildEventEntry
+ {
+ ObjectGuid PlayerGUID;
+ ObjectGuid OtherGUID;
+ uint8 TransactionType = 0;
+ uint8 RankID = 0;
+ uint32 TransactionDate = 0;
+ };
+
+ class GuildEventLogQuery final : public ClientPacket
+ {
+ public:
+ GuildEventLogQuery(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_EVENT_LOG_QUERY, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class GuildEventLogQueryResults final : public ServerPacket
+ {
+ public:
+ GuildEventLogQueryResults() : ServerPacket(SMSG_GUILD_EVENT_LOG_QUERY_RESULTS, 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<GuildEventEntry> Entry;
+ };
+
+ class GuildEventPlayerLeft final : public ServerPacket
+ {
+ public:
+ GuildEventPlayerLeft() : ServerPacket(SMSG_GUILD_EVENT_PLAYER_LEFT, 43) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid LeaverGUID;
+ std::string LeaverName;
+ uint32 LeaverVirtualRealmAddress = 0;
+ ObjectGuid RemoverGUID;
+ std::string RemoverName;
+ uint32 RemoverVirtualRealmAddress = 0;
+ bool Removed = false;
+ };
+
+ class GuildEventNewLeader final : public ServerPacket
+ {
+ public:
+ GuildEventNewLeader() : ServerPacket(SMSG_GUILD_EVENT_NEW_LEADER, 43) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid NewLeaderGUID;
+ std::string NewLeaderName;
+ uint32 NewLeaderVirtualRealmAddress = 0;
+ ObjectGuid OldLeaderGUID;
+ std::string OldLeaderName;
+ uint32 OldLeaderVirtualRealmAddress = 0;
+ bool SelfPromoted = false;
+ };
+
+ class GuildEventTabAdded final : public ServerPacket
+ {
+ public:
+ GuildEventTabAdded() : ServerPacket(SMSG_GUILD_EVENT_TAB_ADDED, 0) { }
+
+ WorldPacket const* Write() override { return &_worldPacket; }
+ };
+
+ class GuildEventTabModified final : public ServerPacket
+ {
+ public:
+ GuildEventTabModified() : ServerPacket(SMSG_GUILD_EVENT_TAB_MODIFIED, 6) { }
+
+ WorldPacket const* Write() override;
+
+ std::string Icon;
+ std::string Name;
+ int32 Tab = 0;
+ };
+
+ class GuildEventTabTextChanged final : public ServerPacket
+ {
+ public:
+ GuildEventTabTextChanged() : ServerPacket(SMSG_GUILD_EVENT_TAB_TEXT_CHANGED, 4) { }
+
+ WorldPacket const* Write() override;
+
+ int32 Tab = 0;
+ };
+
+ class GuildEventBankContentsChanged final : public ServerPacket
+ {
+ public:
+ GuildEventBankContentsChanged() : ServerPacket(SMSG_GUILD_EVENT_BANK_CONTENTS_CHANGED, 0) { }
+
+ WorldPacket const* Write() override { return &_worldPacket; }
+ };
+
+ class GuildPermissionsQuery final : public ClientPacket
+ {
+ public:
+ GuildPermissionsQuery(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_PERMISSIONS_QUERY, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class GuildPermissionsQueryResults final : public ServerPacket
+ {
+ public:
+ struct GuildRankTabPermissions
+ {
+ int32 Flags = 0;
+ int32 WithdrawItemLimit = 0;
+ };
+
+ GuildPermissionsQueryResults() : ServerPacket(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, 20) { }
+
+ WorldPacket const* Write() override;
+
+ int32 NumTabs = 0;
+ int32 WithdrawGoldLimit = 0;
+ int32 Flags = 0;
+ uint32 RankID = 0;
+ std::vector<GuildRankTabPermissions> Tab;
+ };
+
+ class GuildSetRankPermissions final : public ClientPacket
+ {
+ public:
+ GuildSetRankPermissions(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_SET_RANK_PERMISSIONS, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 RankID = 0;
+ int32 RankOrder = 0;
+ int32 WithdrawGoldLimit = 0;
+ uint32 Flags = 0;
+ uint32 OldFlags = 0;
+ int32 TabFlags[GUILD_BANK_MAX_TABS];
+ int32 TabWithdrawItemLimit[GUILD_BANK_MAX_TABS];
+ std::string RankName;
+ };
+
+ class GuildAddRank final : public ClientPacket
+ {
+ public:
+ GuildAddRank(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_ADD_RANK, std::move(packet)) { }
+
+ void Read() override;
+
+ std::string Name;
+ int32 RankOrder = 0;
+ };
+
+ class GuildAssignMemberRank final : public ClientPacket
+ {
+ public:
+ GuildAssignMemberRank(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_ASSIGN_MEMBER_RANK, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Member;
+ int32 RankOrder = 0;
+ };
+
+ class GuildDeleteRank final : public ClientPacket
+ {
+ public:
+ GuildDeleteRank(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_DELETE_RANK, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 RankOrder = 0;
+ };
+
+ class GuildGetRanks final : public ClientPacket
+ {
+ public:
+ GuildGetRanks(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_GET_RANKS, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid GuildGUID;
+ };
+
+ struct GuildRankData
+ {
+ uint32 RankID = 0;
+ uint32 RankOrder = 0;
+ uint32 Flags = 0;
+ uint32 WithdrawGoldLimit = 0;
+ std::string RankName;
+ uint32 TabFlags[GUILD_BANK_MAX_TABS];
+ uint32 TabWithdrawItemLimit[GUILD_BANK_MAX_TABS];
+ };
+
+ class GuildRanks final : public ServerPacket
+ {
+ public:
+ GuildRanks() : ServerPacket(SMSG_GUILD_RANKS, 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<GuildRankData> Ranks;
+ };
+
+ class GuildSendRankChange final : public ServerPacket
+ {
+ public:
+ GuildSendRankChange() : ServerPacket(SMSG_GUILD_SEND_RANK_CHANGE, 43) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Other;
+ ObjectGuid Officer;
+ bool Promote = false;
+ uint32 RankID = 0;
+ };
+
+ class GuildShiftRank final : public ClientPacket
+ {
+ public:
+ GuildShiftRank(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_SHIFT_RANK, std::move(packet)) { }
+
+ void Read() override;
+
+ bool ShiftUp = false;
+ int32 RankOrder = 0;
+ };
+
+ class GuildUpdateInfoText final : public ClientPacket
+ {
+ public:
+ GuildUpdateInfoText(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_UPDATE_INFO_TEXT, std::move(packet)) { }
+
+ void Read() override;
+
+ std::string InfoText;
+ };
+
+ class GuildSetMemberNote final : public ClientPacket
+ {
+ public:
+ GuildSetMemberNote(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_SET_MEMBER_NOTE, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid NoteeGUID;
+ bool IsPublic = false; ///< 0 == Officer, 1 == Public
+ std::string Note;
+ };
+
+ class GuildMemberUpdateNote final : public ServerPacket
+ {
+ public:
+ GuildMemberUpdateNote() : ServerPacket(SMSG_GUILD_MEMBER_UPDATE_NOTE, 21) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Member;
+ bool IsPublic = false; ///< 0 == Officer, 1 == Public
+ std::string Note;
+ };
+
+ class GuildMemberDailyReset final : public ServerPacket
+ {
+ public:
+ GuildMemberDailyReset() : ServerPacket(SMSG_GUILD_MEMBER_DAILY_RESET, 0) { }
+
+ WorldPacket const* Write() override { return &_worldPacket; }
+ };
+
+ class GuildDelete final : public ClientPacket
+ {
+ public:
+ GuildDelete(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_DELETE, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class GuildDemoteMember final : public ClientPacket
+ {
+ public:
+ GuildDemoteMember(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_DEMOTE_MEMBER, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Demotee;
+ };
+
+ class GuildPromoteMember final : public ClientPacket
+ {
+ public:
+ GuildPromoteMember(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_PROMOTE_MEMBER, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Promotee;
+ };
+
+ class GuildOfficerRemoveMember : public ClientPacket
+ {
+ public:
+ GuildOfficerRemoveMember(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_OFFICER_REMOVE_MEMBER, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Removee;
+ };
+
+ class GuildLeave final : public ClientPacket
+ {
+ public:
+ GuildLeave(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_LEAVE, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class GuildChangeNameRequest final : public ClientPacket
+ {
+ public:
+ GuildChangeNameRequest(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_CHANGE_NAME_REQUEST, std::move(packet)) { }
+
+ void Read() override;
+
+ std::string NewName;
+ };
+
+ class GuildFlaggedForRename final : public ServerPacket
+ {
+ public:
+ GuildFlaggedForRename() : ServerPacket(SMSG_GUILD_FLAGGED_FOR_RENAME, 1) { }
+
+ WorldPacket const* Write() override;
+
+ bool FlagSet = false;
+ };
+
+ class RequestGuildPartyState final : public ClientPacket
+ {
+ public:
+ RequestGuildPartyState(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_REQUEST_PARTY_STATE, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid GuildGUID;
+ };
+
+ class GuildPartyState final : public ServerPacket
+ {
+ public:
+ GuildPartyState() : ServerPacket(SMSG_GUILD_PARTY_STATE_RESPONSE, 15) { }
+
+ WorldPacket const* Write() override;
+
+ float GuildXPEarnedMult = 0.0f;
+ int32 NumMembers = 0;
+ int32 NumRequired = 0;
+ bool InGuildParty = false;
+ };
+
+ class RequestGuildRewardsList final : public ClientPacket
+ {
+ public:
+ RequestGuildRewardsList(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_GUILD_REWARDS_LIST, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 CurrentVersion = 0;
+ };
+
+ struct GuildRewardItem
+ {
+ uint32 ItemID = 0;
+ std::vector<uint32> AchievementsRequired;
+ uint32 RaceMask = 0;
+ int32 MinGuildLevel = 0;
+ int32 MinGuildRep = 0;
+ uint64 Cost = 0;
+ };
+
+ class GuildRewardList final : public ServerPacket
+ {
+ public:
+ GuildRewardList() : ServerPacket(SMSG_GUILD_REWARDS_LIST, 8) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<GuildRewardItem> RewardItems;
+ uint32 Version = 0;
+ };
+
+ class GuildBankActivate final : public ClientPacket
+ {
+ public:
+ GuildBankActivate(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_ACTIVATE, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Banker;
+ bool FullUpdate = false;
+ };
+
+ class GuildBankBuyTab final : public ClientPacket
+ {
+ public:
+ GuildBankBuyTab(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_BUY_TAB, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Banker;
+ uint8 BankTab = 0;
+ };
+
+ class GuildBankUpdateTab final : public ClientPacket
+ {
+ public:
+ GuildBankUpdateTab(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_UPDATE_TAB, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Banker;
+ uint8 BankTab = 0;
+ std::string Name;
+ std::string Icon;
+ };
+
+ class GuildBankDepositMoney final : public ClientPacket
+ {
+ public:
+ GuildBankDepositMoney(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_DEPOSIT_MONEY, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Banker;
+ uint64 Money = 0;
+ };
+
+ class GuildBankQueryTab final : public ClientPacket
+ {
+ public:
+ GuildBankQueryTab(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_QUERY_TAB, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Banker;
+ uint8 Tab = 0;
+ bool FullUpdate = false;
+ };
+
+
+ class GuildBankRemainingWithdrawMoneyQuery final : public ClientPacket
+ {
+ public:
+ GuildBankRemainingWithdrawMoneyQuery(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY_QUERY, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class GuildBankRemainingWithdrawMoney final : public ServerPacket
+ {
+ public:
+ GuildBankRemainingWithdrawMoney() : ServerPacket(SMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY, 8) { }
+
+ WorldPacket const* Write() override;
+
+ int64 RemainingWithdrawMoney = 0;
+ };
+
+ class GuildBankWithdrawMoney final : public ClientPacket
+ {
+ public:
+ GuildBankWithdrawMoney(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_WITHDRAW_MONEY, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Banker;
+ uint64 Money = 0;
+ };
+
+ struct GuildBankItemInfo
+ {
+ struct GuildBankSocketEnchant
+ {
+ int32 SocketIndex = 0;
+ int32 SocketEnchantID = 0;
+ };
+
+ WorldPackets::Item::ItemInstance Item;
+ int32 Slot = 0;
+ int32 Count = 0;
+ int32 EnchantmentID = 0;
+ int32 Charges = 0;
+ int32 OnUseEnchantmentID = 0;
+ int32 Flags = 0;
+ bool Locked = false;
+ std::vector<GuildBankSocketEnchant> SocketEnchant;
+ };
+
+ struct GuildBankTabInfo
+ {
+ int32 TabIndex = 0;
+ std::string Name;
+ std::string Icon;
+ };
+
+ class GuildBankQueryResults final : public ServerPacket
+ {
+ public:
+ GuildBankQueryResults() : ServerPacket(SMSG_GUILD_BANK_QUERY_RESULTS, 25) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<GuildBankItemInfo> ItemInfo;
+ std::vector<GuildBankTabInfo> TabInfo;
+ int32 WithdrawalsRemaining = 0;
+ int32 Tab = 0;
+ uint64 Money = 0;
+ bool FullUpdate = false;
+ };
+
+ class GuildBankSwapItems final : public ClientPacket
+ {
+ public:
+ GuildBankSwapItems(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_SWAP_ITEMS, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Banker;
+ int32 StackCount = 0;
+ int32 BankItemCount = 0;
+ uint32 ItemID = 0;
+ uint32 ItemID1 = 0;
+ uint8 ToSlot = 0;
+ uint8 BankSlot = 0;
+ uint8 BankSlot1 = 0;
+ uint8 BankTab = 0;
+ uint8 BankTab1 = 0;
+ uint8 ContainerSlot = 0;
+ uint8 ContainerItemSlot = 0;
+ bool AutoStore = false;
+ bool BankOnly = false;
+ };
+
+ class GuildBankLogQuery final : public ClientPacket
+ {
+ public:
+ GuildBankLogQuery(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_LOG_QUERY, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 Tab = 0;
+ };
+
+ struct GuildBankLogEntry
+ {
+ ObjectGuid PlayerGUID;
+ uint32 TimeOffset = 0;
+ int8 EntryType = 0;
+ Optional<uint64> Money;
+ Optional<int32> ItemID;
+ Optional<int32> Count;
+ Optional<int8> OtherTab;
+ };
+
+ class GuildBankLogQueryResults final : public ServerPacket
+ {
+ public:
+ GuildBankLogQueryResults() : ServerPacket(SMSG_GUILD_BANK_LOG_QUERY_RESULT, 25) { }
+
+ WorldPacket const* Write() override;
+
+ int32 Tab = 0;
+ std::vector<GuildBankLogEntry> Entry;
+ Optional<uint64> WeeklyBonusMoney;
+ };
+
+ class GuildBankTextQuery final : public ClientPacket
+ {
+ public:
+ GuildBankTextQuery(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_TEXT_QUERY, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 Tab = 0;
+ };
+
+ class GuildBankTextQueryResult : public ServerPacket
+ {
+ public:
+ GuildBankTextQueryResult() : ServerPacket(SMSG_GUILD_BANK_TEXT_QUERY_RESULT, 5) { }
+
+ WorldPacket const* Write() override;
+
+ int32 Tab = 0;
+ std::string Text;
+ };
+
+ class GuildBankSetTabText final : public ClientPacket
+ {
+ public:
+ GuildBankSetTabText(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_SET_TAB_TEXT, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 Tab = 0;
+ std::string TabText;
+ };
+
+ class GuildQueryNews final : public ClientPacket
+ {
+ public:
+ GuildQueryNews(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_QUERY_NEWS, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid GuildGUID;
+ };
+
+ struct GuildNewsEvent
+ {
+ int32 Id = 0;
+ uint32 CompletedDate = 0;
+ int32 Type = 0;
+ int32 Flags = 0;
+ int32 Data[2];
+ ObjectGuid MemberGuid;
+ GuidList MemberList;
+ Optional<Item::ItemInstance> Item;
+ };
+
+ class GuildNews final : public ServerPacket
+ {
+ public:
+ GuildNews() : ServerPacket(SMSG_GUILD_NEWS, 25) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<GuildNewsEvent> NewsEvents;
+ };
+
+ class GuildNewsUpdateSticky final : public ClientPacket
+ {
+ public:
+ GuildNewsUpdateSticky(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_NEWS_UPDATE_STICKY, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 NewsID = 0;
+ ObjectGuid GuildGUID;
+ bool Sticky = false;
+ };
+
+ class GuildSetGuildMaster final : public ClientPacket
+ {
+ public:
+ GuildSetGuildMaster(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_SET_GUILD_MASTER, std::move(packet)) { }
+
+ void Read() override;
+
+ std::string NewMasterName;
+ };
+
+ class GuildChallengeUpdateRequest final : public ClientPacket
+ {
+ public:
+ GuildChallengeUpdateRequest(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_CHALLENGE_UPDATE_REQUEST, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class GuildChallengeUpdate final : public ServerPacket
+ {
+ public:
+ GuildChallengeUpdate() : ServerPacket(SMSG_GUILD_CHALLENGE_UPDATE, 120) { }
+
+ WorldPacket const* Write() override;
+
+ int32 CurrentCount[GUILD_CHALLENGES_TYPES];
+ int32 MaxCount[GUILD_CHALLENGES_TYPES];
+ int32 Gold[GUILD_CHALLENGES_TYPES];
+ int32 MaxLevelGold[GUILD_CHALLENGES_TYPES];
+ };
+
+ class SaveGuildEmblem final : public ClientPacket
+ {
+ public:
+ SaveGuildEmblem(WorldPacket&& packet) : ClientPacket(CMSG_SAVE_GUILD_EMBLEM, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Vendor;
+ int32 BStyle = 0;
+ int32 EStyle = 0;
+ int32 BColor = 0;
+ int32 EColor = 0;
+ int32 Bg = 0;
+ };
+
+ class PlayerSaveGuildEmblem final : public ServerPacket
+ {
+ public:
+ PlayerSaveGuildEmblem() : ServerPacket(SMSG_SAVE_GUILD_EMBLEM, 4) { }
+
+ WorldPacket const* Write() override;
+
+ int32 Error = 0;
+ };
}
}
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRosterProfessionData const& rosterProfessionData);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRosterMemberData const& rosterMemberData);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRankData const& rankData);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRewardItem const& rewardItem);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildNewsEvent const& newsEvent);
+
#endif // GuildPackets_h__
diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp
index 8456c68ee67..9277e0b73d5 100644
--- a/src/server/game/Server/Packets/ItemPackets.cpp
+++ b/src/server/game/Server/Packets/ItemPackets.cpp
@@ -19,8 +19,39 @@
void WorldPackets::Item::BuyBackItem::Read()
{
- _worldPacket >> VendorGUID;
- _worldPacket >> Slot;
+ _worldPacket >> VendorGUID
+ >> Slot;
+}
+
+void WorldPackets::Item::BuyItem::Read()
+{
+ _worldPacket >> VendorGUID
+ >> ContainerGUID
+ >> Item
+ >> Quantity
+ >> Muid
+ >> Slot;
+
+ ItemType = static_cast<ItemVendorType>(_worldPacket.ReadBits(2));
+}
+
+WorldPacket const* WorldPackets::Item::BuySucceeded::Write()
+{
+ _worldPacket << VendorGUID
+ << uint32(Muid)
+ << int32(NewQuantity)
+ << uint32(QuantityBought);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Item::BuyFailed::Write()
+{
+ _worldPacket << VendorGUID
+ << uint32(Muid)
+ << uint8(Reason);
+
+ return &_worldPacket;
}
void WorldPackets::Item::GetItemPurchaseData::Read()
@@ -68,11 +99,28 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceDa
return data;
}
+ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData& itemBonusInstanceData)
+{
+ uint32 bonusListIdSize;
+
+ data >> itemBonusInstanceData.Context;
+ data >> bonusListIdSize;
+
+ for (uint32 i = 0u; i < bonusListIdSize; ++i)
+ {
+ uint32 bonusId;
+ data >> bonusId;
+ itemBonusInstanceData.BonusListIDs.push_back(bonusId);
+ }
+
+ return data;
+}
+
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance)
{
- data << itemInstance.ItemID;
- data << itemInstance.RandomPropertiesSeed;
- data << itemInstance.RandomPropertiesID;
+ data << int32(itemInstance.ItemID);
+ data << int32(itemInstance.RandomPropertiesSeed);
+ data << int32(itemInstance.RandomPropertiesID);
data.WriteBit(itemInstance.ItemBonus.HasValue);
data.WriteBit(itemInstance.Modifications.HasValue);
@@ -87,6 +135,24 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const&
return data;
}
+ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemInstance& itemInstance)
+{
+ data >> itemInstance.ItemID;
+ data >> itemInstance.RandomPropertiesSeed;
+ data >> itemInstance.RandomPropertiesID;
+
+ itemInstance.ItemBonus.HasValue = data.ReadBit();
+ itemInstance.Modifications.HasValue = data.ReadBit();
+
+ if (itemInstance.ItemBonus.HasValue)
+ data >> itemInstance.ItemBonus.Value;
+
+ if (itemInstance.Modifications.HasValue)
+ data >> itemInstance.Modifications.Value;
+
+ return data;
+}
+
ByteBuffer& WorldPackets::Item::operator>>(ByteBuffer& data, InvUpdate& invUpdate)
{
invUpdate.Items.resize(data.ReadBits(2));
@@ -109,16 +175,16 @@ void WorldPackets::Item::ItemInstance::Initalize(::Item const* item)
{
ItemBonus.HasValue = true;
ItemBonus.Value.BonusListIDs.insert(ItemBonus.Value.BonusListIDs.end(), bonusListIds.begin(), bonusListIds.end());
- ItemBonus.Value.Context = 0; /// @todo
+ ItemBonus.Value.Context = item->GetUInt32Value(ITEM_FIELD_CONTEXT);
}
- for (uint8 i = 1; i < MAX_ITEM_MODIFIERS; ++i)
+ uint32 mask = item->GetUInt32Value(ITEM_FIELD_MODIFIERS_MASK);
+ Modifications.HasValue = mask != 0;
+
+ for (size_t i = 0; mask != 0; mask >>= 1, ++i)
{
- if (int32 mod = item->GetModifier(ItemModifier(i)))
- {
- Modifications.HasValue = true;
- Modifications.Value.Insert(i - 1, mod);
- }
+ if ((mask & 1) != 0)
+ Modifications.Value.Insert(i, item->GetModifier(ItemModifier(i)));
}
}
diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h
index 65fdcdf3367..1645af8275a 100644
--- a/src/server/game/Server/Packets/ItemPackets.h
+++ b/src/server/game/Server/Packets/ItemPackets.h
@@ -26,6 +26,24 @@ namespace WorldPackets
{
namespace Item
{
+ struct ItemBonusInstanceData
+ {
+ uint8 Context = 0;
+ std::vector<int32> BonusListIDs;
+ };
+
+ struct ItemInstance
+ {
+ void Initalize(::Item const* item);
+ void Initalize(::LootItem const& lootItem);
+
+ uint32 ItemID = 0;
+ uint32 RandomPropertiesSeed = 0;
+ uint32 RandomPropertiesID = 0;
+ Optional<ItemBonusInstanceData> ItemBonus;
+ Optional<CompactArray<int32>> Modifications;
+ };
+
class BuyBackItem final : public ClientPacket
{
public:
@@ -37,6 +55,47 @@ namespace WorldPackets
uint32 Slot = 0;
};
+ class BuyItem final : public ClientPacket
+ {
+ public:
+ BuyItem(WorldPacket&& packet) : ClientPacket(CMSG_BUY_ITEM, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid VendorGUID;
+ ItemInstance Item;
+ uint32 Muid = 0u;
+ uint32 Slot = 0u;
+ ItemVendorType ItemType = ITEM_VENDOR_TYPE_NONE;
+ int32 Quantity = 0;
+ ObjectGuid ContainerGUID;
+ };
+
+ class BuySucceeded final : ServerPacket
+ {
+ public:
+ BuySucceeded() : ServerPacket(SMSG_BUY_SUCCEEDED, 16 + 4 + 4 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid VendorGUID;
+ uint32 Muid = 0u;
+ uint32 QuantityBought = 0u;
+ int32 NewQuantity = 0;
+ };
+
+ class BuyFailed final : ServerPacket
+ {
+ public:
+ BuyFailed() : ServerPacket(SMSG_BUY_FAILED, 16 + 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid VendorGUID;
+ uint32 Muid = 0u;
+ BuyResult Reason = BUY_ERR_CANT_FIND_ITEM;
+ };
+
class GetItemPurchaseData final : public ClientPacket
{
public:
@@ -93,24 +152,6 @@ namespace WorldPackets
uint8 ProficiencyClass = 0;
};
- struct ItemBonusInstanceData
- {
- uint8 Context = 0;
- std::vector<int32> BonusListIDs;
- };
-
- struct ItemInstance
- {
- void Initalize(::Item const* item);
- void Initalize(::LootItem const& lootItem);
-
- uint32 ItemID = 0;
- uint32 RandomPropertiesSeed = 0;
- uint32 RandomPropertiesID = 0;
- Optional<ItemBonusInstanceData> ItemBonus;
- Optional<CompactArray<int32>> Modifications;
- };
-
struct InvUpdate
{
struct InvItem
@@ -222,6 +263,8 @@ namespace WorldPackets
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData);
+ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData& itemBonusInstanceData);
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance);
+ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemInstance& itemInstance);
#endif // ItemPackets_h__
diff --git a/src/server/game/Server/Packets/MailPackets.h b/src/server/game/Server/Packets/MailPackets.h
index 8019c274191..281a48b7248 100644
--- a/src/server/game/Server/Packets/MailPackets.h
+++ b/src/server/game/Server/Packets/MailPackets.h
@@ -38,7 +38,7 @@ namespace WorldPackets
struct MailAttachedItem
{
- MailAttachedItem(::Item const* item, uint8 pos);
+ MailAttachedItem(::Item const* item, uint8 pos);
uint8 Position = 0;
int32 AttachID = 0;
@@ -126,7 +126,7 @@ namespace WorldPackets
std::string Body;
std::vector<MailAttachment> Attachments;
};
-
+
SendMail(WorldPacket&& packet) : ClientPacket(CMSG_SEND_MAIL, std::move(packet)) { }
void Read() override;
diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h
index 53fd7ce8796..9dd39e4c3d9 100644
--- a/src/server/game/Server/Packets/MiscPackets.h
+++ b/src/server/game/Server/Packets/MiscPackets.h
@@ -53,7 +53,7 @@ namespace WorldPackets
ObjectGuid BinderID;
uint32 AreaID = 0;
};
-
+
class BinderConfirm final : public ServerPacket
{
public:
diff --git a/src/server/game/Server/Packets/NPCPackets.cpp b/src/server/game/Server/Packets/NPCPackets.cpp
index 1b1ef3ce613..7bf96b03bab 100644
--- a/src/server/game/Server/Packets/NPCPackets.cpp
+++ b/src/server/game/Server/Packets/NPCPackets.cpp
@@ -16,7 +16,6 @@
*/
#include "NPCPackets.h"
-#include "ItemPackets.h"
void WorldPackets::NPC::Hello::Read()
{
@@ -135,3 +134,9 @@ void WorldPackets::NPC::GossipSelectOption::Read()
uint32 length = _worldPacket.ReadBits(8);
PromotionCode = _worldPacket.ReadString(length);
}
+WorldPacket const* WorldPackets::NPC::PlayerTabardVendorActivate::Write()
+{
+ _worldPacket << Vendor;
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h
index 50c174539b5..bce5dbbd074 100644
--- a/src/server/game/Server/Packets/NPCPackets.h
+++ b/src/server/game/Server/Packets/NPCPackets.h
@@ -158,6 +158,16 @@ namespace WorldPackets
ObjectGuid Guid;
};
+
+ class PlayerTabardVendorActivate final : public ServerPacket
+ {
+ public:
+ PlayerTabardVendorActivate() : ServerPacket(SMSG_TABARD_VENDOR_ACTIVATE, 16) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Vendor;
+ };
}
}
diff --git a/src/server/game/Server/Packets/PacketUtilities.h b/src/server/game/Server/Packets/PacketUtilities.h
index 25e6f27d1d4..6246b637a71 100644
--- a/src/server/game/Server/Packets/PacketUtilities.h
+++ b/src/server/game/Server/Packets/PacketUtilities.h
@@ -73,4 +73,23 @@ namespace WorldPackets
return data;
}
+
+ template <typename T>
+ ByteBuffer& operator>>(ByteBuffer& data, CompactArray<T>& v)
+ {
+ uint32 mask;
+ data >> mask;
+
+ for (size_t index = 0; mask != 0; mask >>= 1, ++index)
+ {
+ if ((mask & 1) != 0)
+ {
+ T value;
+ data >> value;
+ v.Insert(index, value);
+ }
+ }
+
+ return data;
+ }
}
diff --git a/src/server/game/Server/Packets/PetitionPackets.cpp b/src/server/game/Server/Packets/PetitionPackets.cpp
new file mode 100644
index 00000000000..936dea3d3a4
--- /dev/null
+++ b/src/server/game/Server/Packets/PetitionPackets.cpp
@@ -0,0 +1,192 @@
+/*
+* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "PetitionPackets.h"
+
+void WorldPackets::Petition::QueryPetition::Read()
+{
+ _worldPacket >> PetitionID;
+ _worldPacket >> ItemGUID;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Petition::PetitionInfo const& petitionInfo)
+{
+ data << petitionInfo.PetitionID;
+ data << petitionInfo.Petitioner;
+
+ data << petitionInfo.MinSignatures;
+ data << petitionInfo.MaxSignatures;
+ data << petitionInfo.DeadLine;
+ data << petitionInfo.IssueDate;
+ data << petitionInfo.AllowedGuildID;
+ data << petitionInfo.AllowedClasses;
+ data << petitionInfo.AllowedRaces;
+ data << petitionInfo.AllowedGender;
+ data << petitionInfo.AllowedMinLevel;
+ data << petitionInfo.AllowedMaxLevel;
+ data << petitionInfo.NumChoices;
+ data << petitionInfo.StaticType;
+ data << petitionInfo.Muid;
+
+ data.WriteBits(petitionInfo.Title.length(), 7);
+ data.WriteBits(petitionInfo.BodyText.length(), 12);
+
+ for (uint8 i = 0; i < 10; i++)
+ data.WriteBits(petitionInfo.Choicetext[i].length(), 6);
+
+ data.FlushBits();
+
+ for (uint8 i = 0; i < 10; i++)
+ data.WriteString(petitionInfo.Choicetext[i]);
+
+ data.WriteString(petitionInfo.Title);
+ data.WriteString(petitionInfo.BodyText);
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Petition::QueryPetitionResponse::Write()
+{
+ _worldPacket << PetitionID;
+ _worldPacket.WriteBit(Allow);
+ _worldPacket.FlushBits();
+
+ if (Allow)
+ _worldPacket << Info;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Petition::PetitionShowList::Read()
+{
+ _worldPacket >> PetitionUnit;
+}
+
+WorldPacket const* WorldPackets::Petition::ServerPetitionShowList::Write()
+{
+ _worldPacket << Unit;
+ _worldPacket << Price;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Petition::PetitionBuy::Read()
+{
+ uint32 titleLen = _worldPacket.ReadBits(7);
+
+ _worldPacket >> Unit;
+ Title = _worldPacket.ReadString(titleLen);
+}
+
+void WorldPackets::Petition::PetitionShowSignatures::Read()
+{
+ _worldPacket >> Item;
+}
+
+WorldPacket const* WorldPackets::Petition::ServerPetitionShowSignatures::Write()
+{
+ _worldPacket << Item;
+ _worldPacket << Owner;
+ _worldPacket << OwnerAccountID;
+ _worldPacket << PetitionID;
+
+ _worldPacket << uint32(Signatures.size());
+ for (PetitionSignature signature : Signatures)
+ {
+ _worldPacket << signature.Signer;
+ _worldPacket << signature.Choice;
+ }
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Petition::SignPetition::Read()
+{
+ _worldPacket >> PetitionGUID;
+ _worldPacket >> Choice;
+}
+
+WorldPacket const* WorldPackets::Petition::PetitionSignResults::Write()
+{
+ _worldPacket << Item;
+ _worldPacket << Player;
+
+ _worldPacket.WriteBits(Error, 4);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Petition::PetitionAlreadySigned::Write()
+{
+ _worldPacket << SignerGUID;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Petition::DeclinePetition::Read()
+{
+ _worldPacket >> PetitionGUID;
+}
+
+void WorldPackets::Petition::TurnInPetition::Read()
+{
+ _worldPacket >> Item;
+}
+
+WorldPacket const* WorldPackets::Petition::TurnInPetitionResult::Write()
+{
+ _worldPacket.WriteBits(Result, 4);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Petition::OfferPetition::Read()
+{
+ _worldPacket >> ItemGUID;
+ _worldPacket >> TargetPlayer;
+}
+
+WorldPacket const* WorldPackets::Petition::OfferPetitionError::Write()
+{
+ _worldPacket << PlayerGUID;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Petition::PetitionRenameGuild::Read()
+{
+ _worldPacket >> PetitionGuid;
+
+ _worldPacket.ResetBitPos();
+ uint32 nameLen = _worldPacket.ReadBits(7);
+
+ NewGuildName = _worldPacket.ReadString(nameLen);
+}
+
+WorldPacket const* WorldPackets::Petition::PetitionRenameGuildResponse::Write()
+{
+ _worldPacket << PetitionGuid;
+
+ _worldPacket.WriteBits(NewGuildName.length(), 7);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(NewGuildName);
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/PetitionPackets.h b/src/server/game/Server/Packets/PetitionPackets.h
new file mode 100644
index 00000000000..fe136508547
--- /dev/null
+++ b/src/server/game/Server/Packets/PetitionPackets.h
@@ -0,0 +1,246 @@
+/*
+* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef PetitionPackets_h__
+#define PetitionPackets_h__
+
+#include "Packet.h"
+#include "ObjectGuid.h"
+#include "WorldSession.h"
+
+namespace WorldPackets
+{
+ namespace Petition
+ {
+ class QueryPetition final : public ClientPacket
+ {
+ public:
+ QueryPetition(WorldPacket&& packet) : ClientPacket(CMSG_QUERY_PETITION, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid ItemGUID;
+ uint32 PetitionID = 0;
+ };
+
+ struct PetitionInfo
+ {
+ int32 PetitionID = 0;
+ ObjectGuid Petitioner;
+ std::string Title;
+ std::string BodyText;
+ int32 MinSignatures = 0;
+ int32 MaxSignatures = 0;
+ int32 DeadLine = 0;
+ int32 IssueDate = 0;
+ int32 AllowedGuildID = 0;
+ int32 AllowedClasses = 0;
+ int32 AllowedRaces = 0;
+ int16 AllowedGender = 0;
+ int32 AllowedMinLevel = 0;
+ int32 AllowedMaxLevel = 0;
+ int32 NumChoices = 0;
+ int32 StaticType = 0;
+ uint32 Muid = 0;
+ std::string Choicetext[10];
+ };
+
+ class QueryPetitionResponse final : public ServerPacket
+ {
+ public:
+ QueryPetitionResponse() : ServerPacket(SMSG_QUERY_PETITION_RESPONSE, 75) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 PetitionID = 0;
+ bool Allow = false;
+ PetitionInfo Info;
+ };
+
+ class PetitionShowList final : public ClientPacket
+ {
+ public:
+ PetitionShowList(WorldPacket&& packet) : ClientPacket(CMSG_PETITION_SHOW_LIST, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid PetitionUnit;
+ };
+
+ class ServerPetitionShowList final : public ServerPacket
+ {
+ public:
+ ServerPetitionShowList() : ServerPacket(SMSG_PETITION_SHOW_LIST, 20) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Unit;
+ uint32 Price = 0;
+ };
+
+ class PetitionBuy final : public ClientPacket
+ {
+ public:
+ PetitionBuy(WorldPacket&& packet) : ClientPacket(CMSG_PETITION_BUY, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Unit;
+ std::string Title;
+ };
+
+ class PetitionShowSignatures final : public ClientPacket
+ {
+ public:
+ PetitionShowSignatures(WorldPacket&& packet) : ClientPacket(CMSG_PETITION_SHOW_SIGNATURES, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Item;
+ };
+
+ class ServerPetitionShowSignatures final : public ServerPacket
+ {
+ public:
+ struct PetitionSignature
+ {
+ ObjectGuid Signer;
+ int32 Choice = 0;
+ };
+
+ ServerPetitionShowSignatures() : ServerPacket(SMSG_PETITION_SHOW_SIGNATURES, 40) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Item;
+ ObjectGuid Owner;
+ ObjectGuid OwnerAccountID;
+ int32 PetitionID = 0;
+ std::vector<PetitionSignature> Signatures;
+ };
+
+ class SignPetition final : public ClientPacket
+ {
+ public:
+ SignPetition(WorldPacket&& packet) : ClientPacket(CMSG_SIGN_PETITION, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid PetitionGUID;
+ uint8 Choice = 0;
+ };
+
+ class PetitionSignResults final : public ServerPacket
+ {
+ public:
+ PetitionSignResults() : ServerPacket(SMSG_PETITION_SIGN_RESULTS, 33) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Item;
+ ObjectGuid Player;
+ int32 Error = 0; // PetitionError
+ };
+
+ class PetitionAlreadySigned final : public ServerPacket
+ {
+ public:
+ PetitionAlreadySigned() : ServerPacket(SMSG_PETITION_ALREADY_SIGNED, 16) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid SignerGUID;
+ };
+
+ class DeclinePetition final : public ClientPacket
+ {
+ public:
+ DeclinePetition(WorldPacket&& packet) : ClientPacket(CMSG_DECLINE_PETITION, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid PetitionGUID;
+ };
+
+ class TurnInPetition final : public ClientPacket
+ {
+ public:
+ TurnInPetition(WorldPacket&& packet) : ClientPacket(CMSG_TURN_IN_PETITION, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Item;
+ };
+
+ class TurnInPetitionResult final : public ServerPacket
+ {
+ public:
+ TurnInPetitionResult() : ServerPacket(SMSG_TURN_IN_PETITION_RESULTS, 4) { }
+
+ WorldPacket const* Write() override;
+
+ int32 Result = 0; // PetitionError
+ };
+
+ class OfferPetition final : public ClientPacket
+ {
+ public:
+ OfferPetition(WorldPacket&& packet) : ClientPacket(CMSG_OFFER_PETITION, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid TargetPlayer;
+ ObjectGuid ItemGUID;
+ };
+
+ class OfferPetitionError final : public ServerPacket
+ {
+ public:
+ OfferPetitionError() : ServerPacket(SMSG_OFFER_PETITION_ERROR, 16) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid PlayerGUID;
+ };
+
+ class PetitionRenameGuild final : public ClientPacket
+ {
+ public:
+ PetitionRenameGuild(WorldPacket&& packet) : ClientPacket(CMSG_PETITION_RENAME_GUILD, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid PetitionGuid;
+ std::string NewGuildName;
+ };
+
+ class PetitionRenameGuildResponse final : public ServerPacket
+ {
+ public:
+ PetitionRenameGuildResponse() : ServerPacket(SMSG_PETITION_RENAME_GUILD_RESPONSE, 20) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid PetitionGuid;
+ std::string NewGuildName;
+ };
+ }
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Petition::PetitionInfo const& petitionInfo);
+
+#endif // PetitionPackets_h__
diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp
index 50251c71c8b..a79ff8d4c96 100644
--- a/src/server/game/Server/Packets/SpellPackets.cpp
+++ b/src/server/game/Server/Packets/SpellPackets.cpp
@@ -112,15 +112,15 @@ WorldPacket const* WorldPackets::Spells::AuraUpdate::Write()
_worldPacket << uint32(data.ActiveFlags);
_worldPacket << uint16(data.CastLevel);
_worldPacket << uint8(data.Applications);
- _worldPacket << uint32(data.EstimatedPoints.size());
_worldPacket << uint32(data.Points.size());
-
- if (!data.EstimatedPoints.empty())
- _worldPacket.append(data.EstimatedPoints.data(), data.EstimatedPoints.size());
+ _worldPacket << uint32(data.EstimatedPoints.size());
if (!data.Points.empty())
_worldPacket.append(data.Points.data(), data.Points.size());
+ if (!data.EstimatedPoints.empty())
+ _worldPacket.append(data.EstimatedPoints.data(), data.EstimatedPoints.size());
+
_worldPacket.WriteBit(data.CastUnit.HasValue);
_worldPacket.WriteBit(data.Duration.HasValue);
_worldPacket.WriteBit(data.Remaining.HasValue);
@@ -487,3 +487,114 @@ WorldPacket const* WorldPackets::Spells::CooldownEvent::Write()
return &_worldPacket;
}
+
+WorldPacket const* WorldPackets::Spells::ClearCooldowns::Write()
+{
+ _worldPacket << Guid;
+ _worldPacket << uint32(SpellID.size());
+ if (!SpellID.empty())
+ _worldPacket.append(SpellID.data(), SpellID.size());
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::ClearCooldown::Write()
+{
+ _worldPacket << CasterGUID;
+ _worldPacket << uint32(SpellID);
+ _worldPacket.WriteBit(ClearOnHold);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::ModifyCooldown::Write()
+{
+ _worldPacket << int32(SpellID);
+ _worldPacket << UnitGUID;
+ _worldPacket << int32(DeltaTime);
+
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCooldownStruct const& cooldown)
+{
+ data << uint32(cooldown.SrecID);
+ data << uint32(cooldown.ForcedCooldown);
+ return data;
+}
+
+WorldPacket const* WorldPackets::Spells::SpellCooldown::Write()
+{
+ _worldPacket << Caster;
+ _worldPacket << uint8(Flags);
+ _worldPacket << uint32(SpellCooldowns.size());
+ for (SpellCooldownStruct const& cooldown : SpellCooldowns)
+ _worldPacket << cooldown;
+
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellHistoryEntry const& historyEntry)
+{
+ data << uint32(historyEntry.SpellID);
+ data << uint32(historyEntry.ItemID);
+ data << uint32(historyEntry.Category);
+ data << int32(historyEntry.RecoveryTime);
+ data << int32(historyEntry.CategoryRecoveryTime);
+ data.WriteBit(historyEntry.OnHold);
+ data.FlushBits();
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Spells::SendSpellHistory::Write()
+{
+ _worldPacket << uint32(Entries.size());
+ for (SpellHistoryEntry const& historyEntry : Entries)
+ _worldPacket << historyEntry;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::ClearAllSpellCharges::Write()
+{
+ _worldPacket << Unit;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::ClearSpellCharges::Write()
+{
+ _worldPacket << Unit;
+ _worldPacket << int32(Category);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::SetSpellCharges::Write()
+{
+ _worldPacket << int32(Category);
+ _worldPacket << float(Count);
+ _worldPacket.WriteBit(IsPet);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellChargeEntry const& chargeEntry)
+{
+ data << uint32(chargeEntry.Category);
+ data << uint32(chargeEntry.NextRecoveryTime);
+ data << uint8(chargeEntry.ConsumedCharges);
+ return data;
+}
+
+WorldPacket const* WorldPackets::Spells::SendSpellCharges::Write()
+{
+ _worldPacket << uint32(Entries.size());
+ for (SpellChargeEntry const& chargeEntry : Entries)
+ _worldPacket << chargeEntry;
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h
index ed84885f0a0..da877afbf8d 100644
--- a/src/server/game/Server/Packets/SpellPackets.h
+++ b/src/server/game/Server/Packets/SpellPackets.h
@@ -420,6 +420,132 @@ namespace WorldPackets
ObjectGuid CasterGUID;
int32 SpellID;
};
+
+ class ClearCooldowns final : public ServerPacket
+ {
+ public:
+ ClearCooldowns() : ServerPacket(SMSG_CLEAR_COOLDOWNS, 4 + 16) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<int32> SpellID;
+ ObjectGuid Guid;
+ };
+
+ class ClearCooldown final : public ServerPacket
+ {
+ public:
+ ClearCooldown() : ServerPacket(SMSG_CLEAR_COOLDOWN, 16 + 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid CasterGUID;
+ int32 SpellID = 0;
+ bool ClearOnHold = false;
+ };
+
+ class ModifyCooldown final : public ServerPacket
+ {
+ public:
+ ModifyCooldown() : ServerPacket(SMSG_MODIFY_COOLDOWN, 16 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid UnitGUID;
+ int32 DeltaTime = 0;
+ int32 SpellID = 0;
+ };
+
+ struct SpellCooldownStruct
+ {
+ SpellCooldownStruct() { }
+ SpellCooldownStruct(uint32 spellId, uint32 forcedCooldown) : SrecID(spellId), ForcedCooldown(forcedCooldown) { }
+
+ uint32 SrecID = 0;
+ uint32 ForcedCooldown = 0;
+ };
+
+ class SpellCooldown : public ServerPacket
+ {
+ public:
+ SpellCooldown() : ServerPacket(SMSG_SPELL_COOLDOWN, 4 + 16 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<SpellCooldownStruct> SpellCooldowns;
+ ObjectGuid Caster;
+ uint8 Flags = 0;
+ };
+
+ struct SpellHistoryEntry
+ {
+ uint32 SpellID = 0;
+ uint32 ItemID = 0;
+ uint32 Category = 0;
+ int32 RecoveryTime = 0;
+ int32 CategoryRecoveryTime = 0;
+ bool OnHold = false;
+ };
+
+ class SendSpellHistory final : public ServerPacket
+ {
+ public:
+ SendSpellHistory() : ServerPacket(SMSG_SEND_SPELL_HISTORY, 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<SpellHistoryEntry> Entries;
+ };
+
+ class ClearAllSpellCharges final : public ServerPacket
+ {
+ public:
+ ClearAllSpellCharges() : ServerPacket(SMSG_CLEAR_ALL_SPELL_CHARGES, 16) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Unit;
+ };
+
+ class ClearSpellCharges final : public ServerPacket
+ {
+ public:
+ ClearSpellCharges() : ServerPacket(SMSG_CLEAR_SPELL_CHARGES, 20) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Unit;
+ int32 Category = 0;
+ };
+
+ class SetSpellCharges final : public ServerPacket
+ {
+ public:
+ SetSpellCharges() : ServerPacket(SMSG_SET_SPELL_CHARGES, 1 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ bool IsPet = false;
+ float Count = 0.0f;
+ int32 Category = 0;
+ };
+
+ struct SpellChargeEntry
+ {
+ uint32 Category = 0;
+ uint32 NextRecoveryTime = 0;
+ uint8 ConsumedCharges = 0;
+ };
+
+ class SendSpellCharges final : public ServerPacket
+ {
+ public:
+ SendSpellCharges() : ServerPacket(SMSG_SEND_SPELL_CHARGES, 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<SpellChargeEntry> Entries;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 00d136d9c76..882e04cbf63 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -37,6 +37,7 @@
#include "Packets/MiscPackets.h"
#include "Packets/MovementPackets.h"
#include "Packets/NPCPackets.h"
+#include "Packets/PetitionPackets.h"
#include "Packets/QueryPackets.h"
#include "Packets/QuestPackets.h"
#include "Packets/SocialPackets.h"
@@ -141,7 +142,7 @@ void OpcodeTable::Initialize()
#define DEFINE_HANDLER(opcode, status, processing, packetclass, handler) \
ValidateAndSetClientOpcode<packetclass, handler>(opcode, #opcode, status, processing);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_ACCEPT_GUILD_INVITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_HANDLER(CMSG_ACCEPT_GUILD_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::AcceptGuildInvite, &WorldSession::HandleGuildAcceptInvite);
DEFINE_OPCODE_HANDLER_OLD(CMSG_ACCEPT_LEVEL_GRANT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptGrantLevel );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ACCEPT_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ACCEPT_WARGAME_INVITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -185,7 +186,6 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_BANK_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBankItemOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_GROUND_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_HANDLER(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Loot::AutoStoreLootItem, &WorldSession::HandleAutostoreLootItemOpcode);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTO_DECLINE_GUILD_INVITES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoDeclineGuildInvites );
DEFINE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBankerActivateOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_JOIN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LEAVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBattlefieldLeaveOpcode );
@@ -229,7 +229,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_BUSY_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode );
DEFINE_HANDLER(CMSG_BUY_BACK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::BuyBackItem, &WorldSession::HandleBuybackItem);
DEFINE_OPCODE_HANDLER_OLD(CMSG_BUY_BANK_SLOT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyBankSlotOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_BUY_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyItemOpcode );
+ DEFINE_HANDLER(CMSG_BUY_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::BuyItem, &WorldSession::HandleBuyItemOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CAGE_BATTLE_PET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_ADD_EVENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarAddEvent );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_ARENA_TEAM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarArenaTeam );
@@ -325,8 +325,8 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_CREATURE_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Query::QueryCreature, &WorldSession::HandleCreatureQuery);
DEFINE_OPCODE_HANDLER_OLD(CMSG_DANCE_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_HANDLER(CMSG_DB_QUERY_BULK, STATUS_AUTHED, PROCESS_INPLACE, WorldPackets::Query::DBQueryBulk, &WorldSession::HandleDBQueryBulk);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_DECLINE_GUILD_INVITES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_DECLINE_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionDeclineOpcode );
+ DEFINE_HANDLER(CMSG_DECLINE_GUILD_INVITES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::DeclineGuildInvites, &WorldSession::HandleDeclineGuildInvites);
+ DEFINE_HANDLER(CMSG_DECLINE_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::DeclinePetition, &WorldSession::HandleDeclinePetition);
DEFINE_OPCODE_HANDLER_OLD(CMSG_DELETE_EQUIPMENT_SET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete );
DEFINE_HANDLER(CMSG_DEL_FRIEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Social::DelFriend, &WorldSession::HandleDelFriendOpcode);
DEFINE_HANDLER(CMSG_DEL_IGNORE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Social::DelIgnore, &WorldSession::HandleDelIgnoreOpcode);
@@ -408,60 +408,53 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_GROUP_SET_LEADER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSetLeaderOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_GROUP_SET_ROLES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupSetRolesOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_GROUP_SWAP_SUB_GROUP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSwapSubGroupOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_ACCEPT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAcceptOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_ADD_BATTLENET_FRIEND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_ADD_RANK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAddRankOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_ASSIGN_MEMBER_RANK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAssignRankOpcode );
+ DEFINE_HANDLER(CMSG_GUILD_ADD_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildAddRank, &WorldSession::HandleGuildAddRank);
+ DEFINE_HANDLER(CMSG_GUILD_ASSIGN_MEMBER_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildAssignMemberRank, &WorldSession::HandleGuildAssignRank);
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_AUTO_DECLINE_INVITATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANKER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankerActivate );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_BUY_TAB, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankBuyTab );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_DEPOSIT_MONEY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankDepositMoney );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_LOG_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankLogQuery );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_MONEY_WITHDRAWN_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankMoneyWithdrawn );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_NOTE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_QUERY_TAB, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankQueryTab );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_QUERY_TEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryGuildBankTabText );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_SET_TAB_TEXT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_SWAP_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankSwapItems );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_UPDATE_TAB, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankUpdateTab );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_BANK_WITHDRAW_MONEY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankWithdrawMoney );
+ DEFINE_HANDLER(CMSG_GUILD_BANK_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankActivate, &WorldSession::HandleGuildBankActivate);
+ DEFINE_HANDLER(CMSG_GUILD_BANK_BUY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankBuyTab, &WorldSession::HandleGuildBankBuyTab);
+ DEFINE_HANDLER(CMSG_GUILD_BANK_DEPOSIT_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankDepositMoney, &WorldSession::HandleGuildBankDepositMoney);
+ DEFINE_HANDLER(CMSG_GUILD_BANK_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankLogQuery, &WorldSession::HandleGuildBankLogQuery);
+ DEFINE_HANDLER(CMSG_GUILD_BANK_QUERY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankQueryTab, &WorldSession::HandleGuildBankQueryTab);
+ DEFINE_HANDLER(CMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery, &WorldSession::HandleGuildBankMoneyWithdrawn);
+ DEFINE_HANDLER(CMSG_GUILD_BANK_SET_TAB_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankSetTabText, &WorldSession::HandleGuildBankSetTabText);
+ DEFINE_HANDLER(CMSG_GUILD_BANK_SWAP_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankSwapItems, &WorldSession::HandleGuildBankSwapItems);
+ DEFINE_HANDLER(CMSG_GUILD_BANK_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankTextQuery, &WorldSession::HandleGuildBankTextQuery);
+ DEFINE_HANDLER(CMSG_GUILD_BANK_UPDATE_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankUpdateTab, &WorldSession::HandleGuildBankUpdateTab);
+ DEFINE_HANDLER(CMSG_GUILD_BANK_WITHDRAW_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankWithdrawMoney, &WorldSession::HandleGuildBankWithdrawMoney);
+ DEFINE_HANDLER(CMSG_GUILD_CHALLENGE_UPDATE_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildChallengeUpdateRequest, &WorldSession::HandleGuildChallengeUpdateRequest);
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_CHANGE_NAME_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_DECLINE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDeclineOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_DELETE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_DELETE_RANK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDeleteRankOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_DEMOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDemoteOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_DISBAND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDisbandOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_EVENT_LOG_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode );
+ DEFINE_HANDLER(CMSG_GUILD_DECLINE_INVITATION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDeclineInvitation, &WorldSession::HandleGuildDeclineInvitation);
+ DEFINE_HANDLER(CMSG_GUILD_DELETE_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDeleteRank, &WorldSession::HandleGuildDeleteRank);
+ DEFINE_HANDLER(CMSG_GUILD_DEMOTE_MEMBER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDemoteMember, &WorldSession::HandleGuildDemoteMember);
+ DEFINE_HANDLER(CMSG_GUILD_DELETE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDelete, &WorldSession::HandleGuildDelete);
+ DEFINE_HANDLER(CMSG_GUILD_EVENT_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildEventLogQuery, &WorldSession::HandleGuildEventLogQuery);
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_GET_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_GET_RANKS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildGetRanksOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_GET_ROSTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRosterOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_INVITE_BY_NAME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInviteOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_LEAVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaveOpcode );
+ DEFINE_HANDLER(CMSG_GUILD_GET_RANKS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildGetRanks, &WorldSession::HandleGuildGetRanks);
+ DEFINE_HANDLER(CMSG_GUILD_GET_ROSTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildGetRoster, &WorldSession::HandleGuildGetRoster);
+ DEFINE_HANDLER(CMSG_GUILD_INVITE_BY_NAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildInviteByName, &WorldSession::HandleGuildInviteByName);
+ DEFINE_HANDLER(CMSG_GUILD_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildLeave, &WorldSession::HandleGuildLeave);
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_MEMBER_SEND_SOR_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGuildNewsUpdateStickyOpcode);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_OFFICER_REMOVE_MEMBER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildOfficerRemoveMemberOpcode);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_PERMISSIONS_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPermissions );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_PROMOTE_MEMBER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPromoteOpcode );
+ DEFINE_HANDLER(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Guild::GuildNewsUpdateSticky, &WorldSession::HandleGuildNewsUpdateSticky);
+ DEFINE_HANDLER(CMSG_GUILD_OFFICER_REMOVE_MEMBER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildOfficerRemoveMember, &WorldSession::HandleGuildOfficerRemoveMember);
+ DEFINE_HANDLER(CMSG_GUILD_PERMISSIONS_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildPermissionsQuery, &WorldSession::HandleGuildPermissionsQuery);
+ DEFINE_HANDLER(CMSG_GUILD_PROMOTE_MEMBER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildPromoteMember, &WorldSession::HandleGuildPromoteMember);
DEFINE_HANDLER(CMSG_GUILD_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Guild::QueryGuildInfo, &WorldSession::HandleGuildQueryOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_MEMBERS_FOR_RECIPE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_MEMBER_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_NEWS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGuildQueryNewsOpcode );
+ DEFINE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Guild::GuildQueryNews, &WorldSession::HandleGuildQueryNews);
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_REPLACE_GUILD_MASTER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_REQUEST_CHALLENGE_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_REQUEST_CHALLENGE_UPDATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRequestChallengeUpdate);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_REQUEST_MAX_DAILY_XP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRequestMaxDailyXP );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_REQUEST_PARTY_STATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRequestPartyState );
+ DEFINE_HANDLER(CMSG_GUILD_REQUEST_PARTY_STATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::RequestGuildPartyState, &WorldSession::HandleGuildRequestPartyState);
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_SET_ACHIEVEMENT_TRACKING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetAchievementTracking);
DEFINE_HANDLER(CMSG_GUILD_SET_FOCUSED_ACHIEVEMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Achievement::GuildSetFocusedAchievement, &WorldSession::HandleGuildSetFocusedAchievement);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_SET_GUILD_MASTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetGuildMaster );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_SET_MEMBER_NOTE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_SET_NOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetNoteOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_SET_RANK_PERMISSIONS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetRankPermissionsOpcode);
+ DEFINE_HANDLER(CMSG_GUILD_SET_GUILD_MASTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildSetGuildMaster, &WorldSession::HandleGuildSetGuildMaster);
+ DEFINE_HANDLER(CMSG_GUILD_SET_MEMBER_NOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildSetMemberNote, &WorldSession::HandleGuildSetMemberNote);
+ DEFINE_HANDLER(CMSG_GUILD_SET_RANK_PERMISSIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildSetRankPermissions, &WorldSession::HandleGuildSetRankPermissions);
DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_SHIFT_RANK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_UPDATE_INFO_TEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildChangeInfoTextOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_UPDATE_MOTD_TEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildMOTDOpcode );
+ DEFINE_HANDLER(CMSG_GUILD_UPDATE_INFO_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildUpdateInfoText, &WorldSession::HandleGuildUpdateInfoText);
+ DEFINE_HANDLER(CMSG_GUILD_UPDATE_MOTD_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildUpdateMotdText, &WorldSession::HandleGuildUpdateMotdText);
DEFINE_OPCODE_HANDLER_OLD(CMSG_HEARTH_AND_RESURRECT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleHearthAndResurrect );
DEFINE_OPCODE_HANDLER_OLD(CMSG_IGNORE_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_INCREASE_CAST_TIME_FOR_SPELL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -507,9 +500,8 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_BROWSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderBrowse );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_DECLINE_RECRUIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderDeclineRecruit );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_GET_APPLICATIONS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderGetApplications);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_GET_GUILD_POST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_GET_GUILD_POST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderPostRequest );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_GET_RECRUITS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderGetRecruits );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_POST_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderPostRequest );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_REMOVE_RECRUIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderRemoveRecruit );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_SET_GUILD_POST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderSetGuildPost );
DEFINE_HANDLER(CMSG_LIST_INVENTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleListInventoryOpcode);
@@ -635,7 +627,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_NPC_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryNPCText, &WorldSession::HandleNpcTextQueryOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_OBJECT_UPDATE_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleObjectUpdateFailedOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_OBJECT_UPDATE_RESCUED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_OFFER_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOfferPetitionOpcode );
+ DEFINE_HANDLER(CMSG_OFFER_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::OfferPetition, &WorldSession::HandleOfferPetition);
DEFINE_OPCODE_HANDLER_OLD(CMSG_OPENING_CINEMATIC, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOpeningCinematic );
DEFINE_OPCODE_HANDLER_OLD(CMSG_OPEN_GARRISON_MISSION_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_OPEN_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOpenItemOpcode );
@@ -648,12 +640,10 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_SILENCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_UNINVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_UNSILENCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_PETITION_BUY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionBuyOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_PETITION_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionQueryOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_PETITION_RENAME_GUILD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionRenameGuildOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_PETITION_SHOW_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionShowListOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_PETITION_SHOW_SIGNATURES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionShowSignOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_PETITION_SIGN, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionSignOpcode );
+ DEFINE_HANDLER(CMSG_PETITION_BUY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionBuy, &WorldSession::HandlePetitionBuy);
+ DEFINE_HANDLER(CMSG_PETITION_RENAME_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionRenameGuild, &WorldSession::HandlePetitionRenameGuild);
+ DEFINE_HANDLER(CMSG_PETITION_SHOW_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowList, &WorldSession::HandlePetitionShowList);
+ DEFINE_HANDLER(CMSG_PETITION_SHOW_SIGNATURES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowSignatures, &WorldSession::HandlePetitionShowSignatures);
DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_ABANDON, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAbandon );
DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_ACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAction );
DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_FINAL_NOTIF, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -686,10 +676,9 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_QUERY_CORPSE_LOCATION_FROM_CLIENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryCorpseLocationFromClient, &WorldSession::HandleQueryCorpseLocation);
DEFINE_HANDLER(CMSG_QUERY_CORPSE_TRANSPORT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryCorpseTransport, &WorldSession::HandleQueryCorpseTransport);
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_COUNTDOWN_TIMER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_GUILD_XP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryXPOpcode );
DEFINE_HANDLER(CMSG_QUERY_INSPECT_ACHIEVEMENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::QueryInspectAchievements, &WorldSession::HandleQueryInspectAchievements);
DEFINE_HANDLER(CMSG_QUERY_NEXT_MAIL_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailQueryNextMailTime, &WorldSession::HandleQueryNextMailTime);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_PETITION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_HANDLER(CMSG_QUERY_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::QueryPetition, &WorldSession::HandleQueryPetition);
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_SCENARIO_POI, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryTime, &WorldSession::HandleQueryTimeOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_ACCEPT_QUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverAcceptQuestOpcode);
@@ -705,7 +694,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTLOG_REMOVE_QUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTLOG_SWAP_QUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_CONFIRM_ACCEPT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_NPC_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestNPCQuery );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_QUEST_COMPLETION_NPCS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestNPCQuery );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_POI_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_PUSH_RESULT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult );
DEFINE_HANDLER(CMSG_QUEST_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QueryQuestInfo, &WorldSession::HandleQuestQueryOpcode);
@@ -732,7 +721,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_REQUEST_CEMETERY_LIST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::RequestCemeteryList, &WorldSession::HandleRequestCemeteryList);
DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_CONQUEST_FORMULA_CONSTANTS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_FORCED_REACTIONS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_GUILD_REWARDS_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRewardsQueryOpcode );
+ DEFINE_HANDLER(CMSG_REQUEST_GUILD_REWARDS_LIST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Guild::RequestGuildRewardsList, &WorldSession::HandleRequestGuildRewardsList);
DEFINE_HANDLER(CMSG_REQUEST_HONOR_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::RequestHonorStats, &WorldSession::HandleRequestHonorStatsOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_LFG_LIST_BLACKLIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_JOIN_UPDATES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -758,7 +747,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_ROLE_POLL_BEGIN, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRolePollBeginOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ROUTER_CLIENT_LOG_STREAMING_ERROR, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SAVE_CUF_PROFILES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleSaveCUFProfiles );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SAVE_GUILD_EMBLEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSaveGuildEmblemOpcode );
+ DEFINE_HANDLER(CMSG_SAVE_GUILD_EMBLEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::SaveGuildEmblem, &WorldSession::HandleSaveGuildEmblem);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SAVE_PLAYER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SCENE_PLAYBACK_CANCELED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SCENE_PLAYBACK_COMPLETE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -789,7 +778,6 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_FACTION_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_FACTION_INACTIVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionInactiveOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_FACTION_NOT_AT_WAR, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_GUILD_BANK_TEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_INSERT_ITEMS_LEFT_TO_RIGHT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_LFG_BONUS_FACTION_ID, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_LFG_COMMENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -805,7 +793,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ROLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend );
DEFINE_HANDLER(CMSG_SET_SELECTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetSelection, &WorldSession::HandleSetSelectionOpcode);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SHEATHED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleSetSheathedOpcode );
+ DEFINE_HANDLER(CMSG_SET_SHEATHED, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Combat::SetSheathed, &WorldSession::HandleSetSheathedOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SKILL_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SORT_BAGS_RIGHT_TO_LEFT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_HANDLER(CMSG_SET_SPECIALIZATION, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Talent::SetSpecialization, &WorldSession::HandleSetSpecializationOpcode);
@@ -819,7 +807,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_SHOWING_CLOAK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingCloakOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SHOWING_HELM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingHelmOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SHOW_TRADE_SKILL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SIGN_PETITION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_HANDLER(CMSG_SIGN_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::SignPetition, &WorldSession::HandleSignPetition);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SILENCE_PARTY_TALKER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SOCKET_GEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSocketOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SORT_BAGS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -830,7 +818,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_SPLIT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SplitItem, &WorldSession::HandleSplitItemOpcode);
DEFINE_HANDLER(CMSG_STAND_STATE_CHANGE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::StandStateChange, &WorldSession::HandleStandStateChangeOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_START_QUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_START_SPECTATOR_WARGAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_START_SPECTATOR_WAR_GAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_START_WARGAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_STOP_DANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_STORE_LOOT_IN_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -847,7 +835,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapItem, &WorldSession::HandleSwapItem);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SWAP_SUB_GROUPS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SYNC_DANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_TABARD_VENDOR_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode);
+ DEFINE_HANDLER(CMSG_TABARD_VENDOR_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleTabardVendorActivateOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_TAXICLEARALLNODES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TAXIENABLEALLNODES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TAXISHOWNODES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -868,7 +856,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_TRANSMOGRIFY_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTransmogrifyItems );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TRIGGER_CINEMATIC_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TROPHY_MONUMENT_LOAD_SELECTED_TROPHY_ID, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_TURN_IN_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTurnInPetitionOpcode );
+ DEFINE_HANDLER(CMSG_TURN_IN_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::TurnInPetition, &WorldSession::HandleTurnInPetition);
DEFINE_HANDLER(CMSG_TUTORIAL_FLAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::TutorialSetFlag, &WorldSession::HandleTutorialFlag);
DEFINE_HANDLER(CMSG_UI_TIME_REQUEST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::UITimeRequest, &WorldSession::HandleUITimeRequest);
DEFINE_OPCODE_HANDLER_OLD(CMSG_UNACCEPT_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode );
@@ -1000,10 +988,9 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_DROP_TIMER_STARTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECT_PENDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTERED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTERING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EXIT_REQUEST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_STATE_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1056,8 +1043,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BONUS_ROLL_EMPTY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BREAK_TARGET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_BANK_SLOT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_ITEM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_FAILED, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_SUCCEEDED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_ACTION_PENDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_ARENA_TEAM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_CLEAR_PENDING_ACTION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1132,15 +1119,15 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHEAT_IGNORE_DIMISHING_RETURNS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHECK_FOR_BOTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHECK_WARGAME_ENTRY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_ALL_SPELL_CHARGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_ALL_SPELL_CHARGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_BOSS_EMOTES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWNS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWNS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_LOSS_OF_CONTROL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_QUEST_COMPLETED_BIT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_QUEST_COMPLETED_BITS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_SPELL_CHARGES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_SPELL_CHARGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_TARGET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENTCACHE_VERSION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENT_CONTROL_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1166,7 +1153,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTACT_STATUS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONVERT_RUNE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_CHEAT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_LOCATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_RECLAIM_DELAY, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_TRANSPORT_QUERY, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1300,69 +1287,59 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_MONEY_WITHDRAWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_TEXT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_TEXT_QUERY_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_COMPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHANGE_NAME_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT_2, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_DECLINE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_BANK_CONTENTS_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_BANK_MONEY_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_DISBANDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_MOTD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_NEW_LEADER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PLAYER_JOINED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PLAYER_LEFT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PRESENCE_CHANGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_RANKS_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_RANK_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_ADDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_BANK_MONEY_CHANGED, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_DISBANDED, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_MOTD, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_NEW_LEADER, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PLAYER_JOINED, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PLAYER_LEFT, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PRESENCE_CHANGE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_RANK_CHANGED, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_RANKS_UPDATED, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_ADDED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_MODIFIED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_TEXT_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_FLAGGED_FOR_RENAME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_MODIFIED, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_TEXT_CHANGED, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_FLAGGED_FOR_RENAME, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE_DECLINED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE_EXPIRED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_KNOWN_RECIPES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MAX_DAILY_XP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBERS_WITH_RECIPE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_DAILY_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_DAILY_RESET, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_RECIPES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_UPDATE_NOTE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_UPDATE_NOTE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVE_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVE_STARTING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NAME_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_QUERY_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RANKS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RANKS, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_SEND_RANK_CHANGE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_REACTION_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_WEEKLY_CAP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_SEND_RANK_CHANGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_SET_NOTE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_TRADESKILL_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP_GAIN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HEALTH_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1400,7 +1377,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALID_PROMOTION_CODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVENTORY_CHANGE_FAILURE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_IS_QUEST_COMPLETE_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_BONUS_DEBUG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMBAT_LOG_UNK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_ENCHANT_TIME_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_EXPIRE_PURCHASE_REFUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1408,7 +1385,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_REFUND_INFO_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_REFUND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_TEXT_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_ITEM_TEXT_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_TIME_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_UPGRADE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_JOINED_BATTLEGROUND_QUEUE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1492,7 +1469,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MIRROR_IMAGE_COMPONENTED_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MIRROR_IMAGE_CREATURE_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MODIFY_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MODIFY_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONEY_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOTD, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
@@ -1617,9 +1594,9 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETGODMODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_ALREADY_SIGNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_DECLINED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_RENAME_GUILD_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_SIGNATURES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_RENAME_GUILD_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_SIGNATURES, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SIGN_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ACTION_FEEDBACK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ACTION_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1674,7 +1651,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_TIME_WARNING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PONG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_POWER_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_POWER_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PRE_RESSURECT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROC_RESIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROPOSE_LEVEL_GRANT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1683,8 +1660,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_OPTIONS_ENABLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_SEASON, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_BATTLE_PET_NAME_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PETITION_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PETITION_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_INVALID_QUEST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_OFFER_REWARD, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1699,7 +1675,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_FORCE_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_LOG_FULL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_NPC_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_COMPLETION_NPC_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_POI_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_PUSH_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_QUERY_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1761,7 +1737,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_POLL_BEGIN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_POLL_INFORM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RUNE_REGEN_DEBUG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SAVE_GUILD_EMBLEM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SAVE_GUILD_EMBLEM, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SCENARIO_BOOT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SCENARIO_COMPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SCENARIO_OUT_OF_BOUNDS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1782,8 +1758,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_MAIL_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_ALL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_CHARGES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_HISTORY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_CHARGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_HISTORY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1819,7 +1795,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROJECTILE_POSITION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_QUEST_COMPLETED_BIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_RAID_DIFFICULTY, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_SPELL_CHARGES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_SPELL_CHARGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TASK_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TIME_ZONE_INFORMATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_VEHICLE_REC_ID, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1838,7 +1814,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLSTEALLOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_ABSORB_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_CATEGORY_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DAMAGE_SHIELD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DELAYED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DISPEL_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1874,7 +1850,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUPPRESS_NPC_GREETINGS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_COMMS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TABARD_VENDOR_ACTIVATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TABARD_VENDOR_ACTIVATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INFO, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INVOLUNTARILY_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1900,7 +1876,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_PENDING, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UI_TIME, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_CHARACTER_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index 6dfa72cf46b..50c2daa05aa 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -90,7 +90,6 @@ enum OpcodeClient : uint32
CMSG_AUTOSTORE_BANK_ITEM = 0x0732,
CMSG_AUTOSTORE_GROUND_ITEM = 0xBADD,
CMSG_AUTOSTORE_LOOT_ITEM = 0x0609,
- CMSG_AUTO_DECLINE_GUILD_INVITES = 0xBADD,
CMSG_BANKER_ACTIVATE = 0x1B24,
CMSG_BATTLEFIELD_JOIN = 0xBADD,
CMSG_BATTLEFIELD_LEAVE = 0x06F1,
@@ -268,13 +267,17 @@ enum OpcodeClient : uint32
CMSG_GARRISON_MISSION_BONUS_ROLL = 0x02C2,
CMSG_GARRISON_OPEN_TRADESKILL_NPC = 0x099D,
CMSG_GARRISON_PURCHASE_BUILDING = 0x04A2,
+ CMSG_GARRISON_RECRUIT_FOLLOWER = 0x028E,
+ CMSG_GARRISON_REMOVE_FOLLOWER = 0x03A5,
CMSG_GARRISON_REMOVE_FOLLOWER_FROM_BUILDING = 0x01BB,
CMSG_GARRISON_REQUEST_BLUEPRINT_AND_SPECIALIZATION_DATA = 0x16F2,
CMSG_GARRISON_REQUEST_LANDING_PAGE_SHIPMENT_INFO = 0x0623,
CMSG_GARRISON_REQUEST_UPGRADEABLE = 0x02BD,
+ CMSG_GARRISON_SET_BUILDING_ACTIVE = 0x041A,
CMSG_GARRISON_SET_FOLLOWER_INACTIVE = 0x03BC,
CMSG_GARRISON_SET_RECRUITMENT_PREFERENCES = 0x0074,
CMSG_GARRISON_START_MISSION = 0x1624,
+ CMSG_GARRISON_SWAP_BUILDINGS = 0x09BD,
CMSG_GARRISON_UNK1 = 0x02F5,
CMSG_GETDEATHBINDZONE = 0xBADD,
CMSG_GET_CHALLENGE_MODE_REWARDS = 0x1C2F,
@@ -311,34 +314,33 @@ enum OpcodeClient : uint32
CMSG_GROUP_SET_LEADER = 0xBADD,
CMSG_GROUP_SET_ROLES = 0xBADD,
CMSG_GROUP_SWAP_SUB_GROUP = 0xBADD,
- CMSG_GUILD_ACCEPT = 0xBADD,
CMSG_GUILD_ADD_BATTLENET_FRIEND = 0x1437,
CMSG_GUILD_ADD_RANK = 0x1630,
CMSG_GUILD_ASSIGN_MEMBER_RANK = 0x0436,
CMSG_GUILD_AUTO_DECLINE_INVITATION = 0x062F,
- CMSG_GUILD_BANKER_ACTIVATE = 0x19E3,
+ CMSG_GUILD_BANK_ACTIVATE = 0x19E3,
CMSG_GUILD_BANK_BUY_TAB = 0x1BC3,
CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x1B11,
CMSG_GUILD_BANK_LOG_QUERY = 0x0428,
- CMSG_GUILD_BANK_MONEY_WITHDRAWN_QUERY = 0x020D,
CMSG_GUILD_BANK_NOTE = 0xBADD,
CMSG_GUILD_BANK_QUERY_TAB = 0x1139,
- CMSG_GUILD_BANK_QUERY_TEXT = 0x062D,
CMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY_QUERY = 0x063D,
CMSG_GUILD_BANK_SET_TAB_TEXT = 0x0E30,
CMSG_GUILD_BANK_SWAP_ITEMS = 0x1131,
+ CMSG_GUILD_BANK_TEXT_QUERY = 0x062D,
CMSG_GUILD_BANK_UPDATE_TAB = 0x13C1,
- CMSG_GUILD_BANK_WITHDRAW_MONEY = 0xBADD,
+ CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x020D,
+ CMSG_GUILD_CHALLENGE_UPDATE_REQUEST = 0x166E,
CMSG_GUILD_CHANGE_NAME_REQUEST = 0x043E,
- CMSG_GUILD_DECLINE = 0x0667,
+ CMSG_GUILD_DECLINE_INVITATION = 0x0667,
CMSG_GUILD_DELETE = 0x1427,
CMSG_GUILD_DELETE_RANK = 0x0C28,
- CMSG_GUILD_DEMOTE = 0x142F,
- CMSG_GUILD_DISBAND = 0xBADD,
+ CMSG_GUILD_DEMOTE_MEMBER = 0x142F,
CMSG_GUILD_EVENT_LOG_QUERY = 0x0E37,
CMSG_GUILD_GET_ACHIEVEMENT_MEMBERS = 0x0C40,
CMSG_GUILD_GET_RANKS = 0x0C37,
CMSG_GUILD_GET_ROSTER = 0x0638,
+ CMSG_GUILD_INFO = 0xBADD,
CMSG_GUILD_INVITE_BY_NAME = 0x19A4,
CMSG_GUILD_LEAVE = 0x0476,
CMSG_GUILD_MEMBER_SEND_SOR_REQUEST = 0x0666,
@@ -352,15 +354,11 @@ enum OpcodeClient : uint32
CMSG_GUILD_QUERY_NEWS = 0x0676,
CMSG_GUILD_QUERY_RECIPES = 0x1438,
CMSG_GUILD_REPLACE_GUILD_MASTER = 0x163E,
- CMSG_GUILD_REQUEST_CHALLENGE_INFO = 0x166E,
- CMSG_GUILD_REQUEST_CHALLENGE_UPDATE = 0xBADD,
- CMSG_GUILD_REQUEST_MAX_DAILY_XP = 0xBADD,
CMSG_GUILD_REQUEST_PARTY_STATE = 0x0A8E,
CMSG_GUILD_SET_ACHIEVEMENT_TRACKING = 0x1640,
CMSG_GUILD_SET_FOCUSED_ACHIEVEMENT = 0x0C7E,
CMSG_GUILD_SET_GUILD_MASTER = 0x1184,
CMSG_GUILD_SET_MEMBER_NOTE = 0x1C27,
- CMSG_GUILD_SET_NOTE = 0xBADD,
CMSG_GUILD_SET_RANK_PERMISSIONS = 0x0E38,
CMSG_GUILD_SHIFT_RANK = 0x0627,
CMSG_GUILD_UPDATE_INFO_TEXT = 0x0C75,
@@ -412,7 +410,6 @@ enum OpcodeClient : uint32
CMSG_LF_GUILD_GET_APPLICATIONS = 0x043F,
CMSG_LF_GUILD_GET_GUILD_POST = 0x0E68,
CMSG_LF_GUILD_GET_RECRUITS = 0x0430,
- CMSG_LF_GUILD_POST_REQUEST = 0xBADD,
CMSG_LF_GUILD_REMOVE_RECRUIT = 0x0680,
CMSG_LF_GUILD_SET_GUILD_POST = 0x0B3D,
CMSG_LIST_INVENTORY = 0x0B39,
@@ -552,11 +549,9 @@ enum OpcodeClient : uint32
CMSG_PARTY_UNINVITE = 0x1982,
CMSG_PARTY_UNSILENCE = 0xBADD,
CMSG_PETITION_BUY = 0x0010,
- CMSG_PETITION_QUERY = 0xBADD,
CMSG_PETITION_RENAME_GUILD = 0x0920,
CMSG_PETITION_SHOW_LIST = 0x000F,
CMSG_PETITION_SHOW_SIGNATURES = 0x0BC4,
- CMSG_PETITION_SIGN = 0xBADD,
CMSG_PET_ABANDON = 0x0005,
CMSG_PET_ACTION = 0x133A,
CMSG_PET_BATTLE_FINAL_NOTIF = 0x0565,
@@ -589,10 +584,10 @@ enum OpcodeClient : uint32
CMSG_QUERY_CORPSE_LOCATION_FROM_CLIENT = 0x128A,
CMSG_QUERY_CORPSE_TRANSPORT = 0x0908,
CMSG_QUERY_COUNTDOWN_TIMER = 0x09DE,
- CMSG_QUERY_GUILD_XP = 0xBADD,
CMSG_QUERY_INSPECT_ACHIEVEMENTS = 0x0A07,
CMSG_QUERY_NEXT_MAIL_TIME = 0x0B31,
CMSG_QUERY_PETITION = 0x048B,
+ CMSG_QUERY_QUEST_COMPLETION_NPCS = 0x0BD9,
CMSG_QUERY_SCENARIO_POI = 0x09A1,
CMSG_QUERY_TIME = 0x1489,
CMSG_QUESTGIVER_ACCEPT_QUEST = 0x13D3,
@@ -608,8 +603,7 @@ enum OpcodeClient : uint32
CMSG_QUESTLOG_REMOVE_QUEST = 0x0139,
CMSG_QUESTLOG_SWAP_QUEST = 0xBADD,
CMSG_QUEST_CONFIRM_ACCEPT = 0x058D,
- CMSG_QUEST_NPC_QUERY = 0x0B81,
- CMSG_QUEST_POI_QUERY = 0x0BD9,
+ CMSG_QUEST_POI_QUERY = 0x0B81,
CMSG_QUEST_PUSH_RESULT = 0x03D2,
CMSG_QUEST_QUERY = 0x09A6,
CMSG_QUEUED_MESSAGES_END = 0x04DF,
@@ -692,7 +686,6 @@ enum OpcodeClient : uint32
CMSG_SET_FACTION_CHEAT = 0xBADD,
CMSG_SET_FACTION_INACTIVE = 0x09E2,
CMSG_SET_FACTION_NOT_AT_WAR = 0x0A06,
- CMSG_SET_GUILD_BANK_TEXT = 0xBADD,
CMSG_SET_INSERT_ITEMS_LEFT_TO_RIGHT = 0x02C4,
CMSG_SET_LFG_BONUS_FACTION_ID = 0x009D,
CMSG_SET_LFG_COMMENT = 0xBADD,
@@ -733,7 +726,7 @@ enum OpcodeClient : uint32
CMSG_SPLIT_ITEM = 0x0795,
CMSG_STAND_STATE_CHANGE = 0x0ABD,
CMSG_START_QUEST = 0xBADD,
- CMSG_START_SPECTATOR_WARGAME = 0x13A3,
+ CMSG_START_SPECTATOR_WAR_GAME = 0x13A3,
CMSG_START_WARGAME = 0x03A2,
CMSG_STOP_DANCE = 0xBADD,
CMSG_STORE_LOOT_IN_SLOT = 0xBADD,
@@ -790,6 +783,7 @@ enum OpcodeClient : uint32
CMSG_USE_CRITTER_ITEM = 0x0BBE,
CMSG_USE_EQUIPMENT_SET = 0x0756,
CMSG_USE_ITEM = 0x08B6,
+ CMSG_USE_PARTY_GARRISON = 0x14DB,
CMSG_USE_TOY = 0x16E2,
CMSG_VIOLENCE_LEVEL = 0x098D,
CMSG_VOICE_ADD_IGNORE = 0x098A,
@@ -832,8 +826,9 @@ enum OpcodeServer : uint32
SMSG_ABORT_NEW_WORLD = 0x138C,
SMSG_ACCOUNT_CRITERIA_UPDATE = 0x0912,
SMSG_ACCOUNT_DATA_TIMES = 0x0120,
- SMSG_ACCOUNT_INFO_RESPONSE = 0xBADD,
+ SMSG_ACCOUNT_INFO_RESPONSE = 0x03AB,
SMSG_ACCOUNT_MOUNT_UPDATE = 0x0140,
+ SMSG_ACCOUNT_PROFILE = 0x1B1A,
SMSG_ACCOUNT_RESTRICTED_WARNING = 0xBADD,
SMSG_ACCOUNT_TOYS_UPDATE = 0x0590,
SMSG_ACHIEVEMENT_DELETED = 0x050E,
@@ -853,7 +848,11 @@ enum OpcodeServer : uint32
SMSG_ALL_ACHIEVEMENT_DATA = 0x0030,
SMSG_ALL_GUILD_ACHIEVEMENTS = 0x1866,
SMSG_ARCHAEOLOGY_SURVERY_CAST = 0x0008,
+ SMSG_AREA_SHARE_INFO_RESPONSE = 0x0005,
+ SMSG_AREA_SHARE_MAPPINGS_RESPONSE = 0x13E3,
SMSG_AREA_SPIRIT_HEALER_TIME = 0x1182,
+ SMSG_AREA_TRIGGER_DEBUG_PLAYER_INSIDE = 0x0789,
+ SMSG_AREA_TRIGGER_DEBUG_SWEEP = 0x11EB,
SMSG_AREA_TRIGGER_DENIED = 0x018A,
SMSG_AREA_TRIGGER_MESSAGE = 0xBADD,
SMSG_AREA_TRIGGER_MOVEMENT_UPDATE = 0xBADD,
@@ -894,17 +893,16 @@ enum OpcodeServer : uint32
SMSG_AUTH_CHALLENGE = 0x1759,
SMSG_AUTH_RESPONSE = 0x0DA9,
SMSG_AVAILABLE_VOICE_CHANNEL = 0x04D4,
- SMSG_AVERAGE_ITEM_LEVEL_INFORM = 0xBADD,
+ SMSG_AVERAGE_ITEM_LEVEL_INFORM = 0x1332,
SMSG_BARBER_SHOP_RESULT = 0x150D,
SMSG_BATTLEFIELD_LIST = 0x11A1,
SMSG_BATTLEFIELD_MGR_DROP_TIMER_CANCELED = 0x179A,
SMSG_BATTLEFIELD_MGR_DROP_TIMER_STARTED = 0x098B,
SMSG_BATTLEFIELD_MGR_EJECTED = 0x0DAF,
SMSG_BATTLEFIELD_MGR_EJECT_PENDING = 0x09A1,
- SMSG_BATTLEFIELD_MGR_ENTERED = 0x11A3,
- SMSG_BATTLEFIELD_MGR_ENTRY_INVITE = 0xBADD,
+ SMSG_BATTLEFIELD_MGR_ENTERING = 0x11A3,
+ SMSG_BATTLEFIELD_MGR_ENTRY_INVITE = 0x128B,
SMSG_BATTLEFIELD_MGR_EXIT_REQUEST = 0xBADD,
- SMSG_BATTLEFIELD_MGR_INVITE = 0x128B,
SMSG_BATTLEFIELD_MGR_QUEUE_INVITE = 0x0B32,
SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE = 0x0B28,
SMSG_BATTLEFIELD_MGR_STATE_CHANGED = 0x13C3,
@@ -958,7 +956,7 @@ enum OpcodeServer : uint32
SMSG_BREAK_TARGET = 0x11A2,
SMSG_BUY_BANK_SLOT_RESULT = 0xBADD,
SMSG_BUY_FAILED = 0x013A,
- SMSG_BUY_ITEM = 0x0BD1,
+ SMSG_BUY_SUCCEEDED = 0x0BD1,
SMSG_CALENDAR_ACTION_PENDING = 0xBADD,
SMSG_CALENDAR_ARENA_TEAM = 0xBADD,
SMSG_CALENDAR_CLEAR_PENDING_ACTION = 0x1E8A,
@@ -1033,7 +1031,7 @@ enum OpcodeServer : uint32
SMSG_CHEAT_IGNORE_DIMISHING_RETURNS = 0x194C,
SMSG_CHECK_FOR_BOTS = 0xBADD,
SMSG_CHECK_WARGAME_ENTRY = 0x1203,
- SMSG_CLEAR_ALL_SPELL_CHARGE = 0x088B,
+ SMSG_CLEAR_ALL_SPELL_CHARGES = 0x088B,
SMSG_CLEAR_BOSS_EMOTES = 0x118B,
SMSG_CLEAR_COOLDOWN = 0x0226,
SMSG_CLEAR_COOLDOWNS = 0x0BFA,
@@ -1048,6 +1046,7 @@ enum OpcodeServer : uint32
SMSG_COIN_REMOVED = 0x0D30,
SMSG_COMBAT_EVENT_FAILED = 0x1DAF,
SMSG_COMBAT_LOG_MULTIPLE = 0xBADD,
+ SMSG_COMBAT_LOG_UNK = 0x1D8E,
SMSG_COMMENTATOR_MAP_INFO = 0x1922,
SMSG_COMMENTATOR_PARTY_INFO = 0xBADD,
SMSG_COMMENTATOR_PLAYER_INFO = 0x1B23,
@@ -1055,7 +1054,7 @@ enum OpcodeServer : uint32
SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2 = 0xBADD,
SMSG_COMMENTATOR_STATE_CHANGED = 0x133A,
SMSG_COMPLAINT_RESULT = 0x0B15,
- SMSG_COMPLETE_SHIPMENT_RESPONSE = 0x0F3A,
+ SMSG_COMPLETE_SHIPMENT_RESPONSE = 0x0739,
SMSG_COMPRESSED_MOVES = 0xBADD,
SMSG_COMPRESSED_PACKET = 0x07CA,
SMSG_COMSAT_CONNECT_FAIL = 0xBADD,
@@ -1084,8 +1083,11 @@ enum OpcodeServer : uint32
SMSG_DAMAGE_DONE_OBSOLETE = 0xBADD,
SMSG_DANCE_QUERY_RESPONSE = 0xBADD,
SMSG_DANCE_STUDIO_CREATE_RESULT = 0x178D,
+ SMSG_DB_LOOKUP_RESULTS = 0x053A,
SMSG_DB_REPLY = 0x1939,
SMSG_DEATH_RELEASE_LOC = 0x098C,
+ SMSG_DEBUG_AISTATE = 0x091A,
+ SMSG_DEBUG_DRAW_AURA = 0x1919,
SMSG_DEBUG_SERVER_GEO = 0xBADD,
SMSG_DEFENSE_MESSAGE = 0x1442,
SMSG_DESTROY_ARENA_UNIT = 0x19E1,
@@ -1108,8 +1110,9 @@ enum OpcodeServer : uint32
SMSG_DUEL_OUT_OF_BOUNDS = 0x0111,
SMSG_DUEL_REQUESTED = 0x0827,
SMSG_DUEL_WINNER = 0x0935,
- SMSG_DUMP_RIDE_TICKETS_RESPONSE = 0xBADD,
+ SMSG_DUMP_RIDE_TICKETS_RESPONSE = 0x01E1,
SMSG_DURABILITY_DAMAGE_DEATH = 0x01EC,
+ SMSG_DYNAMIC_DROP_ROLL_RESULT = 0x0189,
SMSG_ECHO_PARTY_SQUELCH = 0xBADD,
SMSG_EMOTE = 0x071D,
SMSG_ENABLE_BARBER_SHOP = 0x13A2,
@@ -1132,6 +1135,7 @@ enum OpcodeServer : uint32
SMSG_FLOOD_DETECTED = 0xBADD,
SMSG_FORCEACTIONSHOW = 0xBADD,
SMSG_FORCED_DEATH_UPDATE = 0x09EB,
+ SMSG_FORCE_ACTION_SHOW_RESPONSE = 0x173A,
SMSG_FORCE_ANIM = 0x0028,
SMSG_FORCE_DISPLAY_UPDATE = 0xBADD,
SMSG_FORCE_OBJECT_RELINK = 0x059D,
@@ -1145,7 +1149,7 @@ enum OpcodeServer : uint32
SMSG_GAMEOBJECT_PLAY_SPELL_VISUAL_KIT = 0x01DB,
SMSG_GAMEOBJECT_QUERY_RESPONSE = 0x128A,
SMSG_GAMEOBJECT_RESET_STATE = 0x090E,
- SMSG_GAME_EVENT_DEBUG_LOG = 0xBADD,
+ SMSG_GAME_EVENT_DEBUG_LOG = 0x0121,
SMSG_GAME_SPEED_SET = 0x0D40,
SMSG_GAME_TIME_SET = 0x0B40,
SMSG_GAME_TIME_UPDATE = 0x1709,
@@ -1154,16 +1158,25 @@ enum OpcodeServer : uint32
SMSG_GARRISON_ASSIGN_FOLLOWER_TO_BUILDING_RESULT = 0x0B7C,
SMSG_GARRISON_BUILDING_ACTIVATED = 0x1974,
SMSG_GARRISON_BUILDING_REMOVED = 0x1151,
+ SMSG_GARRISON_BUILDING_SET_ACTIVE_SPECIALIZATION_RESULT = 0x0282,
SMSG_GARRISON_COMPLETE_MISSION_RESULT = 0x0D54,
+ SMSG_GARRISON_DELETE_RESULT = 0x19C1,
SMSG_GARRISON_FOLLOWER_CHANGED_XP = 0x1B64,
SMSG_GARRISON_LANDINGPAGE_SHIPMENTS = 0x1901,
SMSG_GARRISON_LEARN_BLUEPRINT_RESULT = 0x000B,
+ SMSG_GARRISON_LEARN_SPECIALIZATION_RESULT = 0x01D1,
+ SMSG_GARRISON_LIST_FOLLOWERS_CHEAT_RESULT = 0x1942,
SMSG_GARRISON_MISSION_BONUS_ROLL_RESULT = 0x0952,
SMSG_GARRISON_MONUMENT_SELECTED_TROPHY_ID_LOADED = 0x09EA,
+ SMSG_GARRISON_OPEN_ARCHITECT = 0x0004,
+ SMSG_GARRISON_OPEN_MISSION_NPC = 0x0542,
SMSG_GARRISON_OPEN_TRADESKILL_NPC_RESPONSE = 0x09C1,
SMSG_GARRISON_PLACE_BUILDING_RESULT = 0x0082,
+ SMSG_GARRISON_PLOT_PLACED = 0x0583,
SMSG_GARRISON_PLOT_REMOVED = 0x0513,
SMSG_GARRISON_REMOTE_INFO = 0x0151,
+ SMSG_GARRISON_REMOVE_FOLLOWER_FROM_BUILDING_RESULT = 0x0089,
+ SMSG_GARRISON_REMOVE_FOLLOWER_RESULT = 0x196A,
SMSG_GARRISON_REQUEST_BLUEPRINT_AND_SPECIALIZATION_DATA_RESULT = 0x0964,
SMSG_GARRISON_SET_NUM_FOLLOWER_ACTIVATIONS_REMAINING = 0x0D92,
SMSG_GARRISON_START_MISSION_RESULT = 0x0D01,
@@ -1176,9 +1189,15 @@ enum OpcodeServer : uint32
SMSG_GET_GARRISON_INFO_RESULT = 0x0521,
SMSG_GET_SHIPMENT_INFO_RESPONSE = 0x1BAB,
SMSG_GET_TROPHY_LIST_RESPONSE = 0x0126,
+ SMSG_GHOST = 0x0BC2,
+ SMSG_GHOSTEE_GONE = 0x0922,
+ SMSG_GM_ACCOUNT_ONLINE_RESPONSE = 0x1D9E,
+ SMSG_GM_CHANGE_ARENA_RATING = 0x1139,
+ SMSG_GM_CHARACTER_RESTORE_RESPONSE = 0x11E2,
SMSG_GM_MESSAGECHAT = 0xBADD,
SMSG_GM_PLAYER_INFO = 0x0118,
SMSG_GM_REQUEST_PLAYER_INFO = 0x1381,
+ SMSG_GM_SUMMON = 0x1223,
SMSG_GM_TICKET_CASE_STATUS = 0x1D8D,
SMSG_GM_TICKET_GET_TICKET_RESPONSE = 0x0389,
SMSG_GM_TICKET_RESOLVE_RESPONSE = 0x091F,
@@ -1201,20 +1220,18 @@ enum OpcodeServer : uint32
SMSG_GUILD_ACHIEVEMENT_DELETED = 0x1058,
SMSG_GUILD_ACHIEVEMENT_EARNED = 0x1048,
SMSG_GUILD_ACHIEVEMENT_MEMBERS = 0x1826,
- SMSG_GUILD_BANK_LIST = 0x1245,
SMSG_GUILD_BANK_LOG_QUERY_RESULT = 0x1237,
- SMSG_GUILD_BANK_MONEY_WITHDRAWN = 0x1047,
- SMSG_GUILD_BANK_QUERY_TEXT_RESULT = 0x1875,
+ SMSG_GUILD_BANK_QUERY_RESULTS = 0x1245,
+ SMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY = 0x1047,
+ SMSG_GUILD_BANK_TEXT_QUERY_RESULT = 0x1875,
SMSG_GUILD_CANCEL = 0xBADD,
SMSG_GUILD_CHALLENGE_COMPLETED = 0x1836,
- SMSG_GUILD_CHALLENGE_UPDATED = 0x1A06,
+ SMSG_GUILD_CHALLENGE_UPDATE = 0x1A06,
SMSG_GUILD_CHANGE_NAME_RESULT = 0x1006,
SMSG_GUILD_COMMAND_RESULT = 0x1205,
- SMSG_GUILD_COMMAND_RESULT_2 = 0xBADD,
SMSG_GUILD_CRITERIA_DELETED = 0x1805,
SMSG_GUILD_CRITERIA_UPDATE = 0x1208,
SMSG_GUILD_DECLINE = 0xBADD,
- SMSG_GUILD_EVENT = 0xBADD,
SMSG_GUILD_EVENT_BANK_CONTENTS_CHANGED = 0x1045,
SMSG_GUILD_EVENT_BANK_MONEY_CHANGED = 0x1077,
SMSG_GUILD_EVENT_DISBANDED = 0x1A08,
@@ -1236,40 +1253,33 @@ enum OpcodeServer : uint32
SMSG_GUILD_INVITE_DECLINED = 0x1226,
SMSG_GUILD_INVITE_EXPIRED = 0x1246,
SMSG_GUILD_KNOWN_RECIPES = 0x1078,
- SMSG_GUILD_MAX_DAILY_XP = 0xBADD,
SMSG_GUILD_MEMBERS_WITH_RECIPE = 0x1277,
SMSG_GUILD_MEMBER_DAILY_RESET = 0x1015,
SMSG_GUILD_MEMBER_RECIPES = 0x1036,
SMSG_GUILD_MEMBER_UPDATE_NOTE = 0x1846,
SMSG_GUILD_MOVED = 0x1838,
- SMSG_GUILD_MOVE_COMPLETE = 0xBADD,
SMSG_GUILD_MOVE_STARTING = 0x1877,
SMSG_GUILD_NAME_CHANGED = 0x1A07,
SMSG_GUILD_NEWS = 0x1027,
SMSG_GUILD_NEWS_DELETED = 0x1007,
- SMSG_GUILD_NEWS_UPDATE = 0xBADD,
SMSG_GUILD_PARTY_STATE_RESPONSE = 0x1225,
SMSG_GUILD_PERMISSIONS_QUERY_RESULTS = 0x1827,
SMSG_GUILD_QUERY_RESPONSE = 0x1046,
SMSG_GUILD_RANKS = 0x1218,
+ SMSG_GUILD_RECIPES = 0xBADD,
SMSG_GUILD_REPUTATION_REACTION_CHANGED = 0x1068,
- SMSG_GUILD_REPUTATION_WEEKLY_CAP = 0xBADD,
SMSG_GUILD_RESET = 0x1258,
SMSG_GUILD_REWARDS_LIST = 0x1818,
SMSG_GUILD_ROSTER = 0x1026,
SMSG_GUILD_ROSTER_UPDATE = 0x1265,
SMSG_GUILD_SEND_RANK_CHANGE = 0x1207,
- SMSG_GUILD_SET_NOTE = 0xBADD,
- SMSG_GUILD_TRADESKILL_UPDATE = 0xBADD,
- SMSG_GUILD_XP = 0xBADD,
- SMSG_GUILD_XP_GAIN = 0xBADD,
- SMSG_GUILD_XP_UPDATE = 0xBADD,
SMSG_HEALTH_UPDATE = 0x0BE1,
SMSG_HIGHEST_THREAT_UPDATE = 0x059A,
SMSG_HOTFIX_NOTIFY = 0x1304,
SMSG_HOTFIX_NOTIFY_BLOB = 0x1D1D,
SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0xBADD,
SMSG_IGNORE_REQUIREMENTS_CHEAT = 0xBADD,
+ SMSG_IMMIGRANT_HOST_SEARCH_LOG = 0x111A,
SMSG_INCREASE_CAST_TIME_FOR_SPELL = 0x1179,
SMSG_INITIALIZE_FACTIONS = 0x0B10,
SMSG_INITIAL_SETUP = 0x0B07,
@@ -1301,7 +1311,6 @@ enum OpcodeServer : uint32
SMSG_INVALID_PROMOTION_CODE = 0x1F09,
SMSG_INVENTORY_CHANGE_FAILURE = 0x0112,
SMSG_IS_QUEST_COMPLETE_RESPONSE = 0x17E1,
- SMSG_ITEM_BONUS_DEBUG = 0x1D8E,
SMSG_ITEM_COOLDOWN = 0x090F,
SMSG_ITEM_ENCHANT_TIME_UPDATE = 0x010D,
SMSG_ITEM_EXPIRE_PURCHASE_REFUND = 0x1282,
@@ -1309,7 +1318,6 @@ enum OpcodeServer : uint32
SMSG_ITEM_PUSH_RESULT = 0x0183,
SMSG_ITEM_REFUND_INFO_RESPONSE = 0xBADD,
SMSG_ITEM_REFUND_RESULT = 0xBADD,
- SMSG_ITEM_TEXT_QUERY_RESPONSE = 0x011A,
SMSG_ITEM_TIME_UPDATE = 0x0F3E,
SMSG_ITEM_UPGRADE_RESULT = 0x0B2E,
SMSG_JOINED_BATTLEGROUND_QUEUE = 0xBADD,
@@ -1349,6 +1357,7 @@ enum OpcodeServer : uint32
SMSG_LF_GUILD_POST = 0x1817,
SMSG_LF_GUILD_RECRUITS = 0x1008,
SMSG_LIST_INVENTORY = 0x0940,
+ SMSG_LIST_TARGETS = 0x058F,
SMSG_LIVE_REGION_ACCOUNT_RESTORE_RESULT = 0x113A,
SMSG_LIVE_REGION_CHARACTER_COPY_RESULT = 0x082E,
SMSG_LIVE_REGION_GET_ACCOUNT_CHARACTER_LIST_RESULT = 0x11E1,
@@ -1375,6 +1384,7 @@ enum OpcodeServer : uint32
SMSG_LOOT_ROLLS_COMPLETE = 0x0D2F,
SMSG_LOOT_ROLL_WON = 0x071E,
SMSG_LOOT_SLOT_CHANGED = 0xBADD,
+ SMSG_LOOT_UPDATED = 0x0301,
SMSG_LOSS_OF_CONTROL_AURA_UPDATE = 0x0305,
SMSG_MAIL_LIST_RESULT = 0x0B3F,
SMSG_MAIL_QUERY_NEXT_TIME_RESULT = 0x153D,
@@ -1398,6 +1408,8 @@ enum OpcodeServer : uint32
SMSG_MOTD = 0x0442,
SMSG_MOUNT_RESULT = 0x000F,
SMSG_MOVE_APPLY_MOVEMENT_FORCE = 0x06CB,
+ SMSG_MOVE_CHARACTER_CHEAT_FAILURE = 0x00F1,
+ SMSG_MOVE_CHARACTER_CHEAT_SUCCESS = 0x11AA,
SMSG_MOVE_DISABLE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x00C5,
SMSG_MOVE_DISABLE_COLLISION = 0x135A,
SMSG_MOVE_DISABLE_GRAVITY = 0x02C6,
@@ -1502,6 +1514,7 @@ enum OpcodeServer : uint32
SMSG_OPEN_CONTAINER = 0x05AA,
SMSG_OPEN_LFG_DUNGEON_FINDER = 0x0F17,
SMSG_OPEN_SHIPMENT_NPC_FROM_GOSSIP = 0x0709,
+ SMSG_OPEN_SHIPMENT_NPC_RESULT = 0x1B81,
SMSG_OVERRIDE_LIGHT = 0x01EA,
SMSG_PAGE_TEXT = 0x158D,
SMSG_PAGE_TEXT_QUERY_RESPONSE = 0x05A0,
@@ -1578,6 +1591,7 @@ enum OpcodeServer : uint32
SMSG_POWER_UPDATE = 0x0B27,
SMSG_PRE_RESSURECT = 0x0D2E,
SMSG_PROC_RESIST = 0x1DAD,
+ SMSG_PROFILE_DATA_RESPONSE = 0x1902,
SMSG_PROPOSE_LEVEL_GRANT = 0x1B8C,
SMSG_PUREMOUNT_CANCELLED_OBSOLETE = 0xBADD,
SMSG_PVP_CREDIT = 0x13A9,
@@ -1585,6 +1599,9 @@ enum OpcodeServer : uint32
SMSG_PVP_OPTIONS_ENABLED = 0x0320,
SMSG_PVP_SEASON = 0x09E3,
SMSG_QUERY_BATTLE_PET_NAME_RESPONSE = 0x09EC,
+ SMSG_QUERY_ITEM_TEXT_RESPONSE = 0x011A,
+ SMSG_QUERY_OBJ_POSITION = 0x0529,
+ SMSG_QUERY_OBJ_ROTATION = 0x171A,
SMSG_QUERY_PETITION_RESPONSE = 0x13AC,
SMSG_QUERY_TIME_RESPONSE = 0x1DB0,
SMSG_QUESTGIVER_INVALID_QUEST = 0x15E1,
@@ -1597,10 +1614,10 @@ enum OpcodeServer : uint32
SMSG_QUESTGIVER_REQUEST_ITEMS = 0x17B8,
SMSG_QUESTGIVER_STATUS = 0x1567,
SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x17C6,
+ SMSG_QUEST_COMPLETION_NPC_RESPONSE = 0x1591,
SMSG_QUEST_CONFIRM_ACCEPT = 0x15B2,
SMSG_QUEST_FORCE_REMOVED = 0x1D13,
SMSG_QUEST_LOG_FULL = 0x17E4,
- SMSG_QUEST_NPC_QUERY_RESPONSE = 0x1591,
SMSG_QUEST_POI_QUERY_RESPONSE = 0x1715,
SMSG_QUEST_PUSH_RESULT = 0x1797,
SMSG_QUEST_QUERY_RESPONSE = 0x1547,
@@ -1643,6 +1660,7 @@ enum OpcodeServer : uint32
SMSG_REQUEST_PVP_REWARDS_RESPONSE = 0x1DAE,
SMSG_RESEARCH_COMPLETE = 0x0B3A,
SMSG_RESEARCH_SETUP_HISTORY = 0x0A25,
+ SMSG_RESET_AREA_TRIGGER = 0x1B54,
SMSG_RESET_COMPRESSION_CONTEXT = 0xBADD,
SMSG_RESET_FAILED_NOTIFY = 0x1B01,
SMSG_RESET_RANGED_COMBAT_TIMER = 0x0106,
@@ -1677,6 +1695,7 @@ enum OpcodeServer : uint32
SMSG_SCENE_OBJECT_PET_BATTLE_REPLACEMENTS_MADE = 0x098A,
SMSG_SCENE_OBJECT_PET_BATTLE_ROUND_RESULT = 0x0130,
SMSG_SCRIPT_CAST = 0x1B1C,
+ SMSG_SCRIPT_MESSAGE = 0x1119,
SMSG_SELL_ITEM = 0xBADD,
SMSG_SELL_RESPONSE = 0x1352,
SMSG_SEND_ITEM_PASSIVES = 0x059F,
@@ -1686,11 +1705,14 @@ enum OpcodeServer : uint32
SMSG_SEND_SPELL_CHARGES = 0x1A82,
SMSG_SEND_SPELL_HISTORY = 0x1933,
SMSG_SEND_UNLEARN_SPELLS = 0x0BCB,
+ SMSG_SERVER_BUCK_DATA = 0x1EC9,
+ SMSG_SERVER_BUCK_DATA_START = 0x11E4,
SMSG_SERVER_FIRST_ACHIEVEMENT = 0x1413,
SMSG_SERVER_FIRST_ACHIEVEMENTS = 0x0BAC,
- SMSG_SERVER_INFO_RESPONSE = 0xBADD,
+ SMSG_SERVER_INFO_QUERY_RESPONSE = 0x11A4,
+ SMSG_SERVER_INFO_RESPONSE = 0x018B,
SMSG_SERVER_MESSAGE = 0x0683,
- SMSG_SERVER_PERF = 0xBADD,
+ SMSG_SERVER_PERF = 0x0319,
SMSG_SERVER_TIME = 0x0339,
SMSG_SETUP_CURRENCY = 0x0B06,
SMSG_SETUP_TROPHY = 0x0B63,
@@ -1718,8 +1740,10 @@ enum OpcodeServer : uint32
SMSG_SET_PLAY_HOVER_ANIM = 0x02D4,
SMSG_SET_PROFICIENCY = 0x00D3,
SMSG_SET_PROJECTILE_POSITION = 0xBADD,
+ SMSG_SET_PROMOTION_RESPONSE = 0x0A07,
SMSG_SET_QUEST_COMPLETED_BIT = 0x15D3,
SMSG_SET_RAID_DIFFICULTY = 0x051F,
+ SMSG_SET_SERVER_WOW_TIME = 0x0312,
SMSG_SET_SPELL_CHARGES = 0x18AB,
SMSG_SET_TASK_COMPLETE = 0x0B24,
SMSG_SET_TIME_ZONE_INFORMATION = 0x153E,
@@ -1728,9 +1752,10 @@ enum OpcodeServer : uint32
SMSG_SHOW_BANK = 0x1B51,
SMSG_SHOW_MAILBOX = 0x152F,
SMSG_SHOW_NEUTRAL_PLAYER_FACTION_SELECT_UI = 0x053D,
- SMSG_SHOW_RATINGS = 0xBADD,
+ SMSG_SHOW_RATINGS = 0x0F9A,
SMSG_SHOW_TAXI_NODES = 0x12A1,
SMSG_SHOW_TRADE_SKILL_RESPONSE = 0x15C0,
+ SMSG_SHOW_ZONES_CHEAT_RESULT = 0x1123,
SMSG_SOCKET_GEMS = 0x1302,
SMSG_SORT_BAGS_ACK = 0x09E4,
SMSG_SOR_START_EXPERIENCE_INCOMPLETE = 0x198B,
@@ -1820,7 +1845,7 @@ enum OpcodeServer : uint32
SMSG_UPDATE_INSTANCE_OWNERSHIP = 0x093E,
SMSG_UPDATE_LAST_INSTANCE = 0x13A4,
SMSG_UPDATE_OBJECT = 0x122C,
- SMSG_UPDATE_SERVER_PLAYER_POSITION = 0xBADD,
+ SMSG_UPDATE_SERVER_PLAYER_POSITION = 0x01AC,
SMSG_UPDATE_TASK_PROGRESS = 0x1209,
SMSG_UPDATE_WORLD_STATE = 0x03EC,
SMSG_USERLIST_ADD = 0x0441,
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 114b303e7f4..20a72640d49 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -1385,23 +1385,23 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co
//case CMSG_ARENA_TEAM_REMOVE: // not profiled
//case CMSG_ARENA_TEAM_LEADER: // not profiled
case CMSG_LOOT_METHOD: // not profiled
- case CMSG_GUILD_INVITE_BY_NAME: // not profiled
- //case CMSG_GUILD_ACCEPT: // not profiled
- case CMSG_GUILD_DECLINE: // not profiled
+ case CMSG_GUILD_INVITE_BY_NAME: // not profiled
+ case CMSG_ACCEPT_GUILD_INVITE: // not profiled
+ case CMSG_GUILD_DECLINE_INVITATION: // not profiled
case CMSG_GUILD_LEAVE: // not profiled
- case CMSG_GUILD_DISBAND: // not profiled
+ case CMSG_GUILD_DELETE: // not profiled
case CMSG_GUILD_SET_GUILD_MASTER: // not profiled
- //case CMSG_GUILD_MOTD: // not profiled
+ case CMSG_GUILD_UPDATE_MOTD_TEXT: // not profiled
case CMSG_GUILD_SET_RANK_PERMISSIONS: // not profiled
case CMSG_GUILD_ADD_RANK: // not profiled
case CMSG_GUILD_DELETE_RANK: // not profiled
- case CMSG_GUILD_UPDATE_INFO_TEXT: // not profiled
+ case CMSG_GUILD_UPDATE_INFO_TEXT: // not profiled
case CMSG_GUILD_BANK_DEPOSIT_MONEY: // not profiled
- //case CMSG_GUILD_BANK_WITHDRAW_MONEY: // not profiled
+ case CMSG_GUILD_BANK_WITHDRAW_MONEY: // not profiled
case CMSG_GUILD_BANK_BUY_TAB: // not profiled
- //case CMSG_GUILD_BANK_UPDATE_TAB: // not profiled
+ case CMSG_GUILD_BANK_UPDATE_TAB: // not profiled
//case CMSG_SET_GUILD_BANK_TEXT: // not profiled
- //case CMSG_SAVE_GUILD_EMBLEM: // not profiled
+ case CMSG_SAVE_GUILD_EMBLEM: // not profiled
//case MSG_PETITION_RENAME: // not profiled
//case MSG_TALENT_WIPE_CONFIRM: // not profiled
case CMSG_SET_DUNGEON_DIFFICULTY: // not profiled
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index d6bdc0f11fb..0cab4b9bf7a 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -145,6 +145,7 @@ namespace WorldPackets
{
class AttackSwing;
class AttackStop;
+ class SetSheathed;
}
namespace Duel
@@ -166,6 +167,44 @@ namespace WorldPackets
namespace Guild
{
class QueryGuildInfo;
+ class GuildInviteByName;
+ class AcceptGuildInvite;
+ class DeclineGuildInvites;
+ class GuildDeclineInvitation;
+ class GuildGetRoster;
+ class GuildPromoteMember;
+ class GuildDemoteMember;
+ class GuildOfficerRemoveMember;
+ class GuildAssignMemberRank;
+ class GuildLeave;
+ class GuildDelete;
+ class GuildUpdateMotdText;
+ class GuildGetRanks;
+ class GuildAddRank;
+ class GuildDeleteRank;
+ class GuildUpdateInfoText;
+ class GuildSetMemberNote;
+ class GuildEventLogQuery;
+ class GuildBankRemainingWithdrawMoneyQuery;
+ class GuildPermissionsQuery;
+ class GuildSetRankPermissions;
+ class GuildBankActivate;
+ class GuildBankQueryTab;
+ class GuildBankDepositMoney;
+ class GuildBankWithdrawMoney;
+ class GuildBankSwapItems;
+ class GuildBankBuyTab;
+ class GuildBankUpdateTab;
+ class GuildBankLogQuery;
+ class GuildBankTextQuery;
+ class GuildBankSetTabText;
+ class RequestGuildPartyState;
+ class RequestGuildRewardsList;
+ class GuildQueryNews;
+ class GuildNewsUpdateSticky;
+ class GuildSetGuildMaster;
+ class GuildChallengeUpdateRequest;
+ class SaveGuildEmblem;
}
namespace Inspect
@@ -180,6 +219,7 @@ namespace WorldPackets
{
class AutoEquipItem;
class AutoStoreBagItem;
+ class BuyItem;
class BuyBackItem;
class DestroyItem;
class GetItemPurchaseData;
@@ -242,6 +282,19 @@ namespace WorldPackets
class GossipSelectOption;
}
+ namespace Petition
+ {
+ class DeclinePetition;
+ class OfferPetition;
+ class PetitionBuy;
+ class PetitionRenameGuild;
+ class PetitionShowList;
+ class PetitionShowSignatures;
+ class QueryPetition;
+ class SignPetition;
+ class TurnInPetition;
+ }
+
namespace Query
{
class QueryCreature;
@@ -861,44 +914,43 @@ class WorldSession
void HandlePartyAssignmentOpcode(WorldPacket& recvData);
void HandleRolePollBeginOpcode(WorldPacket& recvData);
- void HandlePetitionBuyOpcode(WorldPacket& recvData);
- void HandlePetitionShowSignOpcode(WorldPacket& recvData);
- void HandlePetitionQueryOpcode(WorldPacket& recvData);
- void HandlePetitionRenameGuildOpcode(WorldPacket& recvData);
- void HandlePetitionSignOpcode(WorldPacket& recvData);
- void HandlePetitionDeclineOpcode(WorldPacket& recvData);
- void HandleOfferPetitionOpcode(WorldPacket& recvData);
- void HandleTurnInPetitionOpcode(WorldPacket& recvData);
+ void HandleDeclinePetition(WorldPackets::Petition::DeclinePetition& packet);
+ void HandleOfferPetition(WorldPackets::Petition::OfferPetition& packet);
+ void HandlePetitionBuy(WorldPackets::Petition::PetitionBuy& packet);
+ void HandlePetitionShowSignatures(WorldPackets::Petition::PetitionShowSignatures& packet);
+ void HandleQueryPetition(WorldPackets::Petition::QueryPetition& packet);
+ void HandlePetitionRenameGuild(WorldPackets::Petition::PetitionRenameGuild& packet);
+ void HandleSignPetition(WorldPackets::Petition::SignPetition& packet);
+ void HandleTurnInPetition(WorldPackets::Petition::TurnInPetition& packet);
void HandleGuildQueryOpcode(WorldPackets::Guild::QueryGuildInfo& query);
- void HandleGuildInviteOpcode(WorldPacket& recvPacket);
- void HandleGuildOfficerRemoveMemberOpcode(WorldPacket& recvPacket);
- void HandleGuildAcceptOpcode(WorldPacket& recvPacket);
- void HandleGuildDeclineOpcode(WorldPacket& recvPacket);
- void HandleGuildEventLogQueryOpcode(WorldPacket& recvPacket);
- void HandleGuildRosterOpcode(WorldPacket& recvPacket);
- void HandleGuildRewardsQueryOpcode(WorldPacket& recvPacket);
- void HandleGuildPromoteOpcode(WorldPacket& recvPacket);
- void HandleGuildDemoteOpcode(WorldPacket& recvPacket);
- void HandleGuildAssignRankOpcode(WorldPacket& recvPacket);
- void HandleGuildLeaveOpcode(WorldPacket& recvPacket);
- void HandleGuildDisbandOpcode(WorldPacket& recvPacket);
+ void HandleGuildInviteByName(WorldPackets::Guild::GuildInviteByName& packet);
+ void HandleGuildOfficerRemoveMember(WorldPackets::Guild::GuildOfficerRemoveMember& packet);
+ void HandleGuildAcceptInvite(WorldPackets::Guild::AcceptGuildInvite& invite);
+ void HandleGuildDeclineInvitation(WorldPackets::Guild::GuildDeclineInvitation& decline);
+ void HandleGuildEventLogQuery(WorldPackets::Guild::GuildEventLogQuery& packet);
+ void HandleGuildGetRoster(WorldPackets::Guild::GuildGetRoster& packet);
+ void HandleRequestGuildRewardsList(WorldPackets::Guild::RequestGuildRewardsList& packet);
+ void HandleGuildPromoteMember(WorldPackets::Guild::GuildPromoteMember& promote);
+ void HandleGuildDemoteMember(WorldPackets::Guild::GuildDemoteMember& demote);
+ void HandleGuildAssignRank(WorldPackets::Guild::GuildAssignMemberRank& packet);
+ void HandleGuildLeave(WorldPackets::Guild::GuildLeave& leave);
+ void HandleGuildDelete(WorldPackets::Guild::GuildDelete& packet);
void HandleGuildSetAchievementTracking(WorldPacket& recvPacket);
- void HandleGuildSetGuildMaster(WorldPacket& recvPacket);
- void HandleGuildMOTDOpcode(WorldPacket& recvPacket);
- void HandleGuildNewsUpdateStickyOpcode(WorldPacket& recvPacket);
- void HandleGuildSetNoteOpcode(WorldPacket& recvPacket);
- void HandleGuildGetRanksOpcode(WorldPacket& recvPacket);
- void HandleGuildQueryNewsOpcode(WorldPacket& recvPacket);
- void HandleGuildSetRankPermissionsOpcode(WorldPacket& recvPacket);
- void HandleGuildAddRankOpcode(WorldPacket& recvPacket);
- void HandleGuildDeleteRankOpcode(WorldPacket& recvPacket);
- void HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket);
- void HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket);
- void HandleGuildRequestPartyState(WorldPacket& recvPacket);
- void HandleGuildRequestChallengeUpdate(WorldPacket& recvPacket);
- void HandleGuildRequestMaxDailyXP(WorldPacket& recvPacket);
- void HandleAutoDeclineGuildInvites(WorldPacket& recvPacket);
+ void HandleGuildSetGuildMaster(WorldPackets::Guild::GuildSetGuildMaster& packet);
+ void HandleGuildUpdateMotdText(WorldPackets::Guild::GuildUpdateMotdText& packet);
+ void HandleGuildNewsUpdateSticky(WorldPackets::Guild::GuildNewsUpdateSticky& packet);
+ void HandleGuildSetMemberNote(WorldPackets::Guild::GuildSetMemberNote& packet);
+ void HandleGuildGetRanks(WorldPackets::Guild::GuildGetRanks& packet);
+ void HandleGuildQueryNews(WorldPackets::Guild::GuildQueryNews& newsQuery);
+ void HandleGuildSetRankPermissions(WorldPackets::Guild::GuildSetRankPermissions& packet);
+ void HandleGuildAddRank(WorldPackets::Guild::GuildAddRank& packet);
+ void HandleGuildDeleteRank(WorldPackets::Guild::GuildDeleteRank& packet);
+ void HandleGuildUpdateInfoText(WorldPackets::Guild::GuildUpdateInfoText& packet);
+ void HandleSaveGuildEmblem(WorldPackets::Guild::SaveGuildEmblem& packet);
+ void HandleGuildRequestPartyState(WorldPackets::Guild::RequestGuildPartyState& packet);
+ void HandleGuildChallengeUpdateRequest(WorldPackets::Guild::GuildChallengeUpdateRequest& packet);
+ void HandleDeclineGuildInvites(WorldPackets::Guild::DeclineGuildInvites& packet);
void HandleGuildFinderAddRecruit(WorldPacket& recvPacket);
void HandleGuildFinderBrowse(WorldPacket& recvPacket);
@@ -916,12 +968,12 @@ class WorldSession
void HandleMoveSplineDoneOpcode(WorldPacket& recvPacket);
void SendActivateTaxiReply(ActivateTaxiReply reply);
- void HandleTabardVendorActivateOpcode(WorldPacket& recvPacket);
+ void HandleTabardVendorActivateOpcode(WorldPackets::NPC::Hello& packet);
void HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet);
void HandleBuyBankSlotOpcode(WorldPacket& recvPacket);
void HandleTrainerListOpcode(WorldPackets::NPC::Hello& packet);
void HandleTrainerBuySpellOpcode(WorldPacket& recvPacket);
- void HandlePetitionShowListOpcode(WorldPacket& recvPacket);
+ void HandlePetitionShowList(WorldPackets::Petition::PetitionShowList& packet);
void HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet);
void HandleGossipSelectOptionOpcode(WorldPackets::NPC::GossipSelectOption& packet);
void HandleSpiritHealerActivateOpcode(WorldPacket& recvPacket);
@@ -984,7 +1036,7 @@ class WorldSession
void HandleAutoEquipItemOpcode(WorldPackets::Item::AutoEquipItem& autoEquipItem);
void HandleSellItemOpcode(WorldPackets::Item::SellItem& packet);
void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket);
- void HandleBuyItemOpcode(WorldPacket& recvPacket);
+ void HandleBuyItemOpcode(WorldPackets::Item::BuyItem& packet);
void HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet);
void HandleAutoStoreBagItemOpcode(WorldPackets::Item::AutoStoreBagItem& packet);
void HandleReadItem(WorldPacket& recvPacket);
@@ -997,7 +1049,7 @@ class WorldSession
void HandleAttackSwingOpcode(WorldPackets::Combat::AttackSwing& packet);
void HandleAttackStopOpcode(WorldPackets::Combat::AttackStop& packet);
- void HandleSetSheathedOpcode(WorldPacket& recvPacket);
+ void HandleSetSheathedOpcode(WorldPackets::Combat::SetSheathed& packet);
void HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet);
void HandleOpenItemOpcode(WorldPacket& recvPacket);
@@ -1192,20 +1244,19 @@ class WorldSession
void HandleSetTaxiBenchmarkOpcode(WorldPacket& recvData);
// Guild Bank
- void HandleGuildPermissions(WorldPacket& recvData);
- void HandleGuildBankMoneyWithdrawn(WorldPacket& recvData);
- void HandleGuildBankerActivate(WorldPacket& recvData);
- void HandleGuildBankQueryTab(WorldPacket& recvData);
- void HandleGuildBankLogQuery(WorldPacket& recvData);
- void HandleGuildBankDepositMoney(WorldPacket& recvData);
- void HandleGuildBankWithdrawMoney(WorldPacket& recvData);
- void HandleGuildBankSwapItems(WorldPacket& recvData);
-
- void HandleGuildBankUpdateTab(WorldPacket& recvData);
- void HandleGuildBankBuyTab(WorldPacket& recvData);
- void HandleQueryGuildBankTabText(WorldPacket& recvData);
- void HandleSetGuildBankTabText(WorldPacket& recvData);
- void HandleGuildQueryXPOpcode(WorldPacket& recvData);
+ void HandleGuildPermissionsQuery(WorldPackets::Guild::GuildPermissionsQuery& packet);
+ void HandleGuildBankMoneyWithdrawn(WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery& packet);
+ void HandleGuildBankActivate(WorldPackets::Guild::GuildBankActivate& packet);
+ void HandleGuildBankQueryTab(WorldPackets::Guild::GuildBankQueryTab& packet);
+ void HandleGuildBankLogQuery(WorldPackets::Guild::GuildBankLogQuery& packet);
+ void HandleGuildBankDepositMoney(WorldPackets::Guild::GuildBankDepositMoney& packet);
+ void HandleGuildBankWithdrawMoney(WorldPackets::Guild::GuildBankWithdrawMoney& packet);
+ void HandleGuildBankSwapItems(WorldPackets::Guild::GuildBankSwapItems& packet);
+
+ void HandleGuildBankUpdateTab(WorldPackets::Guild::GuildBankUpdateTab& packet);
+ void HandleGuildBankBuyTab(WorldPackets::Guild::GuildBankBuyTab& packet);
+ void HandleGuildBankTextQuery(WorldPackets::Guild::GuildBankTextQuery& packet);
+ void HandleGuildBankSetTabText(WorldPackets::Guild::GuildBankSetTabText& packet);
// Refer-a-Friend
void HandleGrantLevel(WorldPacket& recvData);
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index 42d2ec72c8e..112893fbc75 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -468,7 +468,7 @@ enum AuraType
SPELL_AURA_408 = 408,
SPELL_AURA_409 = 409,
SPELL_AURA_410 = 410,
- SPELL_AURA_MOD_CHARGES = 411, // NYI
+ SPELL_AURA_MOD_MAX_CHARGES = 411,
SPELL_AURA_412 = 412,
SPELL_AURA_413 = 413,
SPELL_AURA_414 = 414,
@@ -508,19 +508,19 @@ enum AuraType
SPELL_AURA_448 = 448,
SPELL_AURA_449 = 449,
SPELL_AURA_450 = 450,
- SPELL_AURA_451 = 451,
+ SPELL_AURA_OVERRIDE_PET_SPECS = 451, // NYI
SPELL_AURA_452 = 452,
- SPELL_AURA_453 = 453,
- SPELL_AURA_454 = 454,
+ SPELL_AURA_CHARGE_RECOVERY_MOD = 453,
+ SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER = 454,
SPELL_AURA_455 = 455,
- SPELL_AURA_456 = 456,
- SPELL_AURA_457 = 457,
- SPELL_AURA_458 = 458,
+ SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE = 456,
+ SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE_REGEN = 457,
+ SPELL_AURA_IGNORE_DUAL_WIELD_HIT_PENALTY = 458, // NYI
SPELL_AURA_459 = 459,
SPELL_AURA_460 = 460,
SPELL_AURA_461 = 461,
SPELL_AURA_462 = 462,
- SPELL_AURA_463 = 463,
+ SPELL_AURA_CONVER_CRIT_RATING_PCT_TO_PARRY_RATING = 463, // NYI
SPELL_AURA_464 = 464,
SPELL_AURA_465 = 465,
SPELL_AURA_466 = 466,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index b4c27f0214b..24d142da1a3 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -42,6 +42,7 @@
#include "Pet.h"
#include "ReputationMgr.h"
#include "MiscPackets.h"
+#include "SpellHistory.h"
class Aura;
//
@@ -470,7 +471,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //408
&AuraEffect::HandleNULL, //409
&AuraEffect::HandleNULL, //410
- &AuraEffect::HandleNULL, //411 SPELL_AURA_MOD_CHARGES
+ &AuraEffect::HandleNoImmediateEffect, //411 SPELL_AURA_MOD_MAX_CHARGES implemented in SpellHistory::GetMaxCharges
&AuraEffect::HandleNULL, //412
&AuraEffect::HandleNULL, //413
&AuraEffect::HandleNULL, //414
@@ -510,19 +511,19 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //448
&AuraEffect::HandleNULL, //449
&AuraEffect::HandleNULL, //450
- &AuraEffect::HandleNULL, //451
+ &AuraEffect::HandleNULL, //451 SPELL_AURA_OVERRIDE_PET_SPECS
&AuraEffect::HandleNULL, //452
- &AuraEffect::HandleNULL, //453
- &AuraEffect::HandleNULL, //454
+ &AuraEffect::HandleNoImmediateEffect, //453 SPELL_AURA_CHARGE_RECOVERY_MOD implemented in SpellHistory::GetChargeRecoveryTime
+ &AuraEffect::HandleNoImmediateEffect, //454 SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER implemented in SpellHistory::GetChargeRecoveryTime
&AuraEffect::HandleNULL, //455
- &AuraEffect::HandleNULL, //456
- &AuraEffect::HandleNULL, //457
- &AuraEffect::HandleNULL, //458
+ &AuraEffect::HandleNoImmediateEffect, //456 SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE implemented in SpellHistory::GetChargeRecoveryTime
+ &AuraEffect::HandleNoImmediateEffect, //457 SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE_REGEN implemented in SpellHistory::GetChargeRecoveryTime
+ &AuraEffect::HandleNULL, //458 SPELL_AURA_IGNORE_DUAL_WIELD_HIT_PENALTY
&AuraEffect::HandleNULL, //459
&AuraEffect::HandleNULL, //460
&AuraEffect::HandleNULL, //461
&AuraEffect::HandleNULL, //462
- &AuraEffect::HandleNULL, //463
+ &AuraEffect::HandleNULL, //463 SPELL_AURA_CRIT_RATING_AFFECTS_PARRY used by Riposte
&AuraEffect::HandleNULL, //464
&AuraEffect::HandleNULL, //465
&AuraEffect::HandleNULL, //466
@@ -1321,15 +1322,13 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
// Remove cooldown of spells triggered on stance change - they may share cooldown with stance spell
if (spellId)
{
- if (target->GetTypeId() == TYPEID_PLAYER)
- target->ToPlayer()->RemoveSpellCooldown(spellId);
+ target->GetSpellHistory()->ResetCooldown(spellId);
target->CastSpell(target, spellId, true, NULL, this);
}
if (spellId2)
{
- if (target->GetTypeId() == TYPEID_PLAYER)
- target->ToPlayer()->RemoveSpellCooldown(spellId2);
+ target->GetSpellHistory()->ResetCooldown(spellId2);
target->CastSpell(target, spellId2, true, NULL, this);
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 4e239f8a373..cd3b22dfa11 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -26,6 +26,7 @@
#include "Unit.h"
#include "Spell.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
#include "SpellPackets.h"
#include "DynamicObject.h"
#include "ObjectAccessor.h"
@@ -117,7 +118,7 @@ void AuraApplication::_Remove()
void AuraApplication::_InitFlags(Unit* caster, uint32 effMask)
{
// mark as selfcast if needed
- _flags |= (GetBase()->GetCasterGUID() == GetTarget()->GetGUID()) ? AFLAG_NONE : AFLAG_NOCASTER;
+ _flags |= (GetBase()->GetCasterGUID() == GetTarget()->GetGUID()) ? AFLAG_NOCASTER : AFLAG_NONE;
// aura is cast by self or an enemy
// one negative effect and we know aura is negative
@@ -150,7 +151,10 @@ void AuraApplication::_InitFlags(Unit* caster, uint32 effMask)
_flags |= positiveFound ? AFLAG_POSITIVE : AFLAG_NEGATIVE;
}
- if (GetBase()->GetSpellInfo()->AttributesEx8 & SPELL_ATTR8_AURA_SEND_AMOUNT)
+ if (GetBase()->GetSpellInfo()->AttributesEx8 & SPELL_ATTR8_AURA_SEND_AMOUNT ||
+ GetBase()->HasEffectType(SPELL_AURA_MOD_MAX_CHARGES) ||
+ GetBase()->HasEffectType(SPELL_AURA_CHARGE_RECOVERY_MOD) ||
+ GetBase()->HasEffectType(SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER))
_flags |= AFLAG_SCALABLE;
}
@@ -182,6 +186,7 @@ void AuraApplication::_HandleEffect(uint8 effIndex, bool apply)
// Remove all triggered by aura spells vs unlimited duration
aurEff->CleanupTriggeredSpells(GetTarget());
}
+
SetNeedClientUpdate();
}
@@ -218,10 +223,10 @@ void AuraApplication::BuildUpdatePacket(WorldPackets::Spells::AuraInfo& auraInfo
if (auraData.Flags & AFLAG_SCALABLE)
{
- auraData.Points.reserve(aura->GetAuraEffects().size());
+ auraData.Points.resize(aura->GetAuraEffects().size(), 0.0f);
for (AuraEffect const* effect : GetBase()->GetAuraEffects())
if (effect && HasEffect(effect->GetEffIndex())) // Not all of aura's effects have to be applied on every target
- auraData.Points.push_back(float(effect->GetAmount()));
+ auraData.Points[effect->GetEffIndex()] = float(effect->GetAmount());
}
auraInfo.AuraData.Set(auraData);
@@ -462,7 +467,7 @@ void Aura::_ApplyForTarget(Unit* target, Unit* caster, AuraApplication * auraApp
if (m_spellInfo->IsCooldownStartedOnEvent())
{
Item* castItem = !m_castItemGuid.IsEmpty() ? caster->ToPlayer()->GetItemByGuid(m_castItemGuid) : NULL;
- caster->ToPlayer()->AddSpellAndCategoryCooldowns(m_spellInfo, castItem ? castItem->GetEntry() : 0, NULL, true);
+ caster->GetSpellHistory()->StartCooldown(m_spellInfo, castItem ? castItem->GetEntry() : 0, nullptr, true);
}
}
}
@@ -490,12 +495,9 @@ void Aura::_UnapplyForTarget(Unit* target, Unit* caster, AuraApplication * auraA
m_removedApplications.push_back(auraApp);
// reset cooldown state for spells
- if (caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- if (GetSpellInfo()->IsCooldownStartedOnEvent())
- // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
- caster->ToPlayer()->SendCooldownEvent(GetSpellInfo());
- }
+ if (caster && GetSpellInfo()->IsCooldownStartedOnEvent())
+ // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
+ caster->GetSpellHistory()->SendCooldownEvent(GetSpellInfo());
}
// removes aura from all targets
@@ -1055,7 +1057,12 @@ bool Aura::CanBeSaved() const
bool Aura::CanBeSentToClient() const
{
- return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect(GetOwner() ? GetOwner()->GetMap()->GetDifficultyID() : DIFFICULTY_NONE) || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE) || HasEffectType(SPELL_AURA_CAST_WHILE_WALKING);
+ return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect(GetOwner() ? GetOwner()->GetMap()->GetDifficultyID() : DIFFICULTY_NONE)
+ || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE)
+ || HasEffectType(SPELL_AURA_CAST_WHILE_WALKING)
+ || HasEffectType(SPELL_AURA_MOD_MAX_CHARGES)
+ || HasEffectType(SPELL_AURA_CHARGE_RECOVERY_MOD)
+ || HasEffectType(SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER);
}
bool Aura::IsSingleTargetWith(Aura const* aura) const
@@ -1310,7 +1317,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
break;
case 60970: // Heroic Fury (remove Intercept cooldown)
if (target->GetTypeId() == TYPEID_PLAYER)
- target->ToPlayer()->RemoveSpellCooldown(20252, true);
+ target->GetSpellHistory()->ResetCooldown(20252, true);
break;
}
break;
@@ -1470,15 +1477,15 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
// check cooldown
if (caster->GetTypeId() == TYPEID_PLAYER)
{
- if (caster->ToPlayer()->HasSpellCooldown(aura->GetId()))
+ if (caster->GetSpellHistory()->HasCooldown(aura->GetId()))
{
// This additional check is needed to add a minimal delay before cooldown in in effect
// to allow all bubbles broken by a single damage source proc mana return
- if (caster->ToPlayer()->GetSpellCooldownDelay(aura->GetId()) <= 11)
+ if (caster->GetSpellHistory()->GetRemainingCooldown(aura->GetId()) <= 11)
break;
}
else // and add if needed
- caster->ToPlayer()->AddSpellCooldown(aura->GetId(), 0, uint32(time(NULL) + 12));
+ caster->GetSpellHistory()->AddCooldown(aura->GetId(), 0, std::chrono::seconds(12));
}
// effect on caster
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 3a05da9cd1e..8710f312dda 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -79,7 +79,7 @@ class AuraApplication
uint32 GetEffectMask() const { return _effectMask; }
bool HasEffect(uint8 effect) const { ASSERT(effect < MAX_SPELL_EFFECTS); return (_effectMask & (1 << effect)) != 0; }
bool IsPositive() const { return (_flags & AFLAG_POSITIVE) != 0; }
- bool IsSelfcast() const { return (_flags & AFLAG_NOCASTER) == 0; }
+ bool IsSelfcast() const { return (_flags & AFLAG_NOCASTER) != 0; }
uint8 GetEffectsToApply() const { return _effectsToApply; }
void SetRemoveMode(AuraRemoveMode mode) { _removeMode = mode; }
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 60c29ee9d70..3279e524b0c 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -58,6 +58,7 @@
#include "Battlefield.h"
#include "BattlefieldMgr.h"
#include "SpellPackets.h"
+#include "SpellHistory.h"
extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
@@ -841,7 +842,7 @@ void Spell::SelectSpellTargets()
if (m_spellInfo->IsChanneled())
{
uint32 mask = (1 << effect->EffectIndex);
- for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
if (ihit->effectMask & mask)
{
@@ -853,7 +854,7 @@ void Spell::SelectSpellTargets()
else if (m_auraScaleMask)
{
bool checkLvl = !m_UniqueTargetInfo.empty();
- for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end();)
+ for (std::vector<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end();)
{
// remove targets which did not pass min level check
if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask)
@@ -1220,7 +1221,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
case TARGET_REFERENCE_TYPE_LAST:
{
// find last added target for this effect
- for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
+ for (std::vector<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
{
if (ihit->effectMask & (1<<effIndex))
{
@@ -2113,7 +2114,7 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
ObjectGuid targetGUID = target->GetGUID();
// Lookup target in already in list
- for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
if (targetGUID == ihit->targetGUID) // Found in list
{
@@ -2215,7 +2216,7 @@ void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
ObjectGuid targetGUID = go->GetGUID();
// Lookup target in already in list
- for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
+ for (std::vector<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
{
if (targetGUID == ihit->targetGUID) // Found in list
{
@@ -2268,7 +2269,7 @@ void Spell::AddItemTarget(Item* item, uint32 effectMask)
return;
// Lookup target in already in list
- for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
+ for (std::vector<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
{
if (item == ihit->item) // Found in list
{
@@ -2866,7 +2867,7 @@ bool Spell::UpdateChanneledTargetList()
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
}
- for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
{
@@ -3089,7 +3090,7 @@ void Spell::cancel()
break;
case SPELL_STATE_CASTING:
- for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
if ((*ihit).missCondition == SPELL_MISS_NONE)
if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
@@ -3318,7 +3319,7 @@ void Spell::cast(bool skipCheck)
//Clear spell cooldowns after every spell is cast if .cheat cooldown is enabled.
if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN))
- m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
+ m_caster->GetSpellHistory()->ResetCooldown(m_spellInfo->Id, true);
}
SetExecutedCurrently(false);
@@ -3358,10 +3359,10 @@ void Spell::handle_immediate()
// process immediate effects (items, ground, etc.) also initialize some variables
_handle_immediate_phase();
- for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
DoAllEffectOnTarget(&(*ihit));
- for (std::list<GOTargetInfo>::iterator ihit= m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
+ for (std::vector<GOTargetInfo>::iterator ihit= m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
DoAllEffectOnTarget(&(*ihit));
FinishTargetProcessing();
@@ -3401,7 +3402,7 @@ uint64 Spell::handle_delayed(uint64 t_offset)
bool single_missile = (m_targets.HasDst());
// now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
- for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
if (ihit->processed == false)
{
@@ -3416,7 +3417,7 @@ uint64 Spell::handle_delayed(uint64 t_offset)
}
// now recheck gameobject targeting correctness
- for (std::list<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
+ for (std::vector<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
{
if (ighit->processed == false)
{
@@ -3474,7 +3475,7 @@ void Spell::_handle_immediate_phase()
}
// process items
- for (std::list<ItemTargetInfo>::iterator ihit= m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
+ for (std::vector<ItemTargetInfo>::iterator ihit= m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
DoAllEffectOnTarget(&(*ihit));
if (!m_originalCaster)
@@ -3521,30 +3522,7 @@ void Spell::_handle_finish_phase()
void Spell::SendSpellCooldown()
{
- Player* _player = m_caster->ToPlayer();
- if (!_player)
- {
- // Handle pet cooldowns here if needed instead of in PetAI to avoid hidden cooldown restarts
- Creature* _creature = m_caster->ToCreature();
- if (_creature && (_creature->IsPet() || _creature->IsGuardian()))
- _creature->AddCreatureSpellCooldown(m_spellInfo->Id);
-
- return;
- }
-
- // mana/health/etc potions, disabled by client (until combat out as declarate)
- if (m_CastItem && (m_CastItem->IsPotion() || m_spellInfo->IsCooldownStartedOnEvent()))
- {
- // need in some way provided data for Spell::finish SendCooldownEvent
- _player->SetLastPotionId(m_CastItem->GetEntry());
- return;
- }
-
- // have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation)
- if (m_spellInfo->IsCooldownStartedOnEvent() || m_spellInfo->IsPassive() || (_triggeredCastFlags & TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD))
- return;
-
- _player->AddSpellAndCategoryCooldowns(m_spellInfo, m_CastItem ? m_CastItem->GetEntry() : 0, this);
+ m_caster->GetSpellHistory()->HandleCooldowns(m_spellInfo, m_CastItem, this);
}
void Spell::update(uint32 difftime)
@@ -4075,7 +4053,7 @@ void Spell::SendSpellGo()
castData.CastFlags = castFlags;
castData.CastTime = getMSTime();
- WriteSpellGoTargets(castData);
+ UpdateSpellCastDataTargets(castData);
m_targets.Write(castData.Target);
@@ -4125,54 +4103,38 @@ void Spell::SendSpellGo()
}
/// Writes miss and hit targets for a SMSG_SPELL_GO packet
-void Spell::WriteSpellGoTargets(WorldPackets::Spells::SpellCastData& data)
+void Spell::UpdateSpellCastDataTargets(WorldPackets::Spells::SpellCastData& data)
{
// This function also fill data for channeled spells:
- // m_needAliveTargetMask req for stop channelig if one target die
- for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ // m_needAliveTargetMask req for stop channeling if one target die
+ for (TargetInfo& targetInfo : m_UniqueTargetInfo)
{
- if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
+ if (targetInfo.effectMask == 0) // No effect apply - all immune add state
// possibly SPELL_MISS_IMMUNE2 for this??
- ihit->missCondition = SPELL_MISS_IMMUNE2;
- }
-
- // Hit and miss target counts are both uint8, that limits us to 255 targets for each
- // sending more than 255 targets crashes the client (since count sent would be wrong)
- // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
- // target conditions but we still need to limit the number of targets sent and keeping
- // correct count for both hit and miss).
-
- uint32 hit = 0;
+ targetInfo.missCondition = SPELL_MISS_IMMUNE2;
- for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
- {
- if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
+ if (targetInfo.missCondition == SPELL_MISS_NONE) // hits
{
- data.HitTargets.push_back(ihit->targetGUID);
- m_channelTargetEffectMask |= ihit->effectMask;
- }
- }
+ data.HitTargets.push_back(targetInfo.targetGUID);
- for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
- {
- data.HitTargets.push_back(ighit->targetGUID); // Always hits
- }
-
- for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
- {
- if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
+ m_channelTargetEffectMask |= targetInfo.effectMask;
+ }
+ else // misses
{
- data.MissTargets.push_back(ihit->targetGUID);
+ data.MissTargets.push_back(targetInfo.targetGUID);
WorldPackets::Spells::SpellMissStatus missStatus;
- missStatus.Reason = ihit->missCondition;
- if (ihit->missCondition == SPELL_MISS_REFLECT)
- missStatus.ReflectStatus = ihit->reflectResult;
+ missStatus.Reason = targetInfo.missCondition;
+ if (targetInfo.missCondition == SPELL_MISS_REFLECT)
+ missStatus.ReflectStatus = targetInfo.reflectResult;
data.MissStatus.push_back(missStatus);
}
}
+ for (GOTargetInfo const& targetInfo : m_UniqueGOTargetInfo)
+ data.HitTargets.push_back(targetInfo.targetGUID); // Always hits
+
// Reset m_needAliveTargetMask for non channeled spell
if (!m_spellInfo->IsChanneled())
m_channelTargetEffectMask = 0;
@@ -4496,7 +4458,7 @@ void Spell::TakePower()
ObjectGuid targetGUID = m_targets.GetUnitTargetGUID();
if (!targetGUID.IsEmpty())
{
- for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
if (ihit->targetGUID == targetGUID)
{
@@ -4729,7 +4691,7 @@ void Spell::HandleThreatSpells()
// since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
threat /= m_UniqueTargetInfo.size();
- for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
float threatToAdd = threat;
if (ihit->missCondition != SPELL_MISS_NONE)
@@ -4770,7 +4732,7 @@ void Spell::HandleHolyPower(Player* caster)
ObjectGuid targetGUID = m_targets.GetUnitTargetGUID();
if (!targetGUID.IsEmpty())
{
- for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
if (ihit->targetGUID == targetGUID)
{
@@ -4825,23 +4787,26 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_CASTER_DEAD;
// check cooldowns to prevent cheating
- if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE))
+ if (!m_spellInfo->IsPassive())
{
- //can cast triggered (by aura only?) spells while have this flag
- if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURASTATE) && m_caster->ToPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY))
- return SPELL_FAILED_SPELL_IN_PROGRESS;
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ //can cast triggered (by aura only?) spells while have this flag
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURASTATE) && m_caster->ToPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY))
+ return SPELL_FAILED_SPELL_IN_PROGRESS;
- if (m_caster->ToPlayer()->HasSpellCooldown(m_spellInfo->Id))
+ // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
+ if (m_caster->ToPlayer()->GetLastPotionId() && m_CastItem && (m_CastItem->IsPotion() || m_spellInfo->IsCooldownStartedOnEvent()))
+ return SPELL_FAILED_NOT_READY;
+ }
+
+ if (!m_caster->GetSpellHistory()->IsReady(m_spellInfo))
{
if (m_triggeredByAuraSpell)
return SPELL_FAILED_DONT_REPORT;
else
return SPELL_FAILED_NOT_READY;
}
-
- // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
- if (m_caster->ToPlayer()->GetLastPotionId() && m_CastItem && (m_CastItem->IsPotion() || m_spellInfo->IsCooldownStartedOnEvent()))
- return SPELL_FAILED_NOT_READY;
}
if (m_spellInfo->HasAttribute(SPELL_ATTR7_IS_CHEAT_SPELL) && !m_caster->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_ALLOW_CHEAT_SPELLS))
@@ -5526,7 +5491,7 @@ SpellCastResult Spell::CheckCast(bool strict)
TalentEntry const* talent = sTalentStore.LookupEntry(m_misc.TalentId);
if (!talent)
return SPELL_FAILED_DONT_REPORT;
- if (m_caster->ToPlayer()->HasSpellCooldown(talent->SpellID))
+ if (m_caster->GetSpellHistory()->HasCooldown(talent->SpellID))
return SPELL_FAILED_CANT_UNTALENT;
break;
}
@@ -5711,13 +5676,13 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
}
// cooldown
- if (Creature const* creatureCaster = m_caster->ToCreature())
- if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
+ if (Creature* creatureCaster = m_caster->ToCreature())
+ if (!creatureCaster->GetSpellHistory()->IsReady(m_spellInfo))
return SPELL_FAILED_NOT_READY;
// Check if spell is affected by GCD
if (m_spellInfo->StartRecoveryCategory > 0)
- if (m_caster->GetCharmInfo() && m_caster->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo))
+ if (m_caster->GetCharmInfo() && m_caster->GetSpellHistory()->HasGlobalCooldown(m_spellInfo))
return SPELL_FAILED_NOT_READY;
return CheckCast(true);
@@ -5925,7 +5890,7 @@ bool Spell::CanAutoCast(Unit* target)
{
SelectSpellTargets();
//check if among target units, our WANTED target is as well (->only self cast spells return false)
- for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
if (ihit->targetGUID == targetguid)
return true;
}
@@ -6553,7 +6518,7 @@ void Spell::DelayedChannel()
TC_LOG_DEBUG("spells", "Spell %u partially interrupted for %i ms, new duration: %u ms", m_spellInfo->Id, delaytime, m_timer);
- for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
if ((*ihit).missCondition == SPELL_MISS_NONE)
if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
@@ -6758,15 +6723,15 @@ bool Spell::IsNeedSendToClient() const
bool Spell::HaveTargetsForEffect(uint8 effect) const
{
- for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
+ for (std::vector<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
if (itr->effectMask & (1 << effect))
return true;
- for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
+ for (std::vector<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
if (itr->effectMask & (1 << effect))
return true;
- for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
+ for (std::vector<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
if (itr->effectMask & (1 << effect))
return true;
@@ -6920,7 +6885,7 @@ void Spell::HandleLaunchPhase()
if (effect && (m_applyMultiplierMask & (1 << effect->EffectIndex)))
multiplier[effect->EffectIndex] = effect->CalcDamageMultiplier(m_originalCaster, this);
- for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
TargetInfo& target = *ihit;
@@ -7431,13 +7396,11 @@ enum GCDLimits
bool Spell::HasGlobalCooldown() const
{
- // Only player or controlled units have global cooldown
- if (m_caster->GetCharmInfo())
- return m_caster->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo);
- else if (m_caster->GetTypeId() == TYPEID_PLAYER)
- return m_caster->ToPlayer()->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo);
- else
+ // Only players or controlled units have global cooldown
+ if (m_caster->GetTypeId() != TYPEID_PLAYER && !m_caster->GetCharmInfo())
return false;
+
+ return m_caster->GetSpellHistory()->HasGlobalCooldown(m_spellInfo);
}
void Spell::TriggerGlobalCooldown()
@@ -7446,6 +7409,10 @@ void Spell::TriggerGlobalCooldown()
if (!gcd)
return;
+ // Only players or controlled units have global cooldown
+ if (m_caster->GetTypeId() != TYPEID_PLAYER && !m_caster->GetCharmInfo())
+ return;
+
if (m_caster->GetTypeId() == TYPEID_PLAYER)
if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN))
return;
@@ -7467,11 +7434,7 @@ void Spell::TriggerGlobalCooldown()
gcd = MAX_GCD;
}
- // Only players or controlled units have global cooldown
- if (m_caster->GetCharmInfo())
- m_caster->GetCharmInfo()->GetGlobalCooldownMgr().AddGlobalCooldown(m_spellInfo, gcd);
- else if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->GetGlobalCooldownMgr().AddGlobalCooldown(m_spellInfo, gcd);
+ m_caster->GetSpellHistory()->AddGlobalCooldown(m_spellInfo, gcd);
}
void Spell::CancelGlobalCooldown()
@@ -7484,10 +7447,10 @@ void Spell::CancelGlobalCooldown()
return;
// Only players or controlled units have global cooldown
- if (m_caster->GetCharmInfo())
- m_caster->GetCharmInfo()->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo);
- else if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo);
+ if (m_caster->GetTypeId() != TYPEID_PLAYER && !m_caster->GetCharmInfo())
+ return;
+
+ m_caster->GetSpellHistory()->CancelGlobalCooldown(m_spellInfo);
}
bool Spell::HasEffect(SpellEffectName effect) const
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index ebbc429d511..42c5258f4f8 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -438,7 +438,6 @@ class Spell
void setState(uint32 state) { m_spellState = state; }
void DoCreateItem(uint32 i, uint32 itemtype);
- void WriteSpellGoTargets(WorldPackets::Spells::SpellCastData& data);
bool CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect, Position const* losPosition) const;
bool CheckEffectTarget(GameObject const* target, SpellEffectInfo const* effect) const;
@@ -499,6 +498,7 @@ class Spell
void ReSetTimer() { m_timer = m_casttime > 0 ? m_casttime : 0; }
bool IsNextMeleeSwingSpell() const;
bool IsTriggered() const { return (_triggeredCastFlags & TRIGGERED_FULL_MASK) != 0; }
+ bool IsIgnoringCooldowns() const { return (_triggeredCastFlags & TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD) != 0; }
bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; }
bool IsAutoActionResetSpell() const;
@@ -637,7 +637,7 @@ class Spell
bool scaleAura:1;
int32 damage;
};
- std::list<TargetInfo> m_UniqueTargetInfo;
+ std::vector<TargetInfo> m_UniqueTargetInfo;
uint32 m_channelTargetEffectMask; // Mask req. alive targets
struct GOTargetInfo
@@ -647,14 +647,14 @@ class Spell
uint32 effectMask:32;
bool processed:1;
};
- std::list<GOTargetInfo> m_UniqueGOTargetInfo;
+ std::vector<GOTargetInfo> m_UniqueGOTargetInfo;
struct ItemTargetInfo
{
Item *item;
uint32 effectMask;
};
- std::list<ItemTargetInfo> m_UniqueItemInfo;
+ std::vector<ItemTargetInfo> m_UniqueItemInfo;
SpellDestination m_destTargets[MAX_SPELL_EFFECTS];
@@ -715,6 +715,8 @@ class Spell
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* properties, uint32 numSummons);
void CalculateJumpSpeeds(SpellEffectInfo const* effInfo, float dist, float& speedxy, float& speedz);
+ void UpdateSpellCastDataTargets(WorldPackets::Spells::SpellCastData& data);
+
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType& skillid, int32& reqSkillValue, int32& skillValue);
// -------------------------------------------
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 3a358154bc4..c08b3e6ec23 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -32,6 +32,7 @@
#include "DynamicObject.h"
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
#include "Group.h"
#include "UpdateData.h"
#include "MapManager.h"
@@ -411,7 +412,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_SHARE_DAMAGE))
{
uint32 count = 0;
- for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
if (ihit->effectMask & (1<<effIndex))
++count;
@@ -590,7 +591,7 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
case 31789: // Righteous Defense (step 1)
{
// Clear targets for eff 1
- for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ for (std::vector<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
ihit->effectMask &= ~(1<<1);
// not empty (checked), copy
@@ -672,9 +673,7 @@ void Spell::EffectTriggerSpell(SpellEffIndex /*effIndex*/)
return;
// Reset cooldown on stealth if needed
- if (unitTarget->ToPlayer()->HasSpellCooldown(1784))
- unitTarget->ToPlayer()->RemoveSpellCooldown(1784);
-
+ unitTarget->GetSpellHistory()->ResetCooldown(1784);
unitTarget->CastSpell(unitTarget, 1784, true);
return;
}
@@ -778,7 +777,7 @@ void Spell::EffectTriggerSpell(SpellEffIndex /*effIndex*/)
// Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime
&& m_spellInfo->GetCategory() == spellInfo->GetCategory())
- m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
+ m_caster->GetSpellHistory()->ResetCooldown(spellInfo->Id);
// original caster guid only for GO cast
m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID);
@@ -831,7 +830,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex /*effIndex*/)
// Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime
&& m_spellInfo->GetCategory() == spellInfo->GetCategory())
- m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
+ m_caster->GetSpellHistory()->ResetCooldown(spellInfo->Id);
// original caster guid only for GO cast
m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID);
@@ -3175,7 +3174,7 @@ void Spell::EffectInterruptCast(SpellEffIndex effIndex)
if (m_originalCaster)
{
int32 duration = m_spellInfo->GetDuration();
- unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), unitTarget->ModSpellDuration(m_spellInfo, unitTarget, duration, false, 1 << effIndex));
+ unitTarget->GetSpellHistory()->LockSpellSchool(curSpellInfo->GetSchoolMask(), unitTarget->ModSpellDuration(m_spellInfo, unitTarget, duration, false, 1 << effIndex));
}
ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
unitTarget->InterruptSpell(CurrentSpellTypes(i), false);
@@ -3944,7 +3943,7 @@ void Spell::EffectStuck(SpellEffIndex /*effIndex*/)
}
// the player dies if hearthstone is in cooldown, else the player is teleported to home
- if (player->HasSpellCooldown(8690))
+ if (player->GetSpellHistory()->HasCooldown(8690))
{
player->Kill(player);
return;
@@ -4553,8 +4552,8 @@ void Spell::EffectLeapBack(SpellEffIndex /*effIndex*/)
if (!unitTarget)
return;
- float speedxy = float(effectInfo->MiscValue) / 10;
- float speedz = float(damage / 10);
+ float speedxy = effectInfo->MiscValue / 10.f;
+ float speedz = damage / 10.f;
//1891: Disengage
m_caster->JumpTo(speedxy, speedz, m_spellInfo->SpellIconID != 1891);
}
@@ -5616,7 +5615,7 @@ void Spell::EffectCastButtons(SpellEffIndex /*effIndex*/)
if (!spellInfo)
continue;
- if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
+ if (!p_caster->HasSpell(spell_id) || p_caster->GetSpellHistory()->HasCooldown(spell_id))
continue;
if (!spellInfo->HasAttribute(SPELL_ATTR9_SUMMON_PLAYER_TOTEM))
diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp
new file mode 100644
index 00000000000..4060122630d
--- /dev/null
+++ b/src/server/game/Spells/SpellHistory.cpp
@@ -0,0 +1,854 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "SpellHistory.h"
+#include "Pet.h"
+#include "Player.h"
+#include "SpellInfo.h"
+#include "SpellPackets.h"
+#include "World.h"
+
+SpellHistory::Clock::duration const SpellHistory::InfinityCooldownDelay = std::chrono::duration_cast<SpellHistory::Clock::duration>(std::chrono::seconds(MONTH));
+
+template<>
+struct SpellHistory::PersistenceHelper<Player>
+{
+ static CharacterDatabaseStatements const CooldownsDeleteStatement = CHAR_DEL_CHAR_SPELL_COOLDOWNS;
+ static CharacterDatabaseStatements const CooldownsInsertStatement = CHAR_INS_CHAR_SPELL_COOLDOWN;
+ static CharacterDatabaseStatements const ChargesDeleteStatement = CHAR_DEL_CHAR_SPELL_CHARGES;
+ static CharacterDatabaseStatements const ChargesInsertStatement = CHAR_INS_CHAR_SPELL_CHARGES;
+
+ static void SetIdentifier(PreparedStatement* stmt, uint8 index, Unit* owner) { stmt->setUInt64(index, owner->GetGUID().GetCounter()); }
+
+ static bool ReadCooldown(Field* fields, uint32* spellId, CooldownEntry* cooldownEntry)
+ {
+ *spellId = fields[0].GetUInt32();
+ if (!sSpellMgr->GetSpellInfo(*spellId))
+ return false;
+
+ cooldownEntry->CooldownEnd = Clock::from_time_t(time_t(fields[2].GetUInt32()));
+ cooldownEntry->ItemId = fields[1].GetUInt32();
+ return true;
+ }
+
+ static bool ReadCharge(Field* fields, uint32* categoryId, ChargeEntry* chargeEntry)
+ {
+ *categoryId = fields[0].GetUInt32();
+ if (!sSpellCategoryStore.LookupEntry(*categoryId))
+ return false;
+
+ chargeEntry->RechargeStart = Clock::from_time_t(time_t(fields[1].GetUInt32()));
+ chargeEntry->RechargeEnd = Clock::from_time_t(time_t(fields[2].GetUInt32()));
+ return true;
+ }
+
+ static void WriteCooldown(PreparedStatement* stmt, uint8& index, CooldownStorageType::value_type const& cooldown)
+ {
+ stmt->setUInt32(index++, cooldown.first);
+ stmt->setUInt32(index++, cooldown.second.ItemId);
+ stmt->setUInt32(index++, uint32(Clock::to_time_t(cooldown.second.CooldownEnd)));
+ }
+
+ static void WriteCharge(PreparedStatement* stmt, uint8& index, uint32 chargeCategory, ChargeEntry const& charge)
+ {
+ stmt->setUInt32(index++, chargeCategory);
+ stmt->setUInt32(index++, uint32(Clock::to_time_t(charge.RechargeStart)));
+ stmt->setUInt32(index++, uint32(Clock::to_time_t(charge.RechargeEnd)));
+ }
+};
+
+template<>
+struct SpellHistory::PersistenceHelper<Pet>
+{
+ static CharacterDatabaseStatements const CooldownsDeleteStatement = CHAR_DEL_PET_SPELL_COOLDOWNS;
+ static CharacterDatabaseStatements const CooldownsInsertStatement = CHAR_INS_PET_SPELL_COOLDOWN;
+ static CharacterDatabaseStatements const ChargesDeleteStatement = CHAR_DEL_PET_SPELL_CHARGES;
+ static CharacterDatabaseStatements const ChargesInsertStatement = CHAR_INS_PET_SPELL_CHARGES;
+
+ static void SetIdentifier(PreparedStatement* stmt, uint8 index, Unit* owner) { stmt->setUInt32(index, owner->GetCharmInfo()->GetPetNumber()); }
+
+ static bool ReadCooldown(Field* fields, uint32* spellId, CooldownEntry* cooldownEntry)
+ {
+ *spellId = fields[0].GetUInt32();
+ if (!sSpellMgr->GetSpellInfo(*spellId))
+ return false;
+
+ cooldownEntry->CooldownEnd = Clock::from_time_t(time_t(fields[1].GetUInt32()));
+ cooldownEntry->ItemId = 0;
+ return true;
+ }
+
+ static bool ReadCharge(Field* fields, uint32* categoryId, ChargeEntry* chargeEntry)
+ {
+ *categoryId = fields[0].GetUInt32();
+ if (!sSpellCategoryStore.LookupEntry(*categoryId))
+ return false;
+
+ chargeEntry->RechargeStart = Clock::from_time_t(time_t(fields[1].GetUInt32()));
+ chargeEntry->RechargeEnd = Clock::from_time_t(time_t(fields[2].GetUInt32()));
+ return true;
+ }
+
+ static void WriteCooldown(PreparedStatement* stmt, uint8& index, CooldownStorageType::value_type const& cooldown)
+ {
+ stmt->setUInt32(index++, cooldown.first);
+ stmt->setUInt32(index++, uint32(Clock::to_time_t(cooldown.second.CooldownEnd)));
+ }
+
+ static void WriteCharge(PreparedStatement* stmt, uint8& index, uint32 chargeCategory, ChargeEntry const& charge)
+ {
+ stmt->setUInt32(index++, chargeCategory);
+ stmt->setUInt32(index++, uint32(Clock::to_time_t(charge.RechargeStart)));
+ stmt->setUInt32(index++, uint32(Clock::to_time_t(charge.RechargeEnd)));
+ }
+};
+
+template<class OwnerType>
+void SpellHistory::LoadFromDB(PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult)
+{
+ typedef PersistenceHelper<OwnerType> StatementInfo;
+
+ if (cooldownsResult)
+ {
+ do
+ {
+ uint32 spellId;
+ CooldownEntry cooldown;
+ if (StatementInfo::ReadCooldown(cooldownsResult->Fetch(), &spellId, &cooldown))
+ _spellCooldowns[spellId] = cooldown;
+
+ } while (cooldownsResult->NextRow());
+ }
+
+ if (chargesResult)
+ {
+ do
+ {
+ Field* fields = chargesResult->Fetch();
+ uint32 categoryId = 0;
+ ChargeEntry charges;
+ if (StatementInfo::ReadCharge(fields, &categoryId, &charges))
+ _categoryCharges[categoryId].push_back(charges);
+
+ } while (chargesResult->NextRow());
+ }
+}
+
+template<class OwnerType>
+void SpellHistory::SaveToDB(SQLTransaction& trans)
+{
+ typedef PersistenceHelper<OwnerType> StatementInfo;
+
+ uint8 index = 0;
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::CooldownsDeleteStatement);
+ StatementInfo::SetIdentifier(stmt, index++, _owner);
+ trans->Append(stmt);
+
+ for (auto const& p : _spellCooldowns)
+ {
+ if (!p.second.OnHold)
+ {
+ index = 0;
+ stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::CooldownsInsertStatement);
+ StatementInfo::SetIdentifier(stmt, index++, _owner);
+ StatementInfo::WriteCooldown(stmt, index, p);
+ trans->Append(stmt);
+ }
+ }
+
+ stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::ChargesDeleteStatement);
+ StatementInfo::SetIdentifier(stmt, 0, _owner);
+ trans->Append(stmt);
+
+ for (auto const& p : _categoryCharges)
+ {
+ for (ChargeEntry const& charge : p.second)
+ {
+ index = 0;
+ stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::ChargesInsertStatement);
+ StatementInfo::SetIdentifier(stmt, index++, _owner);
+ StatementInfo::WriteCharge(stmt, index, p.first, charge);
+ trans->Append(stmt);
+ }
+ }
+}
+
+void SpellHistory::Update()
+{
+ SQLTransaction t;
+ Clock::time_point now = Clock::now();
+ for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();)
+ {
+ if (itr->second.CooldownEnd < now)
+ itr = _spellCooldowns.erase(itr);
+ else
+ ++itr;
+ }
+
+ for (auto& p : _categoryCharges)
+ {
+ std::deque<ChargeEntry>& chargeRefreshTimes = p.second;
+ while (!chargeRefreshTimes.empty() && chargeRefreshTimes.front().RechargeEnd <= now)
+ chargeRefreshTimes.pop_front();
+ }
+}
+
+void SpellHistory::HandleCooldowns(SpellInfo const* spellInfo, Item const* item, Spell* spell /*= nullptr*/)
+{
+ if (ConsumeCharge(spellInfo->ChargeCategoryEntry))
+ return;
+
+ if (Player* player = _owner->ToPlayer())
+ {
+ // potions start cooldown until exiting combat
+ if (item && (item->IsPotion() || spellInfo->IsCooldownStartedOnEvent()))
+ {
+ player->SetLastPotionId(item->GetEntry());
+ return;
+ }
+ }
+
+ if (spellInfo->IsCooldownStartedOnEvent() || spellInfo->IsPassive() || (spell && spell->IsIgnoringCooldowns()))
+ return;
+
+ StartCooldown(spellInfo, item ? item->GetEntry() : 0, spell);
+}
+
+bool SpellHistory::IsReady(SpellInfo const* spellInfo) const
+{
+ if (spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
+ if (IsSchoolLocked(spellInfo->GetSchoolMask()))
+ return false;
+
+ if (HasCooldown(spellInfo->Id))
+ return false;
+
+ if (!HasCharge(spellInfo->ChargeCategoryEntry))
+ return false;
+
+ return true;
+}
+
+template<class PacketType>
+void SpellHistory::WritePacket(PacketType* packet) const
+{
+ static_assert(!std::is_same<PacketType, PacketType>::value /*static_assert(false)*/, "This packet is not supported.");
+}
+
+template<>
+void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellHistory* sendSpellHistory) const
+{
+ sendSpellHistory->Entries.reserve(_spellCooldowns.size());
+
+ Clock::time_point now = Clock::now();
+ for (auto const& p : _spellCooldowns)
+ {
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(p.first);
+ WorldPackets::Spells::SpellHistoryEntry historyEntry;
+ historyEntry.SpellID = p.first;
+ historyEntry.ItemID = p.second.ItemId;
+ historyEntry.Category = spellInfo->GetCategory();
+
+ if (p.second.OnHold)
+ historyEntry.OnHold = true;
+ else
+ {
+ std::chrono::milliseconds cooldownDuration = std::chrono::duration_cast<std::chrono::milliseconds>(p.second.CooldownEnd - now);
+ if (cooldownDuration.count() <= 0)
+ continue;
+
+ if (spellInfo->GetCategory())
+ historyEntry.CategoryRecoveryTime = uint32(cooldownDuration.count());
+ else
+ historyEntry.RecoveryTime = uint32(cooldownDuration.count());
+ }
+
+ sendSpellHistory->Entries.push_back(historyEntry);
+ }
+}
+
+template<>
+void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellCharges* sendSpellCharges) const
+{
+ sendSpellCharges->Entries.reserve(_categoryCharges.size());
+
+ Clock::time_point now = Clock::now();
+ for (auto const& p : _categoryCharges)
+ {
+ if (!p.second.empty())
+ {
+ std::chrono::milliseconds cooldownDuration = std::chrono::duration_cast<std::chrono::milliseconds>(p.second.front().RechargeEnd - now);
+ if (cooldownDuration.count() <= 0)
+ continue;
+
+ WorldPackets::Spells::SpellChargeEntry chargeEntry;
+ chargeEntry.Category = p.first;
+ chargeEntry.NextRecoveryTime = uint32(cooldownDuration.count());
+ chargeEntry.ConsumedCharges = p.second.size();
+ sendSpellCharges->Entries.push_back(chargeEntry);
+ }
+ }
+}
+
+/*
+template<>
+void SpellHistory::WritePacket(WorldPackets::Pet::PetSpells* petSpells)
+{
+ Clock::time_point now = Clock::now();
+
+ petSpells->Cooldowns.reserve(_spellCooldowns.size());
+ for (auto const& p : _spellCooldowns)
+ {
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(p.first);
+ WorldPackets::Pet::PetSpellCooldown petSpellCooldown;
+ petSpellCooldown.SpellID = p.first;
+ petSpellCooldown.Category = spellInfo->GetCategory();
+
+ if (!p.second.OnHold)
+ {
+ std::chrono::milliseconds cooldownDuration = std::chrono::duration_cast<std::chrono::milliseconds>(p.second.CooldownEnd - now);
+ if (cooldownDuration.count() <= 0)
+ continue;
+
+ if (spellInfo->GetCategory())
+ petSpellCooldown.CategoryDuration = uint32(cooldownDuration.count());
+ else
+ petSpellCooldown.Duration = uint32(cooldownDuration.count());
+ }
+
+ petSpells->Cooldowns.push_back(historyEntry);
+ }
+
+ petSpells->SpellHistory.reserve(_categoryCharges.size());
+ for (auto const& p : _categoryCharges)
+ {
+ if (!p.second.empty())
+ {
+ std::chrono::milliseconds cooldownDuration = std::chrono::duration_cast<std::chrono::milliseconds>(p.second.front().RechargeEnd - now);
+ if (cooldownDuration.count() <= 0)
+ continue;
+
+ WorldPackets::Pet::PetSpellHistory petChargeEntry;
+ petChargeEntry.CategoryID = p.first;
+ petChargeEntry.RecoveryTime = uint32(cooldownDuration.count());
+ petChargeEntry.ConsumedCharges = p.second.size();
+
+ petSpells->SpellHistory.push_back(petChargeEntry);
+ }
+ }
+}
+*/
+
+void SpellHistory::StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spell* spell /*= nullptr*/, bool onHold /*= false*/)
+{
+ // init cooldown values
+ uint32 categoryId = 0;
+ int32 cooldown = -1;
+ int32 categoryCooldown = -1;
+
+ // some special item spells without correct cooldown in SpellInfo
+ // cooldown information stored in item prototype
+ if (itemId)
+ {
+ if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId))
+ {
+ for (uint8 idx = 0; idx < proto->Effects.size(); ++idx)
+ {
+ if (uint32(proto->Effects[idx].SpellID) == spellInfo->Id)
+ {
+ categoryId = proto->Effects[idx].Category;
+ cooldown = proto->Effects[idx].Cooldown;
+ categoryCooldown = proto->Effects[idx].CategoryCooldown;
+ break;
+ }
+ }
+ }
+ }
+
+ // if no cooldown found above then base at DBC data
+ if (cooldown < 0 && categoryCooldown < 0)
+ {
+ categoryId = spellInfo->GetCategory();
+ cooldown = spellInfo->RecoveryTime;
+ categoryCooldown = spellInfo->CategoryRecoveryTime;
+ }
+
+ Clock::time_point curTime = Clock::now();
+ Clock::time_point catrecTime;
+ Clock::time_point recTime;
+ bool needsCooldownPacket = false;
+
+ // overwrite time for selected category
+ if (onHold)
+ {
+ // use +MONTH as infinite cooldown marker
+ catrecTime = categoryCooldown > 0 ? (curTime + InfinityCooldownDelay) : curTime;
+ recTime = cooldown > 0 ? (curTime + InfinityCooldownDelay) : catrecTime;
+ }
+ else
+ {
+ // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
+ // prevent 0 cooldowns set by another way
+ if (cooldown <= 0 && categoryCooldown <= 0 && (categoryId == 76 || (spellInfo->IsAutoRepeatRangedSpell() && spellInfo->Id != 75)))
+ cooldown = _owner->GetAttackTime(RANGED_ATTACK);
+
+ // Now we have cooldown data (if found any), time to apply mods
+ if (Player* modOwner = _owner->GetSpellModOwner())
+ {
+ if (cooldown > 0)
+ modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, cooldown, spell);
+
+ if (categoryCooldown > 0 && !spellInfo->HasAttribute(SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS))
+ modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, categoryCooldown, spell);
+ }
+
+ if (int32 cooldownMod = _owner->GetTotalAuraModifier(SPELL_AURA_MOD_COOLDOWN))
+ {
+ // Apply SPELL_AURA_MOD_COOLDOWN only to own spells
+ Player* playerOwner = GetPlayerOwner();
+ if (!playerOwner || playerOwner->HasSpell(spellInfo->Id))
+ {
+ needsCooldownPacket = true;
+ cooldown += cooldownMod * IN_MILLISECONDS; // SPELL_AURA_MOD_COOLDOWN does not affect category cooldows, verified with shaman shocks
+ }
+ }
+
+ // Apply SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN modifiers
+ // Note: This aura applies its modifiers to all cooldowns of spells with set category, not to category cooldown only
+ if (categoryId)
+ {
+ if (int32 categoryModifier = _owner->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN, categoryId))
+ {
+ if (cooldown > 0)
+ cooldown += categoryModifier;
+
+ if (categoryCooldown > 0)
+ categoryCooldown += categoryModifier;
+ }
+
+ SpellCategoryEntry const* categoryEntry = sSpellCategoryStore.AssertEntry(categoryId);
+ if (categoryEntry->Flags & SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_DAILY_RESET)
+ categoryCooldown = int32(std::chrono::duration_cast<std::chrono::milliseconds>(Clock::from_time_t(sWorld->GetNextDailyQuestsResetTime()) - Clock::now()).count());
+ }
+
+ // replace negative cooldowns by 0
+ if (cooldown < 0)
+ cooldown = 0;
+
+ if (categoryCooldown < 0)
+ categoryCooldown = 0;
+
+ // no cooldown after applying spell mods
+ if (cooldown == 0 && categoryCooldown == 0)
+ return;
+
+ catrecTime = categoryCooldown ? curTime + std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(categoryCooldown)) : curTime;
+ recTime = cooldown ? curTime + std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(cooldown)) : catrecTime;
+ }
+
+ // self spell cooldown
+ if (recTime != curTime)
+ {
+ AddCooldown(spellInfo->Id, itemId, recTime, onHold);
+
+ if (needsCooldownPacket)
+ {
+ if (Player* playerOwner = GetPlayerOwner())
+ {
+ WorldPackets::Spells::SpellCooldown spellCooldown;
+ spellCooldown.Caster = _owner->GetGUID();
+ spellCooldown.Flags = SPELL_COOLDOWN_FLAG_NONE;
+ spellCooldown.SpellCooldowns.emplace_back(spellInfo->Id, uint32(cooldown));
+ playerOwner->SendDirectMessage(spellCooldown.Write());
+ }
+ }
+ }
+
+ // category spells
+ if (categoryId && catrecTime != curTime)
+ {
+ SpellCategoryStore::const_iterator i_scstore = sSpellsByCategoryStore.find(categoryId);
+ if (i_scstore != sSpellsByCategoryStore.end())
+ {
+ for (SpellCategorySet::const_iterator i_scset = i_scstore->second.begin(); i_scset != i_scstore->second.end(); ++i_scset)
+ {
+ if (*i_scset == spellInfo->Id) // skip main spell, already handled above
+ continue;
+
+ AddCooldown(*i_scset, itemId, catrecTime, onHold);
+ }
+ }
+ }
+}
+
+void SpellHistory::SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId /*= 0*/, Spell* spell /*= nullptr*/, bool startCooldown /*= true*/)
+{
+ // start cooldowns at server side, if any
+ if (startCooldown)
+ StartCooldown(spellInfo, itemId, spell);
+
+ if (Player* player = GetPlayerOwner())
+ {
+ // Send activate cooldown timer (possible 0) at client side
+ player->SendDirectMessage(WorldPackets::Spells::CooldownEvent(_owner->GetGUID(), spellInfo->Id).Write());
+
+ uint32 category = spellInfo->GetCategory();
+ if (category && spellInfo->CategoryRecoveryTime)
+ {
+ SpellCategoryStore::const_iterator ct = sSpellsByCategoryStore.find(category);
+ if (ct != sSpellsByCategoryStore.end())
+ {
+ for (auto const& cooldownPair : _spellCooldowns)
+ {
+ uint32 categorySpell = cooldownPair.first;
+ if (!ct->second.count(categorySpell))
+ continue;
+
+ if (categorySpell == spellInfo->Id) // skip main spell, already handled above
+ continue;
+
+ SpellInfo const* spellInfo2 = sSpellMgr->AssertSpellInfo(categorySpell);
+ if (!spellInfo2->IsCooldownStartedOnEvent())
+ continue;
+
+ player->SendDirectMessage(WorldPackets::Spells::CooldownEvent(_owner->GetGUID(), categorySpell).Write());
+ }
+ }
+ }
+ }
+}
+
+void SpellHistory::AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point cooldownEnd, bool onHold /*= false*/)
+{
+ CooldownEntry& cooldownEntry = _spellCooldowns[spellId];
+ cooldownEntry.CooldownEnd = cooldownEnd;
+ cooldownEntry.ItemId = itemId;
+ cooldownEntry.OnHold = onHold;
+}
+
+void SpellHistory::ModifyCooldown(uint32 spellId, int32 cooldownModMs)
+{
+ auto itr = _spellCooldowns.find(spellId);
+ if (!cooldownModMs || itr == _spellCooldowns.end())
+ return;
+
+ Clock::time_point now = Clock::now();
+ Clock::duration offset = std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(cooldownModMs));
+ if (itr->second.CooldownEnd + offset > now)
+ itr->second.CooldownEnd += offset;
+ else
+ _spellCooldowns.erase(itr);
+
+ if (Player* playerOwner = GetPlayerOwner())
+ {
+ WorldPackets::Spells::ModifyCooldown modifyCooldown;
+ modifyCooldown.UnitGUID = _owner->GetGUID();
+ modifyCooldown.SpellID = spellId;
+ modifyCooldown.DeltaTime = cooldownModMs;
+ playerOwner->SendDirectMessage(modifyCooldown.Write());
+ }
+}
+
+void SpellHistory::ResetCooldown(uint32 spellId, bool update /*= false*/)
+{
+ auto itr = _spellCooldowns.find(spellId);
+ if (itr == _spellCooldowns.end())
+ return;
+
+ ResetCooldown(itr, update);
+}
+
+void SpellHistory::ResetCooldown(CooldownStorageType::iterator& itr, bool update /*= false*/)
+{
+ if (update)
+ {
+ if (Player* playerOwner = GetPlayerOwner())
+ {
+ WorldPackets::Spells::ClearCooldown clearCooldown;
+ clearCooldown.CasterGUID = _owner->GetGUID();
+ clearCooldown.SpellID = itr->first;
+ clearCooldown.ClearOnHold = false;
+ playerOwner->SendDirectMessage(clearCooldown.Write());
+ }
+ }
+
+ itr = _spellCooldowns.erase(itr);
+}
+
+void SpellHistory::ResetAllCooldowns()
+{
+ if (Player* playerOwner = GetPlayerOwner())
+ {
+ std::vector<int32> cooldowns;
+ cooldowns.reserve(_spellCooldowns.size());
+ for (auto const& p : _spellCooldowns)
+ cooldowns.push_back(p.first);
+
+ SendClearCooldowns(cooldowns);
+ }
+
+ _spellCooldowns.clear();
+}
+
+bool SpellHistory::HasCooldown(uint32 spellId) const
+{
+ return _spellCooldowns.count(spellId) != 0;
+}
+
+uint32 SpellHistory::GetRemainingCooldown(uint32 spellId) const
+{
+ auto itr = _spellCooldowns.find(spellId);
+ if (itr == _spellCooldowns.end())
+ return 0;
+
+ Clock::time_point now = Clock::now();
+ if (itr->second.CooldownEnd < now)
+ return 0;
+
+ Clock::duration remaining = itr->second.CooldownEnd - now;
+ return uint32(std::chrono::duration_cast<std::chrono::milliseconds>(remaining).count());
+}
+
+void SpellHistory::LockSpellSchool(SpellSchoolMask schoolMask, uint32 lockoutTime)
+{
+ Clock::time_point lockoutEnd = Clock::now() + std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(lockoutTime));
+ for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i)
+ if (SpellSchoolMask(1 << i) & schoolMask)
+ _schoolLockouts[i] = lockoutEnd;
+
+ std::set<uint32> knownSpells;
+ if (Player* plrOwner = _owner->ToPlayer())
+ {
+ for (auto const& p : plrOwner->GetSpellMap())
+ if (p.second->state != PLAYERSPELL_REMOVED)
+ knownSpells.insert(p.first);
+ }
+ else if (Pet* petOwner = _owner->ToPet())
+ {
+ for (auto const& p : petOwner->m_spells)
+ if (p.second.state != PLAYERSPELL_REMOVED)
+ knownSpells.insert(p.first);
+ }
+ else
+ {
+ Creature* creatureOwner = _owner->ToCreature();
+ for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ if (creatureOwner->m_spells[i])
+ knownSpells.insert(creatureOwner->m_spells[i]);
+ }
+
+ WorldPackets::Spells::SpellCooldown spellCooldown;
+ spellCooldown.Caster = _owner->GetGUID();
+ spellCooldown.Flags = SPELL_COOLDOWN_FLAG_NONE;
+ for (uint32 spellId : knownSpells)
+ {
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(spellId);
+ if (spellInfo->IsCooldownStartedOnEvent())
+ continue;
+
+ if (spellInfo->PreventionType != SPELL_PREVENTION_TYPE_SILENCE)
+ continue;
+
+ if ((schoolMask & spellInfo->GetSchoolMask()) && GetRemainingCooldown(spellId) < lockoutTime)
+ {
+ spellCooldown.SpellCooldowns.emplace_back(spellId, lockoutTime);
+ AddCooldown(spellId, 0, lockoutEnd);
+ }
+ }
+
+ if (Player* player = GetPlayerOwner())
+ if (!spellCooldown.SpellCooldowns.empty())
+ player->SendDirectMessage(spellCooldown.Write());
+}
+
+bool SpellHistory::IsSchoolLocked(SpellSchoolMask schoolMask) const
+{
+ Clock::time_point now = Clock::now();
+ for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i)
+ if (SpellSchoolMask(1 << i) & schoolMask)
+ if (_schoolLockouts[i] > now)
+ return true;
+
+ return false;
+}
+
+bool SpellHistory::ConsumeCharge(SpellCategoryEntry const* chargeCategoryEntry)
+{
+ if (!chargeCategoryEntry)
+ return false;
+
+ int32 chargeRecovery = GetChargeRecoveryTime(chargeCategoryEntry);
+ if (chargeRecovery > 0 && GetMaxCharges(chargeCategoryEntry) > 0)
+ {
+ Clock::time_point recoveryStart;
+ std::deque<ChargeEntry>& charges = _categoryCharges[chargeCategoryEntry->ID];
+ if (charges.empty())
+ recoveryStart = Clock::now();
+ else
+ recoveryStart = charges.back().RechargeEnd;
+
+ charges.emplace_back(recoveryStart, std::chrono::milliseconds(chargeRecovery));
+ return true;
+ }
+
+ return false;
+}
+
+void SpellHistory::RestoreCharge(SpellCategoryEntry const* chargeCategoryEntry)
+{
+ if (!chargeCategoryEntry)
+ return;
+
+ auto itr = _categoryCharges.find(chargeCategoryEntry->ID);
+ if (itr != _categoryCharges.end() && !itr->second.empty())
+ {
+ itr->second.pop_back();
+
+ if (Player* player = GetPlayerOwner())
+ {
+ int32 maxCharges = GetMaxCharges(chargeCategoryEntry);
+ int32 usedCharges = itr->second.size();
+ float count = float(maxCharges - usedCharges);
+ if (usedCharges)
+ {
+ ChargeEntry& charge = itr->second.front();
+ std::chrono::milliseconds remaining = std::chrono::duration_cast<std::chrono::milliseconds>(charge.RechargeEnd - Clock::now());
+ std::chrono::milliseconds recharge = std::chrono::duration_cast<std::chrono::milliseconds>(charge.RechargeEnd - charge.RechargeStart);
+ count += 1.0f - float(remaining.count()) / float(recharge.count());
+ }
+
+ WorldPackets::Spells::SetSpellCharges setSpellCharges;
+ setSpellCharges.IsPet = player == _owner;
+ setSpellCharges.Count = count;
+ setSpellCharges.Category = chargeCategoryEntry->ID;
+ player->SendDirectMessage(setSpellCharges.Write());
+ }
+ }
+}
+
+void SpellHistory::ResetCharges(SpellCategoryEntry const* chargeCategoryEntry)
+{
+ if (!chargeCategoryEntry)
+ return;
+
+ auto itr = _categoryCharges.find(chargeCategoryEntry->ID);
+ if (itr != _categoryCharges.end())
+ {
+ _categoryCharges.erase(itr);
+
+ if (Player* player = GetPlayerOwner())
+ {
+ WorldPackets::Spells::ClearSpellCharges clearSpellCharges;
+ clearSpellCharges.Unit = _owner->GetGUID();
+ clearSpellCharges.Category = chargeCategoryEntry->ID;
+ player->SendDirectMessage(clearSpellCharges.Write());
+ }
+ }
+}
+
+void SpellHistory::ResetAllCharges()
+{
+ _categoryCharges.clear();
+
+ if (Player* player = GetPlayerOwner())
+ {
+ WorldPackets::Spells::ClearAllSpellCharges clearAllSpellCharges;
+ clearAllSpellCharges.Unit = _owner->GetGUID();
+ player->SendDirectMessage(clearAllSpellCharges.Write());
+ }
+}
+
+bool SpellHistory::HasCharge(SpellCategoryEntry const* chargeCategoryEntry) const
+{
+ if (!chargeCategoryEntry)
+ return true;
+
+ // Check if the spell is currently using charges (untalented warlock Dark Soul)
+ int32 maxCharges = GetMaxCharges(chargeCategoryEntry);
+ if (maxCharges <= 0)
+ return true;
+
+ auto itr = _categoryCharges.find(chargeCategoryEntry->ID);
+ return itr == _categoryCharges.end() || itr->second.size() < maxCharges;
+}
+
+int32 SpellHistory::GetMaxCharges(SpellCategoryEntry const* chargeCategoryEntry) const
+{
+ if (!chargeCategoryEntry)
+ return 0;
+
+ uint32 charges = chargeCategoryEntry->MaxCharges;
+ charges += _owner->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MAX_CHARGES, chargeCategoryEntry->ID);
+ return charges;
+}
+
+int32 SpellHistory::GetChargeRecoveryTime(SpellCategoryEntry const* chargeCategoryEntry) const
+{
+ if (!chargeCategoryEntry)
+ return 0;
+
+ int32 recoveryTime = chargeCategoryEntry->ChargeRecoveryTime;
+ recoveryTime += _owner->GetTotalAuraModifierByMiscValue(SPELL_AURA_CHARGE_RECOVERY_MOD, chargeCategoryEntry->ID);
+
+ float recoveryTimeF = recoveryTime;
+ recoveryTimeF *= _owner->GetTotalAuraMultiplierByMiscValue(SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER, chargeCategoryEntry->ID);
+
+ if (_owner->HasAuraType(SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE))
+ recoveryTimeF *= _owner->GetFloatValue(UNIT_MOD_CAST_HASTE);
+
+ if (_owner->HasAuraType(SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE_REGEN))
+ recoveryTimeF *= _owner->GetFloatValue(UNIT_FIELD_MOD_HASTE_REGEN);
+
+ return int32(std::floor(recoveryTimeF));
+}
+
+bool SpellHistory::HasGlobalCooldown(SpellInfo const* spellInfo) const
+{
+ auto itr = _globalCooldowns.find(spellInfo->StartRecoveryCategory);
+ return itr != _globalCooldowns.end() && itr->second > Clock::now();
+}
+
+void SpellHistory::AddGlobalCooldown(SpellInfo const* spellInfo, uint32 duration)
+{
+ _globalCooldowns[spellInfo->StartRecoveryCategory] = Clock::now() + std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(duration));
+}
+
+void SpellHistory::CancelGlobalCooldown(SpellInfo const* spellInfo)
+{
+ _globalCooldowns[spellInfo->StartRecoveryCategory] = Clock::time_point(Clock::duration(0));
+}
+
+Player* SpellHistory::GetPlayerOwner() const
+{
+ return _owner->GetCharmerOrOwnerPlayerOrPlayerItself();
+}
+
+void SpellHistory::SendClearCooldowns(std::vector<int32> const& cooldowns) const
+{
+ if (Player const* playerOwner = GetPlayerOwner())
+ {
+ WorldPackets::Spells::ClearCooldowns clearCooldowns;
+ clearCooldowns.Guid = _owner->GetGUID();
+ clearCooldowns.SpellID = cooldowns;
+ playerOwner->SendDirectMessage(clearCooldowns.Write());
+ }
+}
+
+template void SpellHistory::LoadFromDB<Player>(PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult);
+template void SpellHistory::LoadFromDB<Pet>(PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult);
+template void SpellHistory::SaveToDB<Player>(SQLTransaction& trans);
+template void SpellHistory::SaveToDB<Pet>(SQLTransaction& trans);
diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h
new file mode 100644
index 00000000000..38ae922750c
--- /dev/null
+++ b/src/server/game/Spells/SpellHistory.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SpellHistory_h__
+#define SpellHistory_h__
+
+#include "SharedDefines.h"
+#include "QueryResult.h"
+#include "Transaction.h"
+#include <chrono>
+#include <deque>
+
+class Item;
+class Player;
+class Spell;
+class SpellInfo;
+class Unit;
+struct SpellCategoryEntry;
+
+/// Spell cooldown flags sent in SMSG_SPELL_COOLDOWN
+enum SpellCooldownFlags
+{
+ SPELL_COOLDOWN_FLAG_NONE = 0x0,
+ SPELL_COOLDOWN_FLAG_INCLUDE_GCD = 0x1, ///< Starts GCD in addition to normal cooldown specified in the packet
+ SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS = 0x2 ///< Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUDE_GCD set
+};
+
+class SpellHistory
+{
+public:
+ typedef std::chrono::system_clock Clock;
+
+ struct CooldownEntry
+ {
+ CooldownEntry() : ItemId(0), OnHold(false) { }
+ CooldownEntry(Clock::time_point endTime, uint32 itemId) : CooldownEnd(endTime), ItemId(itemId), OnHold(false) { }
+
+ Clock::time_point CooldownEnd;
+ uint32 ItemId;
+ bool OnHold;
+ };
+
+ struct ChargeEntry
+ {
+ ChargeEntry() { }
+ ChargeEntry(Clock::time_point startTime, std::chrono::milliseconds rechargeTime) : RechargeStart(startTime), RechargeEnd(startTime + rechargeTime) { }
+ ChargeEntry(Clock::time_point startTime, Clock::time_point endTime) : RechargeStart(startTime), RechargeEnd(endTime) { }
+
+ Clock::time_point RechargeStart;
+ Clock::time_point RechargeEnd;
+ };
+
+ typedef std::unordered_map<uint32 /*spellId*/, CooldownEntry> CooldownStorageType;
+ typedef std::unordered_map<uint32 /*categoryId*/, std::deque<ChargeEntry>> ChargeStorageType;
+ typedef std::unordered_map<uint32 /*categoryId*/, Clock::time_point> GlobalCooldownStorageType;
+
+ explicit SpellHistory(Unit* owner) : _owner(owner), _schoolLockouts() { }
+
+ template<class OwnerType>
+ void LoadFromDB(PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult);
+
+ template<class OwnerType>
+ void SaveToDB(SQLTransaction& trans);
+
+ void Update();
+
+ void HandleCooldowns(SpellInfo const* spellInfo, Item const* item, Spell* spell = nullptr);
+ bool IsReady(SpellInfo const* spellInfo) const;
+ template<class PacketType>
+ void WritePacket(PacketType* packet) const;
+
+ // Cooldowns
+ static Clock::duration const InfinityCooldownDelay; // used for set "infinity cooldowns" for spells and check
+
+ void StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = nullptr, bool onHold = false);
+ void SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId = 0, Spell* spell = nullptr, bool startCooldown = true);
+
+ template<class Type, class Period>
+ void AddCooldown(uint32 spellId, uint32 itemId, std::chrono::duration<Type, Period> cooldownDuration)
+ {
+ AddCooldown(spellId, itemId, Clock::now() + std::chrono::duration_cast<Clock::duration>(cooldownDuration));
+ }
+
+ void AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point cooldownEnd, bool onHold = false);
+ void ModifyCooldown(uint32 spellId, int32 cooldownModMs);
+ void ResetCooldown(uint32 spellId, bool update = false);
+ void ResetCooldown(CooldownStorageType::iterator& itr, bool update = false);
+ template<typename Predicate>
+ void ResetCooldowns(Predicate predicate, bool update = false)
+ {
+ std::vector<int32> resetCooldowns;
+ resetCooldowns.reserve(_spellCooldowns.size());
+ for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();)
+ {
+ if (predicate(itr))
+ ResetCooldown(itr, false);
+ else
+ ++itr;
+ }
+
+ if (update && !resetCooldowns.empty())
+ SendClearCooldowns(resetCooldowns);
+ }
+
+ void ResetAllCooldowns();
+ bool HasCooldown(uint32 spellId) const;
+ uint32 GetRemainingCooldown(uint32 spellId) const;
+
+ // School lockouts
+ void LockSpellSchool(SpellSchoolMask schoolMask, uint32 lockoutTime);
+ bool IsSchoolLocked(SpellSchoolMask schoolMask) const;
+
+ // Charges
+ bool ConsumeCharge(SpellCategoryEntry const* chargeCategoryEntry);
+ void RestoreCharge(SpellCategoryEntry const* chargeCategoryEntry);
+ void ResetCharges(SpellCategoryEntry const* chargeCategoryEntry);
+ void ResetAllCharges();
+ bool HasCharge(SpellCategoryEntry const* chargeCategoryEntry) const;
+ int32 GetMaxCharges(SpellCategoryEntry const* chargeCategoryEntry) const;
+ int32 GetChargeRecoveryTime(SpellCategoryEntry const* chargeCategoryEntry) const;
+
+ // Global cooldown
+ bool HasGlobalCooldown(SpellInfo const* spellInfo) const;
+ void AddGlobalCooldown(SpellInfo const* spellInfo, uint32 duration);
+ void CancelGlobalCooldown(SpellInfo const* spellInfo);
+
+private:
+ Player* GetPlayerOwner() const;
+ void SendClearCooldowns(std::vector<int32> const& cooldowns) const;
+
+ Unit* _owner;
+ CooldownStorageType _spellCooldowns;
+ Clock::time_point _schoolLockouts[MAX_SPELL_SCHOOL];
+ ChargeStorageType _categoryCharges;
+ GlobalCooldownStorageType _globalCooldowns;
+
+ template<class T>
+ struct PersistenceHelper { };
+};
+
+#endif // SpellHistory_h__
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index a70c73de6df..6abb007c999 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -942,23 +942,20 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] =
{EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 244 SPELL_EFFECT_244
};
-SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap effects)
+SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& effectsMap)
{
Id = spellEntry->ID;
// SpellDifficultyEntry
- for (SpellEffectEntryMap::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
+ for (SpellEffectEntryMap::value_type const& itr : effectsMap)
{
- SpellEffectEntryVector effects = itr->second;
- _effects[itr->first].resize(effects.size());
+ SpellEffectEntryVector const& effects = itr.second;
+ _effects[itr.first].resize(effects.size());
- for (uint32 i = effects.size(); i > 0; --i)
+ for (size_t i = 0; i < effects.size(); ++i)
{
- SpellEffectEntry const* effect = effects[i - 1];
- if (!effect)
- continue;
-
- _effects[itr->first][effect->EffectIndex] = new SpellEffectInfo(spellEntry, this, effect->EffectIndex, effect);
+ if (SpellEffectEntry const* effect = effects[i])
+ _effects[itr.first][effect->EffectIndex] = new SpellEffectInfo(spellEntry, this, effect->EffectIndex, effect);
}
}
@@ -1054,6 +1051,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap effects)
StartRecoveryCategory = _categorie ? _categorie->StartRecoveryCategory : 0;
DmgClass = _categorie ? _categorie->DefenseType : 0;
PreventionType = _categorie ? _categorie->PreventionType : 0;
+ ChargeCategoryEntry = _categorie ? sSpellCategoryStore.LookupEntry(_categorie->ChargeCategory) : 0;
// SpellClassOptionsEntry
SpellClassOptionsEntry const* _class = GetSpellClassOptions();
@@ -1127,6 +1125,15 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap effects)
SpellInfo::~SpellInfo()
{
_UnloadImplicitTargetConditionLists();
+ _UnloadSpellEffects();
+}
+
+void SpellInfo::_UnloadSpellEffects()
+{
+ for (SpellEffectInfoMap::value_type& i : _effects)
+ for (size_t j = 0; j < i.second.size(); ++j)
+ delete i.second[j];
+ _effects.clear();
}
uint32 SpellInfo::GetCategory() const
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index b585588726e..9e39e88d9d3 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -399,6 +399,7 @@ public:
uint32 PreventionType;
int32 RequiredAreasID;
uint32 SchoolMask;
+ SpellCategoryEntry const* ChargeCategoryEntry;
uint32 SpellDifficultyId;
uint32 SpellScalingId;
uint32 SpellAuraOptionsId;
@@ -449,7 +450,7 @@ public:
SpellTotemsEntry const* GetSpellTotems() const;
SpellMiscEntry const* GetSpellMisc() const;
- SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap effects);
+ SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& effectsMap);
~SpellInfo();
uint32 GetCategory() const;
@@ -571,6 +572,7 @@ public:
// unloading helpers
void _UnloadImplicitTargetConditionLists();
+ void _UnloadSpellEffects();
SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const;
SpellEffectInfo const* GetEffect(uint32 difficulty, uint32 index) const;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index c2f482570a1..fff5263bdde 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -925,11 +925,11 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_INSTANCE_UNLOAD_DELAY] = sConfigMgr->GetIntDefault("Instance.UnloadDelay", 30 * MINUTE * IN_MILLISECONDS);
m_int_configs[CONFIG_MAX_PRIMARY_TRADE_SKILL] = sConfigMgr->GetIntDefault("MaxPrimaryTradeSkill", 2);
- m_int_configs[CONFIG_MIN_PETITION_SIGNS] = sConfigMgr->GetIntDefault("MinPetitionSigns", 9);
- if (m_int_configs[CONFIG_MIN_PETITION_SIGNS] > 9)
+ m_int_configs[CONFIG_MIN_PETITION_SIGNS] = sConfigMgr->GetIntDefault("MinPetitionSigns", 4);
+ if (m_int_configs[CONFIG_MIN_PETITION_SIGNS] > 4)
{
- TC_LOG_ERROR("server.loading", "MinPetitionSigns (%i) must be in range 0..9. Set to 9.", m_int_configs[CONFIG_MIN_PETITION_SIGNS]);
- m_int_configs[CONFIG_MIN_PETITION_SIGNS] = 9;
+ TC_LOG_ERROR("server.loading", "MinPetitionSigns (%i) must be in range 0..4. Set to 4.", m_int_configs[CONFIG_MIN_PETITION_SIGNS]);
+ m_int_configs[CONFIG_MIN_PETITION_SIGNS] = 4;
}
m_int_configs[CONFIG_GM_LOGIN_STATE] = sConfigMgr->GetIntDefault("GM.LoginState", 2);
@@ -1329,13 +1329,8 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_DB_PING_INTERVAL] = sConfigMgr->GetIntDefault("MaxPingTime", 30);
// Guild save interval
- m_bool_configs[CONFIG_GUILD_LEVELING_ENABLED] = sConfigMgr->GetBoolDefault("Guild.LevelingEnabled", true);
m_int_configs[CONFIG_GUILD_SAVE_INTERVAL] = sConfigMgr->GetIntDefault("Guild.SaveInterval", 15);
- m_int_configs[CONFIG_GUILD_MAX_LEVEL] = sConfigMgr->GetIntDefault("Guild.MaxLevel", 25);
m_int_configs[CONFIG_GUILD_UNDELETABLE_LEVEL] = sConfigMgr->GetIntDefault("Guild.UndeletableLevel", 4);
- rate_values[RATE_XP_GUILD_MODIFIER] = sConfigMgr->GetFloatDefault("Guild.XPModifier", 0.25f);
- m_int_configs[CONFIG_GUILD_DAILY_XP_CAP] = sConfigMgr->GetIntDefault("Guild.DailyXPCap", 7807500);
- m_int_configs[CONFIG_GUILD_WEEKLY_REP_CAP] = sConfigMgr->GetIntDefault("Guild.WeeklyReputationCap", 4375);
// misc
m_bool_configs[CONFIG_PDUMP_NO_PATHS] = sConfigMgr->GetBoolDefault("PlayerDump.DisallowPaths", true);
@@ -1736,9 +1731,6 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Auctions...");
sAuctionMgr->LoadAuctions();
- TC_LOG_INFO("server.loading", "Loading Guild XP for level...");
- sGuildMgr->LoadGuildXpForLevel();
-
TC_LOG_INFO("server.loading", "Loading Guild rewards...");
sGuildMgr->LoadGuildRewards();
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index c30d4f6ca35..120c96b2073 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -164,7 +164,6 @@ enum WorldBoolConfigs
CONFIG_WARDEN_ENABLED,
CONFIG_ENABLE_MMAPS,
CONFIG_WINTERGRASP_ENABLE,
- CONFIG_GUILD_LEVELING_ENABLED,
CONFIG_UI_QUESTLEVELS_IN_DIALOGS, // Should we add quest levels to the title in the NPC dialogs?
CONFIG_EVENT_ANNOUNCE,
CONFIG_STATS_LIMITS_ENABLE,
@@ -350,10 +349,7 @@ enum WorldIntConfigs
CONFIG_WINTERGRASP_NOBATTLETIME,
CONFIG_WINTERGRASP_RESTART_AFTER_CRASH,
CONFIG_GUILD_SAVE_INTERVAL,
- CONFIG_GUILD_MAX_LEVEL,
CONFIG_GUILD_UNDELETABLE_LEVEL,
- CONFIG_GUILD_DAILY_XP_CAP,
- CONFIG_GUILD_WEEKLY_REP_CAP,
CONFIG_PACKET_SPOOF_POLICY,
CONFIG_PACKET_SPOOF_BANMODE,
CONFIG_PACKET_SPOOF_BANDURATION,
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 889b24480e6..65b2d20c9d2 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -36,6 +36,7 @@
#include "GroupMgr.h"
#include "MMapFactory.h"
#include "DisableMgr.h"
+#include "SpellHistory.h"
class misc_commandscript : public CommandScript
{
@@ -713,7 +714,8 @@ public:
if (!*args)
{
- target->RemoveAllSpellCooldown();
+ target->GetSpellHistory()->ResetAllCooldowns();
+ target->GetSpellHistory()->ResetAllCharges();
handler->PSendSysMessage(LANG_REMOVEALL_COOLDOWN, nameLink.c_str());
}
else
@@ -723,14 +725,16 @@ public:
if (!spellIid)
return false;
- if (!sSpellMgr->GetSpellInfo(spellIid))
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellIid);
+ if (!spellInfo)
{
handler->PSendSysMessage(LANG_UNKNOWN_SPELL, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str());
handler->SetSentErrorMessage(true);
return false;
}
- target->RemoveSpellCooldown(spellIid, true);
+ target->GetSpellHistory()->ResetCooldown(spellIid, true);
+ target->GetSpellHistory()->ResetCharges(spellInfo->ChargeCategoryEntry);
handler->PSendSysMessage(LANG_REMOVE_COOLDOWN, spellIid, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str());
}
return true;
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
index 97c4372f0e6..0b829c2c6dd 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
@@ -27,7 +27,7 @@ enum Yells
SAY_SLAY = 1,
SAY_DEATH = 2,
SAY_SOUL_STORM = 3,
- SAY_CORRUPT_SOUL = 4,
+ SAY_CORRUPT_SOUL = 4
};
enum Spells
@@ -39,9 +39,9 @@ enum Spells
SPELL_TELEPORT = 68988,
SPELL_FEAR = 68950,
SPELL_SOULSTORM = 68872,
- SPELL_SOULSTORM_CHANNEL = 69008, // pre-fight
- SPELL_SOULSTORM_VISUAL = 68870, // pre-cast soulstorm
- SPELL_PURPLE_BANISH_VISUAL = 68862 // Used by Soul Fragment (Aura)
+ SPELL_SOULSTORM_CHANNEL = 69008, // Pre-fight
+ SPELL_SOULSTORM_VISUAL = 68870, // Pre-cast Soulstorm
+ SPELL_PURPLE_BANISH_VISUAL = 68862 // Used by Soul Fragment (Aura)
};
enum Events
@@ -50,7 +50,7 @@ enum Events
EVENT_SHADOW_BOLT = 2,
EVENT_CORRUPT_SOUL = 3,
EVENT_SOULSTORM = 4,
- EVENT_FEAR = 5,
+ EVENT_FEAR = 5
};
enum CombatPhases
@@ -59,6 +59,11 @@ enum CombatPhases
PHASE_2 = 2
};
+enum Misc
+{
+ DATA_SOUL_POWER = 1
+};
+
class boss_bronjahm : public CreatureScript
{
public:
@@ -73,33 +78,30 @@ class boss_bronjahm : public CreatureScript
void Reset() override
{
- events.Reset();
+ _Reset();
events.SetPhase(PHASE_1);
events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000);
events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 20000));
events.ScheduleEvent(EVENT_CORRUPT_SOUL, urand(25000, 35000), 0, PHASE_1);
-
- instance->SetBossState(DATA_BRONJAHM, NOT_STARTED);
}
- void JustReachedHome() override
- {
- DoCast(me, SPELL_SOULSTORM_CHANNEL, true);
- }
+ void JustReachedHome() override
+ {
+ _JustReachedHome();
+ DoCast(me, SPELL_SOULSTORM_CHANNEL, true);
+ }
void EnterCombat(Unit* /*who*/) override
{
+ _EnterCombat();
Talk(SAY_AGGRO);
me->RemoveAurasDueToSpell(SPELL_SOULSTORM_CHANNEL);
-
- instance->SetBossState(DATA_BRONJAHM, IN_PROGRESS);
}
void JustDied(Unit* /*killer*/) override
{
+ _JustDied();
Talk(SAY_DEATH);
-
- instance->SetBossState(DATA_BRONJAHM, DONE);
}
void KilledUnit(Unit* who) override
@@ -128,6 +130,23 @@ class boss_bronjahm : public CreatureScript
summon->CastSpell(summon, SPELL_PURPLE_BANISH_VISUAL, true);
}
+ uint32 GetData(uint32 type) const override
+ {
+ if (type == DATA_SOUL_POWER)
+ {
+ uint32 count = 0;
+ for (ObjectGuid const& guid : summons)
+ {
+ if (Creature* summon = ObjectAccessor::GetCreature(*me, guid))
+ if (summon->GetEntry() == NPC_CORRUPTED_SOUL_FRAGMENT && summon->IsAlive())
+ ++count;
+ }
+ return count;
+ }
+
+ return 0;
+ }
+
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
@@ -143,13 +162,21 @@ class boss_bronjahm : public CreatureScript
switch (eventId)
{
case EVENT_MAGIC_BANE:
- DoCastVictim(SPELL_MAGIC_S_BANE);
+ DoCastAOE(SPELL_MAGIC_S_BANE);
events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 20000));
break;
case EVENT_SHADOW_BOLT:
- if (!me->IsWithinMeleeRange(me->GetVictim()))
+ if (events.IsInPhase(PHASE_2))
+ {
DoCastVictim(SPELL_SHADOW_BOLT);
- events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(1, 2) * IN_MILLISECONDS);
+ }
+ else
+ {
+ if (!me->IsWithinMeleeRange(me->GetVictim()))
+ DoCastVictim(SPELL_SHADOW_BOLT);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 2 * IN_MILLISECONDS);
+ }
break;
case EVENT_CORRUPT_SOUL:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
@@ -165,8 +192,7 @@ class boss_bronjahm : public CreatureScript
me->CastSpell(me, SPELL_SOULSTORM, false);
break;
case EVENT_FEAR:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
- me->CastCustomSpell(SPELL_FEAR, SPELLVALUE_MAX_TARGETS, 1, target, false);
+ me->CastCustomSpell(SPELL_FEAR, SPELLVALUE_MAX_TARGETS, 1, nullptr, false);
events.ScheduleEvent(EVENT_FEAR, urand(8000, 12000), 0, PHASE_2);
break;
default:
@@ -174,7 +200,8 @@ class boss_bronjahm : public CreatureScript
}
}
- DoMeleeAttackIfReady();
+ if (!events.IsInPhase(PHASE_2))
+ DoMeleeAttackIfReady();
}
};
@@ -201,17 +228,11 @@ class npc_corrupted_soul_fragment : public CreatureScript
if (type != CHASE_MOTION_TYPE)
return;
- if (TempSummon* summ = me->ToTempSummon())
- {
- ObjectGuid BronjahmGUID(instance->GetGuidData(DATA_BRONJAHM));
- if (BronjahmGUID.GetCounter() != id)
- return;
-
- if (Creature* bronjahm = ObjectAccessor::GetCreature(*me, BronjahmGUID))
- me->CastSpell(bronjahm, SPELL_CONSUME_SOUL, true);
+ if (instance->GetGuidData(DATA_BRONJAHM).GetCounter() != id)
+ return;
- summ->UnSummon();
- }
+ me->CastSpell((Unit*)nullptr, SPELL_CONSUME_SOUL, true);
+ me->DespawnOrUnsummon();
}
private:
@@ -220,7 +241,7 @@ class npc_corrupted_soul_fragment : public CreatureScript
CreatureAI* GetAI(Creature* creature) const override
{
- return GetInstanceAI<npc_corrupted_soul_fragmentAI>(creature);
+ return GetInstanceAI<npc_corrupted_soul_fragmentAI>(creature, FoSScriptName);
}
};
@@ -238,12 +259,10 @@ class spell_bronjahm_magic_bane : public SpellScriptLoader
if (GetHitUnit()->getPowerType() != POWER_MANA)
return;
- const int32 maxDamage = GetCaster()->GetMap()->GetSpawnMode() == 1 ? 15000 : 10000;
- int32 newDamage = GetHitDamage();
- newDamage += GetHitUnit()->GetMaxPower(POWER_MANA)/2;
- newDamage = std::min<int32>(maxDamage, newDamage);
+ int32 const maxDamage = GetCaster()->GetMap()->IsHeroic() ? 15000 : 10000;
+ int32 newDamage = GetHitDamage() + (GetHitUnit()->GetMaxPower(POWER_MANA) / 2);
- SetHitDamage(newDamage);
+ SetHitDamage(std::min<int32>(maxDamage, newDamage));
}
void Register() override
@@ -261,7 +280,7 @@ class spell_bronjahm_magic_bane : public SpellScriptLoader
class spell_bronjahm_consume_soul : public SpellScriptLoader
{
public:
- spell_bronjahm_consume_soul() : SpellScriptLoader("spell_bronjahm_consume_soul") { }
+ spell_bronjahm_consume_soul() : SpellScriptLoader("spell_bronjahm_consume_soul") { }
class spell_bronjahm_consume_soul_SpellScript : public SpellScript
{
@@ -285,38 +304,22 @@ class spell_bronjahm_consume_soul : public SpellScriptLoader
}
};
-class spell_bronjahm_soulstorm_channel : public SpellScriptLoader
+static uint32 const SoulstormVisualSpells[] =
{
- public:
- spell_bronjahm_soulstorm_channel() : SpellScriptLoader("spell_bronjahm_soulstorm_channel") { }
-
- class spell_bronjahm_soulstorm_channel_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_bronjahm_soulstorm_channel_AuraScript);
-
- void HandlePeriodicTick(AuraEffect const* /*aurEff*/)
- {
- PreventDefaultAction();
- for (uint32 i = 68904; i <= 68907; ++i)
- GetTarget()->CastSpell(GetTarget(), i, true);
- }
-
- void Register() override
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_bronjahm_soulstorm_channel_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_bronjahm_soulstorm_channel_AuraScript();
- }
+ 68904,
+ 68886,
+ 68905,
+ 68896,
+ 68906,
+ 68897,
+ 68907,
+ 68898
};
class spell_bronjahm_soulstorm_visual : public SpellScriptLoader
{
public:
- spell_bronjahm_soulstorm_visual() : SpellScriptLoader("spell_bronjahm_soulstorm_visual") { }
+ spell_bronjahm_soulstorm_visual(char const* scriptName) : SpellScriptLoader(scriptName) { }
class spell_bronjahm_soulstorm_visual_AuraScript : public AuraScript
{
@@ -325,11 +328,7 @@ class spell_bronjahm_soulstorm_visual : public SpellScriptLoader
void HandlePeriodicTick(AuraEffect const* aurEff)
{
PreventDefaultAction();
- if (aurEff->GetTickNumber()%5)
- return;
- GetTarget()->CastSpell(GetTarget(), 68886, true);
- for (uint32 i = 68896; i <= 68898; ++i)
- GetTarget()->CastSpell(GetTarget(), i, true);
+ GetTarget()->CastSpell(GetTarget(), SoulstormVisualSpells[aurEff->GetTickNumber() % 8], true);
}
void Register() override
@@ -344,21 +343,6 @@ class spell_bronjahm_soulstorm_visual : public SpellScriptLoader
}
};
-class DistanceCheck
-{
- public:
- explicit DistanceCheck(Unit* _caster) : caster(_caster) { }
-
- bool operator() (WorldObject* unit) const
- {
- if (caster->GetExactDist2d(unit) <= 10.0f)
- return true;
- return false;
- }
-
- Unit* caster;
-};
-
class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader
{
public:
@@ -368,25 +352,19 @@ class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader
{
PrepareSpellScript(spell_bronjahm_soulstorm_targeting_SpellScript);
- void FilterTargetsInitial(std::list<WorldObject*>& targets)
- {
- targets.remove_if(DistanceCheck(GetCaster()));
- sharedTargets = targets;
- }
-
- // use the same target for first and second effect
- void FilterTargetsSubsequent(std::list<WorldObject*>& targets)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- targets = sharedTargets;
+ Unit* caster = GetCaster();
+ targets.remove_if([caster](WorldObject* target)
+ {
+ return caster->GetExactDist2d(target) <= 10.0f;
+ });
}
void Register() override
{
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsInitial, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_2, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY);
}
-
- std::list<WorldObject*> sharedTargets;
};
SpellScript* GetSpellScript() const override
@@ -395,13 +373,25 @@ class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader
}
};
+class achievement_bronjahm_soul_power : public AchievementCriteriaScript
+{
+ public:
+ achievement_bronjahm_soul_power() : AchievementCriteriaScript("achievement_bronjahm_soul_power") { }
+
+ bool OnCheck(Player* /*source*/, Unit* target) override
+ {
+ return target && target->GetAI()->GetData(DATA_SOUL_POWER) >= 4;
+ }
+};
+
void AddSC_boss_bronjahm()
{
new boss_bronjahm();
new npc_corrupted_soul_fragment();
new spell_bronjahm_magic_bane();
new spell_bronjahm_consume_soul();
- new spell_bronjahm_soulstorm_channel();
- new spell_bronjahm_soulstorm_visual();
+ new spell_bronjahm_soulstorm_visual("spell_bronjahm_soulstorm_channel");
+ new spell_bronjahm_soulstorm_visual("spell_bronjahm_soulstorm_visual");
new spell_bronjahm_soulstorm_targeting();
+ new achievement_bronjahm_soul_power();
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp
index 2f1d4943019..d5f00757039 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp
@@ -128,7 +128,7 @@ class boss_devourer_of_souls : public CreatureScript
struct boss_devourer_of_soulsAI : public BossAI
{
- boss_devourer_of_soulsAI(Creature* creature) : BossAI(creature, DATA_DEVOURER_EVENT)
+ boss_devourer_of_soulsAI(Creature* creature) : BossAI(creature, DATA_DEVOURER_OF_SOULS)
{
Initialize();
beamAngle = 0.f;
@@ -143,20 +143,17 @@ class boss_devourer_of_souls : public CreatureScript
void Reset() override
{
+ _Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
me->SetDisplayId(DISPLAY_ANGER);
me->SetReactState(REACT_AGGRESSIVE);
- events.Reset();
- summons.DespawnAll();
-
Initialize();
-
- instance->SetData(DATA_DEVOURER_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
+ _EnterCombat();
Talk(SAY_FACE_AGGRO);
if (!me->FindNearestCreature(NPC_CRUCIBLE_OF_SOULS, 60)) // Prevent double spawn
@@ -166,8 +163,6 @@ class boss_devourer_of_souls : public CreatureScript
events.ScheduleEvent(EVENT_WELL_OF_SOULS, 30000);
events.ScheduleEvent(EVENT_UNLEASHED_SOULS, 20000);
events.ScheduleEvent(EVENT_WAILING_SOULS, urand(60000, 70000));
-
- instance->SetData(DATA_DEVOURER_EVENT, IN_PROGRESS);
}
void KilledUnit(Unit* victim) override
@@ -175,7 +170,7 @@ class boss_devourer_of_souls : public CreatureScript
if (victim->GetTypeId() != TYPEID_PLAYER)
return;
- int32 textId = 0;
+ uint8 textId = 0;
switch (me->GetDisplayId())
{
case DISPLAY_ANGER:
@@ -197,14 +192,12 @@ class boss_devourer_of_souls : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- summons.DespawnAll();
+ _JustDied();
Position spawnPoint = {5618.139f, 2451.873f, 705.854f, 0};
Talk(SAY_FACE_DEATH);
- instance->SetData(DATA_DEVOURER_EVENT, DONE);
-
int32 entryIndex;
if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
entryIndex = 0;
@@ -402,11 +395,6 @@ class spell_devourer_of_souls_mirrored_soul_proc : public SpellScriptLoader
return true;
}
- bool Load() override
- {
- return true;
- }
-
bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
return GetCaster() && GetCaster()->IsAlive();
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h
index 054e5d5a7bd..ddbc117e7fd 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h
@@ -15,38 +15,44 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef DEF_FORGE_OF_SOULS_H
-#define DEF_FORGE_OF_SOULS_H
+#ifndef FORGE_OF_SOULS_H_
+#define FORGE_OF_SOULS_H_
#define FoSScriptName "instance_forge_of_souls"
#define DataHeader "FOS"
+uint32 const EncounterCount = 2;
+
enum Data
{
- DATA_BRONJAHM = 0,
- DATA_DEVOURER = 1,
- DATA_DEVOURER_EVENT = 2,
- DATA_TEAM_IN_INSTANCE = 3,
+ // Encounter states and GUIDs
+ DATA_BRONJAHM = 0,
+ DATA_DEVOURER_OF_SOULS = 1,
+
+ // Additional Data
+ DATA_TEAM_IN_INSTANCE = 2
};
enum Creatures
{
- CREATURE_BRONJAHM = 36497,
- CREATURE_DEVOURER = 36502,
-
- NPC_SYLVANAS_PART1 = 37596,
- NPC_SYLVANAS_PART2 = 38161,
- NPC_JAINA_PART1 = 37597,
- NPC_JAINA_PART2 = 38160,
- NPC_KALIRA = 37583,
- NPC_ELANDRA = 37774,
- NPC_LORALEN = 37779,
- NPC_KORELN = 37582,
- NPC_CHAMPION_1_HORDE = 37584,
- NPC_CHAMPION_2_HORDE = 37587,
- NPC_CHAMPION_3_HORDE = 37588,
- NPC_CHAMPION_1_ALLIANCE = 37496,
- NPC_CHAMPION_2_ALLIANCE = 37497,
- NPC_CRUCIBLE_OF_SOULS = 37094,
+ NPC_BRONJAHM = 36497,
+ NPC_DEVOURER = 36502,
+ NPC_CORRUPTED_SOUL_FRAGMENT = 36535,
+
+ NPC_SYLVANAS_PART1 = 37596,
+ NPC_SYLVANAS_PART2 = 38161,
+ NPC_JAINA_PART1 = 37597,
+ NPC_JAINA_PART2 = 38160,
+ NPC_KALIRA = 37583,
+ NPC_ELANDRA = 37774,
+ NPC_LORALEN = 37779,
+ NPC_KORELN = 37582,
+ NPC_CHAMPION_1_HORDE = 37584,
+ NPC_CHAMPION_2_HORDE = 37587,
+ NPC_CHAMPION_3_HORDE = 37588,
+ NPC_CHAMPION_1_ALLIANCE = 37496,
+ NPC_CHAMPION_2_ALLIANCE = 37497,
+ NPC_CRUCIBLE_OF_SOULS = 37094
};
-#endif
+
+#endif // FORGE_OF_SOULS_H_
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp
index 8b586ea7fc2..db7628ebada 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp
@@ -20,13 +20,6 @@
#include "forge_of_souls.h"
#include "Player.h"
-#define MAX_ENCOUNTER 2
-
-/* Forge of Souls encounters:
-0- Bronjahm, The Godfather of Souls
-1- The Devourer of Souls
-*/
-
class instance_forge_of_souls : public InstanceMapScript
{
public:
@@ -37,7 +30,7 @@ class instance_forge_of_souls : public InstanceMapScript
instance_forge_of_souls_InstanceScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
- SetBossNumber(MAX_ENCOUNTER);
+ SetBossNumber(EncounterCount);
teamInInstance = 0;
}
@@ -60,10 +53,10 @@ class instance_forge_of_souls : public InstanceMapScript
switch (creature->GetEntry())
{
- case CREATURE_BRONJAHM:
+ case NPC_BRONJAHM:
bronjahm = creature->GetGUID();
break;
- case CREATURE_DEVOURER:
+ case NPC_DEVOURER:
devourerOfSouls = creature->GetGUID();
break;
case NPC_SYLVANAS_PART1:
@@ -100,7 +93,7 @@ class instance_forge_of_souls : public InstanceMapScript
{
case DATA_BRONJAHM:
return bronjahm;
- case DATA_DEVOURER:
+ case DATA_DEVOURER_OF_SOULS:
return devourerOfSouls;
default:
break;
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
index 754b22620d0..511a2044f6a 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
@@ -25,6 +25,7 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
#include "SpellScript.h"
#include "Transport.h"
#include "TransportMgr.h"
@@ -644,10 +645,10 @@ protected:
{
if (Instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS &&
!me->HasUnitState(UNIT_STATE_CASTING) && !me->HasReactState(REACT_PASSIVE) &&
- !me->HasSpellCooldown(BurningPitchId))
+ !me->GetSpellHistory()->HasCooldown(BurningPitchId))
{
DoCastAOE(BurningPitchId, true);
- me->_AddCreatureSpellCooldown(BurningPitchId, time(NULL) + urand(3000, 4000) / IN_MILLISECONDS);
+ me->GetSpellHistory()->AddCooldown(BurningPitchId, 0, std::chrono::milliseconds(urand(3000, 4000)));
}
}
@@ -1469,7 +1470,7 @@ struct npc_gunship_boarding_addAI : public gunship_npc_AI
DoCast(me, SPELL_BATTLE_EXPERIENCE, true);
DoCast(me, SPELL_TELEPORT_TO_ENEMY_SHIP, true);
DoCast(me, Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER : SPELL_MELEE_TARGETING_ON_SKYBREAKER, true);
- me->_AddCreatureSpellCooldown(BurningPitchId, time(NULL) + 3);
+ me->GetSpellHistory()->AddCooldown(BurningPitchId, 0, std::chrono::seconds(3));
std::list<Player*> players;
Trinity::UnitAuraCheck check(true, Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_ON_ORGRIMS_HAMMER_DECK : SPELL_ON_SKYBREAKER_DECK);
@@ -1698,11 +1699,11 @@ class npc_gunship_rocketeer : public CreatureScript
return;
uint32 spellId = me->GetEntry() == NPC_SKYBREAKER_MORTAR_SOLDIER ? SPELL_ROCKET_ARTILLERY_A : SPELL_ROCKET_ARTILLERY_H;
- if (me->HasSpellCooldown(spellId))
+ if (me->GetSpellHistory()->HasCooldown(spellId))
return;
DoCastAOE(spellId, true);
- me->_AddCreatureSpellCooldown(spellId, time(NULL) + 9);
+ me->GetSpellHistory()->AddCooldown(spellId, 0, std::chrono::seconds(9));
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
index d653ec9e57d..e967f4aa8c5 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
@@ -29,7 +29,7 @@ EndScriptData */
#include "Player.h"
#include "SpellInfo.h"
-enum Enums
+enum Texts
{
SAY_AGGRO = 0,
SAY_FORGE = 1,
@@ -38,29 +38,50 @@ enum Enums
SAY_DEATH = 4,
EMOTE_TO_ANVIL = 5,
EMOTE_SHATTER = 6,
+};
+enum Spells
+{
SPELL_HEAT = 52387,
SPELL_SHATTERING_STOMP = 52237,
-
SPELL_TEMPER = 52238,
SPELL_TEMPER_DUMMY = 52654,
-
SPELL_SUMMON_MOLTEN_GOLEM = 52405,
+ SPELL_FORGE_VISUAL = 52654,
// Molten Golem
SPELL_BLAST_WAVE = 23113,
SPELL_IMMOLATION_STRIKE = 52433,
SPELL_SHATTER = 52429,
+};
+enum Events
+{
+ EVENT_PAUSE = 1,
+ EVENT_SHATTERING_STOMP = 2,
+ EVENT_SHATTER = 3,
+ EVENT_FORGE_CAST = 4,
+
+ // Molten Golem
+ EVENT_BLAST = 5,
+ EVENT_IMMOLATION = 6
+};
+
+enum Npcs
+{
NPC_VOLKHAN_ANVIL = 28823,
NPC_MOLTEN_GOLEM = 28695,
NPC_BRITTLE_GOLEM = 28681,
-
MAX_GOLEM = 2,
-
DATA_SHATTER_RESISTANT = 2042
};
+enum Phases
+{
+ PHASE_INTRO = 1,
+ PHASE_NORMAL
+};
+
/*######
## Boss Volkhan
######*/
@@ -68,68 +89,44 @@ class boss_volkhan : public CreatureScript
{
public:
boss_volkhan() : CreatureScript("boss_volkhan") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_volkhanAI>(creature);
- }
-
- struct boss_volkhanAI : public ScriptedAI
+
+ struct boss_volkhanAI : public BossAI
{
- boss_volkhanAI(Creature* creature) : ScriptedAI(creature)
+ boss_volkhanAI(Creature* creature) : BossAI(creature, DATA_VOLKHAN)
{
Initialize();
- instance = creature->GetInstanceScript();
}
void Initialize()
{
- m_bIsStriking = false;
- m_bHasTemper = false;
+ m_bIsStriking = false;
+ m_bHasTemper = false;
m_bCanShatterGolem = false;
-
- m_uiPause_Timer = 3500;
- m_uiShatteringStomp_Timer = 0;
- m_uiShatter_Timer = 5000;
- m_uiDelay_Timer = 1000;
- m_uiSummonPhase = 0;
- GolemsShattered = 0;
+ m_uiDelay_Timer = 1000;
+ m_uiSummonPhase = 0;
+ GolemsShattered = 0;
m_uiHealthAmountModifier = 1;
}
- InstanceScript* instance;
-
- GuidList m_lGolemGUIDList;
-
- bool m_bHasTemper;
- bool m_bIsStriking;
- bool m_bCanShatterGolem;
-
- uint8 GolemsShattered;
- uint32 m_uiPause_Timer;
- uint32 m_uiShatteringStomp_Timer;
- uint32 m_uiShatter_Timer;
- uint32 m_uiDelay_Timer;
- uint32 m_uiSummonPhase;
-
- uint32 m_uiHealthAmountModifier;
-
void Reset() override
{
Initialize();
-
+ _Reset();
DespawnGolem();
m_lGolemGUIDList.clear();
-
- instance->SetBossState(DATA_VOLKHAN, NOT_STARTED);
+ events.SetPhase(PHASE_INTRO);
+ events.ScheduleEvent(EVENT_FORGE_CAST, 2 * IN_MILLISECONDS, 0, PHASE_INTRO);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
-
- instance->SetBossState(DATA_VOLKHAN, IN_PROGRESS);
+ events.SetPhase(PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_PAUSE, 3.5 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_SHATTERING_STOMP, 0 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_SHATTER, 5 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ _EnterCombat();
}
void AttackStart(Unit* who) override
@@ -150,7 +147,7 @@ public:
Talk(SAY_DEATH);
DespawnGolem();
- instance->SetBossState(DATA_VOLKHAN, DONE);
+ _JustDied();
}
void KilledUnit(Unit* who) override
@@ -224,59 +221,61 @@ public:
return 0;
}
- void UpdateAI(uint32 uiDiff) override
+ void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
+ // Return since we have no target and are in CombatPhase
+ if (events.IsInPhase(PHASE_NORMAL) && !UpdateVictim())
return;
- if (m_bIsStriking)
- {
- if (m_uiPause_Timer <= uiDiff)
- {
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
- if (me->GetVictim())
- me->GetMotionMaster()->MoveChase(me->GetVictim());
-
- m_bHasTemper = false;
- m_bIsStriking = false;
- m_uiPause_Timer = 3500;
- }
- else
- m_uiPause_Timer -= uiDiff;
+ events.Update(diff);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- }
- // When to start shatter? After 60, 40 or 20% hp?
- if (!m_bHasTemper && m_uiHealthAmountModifier >= 3)
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (m_uiShatteringStomp_Timer <= uiDiff)
+ switch (eventId)
{
- // Should he stomp even if he has no brittle golem to shatter?
- Talk(SAY_STOMP);
-
- DoCast(me, SPELL_SHATTERING_STOMP);
+ case EVENT_PAUSE:
+ if (m_bIsStriking)
+ {
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
+ if (me->GetVictim())
+ me->GetMotionMaster()->MoveChase(me->GetVictim());
- Talk(EMOTE_SHATTER);
+ m_bHasTemper = false;
+ m_bIsStriking = false;
+ events.ScheduleEvent(EVENT_PAUSE, 3.5 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ }
+ break;
+ case EVENT_SHATTERING_STOMP:
+ if (!m_bHasTemper && m_uiHealthAmountModifier >= 3)
+ {
+ // Should he stomp even if he has no brittle golem to shatter?
+ Talk(SAY_STOMP);
- m_uiShatteringStomp_Timer = 30000;
- m_bCanShatterGolem = true;
- }
- else
- m_uiShatteringStomp_Timer -= uiDiff;
- }
+ DoCast(me, SPELL_SHATTERING_STOMP);
- // Shatter Golems 3 seconds after Shattering Stomp
- if (m_bCanShatterGolem)
- {
- if (m_uiShatter_Timer <= uiDiff)
- {
- ShatterGolem();
- m_uiShatter_Timer = 3000;
- m_bCanShatterGolem = false;
+ Talk(EMOTE_SHATTER);
+ events.ScheduleEvent(EVENT_SHATTERING_STOMP, 30 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ m_bCanShatterGolem = true;
+ }
+ break;
+ case EVENT_SHATTER:
+ if (m_bCanShatterGolem)
+ {
+ ShatterGolem();
+ events.ScheduleEvent(EVENT_SHATTER, 3 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ m_bCanShatterGolem = false;
+ }
+ break;
+ case EVENT_FORGE_CAST:
+ DoCast(me, SPELL_FORGE_VISUAL);
+ events.ScheduleEvent(EVENT_FORGE_CAST, 15 * IN_MILLISECONDS, 0, PHASE_INTRO);
+ break;
+ default:
+ break;
}
- else
- m_uiShatter_Timer -= uiDiff;
}
// Health check
@@ -302,12 +301,10 @@ public:
me->GetMotionMaster()->MoveTargetedHome();
m_uiSummonPhase = 2; // Set Next Phase
break;
-
case 2:
// 2 - Check if reached Anvil
// This is handled in: void JustReachedHome() override
break;
-
case 3:
// 3 - Cast Temper on the Anvil
if (Unit* target = GetClosestCreatureWithEntry(me, NPC_VOLKHAN_ANVIL, 1000.0f, true))
@@ -319,10 +316,9 @@ public:
m_uiDelay_Timer = 1000; // Delay 2 seconds before next phase can begin
m_uiSummonPhase = 4; // Set Next Phase
break;
-
case 4:
// 4 - Wait for delay to expire
- if (m_uiDelay_Timer <= uiDiff)
+ if (m_uiDelay_Timer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0))
{
@@ -333,9 +329,8 @@ public:
m_uiSummonPhase = 5;
}
else
- m_uiDelay_Timer -= uiDiff;
+ m_uiDelay_Timer -= diff;
break;
-
case 5:
// 5 - Spawn the Golems
if (Creature* creatureTarget = GetClosestCreatureWithEntry(me, NPC_VOLKHAN_ANVIL, 1000.0f, true))
@@ -349,13 +344,30 @@ public:
DoMeleeAttackIfReady();
}
+
+ private:
+ GuidList m_lGolemGUIDList;
+ uint32 m_uiHealthAmountModifier;
+ uint8 GolemsShattered;
+ uint32 m_uiDelay_Timer;
+ uint32 m_uiSummonPhase;
+
+ bool m_bHasTemper;
+ bool m_bIsStriking;
+ bool m_bCanShatterGolem;
};
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_volkhanAI>(creature);
+ }
+
};
/*######
## npc_molten_golem
######*/
+
class npc_molten_golem : public CreatureScript
{
public:
@@ -376,18 +388,12 @@ public:
void Initialize()
{
m_bIsFrozen = false;
-
- m_uiBlast_Timer = 20000;
- m_uiDeathDelay_Timer = 0;
- m_uiImmolation_Timer = 5000;
+ events.ScheduleEvent(EVENT_BLAST, 20 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_IMMOLATION, 5 * IN_MILLISECONDS);
}
bool m_bIsFrozen;
- uint32 m_uiBlast_Timer;
- uint32 m_uiDeathDelay_Timer;
- uint32 m_uiImmolation_Timer;
-
void Reset() override
{
Initialize();
@@ -433,30 +439,39 @@ public:
me->DespawnOrUnsummon();
}
- void UpdateAI(uint32 uiDiff) override
+ void UpdateAI(uint32 diff) override
{
// Return since we have no target or if we are frozen
if (!UpdateVictim() || m_bIsFrozen)
return;
- if (m_uiBlast_Timer <= uiDiff)
- {
- DoCast(me, SPELL_BLAST_WAVE);
- m_uiBlast_Timer = 20000;
- }
- else
- m_uiBlast_Timer -= uiDiff;
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiImmolation_Timer <= uiDiff)
+ while (uint32 eventId = events.ExecuteEvent())
{
- DoCastVictim(SPELL_IMMOLATION_STRIKE);
- m_uiImmolation_Timer = 5000;
+ switch (eventId)
+ {
+ case EVENT_BLAST:
+ DoCast(me, SPELL_BLAST_WAVE);
+ events.ScheduleEvent(EVENT_BLAST, 20 * IN_MILLISECONDS);
+ break;
+ case EVENT_IMMOLATION:
+ DoCastVictim(SPELL_IMMOLATION_STRIKE);
+ events.ScheduleEvent(EVENT_BLAST, 5 * IN_MILLISECONDS);
+ break;
+ default:
+ break;
+ }
}
- else
- m_uiImmolation_Timer -= uiDiff;
DoMeleeAttackIfReady();
}
+
+ private:
+ EventMap events;
};
};
diff --git a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
index 728b164cc04..e4369f0348d 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
@@ -93,15 +93,12 @@ enum Factions
FACTION_COMBAT = 1868
};
-enum SetData
+enum Actions
{
- SETDATA_DATA = 1,
- SETDATA_RESET = 1,
- SETDATA_CHANNELER_DIED = 2,
- SETDATA_START_SPAWNING = 3,
- SETDATA_STOP_SPAWNING = 4,
- SETDATA_DESPAWN_ALL_SPAWNS = 5,
- SETDATA_START_ATTACK_AKAMA = 6
+ ACTION_CHANNELER_DIED = 1,
+ ACTION_START_SPAWNING = 2,
+ ACTION_STOP_SPAWNING = 3,
+ ACTION_DESPAWN_ALL_SPAWNS = 4,
};
enum Events
@@ -158,12 +155,11 @@ class boss_shade_of_akama : public CreatureScript
public:
boss_shade_of_akama() : CreatureScript("boss_shade_of_akama") { }
- struct boss_shade_of_akamaAI : public ScriptedAI
+ struct boss_shade_of_akamaAI : public BossAI
{
- boss_shade_of_akamaAI(Creature* creature) : ScriptedAI(creature)
+ boss_shade_of_akamaAI(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA)
{
Initialize();
- instance = creature->GetInstanceScript();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
@@ -177,6 +173,7 @@ public:
void Reset() override
{
+ _Reset();
if (!HasKilledAkamaAndReseting)
{
for (GuidList::const_iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr)
@@ -185,7 +182,7 @@ public:
for (GuidList::const_iterator itr = Spawners.begin(); itr != Spawners.end(); ++itr)
if (Creature* Spawner = ObjectAccessor::GetCreature(*me, *itr))
- Spawner->AI()->SetData(SETDATA_DATA, SETDATA_DESPAWN_ALL_SPAWNS);
+ Spawner->AI()->DoAction(ACTION_DESPAWN_ALL_SPAWNS);
events.ScheduleEvent(EVENT_FIND_CHANNELERS_SPAWNERS, 3000);
events.ScheduleEvent(EVENT_RESET_ENCOUNTER, 5000);
@@ -197,11 +194,6 @@ public:
Initialize();
}
- void JustDied(Unit* /*killer*/) override
- {
- instance->SetBossState(DATA_SHADE_OF_AKAMA, DONE);
- }
-
void EnterCombat(Unit* /*who*/) override { }
void AttackStart(Unit* who) override
@@ -216,9 +208,9 @@ public:
ScriptedAI::AttackStart(who);
}
- void SetData(uint32 data, uint32 value) override
+ void DoAction(int32 actionId) override
{
- if (data == SETDATA_DATA && value == SETDATA_CHANNELER_DIED)
+ if (actionId == ACTION_CHANNELER_DIED)
me->RemoveAuraFromStack(SPELL_SHADE_SOUL_CHANNEL_2);
UpdateSpeed();
@@ -314,7 +306,7 @@ public:
for (GuidList::const_iterator itr = Spawners.begin(); itr != Spawners.end(); ++itr)
if (Creature* Spawner = ObjectAccessor::GetCreature(*me, *itr))
- Spawner->AI()->SetData(SETDATA_DATA, SETDATA_START_SPAWNING);
+ Spawner->AI()->DoAction(ACTION_START_SPAWNING);
break;
}
case EVENT_START_ATTACK_AKAMA:
@@ -353,7 +345,7 @@ public:
for (GuidList::const_iterator itr = Spawners.begin(); itr != Spawners.end(); ++itr)
if (Creature* Spawner = ObjectAccessor::GetCreature(*me, *itr))
- Spawner->AI()->SetData(SETDATA_DATA, SETDATA_DESPAWN_ALL_SPAWNS);
+ Spawner->AI()->DoAction(ACTION_DESPAWN_ALL_SPAWNS);
events.ScheduleEvent(EVENT_FIND_CHANNELERS_SPAWNERS, 10000);
events.ScheduleEvent(EVENT_RESET_ENCOUNTER, 20000);
@@ -378,7 +370,7 @@ public:
for (GuidList::const_iterator itr = Spawners.begin(); itr != Spawners.end(); ++itr)
if (Creature* Spawner = ObjectAccessor::GetCreature(*me, *itr))
- Spawner->AI()->SetData(SETDATA_DATA, SETDATA_STOP_SPAWNING);
+ Spawner->AI()->DoAction(ACTION_STOP_SPAWNING);
}
}
}
@@ -390,8 +382,6 @@ public:
public:
bool HasKilledAkama;
private:
- InstanceScript* instance;
- EventMap events;
GuidList Channelers;
GuidList Spawners;
bool akamaReached;
@@ -433,9 +423,11 @@ public:
void Reset() override
{
me->setFaction(FACTION_FRIENDLY);
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
DoCast(me, SPELL_STEALTH);
Initialize();
+
+ if (instance->GetBossState(DATA_SHADE_OF_AKAMA) != DONE)
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
void JustDied(Unit* /*killer*/) override
@@ -581,7 +573,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
if (Creature* Shade = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SHADE_OF_AKAMA)))
- Shade->AI()->SetData(SETDATA_DATA, SETDATA_CHANNELER_DIED);
+ Shade->AI()->DoAction(ACTION_CHANNELER_DIED);
}
void EnterCombat(Unit* /*who*/) override { }
@@ -603,7 +595,7 @@ public:
else
{
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
- Shade->AI()->SetData(SETDATA_DATA, SETDATA_CHANNELER_DIED);
+ Shade->AI()->DoAction(ACTION_CHANNELER_DIED);
}
}
events.ScheduleEvent(EVENT_CHANNEL, 2000);
@@ -663,36 +655,33 @@ public:
Summons.Summon(summon);
}
- void SetData(uint32 data, uint32 value) override
+ void DoAction(int32 actionId) override
{
- if (data == SETDATA_DATA)
- {
- doSpawning = true;
+ doSpawning = true;
- switch (value)
- {
- case SETDATA_START_SPAWNING:
- if (leftSide)
- {
- events.ScheduleEvent(EVENT_SPAWN_WAVE_B, 100);
- events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, urand(2000, 5000));
- }
- else
- {
- events.ScheduleEvent(EVENT_SPAWN_WAVE_B, 10000);
- events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, urand(2000, 5000));
- }
- break;
- case SETDATA_STOP_SPAWNING:
- doSpawning = false;
- break;
- case SETDATA_DESPAWN_ALL_SPAWNS:
- doSpawning = false;
- Summons.DespawnAll();
- break;
- default:
- break;
- }
+ switch (actionId)
+ {
+ case ACTION_START_SPAWNING:
+ if (leftSide)
+ {
+ events.ScheduleEvent(EVENT_SPAWN_WAVE_B, 100);
+ events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, urand(2000, 5000));
+ }
+ else
+ {
+ events.ScheduleEvent(EVENT_SPAWN_WAVE_B, 10000);
+ events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, urand(2000, 5000));
+ }
+ break;
+ case ACTION_STOP_SPAWNING:
+ doSpawning = false;
+ break;
+ case ACTION_DESPAWN_ALL_SPAWNS:
+ doSpawning = false;
+ Summons.DespawnAll();
+ break;
+ default:
+ break;
}
}
@@ -778,23 +767,16 @@ public:
}
}
- summonerGuid.Clear();
Initialize();
}
void JustDied(Unit* /*killer*/) override
{
if (Creature* Shade = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SHADE_OF_AKAMA)))
- Shade->AI()->SetData(SETDATA_DATA, SETDATA_CHANNELER_DIED);
+ Shade->AI()->DoAction(ACTION_CHANNELER_DIED);
me->DespawnOrUnsummon(5000);
}
- void IsSummonedBy(Unit* /*summoner*/) override
- {
- if (Creature* summoner = (ObjectAccessor::GetCreature((*me), summonerGuid)))
- ENSURE_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me);
- }
-
void EnterCombat(Unit* /*who*/) override { }
void AttackStart(Unit* who) override
@@ -824,7 +806,7 @@ public:
else
{
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
- Shade->AI()->SetData(SETDATA_DATA, SETDATA_CHANNELER_DIED);
+ Shade->AI()->DoAction(ACTION_CHANNELER_DIED);
switchToCombat = true;
if (Unit* target = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AKAMA_SHADE)))
AttackStart(target);
@@ -855,7 +837,6 @@ public:
private:
InstanceScript* instance;
EventMap events;
- ObjectGuid summonerGuid;
bool startedBanishing;
bool switchToCombat;
};
@@ -884,8 +865,6 @@ public:
void Reset() override
{
- summonerGuid.Clear();
-
if (Unit* target = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AKAMA_SHADE)))
AttackStart(target);
}
@@ -895,12 +874,6 @@ public:
me->DespawnOrUnsummon(5000);
}
- void IsSummonedBy(Unit* /*summoner*/) override
- {
- if (Creature* summoner = (ObjectAccessor::GetCreature((*me), summonerGuid)))
- ENSURE_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me);
- }
-
void EnterCombat(Unit* /*who*/) override
{
events.ScheduleEvent(EVENT_HEROIC_STRIKE, 5000);
@@ -947,7 +920,6 @@ public:
private:
InstanceScript* instance;
EventMap events;
- ObjectGuid summonerGuid;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -974,8 +946,6 @@ public:
void Reset() override
{
- summonerGuid.Clear();
-
if (Unit* target = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AKAMA_SHADE)))
AttackStart(target);
}
@@ -985,12 +955,6 @@ public:
me->DespawnOrUnsummon(5000);
}
- void IsSummonedBy(Unit* /*summoner*/) override
- {
- if (Creature* summoner = (ObjectAccessor::GetCreature((*me), summonerGuid)))
- ENSURE_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me);
- }
-
void EnterCombat(Unit* /*who*/) override
{
events.ScheduleEvent(EVENT_DEBILITATING_POISON, urand(500, 2000));
@@ -1027,7 +991,6 @@ public:
private:
InstanceScript* instance;
EventMap events;
- ObjectGuid summonerGuid;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -1054,8 +1017,6 @@ public:
void Reset() override
{
- summonerGuid.Clear();
-
if (Unit* target = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AKAMA_SHADE)))
AttackStart(target);
}
@@ -1065,12 +1026,6 @@ public:
me->DespawnOrUnsummon(5000);
}
- void IsSummonedBy(Unit* /*summoner*/) override
- {
- if (Creature* summoner = (ObjectAccessor::GetCreature((*me), summonerGuid)))
- ENSURE_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me);
- }
-
void EnterCombat(Unit* /*who*/) override
{
events.ScheduleEvent(EVENT_RAIN_OF_FIRE, 18000);
@@ -1107,7 +1062,6 @@ public:
private:
InstanceScript* instance;
EventMap events;
- ObjectGuid summonerGuid;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -1137,7 +1091,6 @@ public:
{
spiritMend = false;
chainHeal = false;
- summonerGuid.Clear();
}
void Reset() override
@@ -1153,12 +1106,6 @@ public:
me->DespawnOrUnsummon(5000);
}
- void IsSummonedBy(Unit* /*summoner*/) override
- {
- if (Creature* summoner = (ObjectAccessor::GetCreature((*me), summonerGuid)))
- ENSURE_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me);
- }
-
void EnterCombat(Unit* /*who*/) override
{
events.ScheduleEvent(EVENT_SPIRIT_HEAL, urand (5000, 6000));
@@ -1208,7 +1155,6 @@ public:
private:
InstanceScript* instance;
EventMap events;
- ObjectGuid summonerGuid;
bool spiritMend;
bool chainHeal;
};
diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
index 2407f3980de..9ffc151b3b9 100644
--- a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
+++ b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
@@ -338,6 +338,13 @@ class npc_warden_mellichar : public CreatureScript
IsRunning = true;
}
+ void JustSummoned(Creature* summon) override
+ {
+ DoZoneInCombat(summon);
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ summon->AI()->AttackStart(target);
+ }
+
bool CanProgress()
{
if (Phase == 7 && instance->GetData(DATA_WARDEN_4) == DONE)
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 9edf3f42b88..98c6781e866 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -25,6 +25,7 @@
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
#include "Containers.h"
enum DeathKnightSpells
@@ -148,7 +149,7 @@ class spell_dk_anti_magic_shell : public SpellScriptLoader
{
// Cannot reduce cooldown by more than 50%
int32 val = std::min(glyph->GetAmount(), int32(absorbedAmount) * 100 / maxHealth);
- player->ModifySpellCooldown(GetId(), -int32(player->GetSpellCooldownDelay(GetId()) * val / 100));
+ player->GetSpellHistory()->ModifyCooldown(GetId(), -int32(player->GetSpellHistory()->GetRemainingCooldown(GetId()) * val / 100));
}
}
diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp
index dd002dedee5..2418e75d22c 100644
--- a/src/server/scripts/Spells/spell_druid.cpp
+++ b/src/server/scripts/Spells/spell_druid.cpp
@@ -25,6 +25,7 @@
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
#include "Containers.h"
enum DruidSpells
@@ -122,8 +123,8 @@ class spell_dru_eclipse : public SpellScriptLoader
if (!caster)
return;
- if (caster->ToPlayer()->GetAuraOfRankedSpell(SPELL_DRUID_NATURES_GRACE))
- caster->ToPlayer()->RemoveSpellCooldown(SPELL_DRUID_NATURES_GRACE_TRIGGER, true);
+ if (caster->GetAuraOfRankedSpell(SPELL_DRUID_NATURES_GRACE))
+ caster->GetSpellHistory()->ResetCooldown(SPELL_DRUID_NATURES_GRACE_TRIGGER, true);
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index a05eab1cd08..31779c4df22 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -36,6 +36,7 @@
#include "SkillDiscovery.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
#include "Vehicle.h"
class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader
@@ -1313,9 +1314,7 @@ class spell_gen_divine_storm_cd_reset : public SpellScriptLoader
void HandleScript(SpellEffIndex /*effIndex*/)
{
- Player* caster = GetCaster()->ToPlayer();
- if (caster->HasSpellCooldown(SPELL_DIVINE_STORM))
- caster->RemoveSpellCooldown(SPELL_DIVINE_STORM, true);
+ GetCaster()->GetSpellHistory()->ResetCooldown(SPELL_DIVINE_STORM, true);
}
void Register() override
@@ -3324,7 +3323,7 @@ class spell_pvp_trinket_wotf_shared_cd : public SpellScriptLoader
{
// This is only needed because spells cast from spell_linked_spell are triggered by default
// Spell::SendSpellCooldown() skips all spells with TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
- GetCaster()->ToPlayer()->AddSpellAndCategoryCooldowns(GetSpellInfo(), GetCastItem() ? GetCastItem()->GetEntry() : 0, GetSpell());
+ GetCaster()->GetSpellHistory()->StartCooldown(GetSpellInfo(), 0, GetSpell());
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index 205965910c1..a0c01479cdb 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -29,6 +29,7 @@
#include "GridNotifiersImpl.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
enum HunterSpells
{
@@ -641,24 +642,20 @@ class spell_hun_readiness : public SpellScriptLoader
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- Player* caster = GetCaster()->ToPlayer();
// immediately finishes the cooldown on your other Hunter abilities except Bestial Wrath
- const SpellCooldowns& cm = caster->ToPlayer()->GetSpellCooldownMap();
- for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();)
+ GetCaster()->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
///! If spellId in cooldown map isn't valid, the above will return a null pointer.
- if (spellInfo &&
- spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER &&
+ if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER &&
spellInfo->Id != SPELL_HUNTER_READINESS &&
spellInfo->Id != SPELL_HUNTER_BESTIAL_WRATH &&
spellInfo->Id != SPELL_DRAENEI_GIFT_OF_THE_NAARU &&
spellInfo->GetRecoveryTime() > 0)
- caster->RemoveSpellCooldown((itr++)->first, true);
- else
- ++itr;
- }
+ return true;
+ return false;
+ }, true);
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index eb5c4c147a8..66c90c85e55 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -26,6 +26,7 @@
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
#include "SkillDiscovery.h"
#include "Battleground.h"
@@ -1355,7 +1356,7 @@ class spell_item_red_rider_air_rifle : public SpellScriptLoader
caster->CastSpell(caster, SPELL_AIR_RIFLE_HOLD_VISUAL, true);
// needed because this spell shares GCD with its triggered spells (which must not be cast with triggered flag)
if (Player* player = caster->ToPlayer())
- player->GetGlobalCooldownMgr().CancelGlobalCooldown(GetSpellInfo());
+ player->GetSpellHistory()->CancelGlobalCooldown(GetSpellInfo());
if (urand(0, 4))
caster->CastSpell(target, SPELL_AIR_RIFLE_SHOOT, false);
else
@@ -2374,7 +2375,7 @@ class spell_item_rocket_boots : public SpellScriptLoader
if (Battleground* bg = caster->GetBattleground())
bg->EventPlayerDroppedFlag(caster);
- caster->RemoveSpellCooldown(SPELL_ROCKET_BOOTS_PROC);
+ caster->GetSpellHistory()->ResetCooldown(SPELL_ROCKET_BOOTS_PROC);
caster->CastSpell(caster, SPELL_ROCKET_BOOTS_PROC, true, NULL);
}
diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp
index ea8630acc59..16e819430d2 100644
--- a/src/server/scripts/Spells/spell_mage.cpp
+++ b/src/server/scripts/Spells/spell_mage.cpp
@@ -24,6 +24,7 @@
#include "Player.h"
#include "ScriptMgr.h"
#include "SpellScript.h"
+#include "SpellHistory.h"
#include "SpellAuraEffects.h"
#include "Pet.h"
#include "GridNotifiers.h"
@@ -326,22 +327,12 @@ class spell_mage_cold_snap : public SpellScriptLoader
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- Player* caster = GetCaster()->ToPlayer();
- // immediately finishes the cooldown on Frost spells
- const SpellCooldowns& cm = caster->GetSpellCooldownMap();
- for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();)
+ GetCaster()->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr)
{
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
-
- if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE &&
- (spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) &&
- spellInfo->Id != SPELL_MAGE_COLD_SNAP && spellInfo->GetRecoveryTime() > 0)
- {
- caster->RemoveSpellCooldown((itr++)->first, true);
- }
- else
- ++itr;
- }
+ return spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) &&
+ spellInfo->Id != SPELL_MAGE_COLD_SNAP && spellInfo->GetRecoveryTime() > 0;
+ }, true);
}
void Register() override
@@ -703,7 +694,7 @@ class spell_mage_glyph_of_ice_block : public SpellScriptLoader
{
PreventDefaultAction();
// Remove Frost Nova cooldown
- GetTarget()->ToPlayer()->RemoveSpellCooldown(SPELL_MAGE_FROST_NOVA, true);
+ GetTarget()->GetSpellHistory()->ResetCooldown(SPELL_MAGE_FROST_NOVA, true);
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index 305f1cce9e3..2af1b8c14f2 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -25,6 +25,7 @@
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
#include "Group.h"
enum PaladinSpells
@@ -600,7 +601,7 @@ class spell_pal_grand_crusader : public SpellScriptLoader
void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
{
- GetTarget()->ToPlayer()->RemoveSpellCooldown(SPELL_PALADIN_AVENGERS_SHIELD, true);
+ GetTarget()->GetSpellHistory()->ResetCooldown(SPELL_PALADIN_AVENGERS_SHIELD, true);
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp
index 902e89f6c56..b70ae177928 100644
--- a/src/server/scripts/Spells/spell_rogue.cpp
+++ b/src/server/scripts/Spells/spell_rogue.cpp
@@ -25,6 +25,7 @@
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "SpellHistory.h"
#include "Containers.h"
enum RogueSpells
@@ -159,11 +160,11 @@ class spell_rog_cheat_death : public SpellScriptLoader
void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
{
Player* target = GetTarget()->ToPlayer();
- if (dmgInfo.GetDamage() < target->GetHealth() || target->HasSpellCooldown(SPELL_ROGUE_CHEAT_DEATH_COOLDOWN) || !roll_chance_i(absorbChance))
+ if (dmgInfo.GetDamage() < target->GetHealth() || target->GetSpellHistory()->HasCooldown(SPELL_ROGUE_CHEAT_DEATH_COOLDOWN) || !roll_chance_i(absorbChance))
return;
target->CastSpell(target, SPELL_ROGUE_CHEAT_DEATH_COOLDOWN, true);
- target->AddSpellCooldown(SPELL_ROGUE_CHEAT_DEATH_COOLDOWN, 0, time(NULL) + 60);
+ target->GetSpellHistory()->AddCooldown(SPELL_ROGUE_CHEAT_DEATH_COOLDOWN, 0, std::chrono::minutes(1));
uint32 health10 = target->CountPctFromMaxHealth(10);
@@ -550,31 +551,21 @@ class spell_rog_preparation : public SpellScriptLoader
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- Player* caster = GetCaster()->ToPlayer();
-
- // immediately finishes the cooldown on certain Rogue abilities
- SpellCooldowns const& cm = caster->GetSpellCooldownMap();
- for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();)
+ Unit* caster = GetCaster();
+ caster->GetSpellHistory()->ResetCooldowns([caster](SpellHistory::CooldownStorageType::iterator itr)
{
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
if (spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE)
- {
- ++itr;
- continue;
- }
+ return false;
- if ((spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_SHADOWSTEP || // Shadowstep
+ return (spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_SHADOWSTEP || // Shadowstep
spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG0_ROGUE_VAN_SPRINT) || // Vanish, Sprint
// Glyph of Preparation
(caster->HasAura(SPELL_ROGUE_GLYPH_OF_PREPARATION) &&
(spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_DISMANTLE_SMOKE_BOMB || // Dismantle, Smoke Bomb
- spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG0_ROGUE_KICK))) // Kick
- {
- caster->RemoveSpellCooldown((itr++)->first, true);
- }
- else
- ++itr;
- }
+ spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG0_ROGUE_KICK)); // Kick
+
+ }, true);
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp
index b5c9c23fa5c..589f67fc39b 100644
--- a/src/server/scripts/Spells/spell_shaman.cpp
+++ b/src/server/scripts/Spells/spell_shaman.cpp
@@ -26,6 +26,7 @@
#include "GridNotifiers.h"
#include "Unit.h"
#include "SpellScript.h"
+#include "SpellHistory.h"
#include "SpellAuraEffects.h"
enum ShamanSpells
@@ -310,7 +311,7 @@ class spell_sha_earth_shield : public SpellScriptLoader
{
//! HACK due to currenct proc system implementation
if (Player* player = GetTarget()->ToPlayer())
- if (player->HasSpellCooldown(SPELL_SHAMAN_EARTH_SHIELD_HEAL))
+ if (player->GetSpellHistory()->HasCooldown(SPELL_SHAMAN_EARTH_SHIELD_HEAL))
return false;
return true;
}
@@ -323,7 +324,7 @@ class spell_sha_earth_shield : public SpellScriptLoader
/// @hack: due to currenct proc system implementation
if (Player* player = GetTarget()->ToPlayer())
- player->AddSpellCooldown(SPELL_SHAMAN_EARTH_SHIELD_HEAL, 0, time(NULL) + 3);
+ player->GetSpellHistory()->AddCooldown(SPELL_SHAMAN_EARTH_SHIELD_HEAL, 0, std::chrono::seconds(3));
}
void Register() override
@@ -462,7 +463,7 @@ class spell_sha_feedback : public SpellScriptLoader
{
PreventDefaultAction(); // will prevent default effect execution
if (Player* target = GetTarget()->ToPlayer())
- target->ModifySpellCooldown(SPELL_SHAMAN_ELEMENTAL_MASTERY, aurEff->GetBaseAmount());
+ target->GetSpellHistory()->ModifyCooldown(SPELL_SHAMAN_ELEMENTAL_MASTERY, aurEff->GetBaseAmount());
}
void Register() override
@@ -832,7 +833,7 @@ class spell_sha_item_t10_elemental_2p_bonus : public SpellScriptLoader
{
PreventDefaultAction();
if (Player* target = GetTarget()->ToPlayer())
- target->ModifySpellCooldown(SPELL_SHAMAN_ELEMENTAL_MASTERY, -aurEff->GetAmount());
+ target->GetSpellHistory()->ModifyCooldown(SPELL_SHAMAN_ELEMENTAL_MASTERY, -aurEff->GetAmount());
}
void Register() override
@@ -949,7 +950,7 @@ class spell_sha_lava_surge_proc : public SpellScriptLoader
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- GetCaster()->ToPlayer()->RemoveSpellCooldown(SPELL_SHAMAN_LAVA_BURST, true);
+ GetCaster()->GetSpellHistory()->ResetCooldown(SPELL_SHAMAN_LAVA_BURST, true);
}
void Register() override
@@ -1017,7 +1018,7 @@ class spell_sha_nature_guardian : public SpellScriptLoader
{
//! HACK due to currenct proc system implementation
if (Player* player = GetTarget()->ToPlayer())
- if (player->HasSpellCooldown(GetSpellInfo()->Id))
+ if (player->GetSpellHistory()->HasCooldown(GetSpellInfo()->Id))
return false;
return GetTarget()->HealthBelowPctDamaged(30, eventInfo.GetDamageInfo()->GetDamage());
@@ -1034,7 +1035,7 @@ class spell_sha_nature_guardian : public SpellScriptLoader
eventInfo.GetProcTarget()->getThreatManager().modifyThreatPercent(GetTarget(), -10);
if (Player* player = GetTarget()->ToPlayer())
- player->AddSpellCooldown(GetSpellInfo()->Id, 0, time(NULL) + aurEff->GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue());
+ player->GetSpellHistory()->AddCooldown(GetSpellInfo()->Id, 0, std::chrono::seconds(aurEff->GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue()));
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index b3caff679df..80e738c7442 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -23,6 +23,7 @@
#include "Player.h"
#include "ScriptMgr.h"
+#include "SpellHistory.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
@@ -697,7 +698,7 @@ class spell_warr_sudden_death : public SpellScriptLoader
{
// Remove cooldown on Colossus Smash
if (Player* player = GetTarget()->ToPlayer())
- player->RemoveSpellCooldown(SPELL_WARRIOR_COLOSSUS_SMASH, true);
+ player->GetSpellHistory()->ResetCooldown(SPELL_WARRIOR_COLOSSUS_SMASH, true);
}
void Register() override
@@ -799,7 +800,7 @@ class spell_warr_sword_and_board : public SpellScriptLoader
{
// Remove cooldown on Shield Slam
if (Player* player = GetTarget()->ToPlayer())
- player->RemoveSpellCooldown(SPELL_WARRIOR_SHIELD_SLAM, true);
+ player->GetSpellHistory()->ResetCooldown(SPELL_WARRIOR_SHIELD_SLAM, true);
}
void Register() override
@@ -932,7 +933,7 @@ class spell_warr_vigilance_trigger : public SpellScriptLoader
// Remove Taunt cooldown
if (Player* target = GetHitPlayer())
- target->RemoveSpellCooldown(SPELL_WARRIOR_TAUNT, true);
+ target->GetSpellHistory()->ResetCooldown(SPELL_WARRIOR_TAUNT, true);
}
void Register() override
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index d4a73ab161f..121417717a4 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -56,6 +56,7 @@ EndContentData */
#include "SpellAuras.h"
#include "Pet.h"
#include "CreatureTextMgr.h"
+#include "SpellHistory.h"
/*########
# npc_air_force_bots
@@ -1208,14 +1209,14 @@ public:
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
- if (player->HasSpellCooldown(SPELL_INT) ||
- player->HasSpellCooldown(SPELL_ARM) ||
- player->HasSpellCooldown(SPELL_DMG) ||
- player->HasSpellCooldown(SPELL_RES) ||
- player->HasSpellCooldown(SPELL_STR) ||
- player->HasSpellCooldown(SPELL_AGI) ||
- player->HasSpellCooldown(SPELL_STM) ||
- player->HasSpellCooldown(SPELL_SPI))
+ if (player->GetSpellHistory()->HasCooldown(SPELL_INT) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_ARM) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_DMG) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_RES) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_STR) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_AGI) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_STM) ||
+ player->GetSpellHistory()->HasCooldown(SPELL_SPI))
player->SEND_GOSSIP_MENU(7393, creature->GetGUID());
else
{
@@ -1282,42 +1283,42 @@ public:
break;
case GOSSIP_SENDER_MAIN + 1:
creature->CastSpell(player, SPELL_DMG, false);
- player->AddSpellCooldown(SPELL_DMG, 0, time(NULL) + 7200);
+ player->GetSpellHistory()->AddCooldown(SPELL_DMG, 0, std::chrono::hours(2));
SendAction(player, creature, action);
break;
case GOSSIP_SENDER_MAIN + 2:
creature->CastSpell(player, SPELL_RES, false);
- player->AddSpellCooldown(SPELL_RES, 0, time(NULL) + 7200);
+ player->GetSpellHistory()->AddCooldown(SPELL_RES, 0, std::chrono::hours(2));
SendAction(player, creature, action);
break;
case GOSSIP_SENDER_MAIN + 3:
creature->CastSpell(player, SPELL_ARM, false);
- player->AddSpellCooldown(SPELL_ARM, 0, time(NULL) + 7200);
+ player->GetSpellHistory()->AddCooldown(SPELL_ARM, 0, std::chrono::hours(2));
SendAction(player, creature, action);
break;
case GOSSIP_SENDER_MAIN + 4:
creature->CastSpell(player, SPELL_SPI, false);
- player->AddSpellCooldown(SPELL_SPI, 0, time(NULL) + 7200);
+ player->GetSpellHistory()->AddCooldown(SPELL_SPI, 0, std::chrono::hours(2));
SendAction(player, creature, action);
break;
case GOSSIP_SENDER_MAIN + 5:
creature->CastSpell(player, SPELL_INT, false);
- player->AddSpellCooldown(SPELL_INT, 0, time(NULL) + 7200);
+ player->GetSpellHistory()->AddCooldown(SPELL_INT, 0, std::chrono::hours(2));
SendAction(player, creature, action);
break;
case GOSSIP_SENDER_MAIN + 6:
creature->CastSpell(player, SPELL_STM, false);
- player->AddSpellCooldown(SPELL_STM, 0, time(NULL) + 7200);
+ player->GetSpellHistory()->AddCooldown(SPELL_STM, 0, std::chrono::hours(2));
SendAction(player, creature, action);
break;
case GOSSIP_SENDER_MAIN + 7:
creature->CastSpell(player, SPELL_STR, false);
- player->AddSpellCooldown(SPELL_STR, 0, time(NULL) + 7200);
+ player->GetSpellHistory()->AddCooldown(SPELL_STR, 0, std::chrono::hours(2));
SendAction(player, creature, action);
break;
case GOSSIP_SENDER_MAIN + 8:
creature->CastSpell(player, SPELL_AGI, false);
- player->AddSpellCooldown(SPELL_AGI, 0, time(NULL) + 7200);
+ player->GetSpellHistory()->AddCooldown(SPELL_AGI, 0, std::chrono::hours(2));
SendAction(player, creature, action);
break;
}
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index f2a805e932a..e95b05bc418 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -112,7 +112,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_MAIL_COUNT, "SELECT COUNT(*) FROM mail WHERE receiver = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHARACTER_SOCIALLIST, "SELECT friend, flags, note FROM character_social JOIN characters ON characters.guid = character_social.friend WHERE character_social.guid = ? AND deleteinfos_name IS NULL LIMIT 255", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, "SELECT spell, item, time FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, "SELECT spell, item, time FROM character_spell_cooldown WHERE guid = ? AND time > UNIX_TIMESTAMP()", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_SPELL_CHARGES, "SELECT categoryId, rechargeStart, rechargeEnd FROM character_spell_charges WHERE guid = ? AND rechargeEnd > UNIX_TIMESTAMP() ORDER BY rechargeEnd", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_DECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GUILD_MEMBER, "SELECT guildid, rank FROM guild_member WHERE guid = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_GUILD_MEMBER_EXTENDED, "SELECT g.guildid, g.name, gr.rname, gr.rid, gm.pnote, gm.offnote "
@@ -230,7 +231,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_GUILD_MEMBER_WITHDRAW, "TRUNCATE guild_member_withdraw", CONNECTION_ASYNC);
// 0: uint32, 1: uint32, 2: uint32
- PrepareStatement(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, gender, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_GUILD_ACHIEVEMENT, "DELETE FROM guild_achievement WHERE guildId = ? AND achievement = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_GUILD_ACHIEVEMENT, "INSERT INTO guild_achievement (guildId, achievement, date, guids) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ? AND criteria = ?", CONNECTION_ASYNC);
@@ -239,8 +240,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GUILD_ACHIEVEMENT, "SELECT achievement, date, guids FROM guild_achievement WHERE guildId = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, "SELECT criteria, counter, date, completedGuid FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_UPD_GUILD_EXPERIENCE, "UPDATE guild SET level = ?, experience = ?, todayExperience = ? WHERE guildId = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE, "UPDATE guild SET todayExperience = 0", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_GUILD_NEWS, "INSERT INTO guild_newslog (guildid, LogGuid, EventType, PlayerGuid, Flags, Value, Timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)"
" ON DUPLICATE KEY UPDATE LogGuid = VALUES (LogGuid), EventType = VALUES (EventType), PlayerGuid = VALUES (PlayerGuid), Flags = VALUES (Flags), Value = VALUES (Value), Timestamp = VALUES (Timestamp)", CONNECTION_ASYNC);
@@ -301,17 +300,14 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_GAME_EVENT_CONDITION_SAVE, "INSERT INTO game_event_condition_save (eventEntry, condition_id, done) VALUES (?, ?, ?)", CONNECTION_ASYNC);
// Petitions
- PrepareStatement(CHAR_SEL_PETITION, "SELECT ownerguid, name, type FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_PETITION, "SELECT ownerguid, name FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PETITION_SIGNATURE, "SELECT playerguid FROM petition_sign WHERE petitionguid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_ALL_PETITION_SIGNATURES, "DELETE FROM petition_sign WHERE playerguid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_DEL_PETITION_SIGNATURE, "DELETE FROM petition_sign WHERE playerguid = ? AND type = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_PETITION_BY_OWNER, "SELECT petitionguid FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_PETITION_TYPE, "SELECT type FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_PETITION_SIGNATURES, "SELECT ownerguid, (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = ?) AS signs, type FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_PETITION_BY_OWNER, "SELECT petitionguid FROM petition WHERE ownerguid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_PETITION_SIGNATURES, "SELECT ownerguid, (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = ?) AS signs FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PETITION_SIG_BY_ACCOUNT, "SELECT playerguid FROM petition_sign WHERE player_account = ? AND petitionguid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PETITION_OWNER_BY_GUID, "SELECT ownerguid FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PETITION_SIG_BY_GUID, "SELECT ownerguid, petitionguid FROM petition_sign WHERE playerguid = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_PETITION_SIG_BY_GUID_TYPE, "SELECT ownerguid, petitionguid FROM petition_sign WHERE playerguid = ? AND type = ?", CONNECTION_SYNCH);
// Arena teams
PrepareStatement(CHAR_SEL_CHARACTER_ARENAINFO, "SELECT arenaTeamId, weekGames, seasonGames, seasonWins, personalRating FROM arena_team_member WHERE guid = ?", CONNECTION_ASYNC);
@@ -492,7 +488,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_GROUP_INSTANCE_BY_MAP_DIFF, "DELETE FROM group_instance USING group_instance LEFT JOIN instance ON group_instance.instance = id WHERE map = ? and difficulty = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INSTANCE_BY_MAP_DIFF, "DELETE FROM instance WHERE map = ? and difficulty = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_MAIL_ITEM_BY_ID, "DELETE FROM mail_items WHERE mail_id = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_PETITION, "INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_PETITION, "INSERT INTO petition (ownerguid, petitionguid, name) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_BY_GUID, "DELETE FROM petition WHERE petitionguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID, "DELETE FROM petition_sign WHERE petitionguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
@@ -516,7 +512,10 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_CHAR_REP_FACTION_CHANGE, "UPDATE character_reputation SET faction = ?, standing = ? WHERE faction = ? AND guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_TITLES_FACTION_CHANGE, "UPDATE characters SET knownTitles = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_RES_CHAR_TITLES_FACTION_CHANGE, "UPDATE characters SET chosenTitle = 0 WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_DEL_CHAR_SPELL_COOLDOWN, "DELETE FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHAR_SPELL_COOLDOWNS, "DELETE FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_CHAR_SPELL_COOLDOWN, "INSERT INTO character_spell_cooldown (guid, spell, item, time) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHAR_SPELL_CHARGES, "DELETE FROM character_spell_charges WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_CHAR_SPELL_CHARGES, "INSERT INTO character_spell_charges (guid, categoryId, rechargeStart, rechargeEnd) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHARACTER, "DELETE FROM characters WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_ACTION, "DELETE FROM character_action WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_AURA, "DELETE FROM character_aura WHERE guid = ?", CONNECTION_ASYNC);
@@ -562,8 +561,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"spellPower, resilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_BY_OWNER, "DELETE FROM petition WHERE ownerguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER, "DELETE FROM petition_sign WHERE ownerguid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, "DELETE FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, "DELETE FROM petition_sign WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs (guid, talentGroup, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? and spell = ? and talentGroup = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, talentGroup) VALUES (?, ?, ?)", CONNECTION_ASYNC);
@@ -615,13 +612,16 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_PET_AURA, "SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges FROM pet_aura WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PET_AURA_EFFECT, "SELECT casterGuid, spell, effectMask, effectIndex, amount, baseAmount FROM pet_aura_effect WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PET_SPELL, "SELECT spell, active FROM pet_spell WHERE guid = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_PET_SPELL_COOLDOWN, "SELECT spell, time FROM pet_spell_cooldown WHERE guid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_PET_SPELL_COOLDOWN, "SELECT spell, time FROM pet_spell_cooldown WHERE guid = ? AND time > UNIX_TIMESTAMP()", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PET_DECLINED_NAME, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = ? AND id = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_PET_AURAS, "DELETE FROM pet_aura WHERE guid = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_DEL_PET_AURA_EFFECTS, "DELETE FROM pet_aura_effect WHERE guid = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_DEL_PET_SPELLS, "DELETE FROM pet_spell WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PET_SPELL_COOLDOWNS, "DELETE FROM pet_spell_cooldown WHERE guid = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_INS_PET_SPELL_COOLDOWN, "INSERT INTO pet_spell_cooldown (guid, spell, time) VALUES (?, ?, ?)", CONNECTION_BOTH);
+ PrepareStatement(CHAR_SEL_PET_SPELL_CHARGES, "SELECT categoryId, rechargeStart, rechargeEnd FROM pet_spell_charges WHERE guid = ? AND rechargeEnd > UNIX_TIMESTAMP() ORDER BY rechargeEnd", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_DEL_PET_SPELL_CHARGES, "DELETE FROM pet_spell_charges WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_PET_SPELL_CHARGES, "INSERT INTO pet_spell_charges (guid, categoryId, rechargeStart, rechargeEnd) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PET_SPELL_BY_SPELL, "DELETE FROM pet_spell WHERE guid = ? and spell = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_PET_SPELL, "INSERT INTO pet_spell (guid, spell, active) VALUES (?, ?, ?)", CONNECTION_BOTH);
PrepareStatement(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, casterGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges) "
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 6252b7e2e95..045a4c1fde6 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -111,6 +111,7 @@ enum CharacterDatabaseStatements
CHAR_SEL_CHARACTER_SOCIALLIST,
CHAR_SEL_CHARACTER_HOMEBIND,
CHAR_SEL_CHARACTER_SPELLCOOLDOWNS,
+ CHAR_SEL_CHARACTER_SPELL_CHARGES,
CHAR_SEL_CHARACTER_DECLINEDNAMES,
CHAR_SEL_GUILD_MEMBER,
CHAR_SEL_GUILD_MEMBER_EXTENDED,
@@ -214,8 +215,6 @@ enum CharacterDatabaseStatements
CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA,
CHAR_SEL_GUILD_ACHIEVEMENT,
CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA,
- CHAR_UPD_GUILD_EXPERIENCE,
- CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE,
CHAR_INS_GUILD_NEWS,
CHAR_SEL_CHANNEL,
@@ -274,14 +273,11 @@ enum CharacterDatabaseStatements
CHAR_SEL_PETITION,
CHAR_SEL_PETITION_SIGNATURE,
CHAR_DEL_ALL_PETITION_SIGNATURES,
- CHAR_DEL_PETITION_SIGNATURE,
CHAR_SEL_PETITION_BY_OWNER,
- CHAR_SEL_PETITION_TYPE,
CHAR_SEL_PETITION_SIGNATURES,
CHAR_SEL_PETITION_SIG_BY_ACCOUNT,
CHAR_SEL_PETITION_OWNER_BY_GUID,
CHAR_SEL_PETITION_SIG_BY_GUID,
- CHAR_SEL_PETITION_SIG_BY_GUID_TYPE,
CHAR_INS_PLAYER_BGDATA,
CHAR_DEL_PLAYER_BGDATA,
@@ -446,7 +442,10 @@ enum CharacterDatabaseStatements
CHAR_UPD_CHAR_REP_FACTION_CHANGE,
CHAR_UPD_CHAR_TITLES_FACTION_CHANGE,
CHAR_RES_CHAR_TITLES_FACTION_CHANGE,
- CHAR_DEL_CHAR_SPELL_COOLDOWN,
+ CHAR_DEL_CHAR_SPELL_COOLDOWNS,
+ CHAR_INS_CHAR_SPELL_COOLDOWN,
+ CHAR_DEL_CHAR_SPELL_CHARGES,
+ CHAR_INS_CHAR_SPELL_CHARGES,
CHAR_DEL_CHARACTER,
CHAR_DEL_CHAR_ACTION,
CHAR_DEL_CHAR_AURA,
@@ -490,8 +489,6 @@ enum CharacterDatabaseStatements
CHAR_INS_CHAR_STATS,
CHAR_DEL_PETITION_BY_OWNER,
CHAR_DEL_PETITION_SIGNATURE_BY_OWNER,
- CHAR_DEL_PETITION_BY_OWNER_AND_TYPE,
- CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE,
CHAR_INS_CHAR_GLYPHS,
CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC,
CHAR_INS_CHAR_TALENT,
@@ -525,6 +522,9 @@ enum CharacterDatabaseStatements
CHAR_DEL_PET_AURA_EFFECTS,
CHAR_DEL_PET_SPELL_COOLDOWNS,
CHAR_INS_PET_SPELL_COOLDOWN,
+ CHAR_SEL_PET_SPELL_CHARGES,
+ CHAR_DEL_PET_SPELL_CHARGES,
+ CHAR_INS_PET_SPELL_CHARGES,
CHAR_DEL_PET_SPELL_BY_SPELL,
CHAR_INS_PET_SPELL,
CHAR_INS_PET_AURA,
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp
index c370f347b93..34c3f37fee2 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp
@@ -91,4 +91,5 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_DEL_DISABLES, "DELETE FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA, "UPDATE creature SET zoneId = ?, areaId = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA, "UPDATE gameobject SET zoneId = ?, areaId = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_SEL_GUILD_REWARDS_REQ_ACHIEVEMENTS, "SELECT AchievementRequired FROM guild_rewards_req_achievements WHERE ItemID = ?", CONNECTION_SYNCH);
}
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h
index 36fd6fbb186..a6495833ec9 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.h
+++ b/src/server/shared/Database/Implementation/WorldDatabase.h
@@ -112,6 +112,7 @@ enum WorldDatabaseStatements
WORLD_DEL_DISABLES,
WORLD_UPD_CREATURE_ZONE_AREA_DATA,
WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA,
+ WORLD_SEL_GUILD_REWARDS_REQ_ACHIEVEMENTS,
MAX_WORLDDATABASE_STATEMENTS
};
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index 15d08a903b9..362b5b05168 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -97,8 +97,7 @@ void ShutdownThreadPool(std::vector<std::thread>& threadPool);
bool LoadRealmInfo();
variables_map GetConsoleArguments(int argc, char** argv, std::string& cfg_file, std::string& cfg_service);
-/// Launch the Trinity server
-extern int main(int argc, char** argv)
+int mainImpl(int argc, char** argv)
{
std::string configFile = _TRINITY_CORE_CONFIG;
std::string configService;
@@ -306,6 +305,25 @@ extern int main(int argc, char** argv)
return World::GetExitCode();
}
+/// Launch the Trinity server
+extern int main(int argc, char** argv)
+{
+ try
+ {
+ return mainImpl(argc, argv);
+ }
+ catch (std::exception& ex)
+ {
+ std::cerr << "Top-level exception caught:" << ex.what() << "\n";
+
+#ifndef NDEBUG // rethrow exception for the debugger
+ throw;
+#else
+ return 1;
+#endif
+ }
+}
+
void ShutdownCLIThread(std::thread* cliThread)
{
if (cliThread != nullptr)