aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/2013_01_15_01_world_misc.sql40
-rw-r--r--sql/updates/world/2013_01_15_02_world_game_event.sql1
-rw-r--r--sql/updates/world/2013_01_15_03_world_misc.sql88
-rw-r--r--sql/updates/world/2013_01_15_04_world_game_event.sql1
-rw-r--r--sql/updates/world/2013_01_15_05_world_creature_addon.sql1
-rw-r--r--sql/updates/world/2013_01_15_06_world_spell_script_names.sql3
-rw-r--r--sql/updates/world/2013_01_16_00_world_gossip_menu.sql4
-rw-r--r--sql/updates/world/2013_01_16_01_world_creature_text.sql7
-rw-r--r--sql/updates/world/2013_01_17_00_world_creature_template.sql2
-rw-r--r--sql/updates/world/2013_01_17_01_world_creature.sql8
-rw-r--r--sql/updates/world/2013_01_18_00_world_misc.sql72
-rw-r--r--sql/updates/world/2013_01_18_01_world_creature_template_addon.sql22
-rw-r--r--sql/updates/world/2013_01_18_02_world_creature_template_addon.sql634
-rw-r--r--sql/updates/world/2013_01_19_00_world_creature_text.sql1
-rw-r--r--sql/updates/world/2013_01_19_01_world_creature_text.sql2
-rw-r--r--sql/updates/world/2013_01_19_02_world_conditions.sql3
-rw-r--r--sql/updates/world/2013_01_19_03_world_creature_text.sql1
-rw-r--r--sql/updates/world/2013_01_19_04_world_creature_addon.sql29
-rw-r--r--sql/updates/world/2013_01_19_04_world_creature_text.sql1
-rw-r--r--sql/updates/world/2013_01_19_05_world_creature_addon.sql2
-rw-r--r--sql/updates/world/2013_01_19_06_world_misc.sql14
-rw-r--r--sql/updates/world/2013_01_19_06_world_trinity_string.sql28
-rw-r--r--sql/updates/world/2013_01_20_00_world_sai.sql1
-rw-r--r--sql/updates/world/2013_01_20_01_world_creature_text.sql10
-rw-r--r--sql/updates/world/2013_01_20_02_world_creature_text.sql10
-rw-r--r--sql/updates/world/2013_01_20_03_world_creature_text.sql15
-rw-r--r--sql/updates/world/2013_01_20_04_world_creature_text.sql12
-rw-r--r--sql/updates/world/2013_01_20_05_world_sai.sql41
-rw-r--r--sql/updates/world/2013_01_20_06_world_creature.sql24
-rw-r--r--sql/updates/world/2013_01_20_07_world_sai.sql5
-rw-r--r--src/server/authserver/Main.cpp4
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp46
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp39
-rw-r--r--src/server/game/Accounts/AccountMgr.h50
-rw-r--r--src/server/game/DataStores/DBCStores.cpp13
-rw-r--r--src/server/game/DataStores/DBCStores.h2
-rw-r--r--src/server/game/DataStores/DBCStructure.h14
-rw-r--r--src/server/game/DataStores/DBCfmt.h2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp39
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp31
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp3
-rw-r--r--src/server/game/Miscellaneous/Language.h27
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp6
-rw-r--r--src/server/game/Server/WorldSession.cpp35
-rw-r--r--src/server/game/Server/WorldSession.h3
-rw-r--r--src/server/game/Server/WorldSocket.cpp199
-rw-r--r--src/server/game/Server/WorldSocket.h43
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp9
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp114
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h9
-rw-r--r--src/server/game/Spells/SpellMgr.cpp2
-rw-r--r--src/server/game/Spells/SpellScript.cpp67
-rw-r--r--src/server/game/Spells/SpellScript.h72
-rw-r--r--src/server/game/World/World.cpp4
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp44
-rw-r--r--src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp112
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp58
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp10
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp515
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp26
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp111
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h19
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp2
-rw-r--r--src/server/scripts/Northrend/zone_sholazar_basin.cpp97
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp3
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.h3
-rw-r--r--src/server/shared/Logging/Appender.cpp4
-rw-r--r--src/server/shared/Logging/Appender.h2
-rw-r--r--src/server/shared/Logging/AppenderConsole.cpp2
-rw-r--r--src/server/shared/Logging/AppenderConsole.h2
-rw-r--r--src/server/shared/Logging/AppenderDB.cpp16
-rw-r--r--src/server/shared/Logging/AppenderDB.h11
-rw-r--r--src/server/shared/Logging/AppenderFile.cpp3
-rw-r--r--src/server/shared/Logging/AppenderFile.h2
-rw-r--r--src/server/shared/Logging/Log.cpp33
-rw-r--r--src/server/shared/Logging/Log.h4
-rw-r--r--src/server/worldserver/Master.cpp2
-rw-r--r--src/server/worldserver/RemoteAccess/RASocket.cpp2
-rw-r--r--src/server/worldserver/worldserver.conf.dist8
81 files changed, 2294 insertions, 716 deletions
diff --git a/sql/updates/world/2013_01_15_01_world_misc.sql b/sql/updates/world/2013_01_15_01_world_misc.sql
new file mode 100644
index 00000000000..48238e5dacf
--- /dev/null
+++ b/sql/updates/world/2013_01_15_01_world_misc.sql
@@ -0,0 +1,40 @@
+-- Vilebranch Speaker
+UPDATE `creature_template` SET `AIName`= '', `ScriptName`= 'mob_vilebranch_speaker' WHERE `entry`=11391;
+DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid`=11391;
+
+-- NPC talk text for Bloodlord Mandokir from sniff
+DELETE FROM `creature_text` WHERE `entry`=11382 AND `groupid`=4;
+INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
+(11382,4,0, '%s goes into a rage after seeing his raptor fall in battle!',16,0,100,0,0,0, 'Bloodlord Mandokir - Ohgan Dead');
+
+-- Bloodlord Mandokir path from sniff
+SET @PATH := 492861;
+DELETE FROM `creature_template_addon` WHERE `entry`=11382;
+INSERT INTO `creature_template_addon` (`entry`,`path_id`,`bytes2`,`auras`) VALUES (11382,@PATH,1, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`delay`,`move_flag`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,-12312.66,-1889.255,131.5301,0,1,0,100,0),
+(@PATH,2,-12368.16,-1861.005,131.5301,0,1,0,100,0),
+(@PATH,3,-12352.66,-1875.505,131.5301,0,1,0,100,0),
+(@PATH,4,-12351.41,-1876.505,130.7801,0,1,0,100,0),
+(@PATH,5,-12347.41,-1877.505,131.0301,0,1,0,100,0),
+(@PATH,6,-12343.16,-1877.505,131.2801,0,1,0,100,0),
+(@PATH,7,-12334.91,-1879.755,131.5301,0,1,0,100,0),
+(@PATH,8,-12329.91,-1889.505,131.0301,0,1,0,100,0),
+(@PATH,9,-12328.66,-1892.255,131.0301,0,1,0,100,0),
+(@PATH,10,-12326.41,-1894.255,131.2801,0,1,0,100,0),
+(@PATH,11,-12318.16,-1896.255,131.2801,0,1,0,100,0),
+(@PATH,12,-12301.41,-1896.255,131.5301,0,1,0,100,0),
+(@PATH,13,-12293.16,-1899.005,131.7801,0,1,0,100,0),
+(@PATH,14,-12292.16,-1899.005,131.7801,0,1,0,100,0),
+(@PATH,15,-12291.16,-1899.005,131.7801,0,1,0,100,0),
+(@PATH,16,-12289.41,-1900.505,131.7801,0,1,0,100,0),
+(@PATH,17,-12287.41,-1902.505,131.7801,0,1,0,100,0),
+(@PATH,18,-12285.41,-1904.755,131.7801,0,1,0,100,0),
+(@PATH,19,-12280.66,-1906.755,131.7801,0,1,0,100,0),
+(@PATH,20,-12276.41,-1907.755,131.7801,0,1,0,100,0),
+(@PATH,21,-12275.41,-1908.755,131.7801,0,1,0,100,0),
+(@PATH,22,-12272.41,-1917.255,131.7801,0,1,0,100,0),
+(@PATH,23,-12268.16,-1921.255,131.5301,0,1,0,100,0),
+(@PATH,24,-12259.91,-1919.255,131.0301,0,1,0,100,0),
+(@PATH,25,-12255.66,-1919.255,130.5301,0,1,0,100,0);
diff --git a/sql/updates/world/2013_01_15_02_world_game_event.sql b/sql/updates/world/2013_01_15_02_world_game_event.sql
new file mode 100644
index 00000000000..3300c0667ce
--- /dev/null
+++ b/sql/updates/world/2013_01_15_02_world_game_event.sql
@@ -0,0 +1 @@
+UPDATE `game_event` SET `start_time`='2013-10-18 01:00:00' WHERE `eventEntry`=12; -- Hallow's End
diff --git a/sql/updates/world/2013_01_15_03_world_misc.sql b/sql/updates/world/2013_01_15_03_world_misc.sql
new file mode 100644
index 00000000000..5de9e0ab13a
--- /dev/null
+++ b/sql/updates/world/2013_01_15_03_world_misc.sql
@@ -0,0 +1,88 @@
+-- Reconnaissance Flight (12671)
+
+SET @QUEST := 12671;
+SET @PLANE := 28710; -- Vic's Flying Machine
+SET @PILOT := 28646; -- Pilot Vic
+SET @VIC := 28746; -- Pilot Vic
+SET @SPELL_PLANE := 52256; -- Vic's Flying Machine Validate (must have condition to target player)
+SET @SPELL_ROCKETS := 52254; -- Air-to-Air Rockets
+SET @NPC_SCREECHER := 28170; -- Frosthowl Screecher
+SET @TEMP_LANDING := 300215; -- TEMP Landing Pad
+
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@VIC;
+UPDATE `creature_template` SET `spell1`='52254',`spell2`='52226',`ScriptName`='npc_vics_flying_machine' WHERE `entry`=@PLANE;
+
+DELETE FROM `creature_template_addon` WHERE `entry`=@PLANE;
+INSERT INTO `creature_template_addon` (`entry`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES
+(@PLANE,0,0,0,1,0,'52211 52260'); -- Flight -- Vic's Flying Machine Aggro Periodic
+
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@VIC,@PLANE) AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@VIC,0,0,0,19,0,100,0,@QUEST,0,0,0,11,@SPELL_PLANE,0,0,0,0,0,7,0,0,0,0,0,0,0,"On quest accept - Cast spell - Invoker");
+
+DELETE FROM `waypoint_data` WHERE `id`=@PLANE;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_flag`,`action`,`action_chance`,`wpguid`) VALUES
+(@PLANE,1,5494.87,4747.031,-187.8783,0,0,0,0,100,0),
+(@PLANE,2,5485.906,4740.681,-184.5172,0,0,0,0,100,0),
+(@PLANE,3,5472.882,4732.441,-172.1562,0,0,0,0,100,0),
+(@PLANE,4,5460.913,4712.542,-157.8784,0,0,0,0,100,0),
+(@PLANE,5,5452.147,4673.518,-137.8906,0,0,0,0,100,0),
+(@PLANE,6,5449.777,4630.711,-126.6684,0,0,0,0,100,0),
+(@PLANE,7,5507.432,4506.089,-126.6684,0,0,0,0,100,0),
+(@PLANE,8,5586.811,4465.319,-126.6684,0,0,0,0,100,0),
+(@PLANE,9,5676.111,4437.874,-126.6684,0,0,0,0,100,0),
+(@PLANE,10,5756.449,4391.051,-91.25155,0,0,0,0,100,0),
+(@PLANE,11,5817.163,4269.269,-91.25155,0,0,0,0,100,0),
+(@PLANE,12,5856.145,4202.824,-68.29334,0,0,0,0,100,0),
+(@PLANE,13,5921.523,4105.534,-68.29334,0,0,0,0,100,0),
+(@PLANE,14,5995.021,4029.883,-13.97897,0,0,0,0,100,0),
+(@PLANE,15,6118.298,3883.733,94.11866,0,0,0,0,100,0),
+(@PLANE,16,6132.932,3750.75,176.5123,0,0,0,0,100,0),
+(@PLANE,17,6165.863,3748.196,198.9567,0,0,0,0,100,0),
+(@PLANE,18,6208.277,3782.189,196.8455,0,0,0,0,100,0),
+(@PLANE,19,6227.615,3836.871,191.6234,0,0,0,0,100,0),
+(@PLANE,20,6218.483,3885.17,191.6234,0,0,0,0,100,0),
+(@PLANE,21,6197.045,3890.053,191.6234,0,0,0,0,100,0),
+(@PLANE,22,6168.752,3864.161,191.6234,0,0,0,0,100,0),
+(@PLANE,23,6204.037,3807.239,191.6234,0,0,0,0,100,0),
+(@PLANE,24,6232.975,3820.852,191.6234,0,0,0,0,100,0),
+(@PLANE,25,6219.879,3854.341,166.6234,0,0,0,0,100,0),
+(@PLANE,26,6210.428,3855.185,154.4848,0,0,0,0,100,0);
+
+DELETE FROM `npc_spellclick_spells` WHERE `npc_entry`=@PLANE;
+INSERT INTO `npc_spellclick_spells` (`npc_entry`,`spell_id`,`cast_flags`,`user_type`) VALUES
+(@PLANE,46598,1,1);
+
+DELETE FROM `vehicle_template_accessory` WHERE `entry`=@PLANE;
+INSERT INTO `vehicle_template_accessory` (`entry`,`accessory_entry`,`seat_id`,`minion`,`description`,`summontype`,`summontimer`) VALUES
+(@PLANE,@PILOT,0,1,'Pilot Vic',7,0);
+
+DELETE FROM `creature_text` WHERE `entry` IN (@PILOT,@PLANE);
+INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
+(@PILOT,0,0,'We''re off! Watch out for those vines!',12,0,100,0,0,0,'Pilot Vic to Vic''s Flying Machine'),
+(@PILOT,1,0,'Looks like the Scourge have hit the area ahead pretty bad...',12,0,100,0,0,0,'Pilot Vic to Vic''s Flying Machine'),
+(@PILOT,2,0,'You see that? She''s... huge!',12,0,100,0,0,0,'Pilot Vic to Vic''s Flying Machine'),
+(@PILOT,3,0,'Here we go! Hold on tight -- there''s rough wind ahead!',12,0,100,0,0,0,'Pilot Vic to Vic''s Flying Machine'),
+(@PILOT,4,0,'The glacier is seeping in from Icecrown... and undead everywhere! Wait ''til the professor gets a hold of this!',12,0,100,0,0,0,'Pilot Vic to Vic''s Flying Machine'),
+(@PILOT,5,0,'They''re coming at us! Be quick with those rockets!',12,0,100,0,0,0,'Pilot Vic to Vic''s Flying Machine'),
+(@PILOT,6,0,'Aggggh! I''m hit! You''re going to have to get us back! Quick, before the plane explodes!',12,0,100,0,0,0,'Pilot Vic to Vic''s Flying Machine'),
+(@PLANE,0,0,'The engine''s blown! Fly Vic''s Flying Machine back to Lakeside Landing!',41,0,100,0,0,0,'Vic''s Flying Machine to Pilot Vic');
+
+DELETE FROM `conditions` WHERE `SourceEntry`=@SPELL_ROCKETS AND `SourceTypeOrReferenceId`=13;
+DELETE FROM `conditions` WHERE `SourceEntry`=52226 AND `SourceTypeOrReferenceId`=17;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(13,1,@SPELL_ROCKETS,0,0,31,0,3,28170,0,0,0,0,'','Air-to-Air Rockets can target Frosthowl Screecher'),
+-- because vehicles ignore spell focus we add an extra condition to fill in for this
+(17,0,52226,0,0,30,0,300215,10,0,0,0,0,'','Requires TEMP Landing Pad near to cast Land Flying Machine');
+
+-- guessed position
+DELETE FROM `gameobject` WHERE `id`=@TEMP_LANDING;
+INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES
+(3552,@TEMP_LANDING,571,1,1,5505.58,4748.35,-194.434,0,0,0,0,0,300,0,1);
+
+-- Frosthowl Screecher
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@NPC_SCREECHER;
+DELETE FROM `creature_ai_scripts` WHERE `creature_id`=@NPC_SCREECHER;
+DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid`=@NPC_SCREECHER;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@NPC_SCREECHER,0,0,0,0,0,100,0,3000,4000,3000,4000,11,52257,0,0,0,0,0,2,0,0,0,0,0,0,0,'Cast Shadow Bolt');
diff --git a/sql/updates/world/2013_01_15_04_world_game_event.sql b/sql/updates/world/2013_01_15_04_world_game_event.sql
new file mode 100644
index 00000000000..cfbd399e43d
--- /dev/null
+++ b/sql/updates/world/2013_01_15_04_world_game_event.sql
@@ -0,0 +1 @@
+UPDATE `game_event` SET `start_time`='2013-09-13 00:01:00' WHERE `eventEntry`=11; -- Harvest Festival
diff --git a/sql/updates/world/2013_01_15_05_world_creature_addon.sql b/sql/updates/world/2013_01_15_05_world_creature_addon.sql
new file mode 100644
index 00000000000..94782891ca1
--- /dev/null
+++ b/sql/updates/world/2013_01_15_05_world_creature_addon.sql
@@ -0,0 +1 @@
+DELETE FROM `creature_addon` WHERE guid=49286;
diff --git a/sql/updates/world/2013_01_15_06_world_spell_script_names.sql b/sql/updates/world/2013_01_15_06_world_spell_script_names.sql
new file mode 100644
index 00000000000..0e327bdc63d
--- /dev/null
+++ b/sql/updates/world/2013_01_15_06_world_spell_script_names.sql
@@ -0,0 +1,3 @@
+DELETE FROM `spell_script_names` WHERE `spell_id`=24314;
+INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
+(24314, 'spell_threatening_gaze');
diff --git a/sql/updates/world/2013_01_16_00_world_gossip_menu.sql b/sql/updates/world/2013_01_16_00_world_gossip_menu.sql
new file mode 100644
index 00000000000..1b0554931fa
--- /dev/null
+++ b/sql/updates/world/2013_01_16_00_world_gossip_menu.sql
@@ -0,0 +1,4 @@
+-- Add some missing go gossip
+DELETE FROM `gossip_menu` WHERE `entry` IN (6448,6449,6450,6451);
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES
+(6448,7669),(6449,7670),(6450,7673),(6451,7674);
diff --git a/sql/updates/world/2013_01_16_01_world_creature_text.sql b/sql/updates/world/2013_01_16_01_world_creature_text.sql
new file mode 100644
index 00000000000..69bdd91b886
--- /dev/null
+++ b/sql/updates/world/2013_01_16_01_world_creature_text.sql
@@ -0,0 +1,7 @@
+-- Text for Crushridge Warmonger
+SET @ENTRY := 2287;
+DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
+INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
+(@ENTRY,0,0,'Raaar!!! Me smash $R',12,0,100,0,0,0,'Crushridge Warmonger'),
+(@ENTRY,0,1,'Me smash! You die!',12,0,100,0,0,0,'Crushridge Warmonger'),
+(@ENTRY,0,2,'I''ll crush you!',12,0,100,0,0,0,'Crushridge Warmonger');
diff --git a/sql/updates/world/2013_01_17_00_world_creature_template.sql b/sql/updates/world/2013_01_17_00_world_creature_template.sql
new file mode 100644
index 00000000000..af602096440
--- /dev/null
+++ b/sql/updates/world/2013_01_17_00_world_creature_template.sql
@@ -0,0 +1,2 @@
+-- proper faction for Bran in Halls of Stone
+UPDATE `creature_template` SET `faction_A`=1665,`faction_H`=1665 WHERE `entry` IN (28070,31366);
diff --git a/sql/updates/world/2013_01_17_01_world_creature.sql b/sql/updates/world/2013_01_17_01_world_creature.sql
new file mode 100644
index 00000000000..84ded6edcb2
--- /dev/null
+++ b/sql/updates/world/2013_01_17_01_world_creature.sql
@@ -0,0 +1,8 @@
+-- Spawn 4 missing Zul'Gurub Panther Triggers
+SET @GUID := 48311;
+DELETE FROM `creature` WHERE `guid` IN (@GUID,@GUID+1,@GUID+2,@GUID+3);
+INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`, `position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES
+(@GUID,15091,309,1,1,0,0,-11518.29,-1649.965,41.38264,5.131268,7200,0,0,1,0,0,0,0,0),
+(@GUID+1,15091,309,1,1,0,0,-11518.51,-1649.303,41.38264,5.864306,7200,0,0,1,0,0,0,0,0),
+(@GUID+2,15091,309,1,1,0,0,-11518.46,-1651.542,41.38264,0.2617994,7200,0,0,1,0,0,0,0,0),
+(@GUID+3,15091,309,1,1,0,0,-11516.86,-1604.25,41.38264,5.288348,7200,0,0,1,0,0,0,0,0);
diff --git a/sql/updates/world/2013_01_18_00_world_misc.sql b/sql/updates/world/2013_01_18_00_world_misc.sql
new file mode 100644
index 00000000000..e15a13f51a5
--- /dev/null
+++ b/sql/updates/world/2013_01_18_00_world_misc.sql
@@ -0,0 +1,72 @@
+SET @BRANN := 29579;
+SET @SNOW_TARGET := 29599;
+SET @QUEST := 12920;
+SET @GOSSIP := 9853;
+
+UPDATE `creature_template` SET `gossip_menu_id`=@GOSSIP, `minlevel`=80,`maxlevel`=80,`npcflag`=`npcflag`|1,`unit_flags`=`unit_flags`|32776, `AIName` = 'SmartAI', `equipment_id`=2485 WHERE `entry`=@BRANN;
+UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry`=@SNOW_TARGET;
+UPDATE `creature_model_info` SET `bounding_radius`=0.347,`combat_reach`=1.5,`gender`=0 WHERE `modelid`=26356;
+DELETE FROM `creature_template_addon` WHERE `entry` IN (@BRANN,@SNOW_TARGET);
+INSERT INTO `creature_template_addon` (`entry`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES
+(@BRANN,0,0,2,0, ''),
+(@SNOW_TARGET,0,0,1,0, '54717');
+DELETE FROM `creature_equip_template` WHERE `entry`=2485;
+INSERT INTO `creature_equip_template` (`entry`,`itemEntry1`,`itemEntry2`,`itemEntry3`) VALUES
+(2485,0,0,25972);
+
+DELETE FROM `npc_spellclick_spells` WHERE `npc_entry`=@BRANN;
+INSERT INTO `npc_spellclick_spells` (`npc_entry`,`spell_id`,`cast_flags`,`user_type`) VALUES
+(@BRANN,46598,1,1);
+DELETE FROM `vehicle_template_accessory` WHERE `entry`=@BRANN;
+INSERT INTO `vehicle_template_accessory` (`entry`,`accessory_entry`,`seat_id`,`minion`,`description`,`summontype`,`summontimer`) VALUES
+(@BRANN,@SNOW_TARGET,0,1,'Brann Snow Target',7,0);
+
+DELETE FROM `gossip_menu` WHERE `entry`=@GOSSIP AND `text_id`=13641;
+DELETE FROM `gossip_menu` WHERE `entry`=10145 AND `text_id`=14089;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES
+(@GOSSIP,13641),(10145,14089);
+DELETE FROM `gossip_menu_option` WHERE `menu_id`=@GOSSIP AND `id` IN (0,1);
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`)VALUES
+(@GOSSIP,0,0,'Do you understand me? We should be able to understand each other now.',1,1,0,0,0,0,''),
+(@GOSSIP,1,0,'What kind of help do you require?',1,1,10145,0,0,0,'');
+
+DELETE FROM `creature_text` WHERE `entry`=@BRANN;
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`) VALUES
+(@BRANN,0,0,"I... I can understand you now! Well, now that we can talk to each other, you have some explaining to do!",12,0,100,5,0,0,'Brann Bronzebeard text0'),
+(@BRANN,1,0,"How did you get my communicator from the Explorers League?",12,0,100,5,0,0,'Brann Bronzebeard text1'),
+(@BRANN,2,0,"If the Explorers League sent men, I didn't see any trace of them. I found your note buried in a camp overrun by iron dwarves.",12,0,100,0,0,0,'Player text2'),
+(@BRANN,3,0,"You have my thanks for dispatching the iron dwarves. But why would the Horde have an interest in me?",12,0,100,6,0,0,'Brann Bronzebeard text3'),
+(@BRANN,4,0,"A scout found the remains of your journal in Thor Modan. We've been looking for you ever since.",12,0,100,0,0,0,'Player text4'),
+(@BRANN,5,0,"That wouldn't be Scout Vor'takh, would it? Even I know of his reputation for ruthlessness. He means to abduct me, then?",12,0,100,5,0,0,'Brann Bronzebeard text5'),
+(@BRANN,6,0,"If you've seen the journal, then you know what I've been discovering. The titans' own creations are at war with each other!",12,0,100,5,0,0,'Brann Bronzebeard text6'),
+(@BRANN,7,0,"Loken and his iron dwarf minions have ousted the Earthen from Ulduar and taken over the city.",12,0,100,5,0,0,'Brann Bronzebeard text7'),
+(@BRANN,8,0,"If we spend our time and strength fighting with each other, Loken will use Ulduar's resources to destroy both Horde and Alliance.",12,0,100,6,0,0,'Brann Bronzebeard text8'),
+(@BRANN,9,0,"Speak to the commander at your post, lad, and persuade him to abandon Vor'takh's foolish plan.",12,0,100,6,0,0,'Brann Bronzebeard Text10');
+
+DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid` IN (@BRANN,@SNOW_TARGET);
+DELETE FROM `smart_scripts` WHERE `source_type`=9 AND `entryorguid`=@BRANN*100;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@BRANN,0,0,1,62,0,100,0,@GOSSIP,0,0,0,11,55579,2,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard - On gossip select - Spellcast Trigger Brann Signal'),
+(@BRANN,0,1,0,61,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard - On gossip select - Close gossip'),
+(@BRANN,0,2,0,8,0,100,0,55578,0,0,0,80,@BRANN*100,0,0,0,0,0,1,0,0,0,0,0,0,0,'Brann Bronzebeard - On spellhit Brann Signal to Self - Start script'),
+(@SNOW_TARGET,0,0,0,11,0,100,0,0,0,0,0,3,0,26241,0,0,0,0,1,0,0,0,0,0,0,0,'Brann Snow Target - On spawn - Morph to model'),
+(@BRANN*100,9,0,0,0,0,100,0,0,0,0,0,66,0,0,0,0,0,0,23,0,0,0,0,0,0,0,'Brann Bronzebeard script - Say text0'),
+(@BRANN*100,9,1,0,0,0,100,0,2000,2000,0,0,1,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Say text0'),
+(@BRANN*100,9,2,0,0,0,100,0,3100,3100,0,0,5,25,0,0,0,0,0,1,0,0,0,0,0,0,0,'Brann Bronzebeard script - Play emote point'),
+(@BRANN*100,9,3,0,0,0,100,0,3200,3200,0,0,1,1,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Say text1'),
+(@BRANN*100,9,4,0,0,0,100,0,5600,5600,0,0,84,2,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Player say text2'),
+(@BRANN*100,9,5,0,0,0,100,0,6300,6300,0,0,1,3,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Say text3'),
+(@BRANN*100,9,6,0,0,0,100,0,7200,7200,0,0,84,4,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Player say text4'),
+(@BRANN*100,9,7,0,0,0,100,0,6400,6400,0,0,1,5,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Say text5'),
+(@BRANN*100,9,8,0,0,0,100,0,7200,7200,0,0,1,6,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Say text6'),
+(@BRANN*100,9,9,0,0,0,100,0,7200,7200,0,0,1,7,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Say text7'),
+(@BRANN*100,9,10,0,0,0,100,0,7200,7200,0,0,1,8,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Say text8'),
+(@BRANN*100,9,11,0,0,0,100,0,7100,7100,0,0,1,9,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Say text9'),
+(@BRANN*100,9,12,0,0,0,100,0,3000,3000,0,0,33,@BRANN,0,0,0,0,0,7,0,0,0,0,0,0,0,'Brann Bronzebeard script - Quest credit');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=55578;
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=@GOSSIP;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13,1,55578,0,31,3,@BRANN,0,0,'', 'Spell Brann Signal to Self targets Brann'),
+(15,@GOSSIP,0,0,9,@QUEST,0,0,0,'', 'Show gossip menu option if player has quest 12920'),
+(15,@GOSSIP,1,0,9,12926,0,0,0,'', 'Show gossip menu option if player has quest 12926');
diff --git a/sql/updates/world/2013_01_18_01_world_creature_template_addon.sql b/sql/updates/world/2013_01_18_01_world_creature_template_addon.sql
new file mode 100644
index 00000000000..e3d6feaeecd
--- /dev/null
+++ b/sql/updates/world/2013_01_18_01_world_creature_template_addon.sql
@@ -0,0 +1,22 @@
+-- remove auras that are already applied in SAI
+UPDATE `creature_template_addon` SET `auras`='' WHERE `entry` IN (
+215, -- Defias Night Runner
+579, -- Shadowhide Assassin
+938, -- Kurzen Commando
+1040, -- Fen Creeper
+8550, -- Shadowmage
+9299, -- Gaeriyan
+10414, -- Patchwork Horror
+10426, -- Crimson Inquisitor
+10471, -- Scholomance Acolyte
+11885, -- Blighthound
+16017, -- Patchwork Golem
+16375, -- Sewage Slime
+21080, -- Dormant Infernal
+22853, -- Illidari Defiler
+24818, -- Anvilrage Taskmaster
+25596, -- Infected Kodo Beast
+25781, -- Oil Pool
+26624, -- Wretched Belcher
+26782, -- Crystalline Keeper
+28161); -- Chicken Escapee
diff --git a/sql/updates/world/2013_01_18_02_world_creature_template_addon.sql b/sql/updates/world/2013_01_18_02_world_creature_template_addon.sql
new file mode 100644
index 00000000000..716d59d8724
--- /dev/null
+++ b/sql/updates/world/2013_01_18_02_world_creature_template_addon.sql
@@ -0,0 +1,634 @@
+-- delete 632 creature_template_addon data that contain no information (bytes2=1 is the default)
+DELETE FROM `creature_template_addon` WHERE `entry` IN (
+890, -- Fawn
+6827, -- Crab
+8996, -- Voidwalker Minion
+9396, -- Ground Pounder
+10928, -- Succubus Minion
+15475, -- Beetle
+15547, -- Spectral Charger
+15548, -- Spectral Stallion
+15974, -- Dread Creeper
+15975, -- Carrion Spinner
+15979, -- Tomb Horror
+16017, -- Patchwork Golem
+16020, -- Mad Scientist
+16021, -- Living Monstrosity
+16022, -- Surgical Assistant
+16025, -- Stitched Giant
+16030, -- Maggot
+16036, -- Frenzied Bat
+16037, -- Plagued Bat
+16056, -- Diseased Maggot
+16057, -- Rotting Maggot
+16067, -- Deathcharger Steed
+16068, -- Larva
+16137, -- Naxxramas Military Sub-Boss Trigger
+16145, -- Death Knight Captain
+16154, -- Risen Squire
+16156, -- Dark Touched Warrior
+16165, -- Necro Knight
+16171, -- Coldmist Widow
+16173, -- Shadowbat
+16174, -- Greater Shadowbat
+16175, -- Vampiric Shadowbat
+16176, -- Shadowbeast
+16177, -- Dreadbeast
+16178, -- Phase Hound
+16194, -- Unholy Axe
+16211, -- Naxxramas Combat Dummy
+16215, -- Unholy Staff
+16216, -- Unholy Swords
+16244, -- Infectious Ghoul
+16297, -- Mutated Grub
+16375, -- Sewage Slime
+16412, -- Ghostly Baker
+16459, -- Wanton Hostess
+16460, -- Night Mistress
+16481, -- Ghastly Haunt
+16482, -- Trapped Soul
+16485, -- Arcane Watchman
+16488, -- Arcane Anomaly
+16489, -- Chaotic Sentience
+16491, -- Mana Feeder
+16492, -- Syphoner
+16506, -- Naxxramas Worshipper
+16525, -- Spell Shade
+16529, -- Magical Horror
+16530, -- Mana Warp
+16539, -- Homunculus
+16545, -- Ethereal Spellfilcher
+16595, -- Fleshbeast
+17260, -- Nightbane Helper Target
+17316, -- Chess Square, OUTSIDE BLACK (DND)
+17467, -- Skunk
+17644, -- Infernal Target
+17645, -- Infernal Relay
+17660, -- Skeletal Gryphon
+18955, -- Camera Shaker - 30-90 seconds
+20061, -- Frostbite Invisible Stalker
+21080, -- Dormant Infernal
+21728, -- Skettis Surger
+21804, -- Skettis Kaliri
+21921, -- Chess - Sound Bunny
+22519, -- Chess Piece: Karazhan Invisible Stalker
+22520, -- Chess Piece: Status Bar
+22523, -- Karazhan - Chess, Victory Dummy Tool
+22986, -- Skettis - Invis Raven Stone
+22991, -- Monstrous Kaliri Egg Trigger
+23225, -- Netherwing Drake Escape Point
+23638, -- Longtusk Fisherman
+23643, -- Unstable Mur'ghoul
+23644, -- Mur'ghoul Flesheater
+23645, -- Mur'ghoul Corrupter
+23667, -- Winterskorn Rune-Seer
+23668, -- Winterskorn Rune-Caster
+23669, -- Winterskorn Oracle
+23670, -- Winterskorn Elder
+23674, -- Iron Rune Sage
+23677, -- Frost Nymph
+23678, -- Chill Nymph
+23755, -- Blockade Pirate
+23771, -- Blockade Cannon
+23809, -- Vengeance Landing Cannoneer
+23810, -- Blockade Explosion Bunny
+23821, -- Valgarde Harpoon Target
+23867, -- Vengeance Landing Combatant Trigger
+23870, -- Ember Clutch Ancient
+23874, -- Thornvine Creeper
+23876, -- Spore
+23884, -- Vengeance Landing Crossbow Trigger
+23885, -- Lyana Trigger
+23886, -- Bull Lion Seal
+23887, -- Lion Seal
+23915, -- Westguard Cannon Trigger
+23916, -- Westguard Cannon Trigger (Water)
+23917, -- Cannon Source Trigger
+23919, -- Ice Elemental
+23929, -- Giant Tidecrawler
+23930, -- Trained Plaguehound
+23934, -- North Fleet Salvager
+24076, -- Winterskorn Worg
+24082, -- Proto-Drake Handler
+24084, -- Tunneling Ghoul
+24104, -- New Agamand Deathguard
+24110, -- ELM General Purpose Bunny Large
+24174, -- Fjord Rat
+24177, -- Decomposing Ghoul
+24182, -- Winterskorn Dwelling Credit
+24184, -- Winterskorn Barracks Credit
+24340, -- Rampaging Earth Elemental
+24439, -- Sack of Relics
+24440, -- Gjalerbron Gargoyle
+24469, -- Magnataur Huntress
+24562, -- Nerub'ar Invader
+24567, -- Den Vermin
+24613, -- Mammoth Calf
+24614, -- Wooly Mammoth
+24633, -- Rabid Brown Bear
+24635, -- Dragonflayer Harpooner
+24637, -- Great Reef Shark
+24642, -- Drunken Northsea Pirate
+24653, -- Flying Machine
+24673, -- Frostwing Chimaera
+24676, -- Crazed Northsea Slaver
+24677, -- Spearfang Worg
+24681, -- Island Shoveltusk
+24694, -- Vrykul Harpoon Gun (Wyrmskull)
+24846, -- Iron Dwarf
+24862, -- Mage Hunter Target
+24863, -- Frosthorn Kid
+24871, -- Risen Vrykul Ancestor
+24872, -- Blood Shade
+24883, -- Rodin Lightning Enabler
+24901, -- Maddened Frosthorn
+25198, -- Winterfin Gatherer
+25201, -- Winterfin Tadpole
+25204, -- Glimmer Bay Orca
+25215, -- Winterfin Shorestriker
+25216, -- Winterfin Oracle
+25217, -- Winterfin Warrior
+25225, -- Practice Dummy
+25350, -- Risen Longrunner
+25351, -- Ghostly Sage
+25355, -- Beryl Hound
+25362, -- Warsong Swine
+25377, -- Brittle Skeleton
+25378, -- En'kilah Necromancer
+25383, -- En'kilah Abomination
+25390, -- En'kilah Hatchling
+25391, -- En'kilah Focus Crystal
+25393, -- En'kilah Ghoul
+25396, -- Naxxanar Skeletal Mage
+25415, -- Enraged Tempest
+25417, -- Raging Boiler
+25419, -- Boiling Spirit
+25422, -- Mystical Webbing
+25428, -- Magmoth Shaman
+25429, -- Magmoth Forager
+25431, -- Kaskala Ancestor
+25432, -- Mate of Magmothregar
+25433, -- Offspring of Magmothregar
+25452, -- Scourged Mammoth
+25454, -- Tundra Crawler
+25464, -- Bloodspore Moth
+25468, -- Bloodspore Roaster
+25501, -- Gammoth Tender
+25534, -- En'kilah Blood Globe
+25600, -- Unliving Swine
+25610, -- Scourge Prisoner
+25615, -- Plagued Magnataur
+25623, -- Harvest Collector
+25651, -- Cultist Necrolyte
+25660, -- Festering Ghoul
+25668, -- Vengeful Taunka Spirit
+25670, -- ELM General Purpose Bunny (scale x3)
+25675, -- Tundra Wolf
+25677, -- Borean Frog
+25684, -- Talramas Abomination
+25685, -- Gorloc Waddler
+25686, -- Gorloc Gibberer
+25687, -- Gorloc Steam Belcher
+25699, -- Gorloc Mud Splasher
+25700, -- Gorloc Hunter
+25701, -- Gorloc Dredger
+25707, -- Magic-bound Ancient
+25709, -- Glacial Ancient
+25713, -- Blue Drakonid Supplicant
+25715, -- Frozen Elemental
+25717, -- Coldarra Scalesworn
+25718, -- Coldarra Mage Slayer
+25719, -- Coldarra Spellbinder
+25721, -- Arcane Serpent
+25722, -- Coldarra Spellweaver
+25724, -- Ascended Mage Hunter
+25728, -- Coldarra Wyrmkin
+25781, -- Oil Pool
+25829, -- Marsh Fawn
+25843, -- Northsea Thug
+25880, -- Minion of Kaw
+25981, -- Scourged Footman
+26047, -- Warsong Worg
+26126, -- Bone Warrior
+26161, -- Farshire Grain Credit
+26175, -- Coldarra - Drake Hunt Invisman
+26189, -- Fleeing Cultist
+26199, -- Snowfall Glade Den Mother
+26200, -- Snowfall Glade Pup
+26201, -- Snowfall Glade Shaman
+26202, -- Ziggurat Defender
+26402, -- Anub'ar Ambusher
+26411, -- Deranged Indu'le Villager
+26413, -- Anub'ar Dreadweaver
+26418, -- Longhoof Grazer
+26435, -- Taunka Move Trigger
+26446, -- Ice Serpent
+26455, -- Moonrest Highborne
+26458, -- Drakkari Plaguebringer
+26461, -- Scourge Corpserender
+26472, -- Highland Mustang
+26480, -- Magnataur Youngling
+26481, -- Magnataur Alpha
+26482, -- Arctic Grizzly
+26488, -- Taunka Pack Kodo
+26492, -- Wastes Digger
+26525, -- Cockroach
+26555, -- Scourge Hulk
+26606, -- Anub'ar Slayer
+26624, -- Wretched Belcher
+26625, -- Darkweb Recluse
+26628, -- Drakkari Scytheclaw
+26636, -- Risen Drakkari Soulmage
+26644, -- Ursus Mauler
+26646, -- Saronite Horror
+26658, -- Reckless Scavenger
+26662, -- Azjol-anak Battleguard
+26669, -- Ymirjar Savage
+26670, -- Ymirjar Flesh Hunter
+26675, -- Spider Summon Target
+26705, -- Snowplain Disciple
+26706, -- Infected Grizzly Bear
+26711, -- Injured Mammoth
+26712, -- Crystal Channel Target
+26728, -- Mage Hunter Initiate
+26729, -- Steward
+26782, -- Crystalline Keeper
+26792, -- Crystalline Protector
+26793, -- Crystalline Frayer
+26889, -- The End of the Line Area Trigger Kill Credit Bunny
+26891, -- Undead Miner
+26937, -- Gong Bunny
+26948, -- Hulking Atrocity
+27165, -- Drained Moonrest Highborne
+27230, -- Silvercoat Stag
+27247, -- Devout Bodyguard
+27254, -- Emerald Lasher
+27283, -- Risen Wintergarde Mage
+27286, -- Dreadbone Invader
+27290, -- Hungering Dead
+27358, -- Burning Depths Necromancer
+27363, -- Smoldering Geist
+27375, -- Risen Gryphon Rider Target
+27402, -- Bone Target Bunny
+27403, -- Strange Ore Target
+27408, -- Duskhowl Prowler
+27418, -- Rothin's Spell Bunny
+27421, -- Fern Feeder Moth
+27438, -- Rainbow Trout
+27449, -- Neltharion's Flame Fire Bunny
+27452, -- Invisible Stalker Grizzly Hills
+27460, -- Mother of Bambina
+27496, -- Refurbished Shredder
+27513, -- Covetous Geist
+27551, -- Enraged Apparition
+27552, -- Reanimated Noble
+27607, -- Plague Wagon
+27633, -- Azure Inquisitor
+27635, -- Azure Spellbinder
+27636, -- Azure Ley-Whelp
+27639, -- Ring-Lord Sorceress
+27640, -- Ring-Lord Conjurer
+27641, -- Centrifuge Construct
+27685, -- Frigid Ghoul Attacker
+27686, -- Frigid Geist Attacker
+27688, -- Alliance Lumberboat
+27689, -- Alliance Lumberboat Explosions
+27702, -- Horde Lumberboat
+27725, -- Ruby Guardian
+27737, -- Risen Zombie
+27745, -- Lordaeron Footman
+27746, -- Lordaeron Knight
+27747, -- High Elf Mage-Priest
+27752, -- High Elf Sorceress
+27823, -- Naxxramas Dreadguard
+27824, -- Naxxramas Shade
+27827, -- Grain Crate Helper
+27836, -- Wailing Soul
+27852, -- Wintergrasp Control Arms
+27869, -- Wintergrasp Detection Unit
+27909, -- Darkweb Victim
+27927, -- Dragonflayer Guardian
+27965, -- Dark Rune Shaper
+27970, -- Raging Construct
+27971, -- Unrelenting Construct
+28001, -- Dreadsaber
+28002, -- Mangal Crocolisk
+28003, -- Bittertide Hydra
+28005, -- Wastes Scavenger
+28008, -- Galakrond Spell Dummy
+28010, -- Stranded Thresher
+28011, -- Emperor Cobra
+28016, -- Drakuru
+28024, -- Rainspeaker Warrior
+28025, -- Rainspeaker Oracle
+28130, -- Invis Lightning Stalker
+28161, -- Chicken Escapee
+28169, -- Stratholme Resident
+28170, -- Frosthowl Screecher
+28202, -- Zul'Drak Rat
+28217, -- Injured Rainspeaker Oracle
+28218, -- Snowblind Ghoul
+28220, -- Frostbitten Corpse
+28221, -- Trapdoor Crawler
+28231, -- Crystalline Tender
+28233, -- Zul'Drak Bat
+28234, -- Tribunal of the Ages
+28242, -- Risen Reaver
+28246, -- Sky Terror
+28254, -- Mistwhisper Lightning Target
+28268, -- Scourged Argent Footman
+28274, -- Plague Sprayer
+28277, -- Harry's Bomber
+28351, -- Flame Breath Trigger (Skadi)
+28367, -- Acherus Dummy
+28407, -- Fjord Penguin
+28417, -- Priest of Rhunok
+28419, -- Frenzied Geist
+28440, -- Tundra Penguin
+28452, -- Elemental Rift
+28466, -- Fruit Tosser
+28492, -- Drak'Tharon - Drakuru Event Invisman 00
+28498, -- The Lich King
+28504, -- Jin'Alai Medicine Man
+28519, -- Withered Troll
+28523, -- Nass Target KC Bunny
+28559, -- Citizen of New Avalon
+28560, -- Citizen of New Avalon
+28584, -- Unbound Firestorm
+28585, -- Slag
+28605, -- Havenshire Stallion
+28627, -- Wood Pile Dummy
+28643, -- Rain of Darkness Dummy
+28655, -- Sky Darkener Target
+28660, -- Citizen of Havenshire
+28662, -- Citizen of Havenshire
+28717, -- Overlord Drakuru
+28733, -- Anub'ar Shadowcaster
+28739, -- Blight Cauldron Bunny 00
+28745, -- Alarmed Blightguard
+28750, -- Blight Geist
+28751, -- Geist WP Bunny
+28769, -- Shadowy Tormentor
+28778, -- Scourgewagon Bunny
+28789, -- Explosion Guy
+28804, -- Plague Spreader
+28826, -- Stormfury Revenant
+28833, -- Scarlet Cannon
+28835, -- Stormforged Construct
+28839, -- Scarlet Cover Dummy
+28850, -- Scarlet Land Cannon
+28901, -- Acherus Deathcharger
+28903, -- Scourge Plaguehound
+28905, -- Gluttonous Geist
+28906, -- Scourge Gryphon
+28920, -- Stormforged Giant
+28931, -- Blightblood Troll
+28932, -- Blight Effect Bunny
+28935, -- Acherus Dummy
+28960, -- Totally Generic Bunny (JSB)
+29013, -- Perch Guardian
+29026, -- Kolramas Slime
+29027, -- Wild Growth Stalker
+29036, -- Servant of Freya
+29048, -- Ulduar Monitor
+29104, -- Scarlet Ballista
+29128, -- Anub'ar Prime Guard
+29189, -- Howling Geist
+29301, -- Camp Winterhoof Wayfarer
+29326, -- Ichoron Summon Target
+29328, -- Arctic Hare
+29392, -- Ravenous Jaws
+29395, -- Erekem Guard
+29444, -- Drakkari Snake
+29449, -- Vargul Deathwaker
+29450, -- Vargul Runelord
+29452, -- Vargul Blighthound
+29461, -- Icetip Crawler
+29466, -- Goblin Prisoner
+29479, -- Shoveltusk Forager
+29483, -- K3 Perimeter Turret
+29485, -- Dolomite Giant
+29486, -- Tamed Shoveltusk
+29487, -- Wild Shoveltusk
+29504, -- Seething Revenant
+29517, -- Darkmender's Ghoul
+29521, -- Unworthy Initiate Anchor
+29549, -- Brunnhildar Riding Bear
+29551, -- Brunnhildar Bearhandler
+29558, -- Frost Giant Target Bunny
+29559, -- Lion Seal Whelp
+29562, -- Icemaw Bear
+29614, -- Onslaught Darkweaver
+29630, -- Fanged Pit Viper
+29682, -- Slad'ran Summon Target
+29697, -- Drakuru Prophet
+29700, -- Drakuru Shackles
+29710, -- Onslaught Destrier
+29730, -- Frostborn Stormrider
+29746, -- Databank
+29752, -- Databank Core
+29774, -- Spitting Cobra
+29798, -- Hyldsmeet Proto-Drake
+29805, -- Captive Proto Drake Beam Bunny
+29811, -- Frostborn Scout
+29820, -- Drakkari God Hunter
+29822, -- Drakkari Fire Weaver
+29826, -- Drakkari Medicine Man
+29830, -- Living Mojo
+29832, -- Drakkari Golem
+29912, -- Obedience Crystal
+29920, -- Ruins Dweller
+29958, -- Tundra Ram
+29960, -- Earthen Stoneguard
+30012, -- Victorious Challenger
+30046, -- Yulda the Stormspeaker
+30066, -- Valkyrion Harpoon Gun
+30071, -- Stitched Colossus
+30078, -- [DND]Wyrmrest Temple Beam Target
+30172, -- Ahn'kahar Swarm Egg
+30173, -- Ahn'kahar Guardian Egg
+30181, -- Jedoga Controller
+30236, -- Argent Cannon
+30250, -- Valhalas Vargul
+30277, -- Ahn'kahar Slasher
+30278, -- Ahn'kahar Spell Flinger
+30286, -- Frostbringer
+30298, -- Invisible Stalker (Float, Uninteractible, LargeAOI)
+30312, -- Shadow Vault Boneguard
+30335, -- Shadow Vault Gryphon
+30416, -- Bound Fire Elemental
+30418, -- Bound Air Elemental
+30419, -- Bound Water Elemental
+30430, -- Sentry Worg
+30576, -- Vile Like Fire! Kill Credit Bunny
+30599, -- Vile Like Fire! Fire Bunny
+30633, -- Water Terror
+30640, -- [DND] Icecrown Airship (A) - Cannon Target
+30642, -- Water Terror
+30649, -- [DND] Icecrown Airship (H) - Cannon Target
+30651, -- [DND] Icecrown Airship (A) - Cannon, Odd
+30675, -- Argent Champion
+30687, -- Skeletal Constructor
+30689, -- Chained Abomination
+30701, -- Vile Creeper
+30842, -- Wandering Shadow
+30845, -- Living Lasher
+30848, -- Whispering Wind
+30857, -- Defense Dummy Target
+30887, -- Scourge Package
+30894, -- Lithe Stalker
+30897, -- Marnak
+30898, -- Kaddrak
+30899, -- Abedneum
+30900, -- Argent Mason
+30920, -- Lumbering Atrocity
+30947, -- Eidolon Watcher
+30951, -- Restless Lookout
+30952, -- Hungering Plaguehound
+30960, -- Risen Soldier
+30985, -- Summoned Soldier
+31041, -- Dispirited Ent
+31043, -- Reanimated Crusader
+31049, -- Geist Return Bunny
+31075, -- Scourge Bomb
+31077, -- Safirdrang's Chill Target
+31126, -- Agitated Stratholme Citizen
+31127, -- Agitated Stratholme Resident
+31131, -- Containment Crystal
+31140, -- Hulking Abomination
+31142, -- Icy Ghoul
+31145, -- Shadow Adept
+31147, -- Vicious Geist
+31150, -- Plagued Fiend
+31155, -- Malefic Necromancer
+31205, -- Risen Alliance Soldier
+31233, -- Sinewy Wolf
+31245, -- Invisible Ooze Stalker
+31250, -- Ebon Blade Defender
+31251, -- Shadow Vault Skirmisher
+31262, -- Blight Falconer
+31266, -- Shadow Vault Assaulter
+31280, -- Ymirheim Spear Gun
+31328, -- Fleeing Horde Soldier
+31330, -- Fleeing Horde Soldier
+31353, -- [DND] Icecrown Airship (N) - Attack Controller
+31411, -- Hulking Horror
+31438, -- Shadow Vault Abomination
+31554, -- Restless Lookout
+31556, -- Hungering Plaguehound
+31644, -- Cosmetic Trigger - Phase 1 - LAB
+31685, -- Borean Marmot
+31718, -- Frostbrood Whelp
+31731, -- Wyrm Reanimator
+31738, -- Cultist Corrupter
+31747, -- Necrotic Webspinner
+31754, -- Glacial Bonelord
+31779, -- Skeletal Archmage
+31780, -- Fallen Spiderlord
+31783, -- Vrykul Necrolord
+31786, -- Oil Slick
+31797, -- Ancient Sentinel
+31812, -- Decomposed Ghoul
+31813, -- Frostskull Magus
+31836, -- Blue Dragon Egg
+31847, -- Scavenging Geist
+31900, -- Scourge Banner-Bearer
+31915, -- Horde Transport Dropoff Bunny
+32149, -- Fallen Hero's Spirit
+32155, -- Destroyed War Machine
+32161, -- Scourge War Engineer
+32202, -- Desolation KC Bunny
+32236, -- Dark Subjugator
+32250, -- Overseer Faedris
+32255, -- Converted Hero
+32257, -- Scourge Converter
+32258, -- Gold Beetle
+32260, -- Enslaved Minion
+32262, -- Shadow Channeler
+32264, -- Aldur'thar Channel Bunny
+32278, -- Harbinger of Horror
+32280, -- Corp'rethar Guardian
+32284, -- Scourge Soulbinder
+32349, -- Cultist Shard Watcher
+32469, -- Ebon Blade Geist
+32479, -- Bone Guard
+32482, -- Pustulent Colossus
+32490, -- Scourge Deathcharger
+32498, -- Glacier Penguin
+32502, -- Ravaged Ghoul
+32505, -- Vargul Wanderer
+32507, -- Cultist Acolyte
+32520, -- Totally Generic Bunny (All Phase)
+32541, -- Initiate's Training Dummy
+32542, -- Disciple's Training Dummy
+32543, -- Veteran's Training Dummy
+32545, -- Initiate's Training Dummy
+32546, -- Ebon Knight's Training Dummy
+32593, -- Skittering Swarmer
+32647, -- Warsong Hold Practice Dummy
+32720, -- Violetta
+32770, -- Enraged Fleshrender
+32771, -- Stitched Brute
+32772, -- Skeletal Footsoldier
+32874, -- Iron Ring Guard
+32875, -- Iron Honor Guard
+32879, -- Thorim Controller
+32885, -- Captured Mercenary Soldier
+32892, -- Thorim Event Bunny
+32922, -- Dark Rune Champion
+32923, -- Dark Rune Commoner
+32924, -- Dark Rune Evoker
+32925, -- Dark Rune Warbringer
+33140, -- Thorim Golem Right Hand Bunny
+33141, -- Thorim Golem Left Hand Bunny
+33229, -- Melee Target
+33337, -- XT-Toy Pile
+33378, -- Thunder Orb
+33430, -- Guardian Lasher
+33431, -- Forest Swarmer
+33500, -- Vezax Bunny
+33525, -- Mangrove Ent
+33526, -- Ironroot Lasher
+33527, -- Nature's Blade
+33575, -- Channel Stalker Freya
+33661, -- Armsweep Stalker Kologarn
+33699, -- Storm Tempered Keeper
+33722, -- Storm Tempered Keeper
+33772, -- Faceless Horror
+33809, -- Rubble Stalker Kologarn
+33818, -- Twilight Adherent
+33819, -- Twilight Frost Mage
+33820, -- Twilight Pyromancer
+33822, -- Twilight Guardian
+33824, -- Twilight Shadowblade
+33838, -- Enslaved Fire Elemental
+33856, -- Bot Summon Trigger
+34014, -- Sanctum Sentry
+34069, -- Molten Colossus
+34133, -- Champion of Hodir
+34134, -- Winter Revenant
+34135, -- Winter Rumbler
+34137, -- Winter Jormungar
+34144, -- Expedition Mercenary
+34145, -- Expedition Engineer
+34146, -- Snow Mound (4)
+34150, -- Snow Mound (6)
+34151, -- Snow Mound (8)
+34184, -- Clockwork Mechanic
+34190, -- Hardened Iron Golem
+34191, -- Trash
+34196, -- Rune Etched Sentry
+34198, -- Iron Mender
+34267, -- Parts Recovery Technician
+34271, -- XD-175 Compactobot
+34273, -- XB-488 Disposalbot
+34300, -- Mature Lasher
+34319, -- [DND] Champion Go-To Bunny
+34716, -- Captive Aspirant
+34907, -- Kvaldir Harpooner
+35106, -- Black Knight Caster
+35473, -- Argent Tournament Post
+35482, -- Hungry Jormungar
+36829, -- Deathspeaker High Priest
+40091, -- Orb Rotation Focus
+40146); -- Halion Controller
diff --git a/sql/updates/world/2013_01_19_00_world_creature_text.sql b/sql/updates/world/2013_01_19_00_world_creature_text.sql
new file mode 100644
index 00000000000..ed52fe13b29
--- /dev/null
+++ b/sql/updates/world/2013_01_19_00_world_creature_text.sql
@@ -0,0 +1 @@
+UPDATE `creature_text` SET `sound`=5802 WHERE `entry`=4832 AND `groupid`=0;
diff --git a/sql/updates/world/2013_01_19_01_world_creature_text.sql b/sql/updates/world/2013_01_19_01_world_creature_text.sql
new file mode 100644
index 00000000000..4fb6bc55c87
--- /dev/null
+++ b/sql/updates/world/2013_01_19_01_world_creature_text.sql
@@ -0,0 +1,2 @@
+UPDATE `creature_text` SET `text`='Just...Dust…',`sound`=5803 WHERE `entry`=4832 AND `groupid`=2;
+UPDATE `creature_text` SET `text`='Who dares disturb my meditation!' WHERE `entry`=4832 AND `groupid`=0;
diff --git a/sql/updates/world/2013_01_19_02_world_conditions.sql b/sql/updates/world/2013_01_19_02_world_conditions.sql
new file mode 100644
index 00000000000..744029f4fa0
--- /dev/null
+++ b/sql/updates/world/2013_01_19_02_world_conditions.sql
@@ -0,0 +1,3 @@
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=35475;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 7, 35475, 0, 0, 27, 0, 80, 2, 0, 0, 0, 0, '', 'Drums of War - level restriction');
diff --git a/sql/updates/world/2013_01_19_03_world_creature_text.sql b/sql/updates/world/2013_01_19_03_world_creature_text.sql
new file mode 100644
index 00000000000..d9a15f4da7a
--- /dev/null
+++ b/sql/updates/world/2013_01_19_03_world_creature_text.sql
@@ -0,0 +1 @@
+UPDATE `creature_text` SET `text`='Just...Dust...' WHERE `entry`=4832 AND `groupid`=2;
diff --git a/sql/updates/world/2013_01_19_04_world_creature_addon.sql b/sql/updates/world/2013_01_19_04_world_creature_addon.sql
new file mode 100644
index 00000000000..fbe99d8edf2
--- /dev/null
+++ b/sql/updates/world/2013_01_19_04_world_creature_addon.sql
@@ -0,0 +1,29 @@
+UPDATE `creature_addon` SET `auras`='' WHERE `guid` IN (
+9785,9784,9771, -- Devotion Aura On Dragonmaw Swamprunner, Centurion, Bonewarder
+5056, -- Unholy Shield on Morbent Fel
+16707,16719,16733,16735,16737,16751,16754,16771,16796,16863,16962,16963,16987,17004,17005,17006,17010,17013,17017,17018,17021,17028, -- Stealth on Syndicate Spy
+16709,16880,16881,16882,16883,16901,16985,17031,17032,17044,17047,17048,17051,17097, -- Stealth on Syndicate Assassin
+11547,11550,11577,11608,11612,11654,11696,11812,11976,12904,12910,12912,13251,13303,13304,13310,13311,13313,13315, -- Stealth on Syndicate Highwayman
+14652, -- Shadow Channeling on Marez Cowl
+13594,13598, -- Defensive Stance on Bael'dun Excavator
+14055, -- Stealth on Mad Magglish
+33157,33158,33159,33160,33161,33162, -- Stealth on Felmusk Shadowstalker
+34187,34189,34191, -- Bear form on Cenarion Protector
+32349, -- Sleep visual on Relara Whitemoon
+40101,40087,40055,40050,40042,40030,40012,40001, -- Inner Fire on Scarlet Chaplain
+31208,31214,31360,31385,31387,31390,31391,31393,31463,31473,31607,31608,31617,31619,31622, -- Fire Shield on Fireman Scalebane
+81447,81446,81444,81440,43695,42624,42622,42607,42605, -- Demon Skin on Sandfury Shadowcaster
+91931,92324,92513,92665,92670,92671, -- Disease Cloud on Stiched Golem
+48477,48563,48585,48761,48765,48768,48769,48772,48809,48816,48818,48827,48832,48836,48837,48921,48922,48923,48924,48926,48983,48987,48993,48999,91411,91412,91415, -- Disease Cloud on Diseased Ghoul
+81927,81931,81940,81987,81995,82301,82316,82341,82355,82378,82394,82396,82397,82413,82426,82479,82510,82611,82612,82613,82615,82662,82763,82771, -- Draining Touch on Vampiric Mistbat
+61856,61928,61931,61940, -- Thorns on Barbed Crawler
+67462,67465,67468,67469, -- Arcane Shield on Warp Aberration
+74883, -- Freeze Anim on Legion Hold Fel Reaver
+132572, -- Shroud of Death on Time-Lost Skettis High Priest
+76348,76349,76351,76353,76355,76356,76358,76359,76360,76362,76363,76364,76365,76366,76368,76369,76370,76371,76372,76373,76374,76376, -- Ghostly Facade on Cleric of Karabor
+12803,12802,12801,12800,12799,12798, -- Lightning Shield on Ashtongue Stormcaller
+132849,132850,132852,132853,132855,132851,132854,132856,132857, -- Phasing Invisibility on Blackwind Warp Chaser
+32943, -- Cat form on Becanna Edune
+132863, -- Oil coat on Oil-Stained Wolf
+126539,126542,126553,126556,126562,126564,126567,126568,126569,126572,126574,126579,126582, -- Arcane Missiles on Crazed Mana-Wraith
+127067); -- Head Crack on Drakkari Earthhshaker
diff --git a/sql/updates/world/2013_01_19_04_world_creature_text.sql b/sql/updates/world/2013_01_19_04_world_creature_text.sql
new file mode 100644
index 00000000000..c14cf5c149a
--- /dev/null
+++ b/sql/updates/world/2013_01_19_04_world_creature_text.sql
@@ -0,0 +1 @@
+UPDATE `creature_text` SET `text`='Who dares disturb my meditation?' WHERE `entry`=4832 AND `groupid`=0;
diff --git a/sql/updates/world/2013_01_19_05_world_creature_addon.sql b/sql/updates/world/2013_01_19_05_world_creature_addon.sql
new file mode 100644
index 00000000000..0a384501e36
--- /dev/null
+++ b/sql/updates/world/2013_01_19_05_world_creature_addon.sql
@@ -0,0 +1,2 @@
+-- delete 31 creature_addon data that contain no information (bytes2=1 is the default)
+DELETE FROM `creature_addon` WHERE `guid` IN (132572,126539,126542,126553,126556,126562,126564,126567,126568,126569,126572,126574,126579,126582,127067,132849,132850,132851,132852,132853,132854,132855,132856,132857,132863,108034,108035,108036,108037,203372,203373);
diff --git a/sql/updates/world/2013_01_19_06_world_misc.sql b/sql/updates/world/2013_01_19_06_world_misc.sql
new file mode 100644
index 00000000000..55d9777a71c
--- /dev/null
+++ b/sql/updates/world/2013_01_19_06_world_misc.sql
@@ -0,0 +1,14 @@
+UPDATE `quest_template` SET `PrevQuestId`=12872 WHERE `Id` IN (12871,12885);
+UPDATE `quest_template` SET `PrevQuestId`=12928 WHERE `Id` IN (12929,13273);
+
+UPDATE `gameobject_template` SET `flags`=`flags`|4 WHERE `entry` IN
+(188364,188501,188502,188503,186684,186390,186950,186954,186955,186912,186662,186618,186587,186595,186607,186938,187027,186427,187026,187022,187023,188702,188703,188705,189983,186632,186619,186591,186397,
+186640,186679,186828,186830,186832,186885,186886,187033,187381,187577,187683,187684,187685,187686,187687,187885,187886,188015,188016,188017,188066,188120,188462,188489,188646,188650,188658,188659,189288,
+189293,189295,189298,189306,190127,190189,190354,190483,190484,190578,190612,190613,190614,190623,190624,190625,190643,190696,190720,191179,191567,191814,191815,192058,192171,192172,192556,192676,192693,
+193091,193092,193196,193197,193404,193560,193561,193767,193792,193793,193943,193945,193946,194158,194159,194238,194340,194341,194423,194424,195022,195037,195274,195344,201367,201384,201794,201937);
+
+UPDATE `gameobject_template` SET `flags`=`flags`|16 WHERE `entry` IN
+(193603,193905,193967,194158,194159,195046,195047,195323,195324,195374,195375,195631,195632,195633,195635,195709,195710,201710,201959);
+
+UPDATE `gameobject_template` SET `faction`=94 WHERE `entry` IN (195046,195047,195631,195632,195633,195635);
+UPDATE `gameobject_template` SET `faction`=35 WHERE `entry` IN (201710,201959);
diff --git a/sql/updates/world/2013_01_19_06_world_trinity_string.sql b/sql/updates/world/2013_01_19_06_world_trinity_string.sql
new file mode 100644
index 00000000000..322d43a7720
--- /dev/null
+++ b/sql/updates/world/2013_01_19_06_world_trinity_string.sql
@@ -0,0 +1,28 @@
+DELETE FROM `trinity_string` WHERE `entry` BETWEEN 820 AND 842;
+INSERT INTO `trinity_string`(`entry`,`content_default`) VALUES
+(820,'* has gossip (%u)'),
+(821,'* is quest giver (%u)'),
+(822,'* is class trainer (%u)'),
+(823,'* is profession trainer(%u)'),
+(824,'* is ammo vendor (%u)'),
+(825,'* is food vendor(%u)'),
+(826,'* is poison vendor (%u)'),
+(827,'* is reagent vendor (%u)'),
+(828,'* can repair (%u)'),
+(829,'* is flight master (%u)'),
+(830,'* is spirit healer (%u)'),
+(831,'* is spirit guide (%u)'),
+(832,'* is innkeeper (%u)'),
+(833,'* is banker (%u)'),
+(834,'* is petitioner (%u)'),
+(835,'* is tabard designer (%u)'),
+(836,'* is battle master (%u)'),
+(837,'* is auctioneer (%u)'),
+(838,'* is stable master (%u)'),
+(839,'* is guild banker (%u)'),
+(840,'* has spell click (%u)'),
+(841,'* is mailbox (%u)'),
+(842,'* is player vehicle (%u)');
+
+UPDATE `trinity_string` SET `content_default`='* is vendor (%u)' WHERE `entry`=545;
+UPDATE `trinity_string` SET `content_default`='* is trainer (%u)' WHERE `entry`=546;
diff --git a/sql/updates/world/2013_01_20_00_world_sai.sql b/sql/updates/world/2013_01_20_00_world_sai.sql
new file mode 100644
index 00000000000..d4e4bb81c41
--- /dev/null
+++ b/sql/updates/world/2013_01_20_00_world_sai.sql
@@ -0,0 +1 @@
+UPDATE `smart_scripts` SET `event_type`=25,`event_flags`=0,`event_param1`=0,`event_param2`=0 WHERE `entryorguid`=16029 AND `source_type`=0 AND `id`=0; -- Sludge Belcher
diff --git a/sql/updates/world/2013_01_20_01_world_creature_text.sql b/sql/updates/world/2013_01_20_01_world_creature_text.sql
new file mode 100644
index 00000000000..d543b02d9fc
--- /dev/null
+++ b/sql/updates/world/2013_01_20_01_world_creature_text.sql
@@ -0,0 +1,10 @@
+UPDATE `creature_text` SET `sound`=14344 WHERE `entry`=29310 AND `groupid`=1 AND `id`=0;
+UPDATE `creature_text` SET `sound`=14345 WHERE `entry`=29310 AND `groupid`=1 AND `id`=1;
+UPDATE `creature_text` SET `text`='Yogg-Saron! Grant me your power!', `sound`=14346 WHERE `entry`=29310 AND `groupid`=2 AND `id`=0;
+UPDATE `creature_text` SET `sound`=14347 WHERE `entry`=29310 AND `groupid`=2 AND `id`=1;
+UPDATE `creature_text` SET `sound`=14348 WHERE `entry`=29310 AND `groupid`=3 AND `id`=0;
+UPDATE `creature_text` SET `sound`=14349 WHERE `entry`=29310 AND `groupid`=3 AND `id`=1;
+UPDATE `creature_text` SET `sound`=14351 WHERE `entry`=29310 AND `groupid`=4;
+UPDATE `creature_text` SET `sound`=14354 WHERE `entry`=29310 AND `groupid`=5 AND `id`=2;
+UPDATE `creature_text` SET `sound`=14355 WHERE `entry`=29310 AND `groupid`=5 AND `id`=3;
+UPDATE `creature_text` SET `text`='The faithful shall be exalted, but there is more work to be done. We will press on until all of Azeroth lies beneath his shadow!', `sound`=14356 WHERE `entry`=29310 AND `groupid`=5 AND `id`=4;
diff --git a/sql/updates/world/2013_01_20_02_world_creature_text.sql b/sql/updates/world/2013_01_20_02_world_creature_text.sql
new file mode 100644
index 00000000000..25c8c046dfc
--- /dev/null
+++ b/sql/updates/world/2013_01_20_02_world_creature_text.sql
@@ -0,0 +1,10 @@
+UPDATE `creature_text` SET `sound`=14430, `type`=14 WHERE `entry`=29306 AND `groupid`=0;
+UPDATE `creature_text` SET `sound`=14431, `type`=14 WHERE `entry`=29306 AND `groupid`=4;
+UPDATE `creature_text` SET `sound`=14432, `type`=14 WHERE `entry`=29306 AND `groupid`=5;
+UPDATE `creature_text` SET `sound`=14433, `type`=14 WHERE `entry`=29306 AND `groupid`=3 AND `id`=0;
+UPDATE `creature_text` SET `sound`=14434, `type`=14 WHERE `entry`=29306 AND `groupid`=3 AND `id`=1;
+UPDATE `creature_text` SET `sound`=14435, `type`=14 WHERE `entry`=29306 AND `groupid`=3 AND `id`=2;
+UPDATE `creature_text` SET `sound`=14436, `type`=14 WHERE `entry`=29306 AND `groupid`=1 AND `id`=0;
+UPDATE `creature_text` SET `sound`=14437, `type`=14, `text`='Who needs gods when we ARE gods?' WHERE `entry`=29306 AND `groupid`=1 AND `id`=1;
+UPDATE `creature_text` SET `sound`=14438, `type`=14 WHERE `entry`=29306 AND `groupid`=1 AND `id`=2;
+UPDATE `creature_text` SET `sound`=14439, `type`=14 WHERE `entry`=29306 AND `groupid`=2;
diff --git a/sql/updates/world/2013_01_20_03_world_creature_text.sql b/sql/updates/world/2013_01_20_03_world_creature_text.sql
new file mode 100644
index 00000000000..1ea2c121e1e
--- /dev/null
+++ b/sql/updates/world/2013_01_20_03_world_creature_text.sql
@@ -0,0 +1,15 @@
+-- Moorabi
+UPDATE `creature_text` SET `sound`=14721, `text`='We fought back da Scourge. What chance joo thinkin'' JOO got?' WHERE `entry`=29305 AND `groupid`=0;
+UPDATE `creature_text` SET `sound`=14722 WHERE `entry`=29305 AND `groupid`=3;
+UPDATE `creature_text` SET `sound`=14723, `text`='Da ground gonna swallow you up!' WHERE `entry`=29305 AND `groupid`=4;
+UPDATE `creature_text` SET `sound`=14726, `text`='Who gonna stop me? You?' WHERE `entry`=29305 AND `groupid`=1 AND `id`=0;
+UPDATE `creature_text` SET `sound`=14727, `text`='Not so tough now!!' WHERE `entry`=29305 AND `groupid`=1 AND `id`=1;
+UPDATE `creature_text` SET `sound`=14728, `text`='If our gods can die... den so can we....' WHERE `entry`=29305 AND `groupid`=2;
+
+-- Slad'ran
+UPDATE `creature_text` SET `sound`=14444, `type`=14 WHERE `entry`=29304 AND `groupid`=3;
+UPDATE `creature_text` SET `sound`=14445, `type`=14, `text`='A thousssand fangsss gonna rend your flesh!' WHERE `entry`=29304 AND `groupid`=4;
+UPDATE `creature_text` SET `sound`=14446, `type`=14, `text`='You not breathin''? Good.' WHERE `entry`=29304 AND `groupid`=1 AND `id`=0;
+UPDATE `creature_text` SET `sound`=14447, `type`=14 WHERE `entry`=29304 AND `groupid`=1 AND `id`=1;
+UPDATE `creature_text` SET `sound`=14448, `type`=14, `text`='I eat you next, mon.' WHERE `entry`=29304 AND `groupid`=1 AND `id`=2;
+UPDATE `creature_text` SET `sound`=14449, `type`=14, `text`='I sssee now... Ssscourge wasss not... our greatessst enemy....' WHERE `entry`=29304 AND `groupid`=2;
diff --git a/sql/updates/world/2013_01_20_04_world_creature_text.sql b/sql/updates/world/2013_01_20_04_world_creature_text.sql
new file mode 100644
index 00000000000..5c457530f92
--- /dev/null
+++ b/sql/updates/world/2013_01_20_04_world_creature_text.sql
@@ -0,0 +1,12 @@
+-- Text for Crushridge Warmonger
+SET @ENTRY := 2287;
+DELETE FROM `creature_text` WHERE `entry`=@ENTRY AND `groupid`=1;
+INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
+(@ENTRY,1,0,'%s goes into a frenzy!',16,0,100,0,0,0,'Crushridge Warmonger');
+
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid` = 12236 AND `id`=9;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid` = 2428 AND `id`=10;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid` = 2287 AND `id`=1;
+UPDATE `smart_scripts` SET `event_flags`=1 WHERE `entryorguid` = 2287 AND `id`=3;
+UPDATE `smart_scripts` SET `action_param1`=1 WHERE `entryorguid` = 2287 AND `id`=4;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid` = 8561 AND `id`=11;
diff --git a/sql/updates/world/2013_01_20_05_world_sai.sql b/sql/updates/world/2013_01_20_05_world_sai.sql
new file mode 100644
index 00000000000..9539bc546b1
--- /dev/null
+++ b/sql/updates/world/2013_01_20_05_world_sai.sql
@@ -0,0 +1,41 @@
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=14390 AND `source_type`=0 AND `id`=9;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=2587 AND `source_type`=0 AND `id`=8;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=4064 AND `source_type`=0 AND `id`=9;
+UPDATE `smart_scripts` SET `link`=3 WHERE `entryorguid`=29181 AND `source_type`=0 AND `id`=2;
+UPDATE `smart_scripts` SET `link`=0,`event_type`=61,`event_param2`=0,`event_param3`=0 WHERE `entryorguid`=29181 AND `source_type`=0 AND `id`=3;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=29186 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=29199 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=29199 AND `source_type`=0 AND `id`=2;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=29204 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=29204 AND `source_type`=0 AND `id`=2;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=29200 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=29200 AND `source_type`=0 AND `id`=2;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=29176 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=500 AND `source_type`=0 AND `id`=10;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=4462 AND `source_type`=0 AND `id`=10;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=14467 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=2719 AND `source_type`=0 AND `id`=3;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=6004 AND `source_type`=0 AND `id`=9;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=23580 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=17270 AND `source_type`=0 AND `id`=13;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=29836 AND `source_type`=0 AND `id`=13;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=578 AND `source_type`=0 AND `id`=8;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=1397 AND `source_type`=0 AND `id`=14;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=1123 AND `source_type`=0 AND `id`=10;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=1123 AND `source_type`=0 AND `id`=16;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=3142 AND `source_type`=0 AND `id`=0;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=15641 AND `source_type`=0 AND `id`=9;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=424 AND `source_type`=0 AND `id`=9;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=19507 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=3643 AND `source_type`=1 AND `id`=0;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=1162 AND `source_type`=0 AND `id`=9;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=1162 AND `source_type`=0 AND `id`=10;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=3987 AND `source_type`=0 AND `id`=1;
+
+UPDATE `smart_scripts` SET `event_flags`=0 WHERE `entryorguid`=6066 AND `source_type`=0 AND `id`=0;
+UPDATE `smart_scripts` SET `event_flags`=1 WHERE `entryorguid`=8477 AND `source_type`=0 AND `id`=0;
+UPDATE `smart_scripts` SET `event_flags`=0 WHERE `entryorguid`=29206 AND `source_type`=0 AND `id`=0;
+UPDATE `smart_scripts` SET `event_flags`=0 WHERE `entryorguid`=29182 AND `source_type`=0 AND `id` IN (0,1);
+UPDATE `smart_scripts` SET `event_flags`=0 WHERE `entryorguid`=29177 AND `source_type`=0 AND `id`=0;
+UPDATE `smart_scripts` SET `event_flags`=1 WHERE `entryorguid`=29684 AND `source_type`=0 AND `id` IN (0,1);
+UPDATE `smart_scripts` SET `event_flags`=1 WHERE `entryorguid`=15631 AND `source_type`=0 AND `id`=0;
diff --git a/sql/updates/world/2013_01_20_06_world_creature.sql b/sql/updates/world/2013_01_20_06_world_creature.sql
new file mode 100644
index 00000000000..c00ff11ea4a
--- /dev/null
+++ b/sql/updates/world/2013_01_20_06_world_creature.sql
@@ -0,0 +1,24 @@
+-- Image of Commander Ameer <The Protectorate> (22919)
+SET @GUID := 43492;
+
+UPDATE `creature_template` SET `npcflag`=`npcflag`|2,`unit_flags`=`unit_flags`&~33554432 WHERE `entry`=22919;
+
+DELETE FROM `creature` WHERE `guid`=@GUID;
+INSERT INTO `creature` (`guid`,`id`,`map`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`curhealth`) VALUES
+(@GUID,22919,530,3866.55,5978.68,291.792,4.10061,300,6986);
+
+DELETE FROM `creature_questrelation` WHERE `id`=22919;
+INSERT INTO `creature_questrelation` (`id`,`quest`) VALUES
+(22919,10981), -- Nexus-Prince Shaffar's Personal Chamber
+(22919,10975), -- Purging the Chambers of Bash'ir
+(22919,10977), -- Stasis Chambers of the Mana-Tombs
+(22919,10976); -- The Mark of the Nexus-King
+
+DELETE FROM `creature_involvedrelation` WHERE `id`=22919;
+INSERT INTO `creature_involvedrelation` (`id`,`quest`) VALUES
+(22919,10981), -- Nexus-Prince Shaffar's Personal Chamber
+(22919,10975), -- Purging the Chambers of Bash'ir
+(22919,10974), -- Stasis Chambers of Bash'ir
+(22919,10977), -- Stasis Chambers of the Mana-Tombs
+(22919,10982), -- The Eye of Haramad
+(22919,10976); -- The Mark of the Nexus-King
diff --git a/sql/updates/world/2013_01_20_07_world_sai.sql b/sql/updates/world/2013_01_20_07_world_sai.sql
new file mode 100644
index 00000000000..f8d001e73db
--- /dev/null
+++ b/sql/updates/world/2013_01_20_07_world_sai.sql
@@ -0,0 +1,5 @@
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=234 AND `source_type`=0 AND `id`=0;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=2554 AND `source_type`=0 AND `id`=9;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=12265 AND `source_type`=0 AND `id`=1;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=12265 AND `source_type`=0 AND `id`=3;
+UPDATE `smart_scripts` SET `event_type`=61 WHERE `entryorguid`=16704 AND `source_type`=0 AND `id`=13;
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp
index f4f73e2c33d..c87df4ef7ab 100644
--- a/src/server/authserver/Main.cpp
+++ b/src/server/authserver/Main.cpp
@@ -134,8 +134,6 @@ extern int main(int argc, char **argv)
if (!StartDB())
return 1;
- sLog->SetRealmID(0); // ensure we've set realm to 0 (authserver realmid)
-
// Get the list of realms for the server
sRealmList->Initialize(ConfigMgr::GetIntDefault("RealmsStateUpdateDelay", 20));
if (sRealmList->size() == 0)
@@ -272,7 +270,7 @@ bool StartDB()
}
sLog->outInfo(LOG_FILTER_AUTHSERVER, "Started auth database connection pool.");
- sLog->EnableDBAppenders();
+ sLog->SetRealmId(0); // Enables DB appenders when realm is set.
return true;
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index c08e085e816..84c9dffabd2 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -2121,18 +2121,20 @@ SmartScriptHolder SmartScript::CreateEvent(SMART_EVENT e, uint32 event_flags, ui
ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*= NULL*/)
{
- Unit* trigger = NULL;
+ Unit* scriptTrigger = NULL;
if (invoker)
- trigger = invoker;
+ scriptTrigger = invoker;
else if (Unit* tempLastInvoker = GetLastInvoker())
- trigger = tempLastInvoker;
+ scriptTrigger = tempLastInvoker;
+
+ WorldObject* baseObject = GetBaseObject();
ObjectList* l = new ObjectList();
switch (e.GetTargetType())
{
case SMART_TARGET_SELF:
- if (GetBaseObject())
- l->push_back(GetBaseObject());
+ if (baseObject)
+ l->push_back(baseObject);
break;
case SMART_TARGET_VICTIM:
if (me && me->getVictim())
@@ -2160,17 +2162,17 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
break;
case SMART_TARGET_NONE:
case SMART_TARGET_ACTION_INVOKER:
- if (trigger)
- l->push_back(trigger);
+ if (scriptTrigger)
+ l->push_back(scriptTrigger);
break;
case SMART_TARGET_ACTION_INVOKER_VEHICLE:
- if (trigger && trigger->GetVehicle() && trigger->GetVehicle()->GetBase())
- l->push_back(trigger->GetVehicle()->GetBase());
+ if (scriptTrigger && scriptTrigger->GetVehicle() && scriptTrigger->GetVehicle()->GetBase())
+ l->push_back(scriptTrigger->GetVehicle()->GetBase());
break;
case SMART_TARGET_INVOKER_PARTY:
- if (trigger)
+ if (scriptTrigger)
{
- if (Player* player = trigger->ToPlayer())
+ if (Player* player = scriptTrigger->ToPlayer())
{
if (Group* group = player->GetGroup())
{
@@ -2182,7 +2184,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
// this even if there is a group (thus the else-check), it will add the
// same player to the list twice. We don't want that to happen.
else
- l->push_back(trigger);
+ l->push_back(scriptTrigger);
}
}
break;
@@ -2198,7 +2200,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (me && me == *itr)
continue;
- if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && GetBaseObject()->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist))
+ if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist))
l->push_back(*itr);
}
@@ -2255,7 +2257,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (go && go == *itr)
continue;
- if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && GetBaseObject()->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist))
+ if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist))
l->push_back(*itr);
}
@@ -2265,13 +2267,13 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
case SMART_TARGET_CREATURE_GUID:
{
Creature* target = NULL;
- if (!trigger && !GetBaseObject())
+ if (!scriptTrigger && !baseObject)
{
sLog->outError(LOG_FILTER_SQL, "SMART_TARGET_CREATURE_GUID can not be used without invoker");
break;
}
- target = FindCreatureNear(trigger ? trigger : GetBaseObject(), e.target.unitGUID.dbGuid);
+ target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid);
if (target && (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry))
l->push_back(target);
@@ -2280,13 +2282,13 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
case SMART_TARGET_GAMEOBJECT_GUID:
{
GameObject* target = NULL;
- if (!trigger && !GetBaseObject())
+ if (!scriptTrigger && !baseObject)
{
sLog->outError(LOG_FILTER_SQL, "SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker");
break;
}
- target = FindGameObjectNear(trigger ? trigger : GetBaseObject(), e.target.goGUID.dbGuid);
+ target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid);
if (target && (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry))
l->push_back(target);
@@ -2296,9 +2298,9 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
// will always return a valid pointer, even if empty list
ObjectList* units = GetWorldObjectsInDist((float)e.target.playerRange.maxDist);
- if (!units->empty() && GetBaseObject())
+ if (!units->empty() && baseObject)
for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
- if (IsPlayer(*itr) && GetBaseObject()->IsInRange(*itr, (float)e.target.playerRange.minDist, (float)e.target.playerRange.maxDist))
+ if (IsPlayer(*itr) && baseObject->IsInRange(*itr, (float)e.target.playerRange.minDist, (float)e.target.playerRange.maxDist))
l->push_back(*itr);
delete units;
@@ -2325,14 +2327,14 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
}
case SMART_TARGET_CLOSEST_CREATURE:
{
- Creature* target = GetClosestCreatureWithEntry(GetBaseObject(), e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), e.target.closest.dead ? false : true);
+ Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), e.target.closest.dead ? false : true);
if (target)
l->push_back(target);
break;
}
case SMART_TARGET_CLOSEST_GAMEOBJECT:
{
- GameObject* target = GetClosestGameObjectWithEntry(GetBaseObject(), e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100));
+ GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100));
if (target)
l->push_back(target);
break;
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index 01ba222d93b..3c3eded1f68 100644
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -24,10 +24,11 @@
#include "SHA1.h"
#include "WorldSession.h"
-namespace AccountMgr
+AccountMgr::AccountMgr()
{
+}
-AccountOpResult CreateAccount(std::string username, std::string password)
+AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password)
{
if (utf8length(username) > MAX_ACCOUNT_STR)
return AOR_NAME_TOO_LONG; // username's too long
@@ -52,7 +53,7 @@ AccountOpResult CreateAccount(std::string username, std::string password)
return AOR_OK; // everything's fine
}
-AccountOpResult DeleteAccount(uint32 accountId)
+AccountOpResult AccountMgr::DeleteAccount(uint32 accountId)
{
// Check if accounts exists
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BY_ID);
@@ -124,7 +125,7 @@ AccountOpResult DeleteAccount(uint32 accountId)
return AOR_OK;
}
-AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword)
+AccountOpResult AccountMgr::ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword)
{
// Check if accounts exists
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BY_ID);
@@ -154,7 +155,7 @@ AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::s
return AOR_OK;
}
-AccountOpResult ChangePassword(uint32 accountId, std::string newPassword)
+AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPassword)
{
std::string username;
@@ -177,7 +178,7 @@ AccountOpResult ChangePassword(uint32 accountId, std::string newPassword)
return AOR_OK;
}
-uint32 GetId(std::string const& username)
+uint32 AccountMgr::GetId(std::string const& username)
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCOUNT_ID_BY_USERNAME);
stmt->setString(0, username);
@@ -186,7 +187,7 @@ uint32 GetId(std::string const& username)
return (result) ? (*result)[0].GetUInt32() : 0;
}
-uint32 GetSecurity(uint32 accountId)
+uint32 AccountMgr::GetSecurity(uint32 accountId)
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCOUNT_ACCESS_GMLEVEL);
stmt->setUInt32(0, accountId);
@@ -195,7 +196,7 @@ uint32 GetSecurity(uint32 accountId)
return (result) ? (*result)[0].GetUInt8() : uint32(SEC_PLAYER);
}
-uint32 GetSecurity(uint32 accountId, int32 realmId)
+uint32 AccountMgr::GetSecurity(uint32 accountId, int32 realmId)
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_GMLEVEL_BY_REALMID);
stmt->setUInt32(0, accountId);
@@ -205,7 +206,7 @@ uint32 GetSecurity(uint32 accountId, int32 realmId)
return (result) ? (*result)[0].GetUInt8() : uint32(SEC_PLAYER);
}
-bool GetName(uint32 accountId, std::string& name)
+bool AccountMgr::GetName(uint32 accountId, std::string& name)
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_USERNAME_BY_ID);
stmt->setUInt32(0, accountId);
@@ -220,7 +221,7 @@ bool GetName(uint32 accountId, std::string& name)
return false;
}
-bool CheckPassword(uint32 accountId, std::string password)
+bool AccountMgr::CheckPassword(uint32 accountId, std::string password)
{
std::string username;
@@ -238,7 +239,7 @@ bool CheckPassword(uint32 accountId, std::string password)
return (result) ? true : false;
}
-uint32 GetCharactersCount(uint32 accountId)
+uint32 AccountMgr::GetCharactersCount(uint32 accountId)
{
// check character count
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SUM_CHARS);
@@ -248,7 +249,7 @@ uint32 GetCharactersCount(uint32 accountId)
return (result) ? (*result)[0].GetUInt64() : 0;
}
-bool normalizeString(std::string& utf8String)
+bool AccountMgr::normalizeString(std::string& utf8String)
{
wchar_t buffer[MAX_ACCOUNT_STR+1];
@@ -266,7 +267,7 @@ bool normalizeString(std::string& utf8String)
return WStrToUtf8(buffer, maxLength, utf8String);
}
-std::string CalculateShaPassHash(std::string const& name, std::string const& password)
+std::string AccountMgr::CalculateShaPassHash(std::string const& name, std::string const& password)
{
SHA1Hash sha;
sha.Initialize();
@@ -278,29 +279,27 @@ std::string CalculateShaPassHash(std::string const& name, std::string const& pas
return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength());
}
-bool IsPlayerAccount(uint32 gmlevel)
+bool AccountMgr::IsPlayerAccount(uint32 gmlevel)
{
return gmlevel == SEC_PLAYER;
}
-bool IsModeratorAccount(uint32 gmlevel)
+bool AccountMgr::IsModeratorAccount(uint32 gmlevel)
{
return gmlevel >= SEC_MODERATOR && gmlevel <= SEC_CONSOLE;
}
-bool IsGMAccount(uint32 gmlevel)
+bool AccountMgr::IsGMAccount(uint32 gmlevel)
{
return gmlevel >= SEC_GAMEMASTER && gmlevel <= SEC_CONSOLE;
}
-bool IsAdminAccount(uint32 gmlevel)
+bool AccountMgr::IsAdminAccount(uint32 gmlevel)
{
return gmlevel >= SEC_ADMINISTRATOR && gmlevel <= SEC_CONSOLE;
}
-bool IsConsoleAccount(uint32 gmlevel)
+bool AccountMgr::IsConsoleAccount(uint32 gmlevel)
{
return gmlevel == SEC_CONSOLE;
}
-
-} // Namespace AccountMgr
diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h
index 7154cf0e867..c8de5688e73 100644
--- a/src/server/game/Accounts/AccountMgr.h
+++ b/src/server/game/Accounts/AccountMgr.h
@@ -21,6 +21,7 @@
#include "Define.h"
#include <string>
+#include <ace/Singleton.h>
enum AccountOpResult
{
@@ -34,27 +35,34 @@ enum AccountOpResult
#define MAX_ACCOUNT_STR 16
-namespace AccountMgr
+class AccountMgr
{
- AccountOpResult CreateAccount(std::string username, std::string password);
- AccountOpResult DeleteAccount(uint32 accountId);
- AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword);
- AccountOpResult ChangePassword(uint32 accountId, std::string newPassword);
- bool CheckPassword(uint32 accountId, std::string password);
-
- uint32 GetId(std::string const& username);
- uint32 GetSecurity(uint32 accountId);
- uint32 GetSecurity(uint32 accountId, int32 realmId);
- bool GetName(uint32 accountId, std::string& name);
- uint32 GetCharactersCount(uint32 accountId);
- std::string CalculateShaPassHash(std::string const& name, std::string const& password);
-
- bool normalizeString(std::string& utf8String);
- bool IsPlayerAccount(uint32 gmlevel);
- bool IsModeratorAccount(uint32 gmlevel);
- bool IsGMAccount(uint32 gmlevel);
- bool IsAdminAccount(uint32 gmlevel);
- bool IsConsoleAccount(uint32 gmlevel);
-}
+ friend class ACE_Singleton<AccountMgr, ACE_Null_Mutex>;
+ private:
+ AccountMgr();
+
+ public:
+ static AccountOpResult CreateAccount(std::string username, std::string password);
+ static AccountOpResult DeleteAccount(uint32 accountId);
+ static AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword);
+ static AccountOpResult ChangePassword(uint32 accountId, std::string newPassword);
+ static bool CheckPassword(uint32 accountId, std::string password);
+
+ static uint32 GetId(std::string const& username);
+ static uint32 GetSecurity(uint32 accountId);
+ static uint32 GetSecurity(uint32 accountId, int32 realmId);
+ static bool GetName(uint32 accountId, std::string& name);
+ static uint32 GetCharactersCount(uint32 accountId);
+
+ static std::string CalculateShaPassHash(std::string const& name, std::string const& password);
+ static bool normalizeString(std::string& utf8String);
+ static bool IsPlayerAccount(uint32 gmlevel);
+ static bool IsModeratorAccount(uint32 gmlevel);
+ static bool IsGMAccount(uint32 gmlevel);
+ static bool IsAdminAccount(uint32 gmlevel);
+ static bool IsConsoleAccount(uint32 gmlevel);
+};
+
+#define sAccountMgr ACE_Singleton<AccountMgr, ACE_Null_Mutex>::instance()
#endif
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 3fdff8e11d6..853ecb4e786 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -62,6 +62,7 @@ DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEnt
DBCStorage <BattlemasterListEntry> sBattlemasterListStore(BattlemasterListEntryfmt);
DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore(BarberShopStyleEntryfmt);
DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore(CharStartOutfitEntryfmt);
+std::map<uint32, CharStartOutfitEntry const*> sCharStartOutfitMap;
DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt);
DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt);
DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt);
@@ -284,6 +285,10 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc");
+ for (uint32 i = 0; i < sCharStartOutfitStore.GetNumRows(); ++i)
+ if (CharStartOutfitEntry const* outfit = sCharStartOutfitStore.LookupEntry(i))
+ sCharStartOutfitMap[outfit->Race | (outfit->Class << 8) | (outfit->Gender << 16)] = outfit;
+
LoadDBC(availableDbcLocales, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc");
@@ -872,3 +877,11 @@ uint32 GetLiquidFlags(uint32 liquidType)
return 0;
}
+CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender)
+{
+ std::map<uint32, CharStartOutfitEntry const*>::const_iterator itr = sCharStartOutfitMap.find(race | (class_ << 8) | (gender << 16));
+ if (itr == sCharStartOutfitMap.end())
+ return NULL;
+
+ return itr->second;
+}
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index c77d0ee32f1..48a2cb3fe4e 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -65,6 +65,8 @@ uint32 GetLiquidFlags(uint32 liquidType);
PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level);
PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundBracketId id);
+CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender);
+
extern DBCStorage <AchievementEntry> sAchievementStore;
extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index aa19863ec29..529c84744bd 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -629,13 +629,13 @@ struct BattlemasterListEntry
struct CharStartOutfitEntry
{
//uint32 Id; // 0
- uint32 RaceClassGender; // 1 (UNIT_FIELD_BYTES_0 & 0x00FFFFFF) comparable (0 byte = race, 1 byte = class, 2 byte = gender)
- int32 ItemId[MAX_OUTFIT_ITEMS]; // 2-13
- //int32 ItemDisplayId[MAX_OUTFIT_ITEMS]; // 14-25 not required at server side
- //int32 ItemInventorySlot[MAX_OUTFIT_ITEMS]; // 26-37 not required at server side
- //uint32 Unknown1; // 38, unique values (index-like with gaps ordered in other way as ids)
- //uint32 Unknown2; // 39
- //uint32 Unknown3; // 40
+ uint8 Race; // 1
+ uint8 Class; // 2
+ uint8 Gender; // 3
+ //uint8 Unused; // 4
+ int32 ItemId[MAX_OUTFIT_ITEMS]; // 5-28
+ //int32 ItemDisplayId[MAX_OUTFIT_ITEMS]; // 29-52 not required at server side
+ //int32 ItemInventorySlot[MAX_OUTFIT_ITEMS]; // 53-76 not required at server side
};
struct CharTitlesEntry
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index b7d966757c8..c82fdf868b3 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -31,7 +31,7 @@ char const AuctionHouseEntryfmt[] = "niiixxxxxxxxxxxxxxxxx";
char const BankBagSlotPricesEntryfmt[] = "ni";
char const BarberShopStyleEntryfmt[] = "nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii";
char const BattlemasterListEntryfmt[] = "niiiiiiiiixssssssssssssssssxiixx";
-char const CharStartOutfitEntryfmt[] = "xniiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char const CharTitlesEntryfmt[] = "nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
char const ChatChannelsEntryfmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxx";
char const ChrClassesEntryfmt[] = "nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 5b3969c9b9d..93d4796f21a 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -2148,7 +2148,7 @@ bool Creature::LoadCreaturesAddon(bool reload)
if (HasAura(*itr))
{
if (!reload)
- sLog->outError(LOG_FILTER_SQL, "Creature (GUID: %u Entry: %u) has duplicate aura (spell %u) in `auras` field.", GetGUIDLow(), GetEntry(), *itr);
+ sLog->outError(LOG_FILTER_SQL, "Creature (GUID: %u Entry: %u) has duplicate aura (spell %u) in `auras` field.", GetDBTableGUIDLow(), GetEntry(), *itr);
continue;
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 5fee82c5ece..073fadde314 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1120,7 +1120,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
addActionButton(action_itr->button, action_itr->action, action_itr->type);
// original items
- if (CharStartOutfitEntry const* oEntry = sCharStartOutfitStore.LookupEntry(RaceClassGender))
+ if (CharStartOutfitEntry const* oEntry = GetCharStartOutfitEntry(createInfo->Race, createInfo->Class, createInfo->Gender))
{
for (int j = 0; j < MAX_OUTFIT_ITEMS; ++j)
{
@@ -3432,6 +3432,19 @@ void Player::AddNewMailDeliverTime(time_t deliver_time)
}
}
+void DeleteSpellFromAllPlayers(uint32 spellId)
+{
+ CharacterDatabaseStatements stmts[2] = {CHAR_DEL_INVALID_SPELL_SPELLS, CHAR_DEL_INVALID_SPELL_TALENTS};
+ for (uint8 i = 0; i < 2; i++)
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(stmts[i]);
+
+ stmt->setUInt32(0, spellId);
+
+ CharacterDatabase.Execute(stmt);
+ }
+}
+
bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
@@ -3442,11 +3455,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
{
sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId);
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
-
- stmt->setUInt32(0, spellId);
-
- CharacterDatabase.Execute(stmt);
+ DeleteSpellFromAllPlayers(spellId);
}
else
sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
@@ -3461,11 +3470,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
{
sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addTalent: Broken spell #%u learning not allowed, deleting for all characters in `character_talent`.", spellId);
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
-
- stmt->setUInt32(0, spellId);
-
- CharacterDatabase.Execute(stmt);
+ DeleteSpellFromAllPlayers(spellId);
}
else
sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addTalent: Broken spell #%u learning not allowed.", spellId);
@@ -3515,11 +3520,7 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent
{
sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId);
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
-
- stmt->setUInt32(0, spellId);
-
- CharacterDatabase.Execute(stmt);
+ DeleteSpellFromAllPlayers(spellId);
}
else
sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
@@ -3534,11 +3535,7 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent
{
sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.", spellId);
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
-
- stmt->setUInt32(0, spellId);
-
- CharacterDatabase.Execute(stmt);
+ DeleteSpellFromAllPlayers(spellId);
}
else
sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Broken spell #%u learning not allowed.", spellId);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index fe0a1e88885..49b86cff864 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -14452,7 +14452,8 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
Unit* actionTarget = !isVictim ? target : this;
DamageInfo damageInfo = DamageInfo(actor, actionTarget, damage, procSpell, procSpell ? SpellSchoolMask(procSpell->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL, SPELL_DIRECT_DAMAGE);
- ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, NULL, &damageInfo, NULL /*HealInfo*/);
+ HealInfo healInfo = HealInfo(actor, actionTarget, damage, procSpell, procSpell ? SpellSchoolMask(procSpell->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL);
+ ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, NULL, &damageInfo, &healInfo);
ProcTriggeredList procTriggered;
// Fill procTriggered list
@@ -14483,6 +14484,10 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
continue;
+ // AuraScript Hook
+ if (!triggerData.aura->CallScriptCheckProcHandlers(itr->second, eventInfo))
+ continue;
+
// Triggered spells not triggering additional spells
bool triggered = !(spellProto->AttributesEx3 & SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED) ?
(procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) : false;
@@ -14531,15 +14536,21 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
SpellInfo const* spellInfo = i->aura->GetSpellInfo();
uint32 Id = i->aura->GetId();
+ AuraApplication const* aurApp = i->aura->GetApplicationOfTarget(GetGUID());
+
+ bool prepare = i->aura->CallScriptPrepareProcHandlers(aurApp, eventInfo);
+
// For players set spell cooldown if need
uint32 cooldown = 0;
- if (GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown)
+ if (prepare && GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown)
cooldown = i->spellProcEvent->cooldown;
// Note: must SetCantProc(false) before return
if (spellInfo->AttributesEx3 & SPELL_ATTR3_DISABLE_PROC)
SetCantProc(true);
+ i->aura->CallScriptProcHandlers(aurApp, eventInfo);
+
// This bool is needed till separate aura effect procs are still here
bool handled = false;
if (HandleAuraProc(target, damage, i->aura, procSpell, procFlag, procExtra, cooldown, &handled))
@@ -14558,6 +14569,13 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex);
ASSERT(triggeredByAura);
+ bool prevented = i->aura->CallScriptEffectProcHandlers(triggeredByAura, aurApp, eventInfo);
+ if (prevented)
+ {
+ takeCharges = true;
+ continue;
+ }
+
switch (triggeredByAura->GetAuraType())
{
case SPELL_AURA_PROC_TRIGGER_SPELL:
@@ -14725,13 +14743,16 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
takeCharges = true;
break;
} // switch (triggeredByAura->GetAuraType())
+ i->aura->CallScriptAfterEffectProcHandlers(triggeredByAura, aurApp, eventInfo);
} // for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
} // if (!handled)
// Remove charge (aura can be removed by triggers)
- if (useCharges && takeCharges)
+ if (prepare && useCharges && takeCharges)
i->aura->DropCharge();
+ i->aura->CallScriptAfterProcHandlers(aurApp, eventInfo);
+
if (spellInfo->AttributesEx3 & SPELL_ATTR3_DISABLE_PROC)
SetCantProc(false);
}
@@ -14752,7 +14773,7 @@ void Unit::GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTrigge
if (!(*itr)->GetRemoveMode())
if ((*itr)->GetBase()->IsProcTriggeredOnEvent(*itr, eventInfo))
{
- (*itr)->GetBase()->PrepareProcToTrigger();
+ (*itr)->GetBase()->PrepareProcToTrigger(*itr, eventInfo);
aurasTriggeringProc.push_back(*itr);
}
}
@@ -14764,7 +14785,7 @@ void Unit::GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTrigge
{
if (itr->second->GetBase()->IsProcTriggeredOnEvent(itr->second, eventInfo))
{
- itr->second->GetBase()->PrepareProcToTrigger();
+ itr->second->GetBase()->PrepareProcToTrigger(itr->second, eventInfo);
aurasTriggeringProc.push_back(itr->second);
}
}
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 619d819bf9b..30257797470 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -2956,10 +2956,9 @@ void ObjectMgr::PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint3
if (count < -1)
sLog->outError(LOG_FILTER_SQL, "Invalid count %i specified on item %u be removed from original player create info (use -1)!", count, itemId);
- uint32 RaceClass = (race_) | (class_ << 8);
for (uint32 gender = 0; gender < GENDER_NONE; ++gender)
{
- if (CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(RaceClass | (gender << 16)))
+ if (CharStartOutfitEntry const* entry = GetCharStartOutfitEntry(race_, class_, gender))
{
bool found = false;
for (uint8 x = 0; x < MAX_OUTFIT_ITEMS; ++x)
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index 292833c3955..35b0a6f8569 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -742,7 +742,32 @@ enum TrinityStrings
LANG_COMMAND_CREATURESTORAGE_NOTFOUND = 818,
LANG_CHANNEL_CITY = 819,
- // Room for in-game strings 820-999 not used
+
+ LANG_NPCINFO_GOSSIP = 820,
+ LANG_NPCINFO_QUESTGIVER = 821,
+ LANG_NPCINFO_TRAINER_CLASS = 822,
+ LANG_NPCINFO_TRAINER_PROFESSION = 823,
+ LANG_NPCINFO_VENDOR_AMMO = 824,
+ LANG_NPCINFO_VENDOR_FOOD = 825,
+ LANG_NPCINFO_VENDOR_POISON = 826,
+ LANG_NPCINFO_VENDOR_REAGENT = 827,
+ LANG_NPCINFO_REPAIR = 828,
+ LANG_NPCINFO_FLIGHTMASTER = 829,
+ LANG_NPCINFO_SPIRITHEALER = 830,
+ LANG_NPCINFO_SPIRITGUIDE = 831,
+ LANG_NPCINFO_INNKEEPER = 832,
+ LANG_NPCINFO_BANKER = 833,
+ LANG_NPCINFO_PETITIONER = 834,
+ LANG_NPCINFO_TABARDDESIGNER = 835,
+ LANG_NPCINFO_BATTLEMASTER = 836,
+ LANG_NPCINFO_AUCTIONEER = 837,
+ LANG_NPCINFO_STABLEMASTER = 838,
+ LANG_NPCINFO_GUILD_BANKER = 839,
+ LANG_NPCINFO_SPELLCLICK = 840,
+ LANG_NPCINFO_MAILBOX = 841,
+ LANG_NPCINFO_PLAYER_VEHICLE = 842,
+
+ // Room for in-game strings 843-999 not used
// Level 4 (CLI only commands)
LANG_COMMAND_EXIT = 1000,
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
index a1ac4ccb679..1958774380e 100755
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
@@ -103,7 +103,6 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T &owner)
return;
*/
-
D::_addUnitStateMove(owner);
i_targetReached = false;
i_recalculateTravel = false;
@@ -111,6 +110,11 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T &owner)
Movement::MoveSplineInit init(owner);
init.MoveTo(x, y, z);
init.SetWalk(((D*)this)->EnableWalking());
+ // Using the same condition for facing target as the one that is used for SetInFront on movement end
+ // - applies to ChaseMovementGenerator mostly
+ if (i_angle == 0.f)
+ init.SetFacing(i_target.getTarget());
+
init.Launch();
}
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 990963b8c4d..6a26dafde79 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -95,17 +95,28 @@ bool WorldSessionFilter::Process(WorldPacket* packet)
/// WorldSession constructor
WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter):
-m_muteTime(mute_time), m_timeOutTime(0), _player(NULL), m_Socket(sock),
-_security(sec), _accountId(id), m_expansion(expansion), _logoutTime(0),
-m_inQueue(false), m_playerLoading(false), m_playerLogout(false),
-m_playerRecentlyLogout(false), m_playerSave(false),
-m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
-m_sessionDbLocaleIndex(locale),
-m_latency(0), m_TutorialsChanged(false), recruiterId(recruiter),
-isRecruiter(isARecruiter), timeLastWhoCommand(0)
+ m_muteTime(mute_time),
+ m_timeOutTime(0),
+ _player(NULL),
+ m_Socket(sock),
+ _security(sec),
+ _accountId(id),
+ m_expansion(expansion),
+ _warden(NULL),
+ _logoutTime(0),
+ m_inQueue(false),
+ m_playerLoading(false),
+ m_playerLogout(false),
+ m_playerRecentlyLogout(false),
+ m_playerSave(false),
+ m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
+ m_sessionDbLocaleIndex(locale),
+ m_latency(0),
+ m_TutorialsChanged(false),
+ recruiterId(recruiter),
+ isRecruiter(isARecruiter),
+ timeLastWhoCommand(0)
{
- _warden = NULL;
-
if (sock)
{
m_Address = sock->GetRemoteAddress();
@@ -727,8 +738,8 @@ void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string c
void WorldSession::SendAccountDataTimes(uint32 mask)
{
- WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4 + 1 + 4 + 8 * 4); // changed in WotLK
- data << uint32(time(NULL)); // unix time of something
+ WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4 + 1 + 4 + NUM_ACCOUNT_DATA_TYPES * 4);
+ data << uint32(time(NULL)); // Server time
data << uint8(1);
data << uint32(mask); // type mask
for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 39f5425d9df..abe048279db 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -181,9 +181,6 @@ class CharacterCreateInfo
/// Server side data
uint8 CharCount;
-
- private:
- virtual ~CharacterCreateInfo(){};
};
/// Player session in the World
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index b47f801ab29..b9955fac523 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -159,27 +159,29 @@ int WorldSocket::SendPacket(WorldPacket const& pct)
if (closing_)
return -1;
- // Dump outgoing packet.
+ // Dump outgoing packet
if (sPacketLog->CanLogPacket())
sPacketLog->LogPacket(pct, SERVER_TO_CLIENT);
+ WorldPacket const* pkt = &pct;
+
+
if (m_Session)
- sLog->outTrace(LOG_FILTER_OPCODES, "S->C %s %s", m_Session->GetPlayerInfo().c_str(), GetOpcodeNameForLogging(pct.GetOpcode()).c_str());
+ sLog->outTrace(LOG_FILTER_OPCODES, "S->C: %s %s", m_Session->GetPlayerInfo().c_str(), GetOpcodeNameForLogging(pkt->GetOpcode()).c_str());
- // Create a copy of the original packet; this is to avoid issues if a hook modifies it.
- sScriptMgr->OnPacketSend(this, WorldPacket(pct));
+ sScriptMgr->OnPacketSend(this, *pkt);
- ServerPktHeader header(pct.size()+2, pct.GetOpcode());
+ ServerPktHeader header(pkt->size()+2, pkt->GetOpcode());
m_Crypt.EncryptSend ((uint8*)header.header, header.getHeaderLength());
- if (m_OutBuffer->space() >= pct.size() + header.getHeaderLength() && msg_queue()->is_empty())
+ if (m_OutBuffer->space() >= pkt->size() + header.getHeaderLength() && msg_queue()->is_empty())
{
// Put the packet on the buffer.
if (m_OutBuffer->copy((char*) header.header, header.getHeaderLength()) == -1)
ACE_ASSERT (false);
- if (!pct.empty())
- if (m_OutBuffer->copy((char*) pct.contents(), pct.size()) == -1)
+ if (!pkt->empty())
+ if (m_OutBuffer->copy((char*) pkt->contents(), pkt->size()) == -1)
ACE_ASSERT (false);
}
else
@@ -187,12 +189,12 @@ int WorldSocket::SendPacket(WorldPacket const& pct)
// Enqueue the packet.
ACE_Message_Block* mb;
- ACE_NEW_RETURN(mb, ACE_Message_Block(pct.size() + header.getHeaderLength()), -1);
+ ACE_NEW_RETURN(mb, ACE_Message_Block(pkt->size() + header.getHeaderLength()), -1);
mb->copy((char*) header.header, header.getHeaderLength());
- if (!pct.empty())
- mb->copy((const char*)pct.contents(), pct.size());
+ if (!pkt->empty())
+ mb->copy((const char*)pkt->contents(), pkt->size());
if (msg_queue()->enqueue_tail(mb, (ACE_Time_Value*)&ACE_Time_Value::zero) == -1)
{
@@ -245,20 +247,7 @@ int WorldSocket::open (void *a)
m_Address = remote_addr.get_host_addr();
- // Send startup packet.
- WorldPacket packet (SMSG_AUTH_CHALLENGE, 24);
- packet << uint32(1); // 1...31
- packet << m_Seed;
-
- BigNumber seed1;
- seed1.SetRand(16 * 8);
- packet.append(seed1.AsByteArray(16), 16); // new encryption seeds
-
- BigNumber seed2;
- seed2.SetRand(16 * 8);
- packet.append(seed2.AsByteArray(16), 16); // new encryption seeds
-
- if (SendPacket(packet) == -1)
+ if (HandleSendAuthSession() == -1)
return -1;
// Register with ACE Reactor
@@ -461,7 +450,7 @@ int WorldSocket::Update (void)
int ret;
do
- ret = handle_output (get_handle());
+ ret = handle_output(get_handle());
while (ret > 0);
return ret;
@@ -469,18 +458,18 @@ int WorldSocket::Update (void)
int WorldSocket::handle_input_header (void)
{
- ACE_ASSERT (m_RecvWPct == NULL);
+ ACE_ASSERT(m_RecvWPct == NULL);
- ACE_ASSERT (m_Header.length() == sizeof(ClientPktHeader));
+ ACE_ASSERT(m_Header.length() == sizeof(ClientPktHeader));
- m_Crypt.DecryptRecv ((uint8*) m_Header.rd_ptr(), sizeof(ClientPktHeader));
+ m_Crypt.DecryptRecv ((uint8*)m_Header.rd_ptr(), sizeof(ClientPktHeader));
- ClientPktHeader& header = *((ClientPktHeader*) m_Header.rd_ptr());
+ ClientPktHeader& header = *((ClientPktHeader*)m_Header.rd_ptr());
EndianConvertReverse(header.size);
EndianConvert(header.cmd);
- if ((header.size < 4) || (header.size > 10240) || (header.cmd > 10240))
+ if ((header.size < 4) || (header.size > 10240) || (header.cmd > 10240))
{
Player* _player = m_Session ? m_Session->GetPlayer() : NULL;
sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::handle_input_header(): client (account: %u, char [GUID: %u, name: %s]) sent malformed packet (size: %d, cmd: %d)",
@@ -495,11 +484,11 @@ int WorldSocket::handle_input_header (void)
header.size -= 4;
- ACE_NEW_RETURN (m_RecvWPct, WorldPacket ((uint16) header.cmd, header.size), -1);
+ ACE_NEW_RETURN(m_RecvWPct, WorldPacket ((uint16)header.cmd, header.size), -1);
if (header.size > 0)
{
- m_RecvWPct->resize (header.size);
+ m_RecvWPct->resize(header.size);
m_RecvPct.base ((char*) m_RecvWPct->contents(), m_RecvWPct->size());
}
else
@@ -666,7 +655,7 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
ACE_ASSERT (new_pct);
// manage memory ;)
- ACE_Auto_Ptr<WorldPacket> aptr (new_pct);
+ ACE_Auto_Ptr<WorldPacket> aptr(new_pct);
const ACE_UINT16 opcode = new_pct->GetOpcode();
@@ -677,15 +666,16 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
if (sPacketLog->CanLogPacket())
sPacketLog->LogPacket(*new_pct, CLIENT_TO_SERVER);
+ std::string opcodeName = GetOpcodeNameForLogging(opcode);
if (m_Session)
- sLog->outTrace(LOG_FILTER_OPCODES, "C->S %s %s", m_Session->GetPlayerInfo().c_str(), GetOpcodeNameForLogging(new_pct->GetOpcode()).c_str());
+ sLog->outTrace(LOG_FILTER_OPCODES, "C->S: %s %s", m_Session->GetPlayerInfo().c_str(), opcodeName.c_str());
try
{
switch (opcode)
{
case CMSG_PING:
- return HandlePing (*new_pct);
+ return HandlePing(*new_pct);
case CMSG_AUTH_SESSION:
if (m_Session)
{
@@ -694,18 +684,17 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
}
sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
- return HandleAuthSession (*new_pct);
+ return HandleAuthSession(*new_pct);
case CMSG_KEEP_ALIVE:
- sLog->outDebug(LOG_FILTER_NETWORKIO, "%s", GetOpcodeNameForLogging(opcode).c_str());
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "%s", opcodeName.c_str());
sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
return 0;
default:
{
- ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
-
+ ACE_GUARD_RETURN(LockType, Guard, m_SessionLock, -1);
if (!m_Session)
{
- sLog->outError(LOG_FILTER_NETWORKIO, "ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
+ sLog->outError(LOG_FILTER_OPCODES, "ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
return -1;
}
@@ -715,7 +704,7 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
// OK, give the packet to WorldSession
aptr.release();
- // WARNINIG here we call it with locks held.
+ // WARNING here we call it with locks held.
// Its possible to cause deadlock if QueuePacket calls back
m_Session->QueuePacket(new_pct);
return 0;
@@ -724,8 +713,8 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
}
catch (ByteBufferException &)
{
- sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.",
- opcode, GetRemoteAddress().c_str(), m_Session ? int32(m_Session->GetAccountId()) : -1);
+ sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet %s from client %s, accountid=%i. Disconnected client.",
+ opcodeName.c_str(), GetRemoteAddress().c_str(), m_Session ? int32(m_Session->GetAccountId()) : -1);
new_pct->hexlike();
return -1;
}
@@ -733,36 +722,47 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
ACE_NOTREACHED (return 0);
}
+int WorldSocket::HandleSendAuthSession()
+{
+ WorldPacket packet(SMSG_AUTH_CHALLENGE, 37);
+ packet << uint32(1); // 1...31
+ packet << uint32(m_Seed);
+
+ BigNumber seed1;
+ seed1.SetRand(16 * 8);
+ packet.append(seed1.AsByteArray(16), 16); // new encryption seeds
+
+ BigNumber seed2;
+ seed2.SetRand(16 * 8);
+ packet.append(seed2.AsByteArray(16), 16); // new encryption seeds
+ return SendPacket(packet);
+}
+
int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
{
- // NOTE: ATM the socket is singlethread, have this in mind ...
uint8 digest[20];
uint32 clientSeed;
- uint32 unk2, unk3, unk5, unk6, unk7;
- uint64 unk4;
- uint32 BuiltNumberClient;
- uint32 id, security;
- //uint8 expansion = 0;
+ uint8 security;
+ uint32 id;
LocaleConstant locale;
std::string account;
SHA1Hash sha;
+ uint32 clientBuild;
+ uint32 unk2, unk3, unk5, unk6, unk7;
+ uint64 unk4;
BigNumber v, s, g, N;
WorldPacket packet, SendAddonPacked;
-
BigNumber k;
if (sWorld->IsClosed())
{
- packet.Initialize(SMSG_AUTH_RESPONSE, 1);
- packet << uint8(AUTH_REJECT);
- SendPacket(packet);
-
+ SendAuthResponseError(AUTH_REJECT);
sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: World closed, denying client (%s).", GetRemoteAddress().c_str());
return -1;
}
// Read the content of the packet
- recvPacket >> BuiltNumberClient; // for now no use
+ recvPacket >> clientBuild;
recvPacket >> unk2;
recvPacket >> account;
recvPacket >> unk3;
@@ -772,7 +772,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
recvPacket.read(digest, 20);
sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, unk3 %u, clientseed %u",
- BuiltNumberClient,
+ clientBuild,
unk2,
account.c_str(),
unk3,
@@ -788,11 +788,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
// Stop if the account is not found
if (!result)
{
- packet.Initialize (SMSG_AUTH_RESPONSE, 1);
- packet << uint8 (AUTH_UNKNOWN_ACCOUNT);
-
- SendPacket(packet);
-
+ SendAuthResponseError(AUTH_UNKNOWN_ACCOUNT);
sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: Sent Auth Response (unknown account).");
return -1;
}
@@ -810,37 +806,30 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
v.SetHexStr(fields[4].GetCString());
s.SetHexStr (fields[5].GetCString());
- const char* sStr = s.AsHexStr(); //Must be freed by OPENSSL_free()
- const char* vStr = v.AsHexStr(); //Must be freed by OPENSSL_free()
+ const char* sStr = s.AsHexStr(); // Must be freed by OPENSSL_free()
+ const char* vStr = v.AsHexStr(); // Must be freed by OPENSSL_free()
sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: (s, v) check s: %s v: %s",
- sStr,
- vStr);
+ sStr,
+ vStr);
- OPENSSL_free ((void*) sStr);
- OPENSSL_free ((void*) vStr);
+ OPENSSL_free((void*)sStr);
+ OPENSSL_free((void*)vStr);
///- Re-check ip locking (same check as in realmd).
if (fields[3].GetUInt8() == 1) // if ip is locked
{
if (strcmp (fields[2].GetCString(), GetRemoteAddress().c_str()))
{
- packet.Initialize (SMSG_AUTH_RESPONSE, 1);
- packet << uint8 (AUTH_FAILED);
- SendPacket(packet);
-
+ SendAuthResponseError(AUTH_FAILED);
sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs).");
return -1;
}
}
id = fields[0].GetUInt32();
- /*
- if (security > SEC_ADMINISTRATOR) // prevent invalid security settings in DB
- security = SEC_ADMINISTRATOR;
- */
- k.SetHexStr (fields[1].GetCString());
+ k.SetHexStr(fields[1].GetCString());
int64 mutetime = fields[7].GetInt64();
//! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now.
@@ -866,10 +855,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
// Must be done before WorldSession is created
if (sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED) && os != "Win" && os != "OSX")
{
- packet.Initialize(SMSG_AUTH_RESPONSE, 1);
- packet << uint8(AUTH_REJECT);
- SendPacket(packet);
-
+ SendAuthResponseError(AUTH_REJECT);
sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: Client %s attempted to log in using invalid client OS (%s).", GetRemoteAddress().c_str(), os.c_str());
return -1;
}
@@ -900,10 +886,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
if (banresult) // if account banned
{
- packet.Initialize (SMSG_AUTH_RESPONSE, 1);
- packet << uint8 (AUTH_BANNED);
- SendPacket(packet);
-
+ SendAuthResponseError(AUTH_BANNED);
sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: Sent Auth Response (Account banned).");
return -1;
}
@@ -911,13 +894,9 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
// Check locked state for server
AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit();
sLog->outDebug(LOG_FILTER_NETWORKIO, "Allowed Level: %u Player Level %u", allowedAccountType, AccountTypes(security));
- if (AccountTypes(security) < allowedAccountType)
+ if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType)
{
- WorldPacket Packet (SMSG_AUTH_RESPONSE, 1);
- Packet << uint8 (AUTH_UNAVAILABLE);
-
- SendPacket(packet);
-
+ SendAuthResponseError(AUTH_UNAVAILABLE);
sLog->outInfo(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: User tries to login but his security level is not enough");
return -1;
}
@@ -926,29 +905,25 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
uint32 t = 0;
uint32 seed = m_Seed;
- sha.UpdateData (account);
- sha.UpdateData ((uint8 *) & t, 4);
- sha.UpdateData ((uint8 *) & clientSeed, 4);
- sha.UpdateData ((uint8 *) & seed, 4);
- sha.UpdateBigNumbers (&k, NULL);
+ sha.UpdateData(account);
+ sha.UpdateData((uint8*)&t, 4);
+ sha.UpdateData((uint8*)&clientSeed, 4);
+ sha.UpdateData((uint8*)&seed, 4);
+ sha.UpdateBigNumbers(&k, NULL);
sha.Finalize();
std::string address = GetRemoteAddress();
- if (memcmp (sha.GetDigest(), digest, 20))
+ if (memcmp(sha.GetDigest(), digest, 20))
{
- packet.Initialize (SMSG_AUTH_RESPONSE, 1);
- packet << uint8 (AUTH_FAILED);
-
- SendPacket(packet);
-
+ SendAuthResponseError(AUTH_FAILED);
sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", id, account.c_str(), address.c_str());
return -1;
}
sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.",
- account.c_str(),
- address.c_str());
+ account.c_str(),
+ address.c_str());
// Check if this user is by any chance a recruiter
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_RECRUITER);
@@ -971,7 +946,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
LoginDatabase.Execute(stmt);
// NOTE ATM the socket is single-threaded, have this in mind ...
- ACE_NEW_RETURN (m_Session, WorldSession (id, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1);
+ ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1);
m_Crypt.Init(&k);
@@ -985,10 +960,9 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
// Sleep this Network thread for
uint32 sleepTime = sWorld->getIntConfig(CONFIG_SESSION_ADD_DELAY);
- ACE_OS::sleep (ACE_Time_Value (0, sleepTime));
-
- sWorld->AddSession (m_Session);
+ ACE_OS::sleep(ACE_Time_Value(0, sleepTime));
+ sWorld->AddSession(m_Session);
return 0;
}
@@ -1049,7 +1023,14 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket)
}
}
- WorldPacket packet (SMSG_PONG, 4);
+ WorldPacket packet(SMSG_PONG, 4);
packet << ping;
return SendPacket(packet);
}
+
+void WorldSocket::SendAuthResponseError(uint8 code)
+{
+ WorldPacket packet(SMSG_AUTH_RESPONSE, 1);
+ packet << uint8(code);
+ SendPacket(packet);
+} \ No newline at end of file
diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h
index 6b59647bb6c..2d5762ef60e 100644
--- a/src/server/game/Server/WorldSocket.h
+++ b/src/server/game/Server/WorldSocket.h
@@ -97,13 +97,13 @@ class WorldSocket : public WorldHandler
typedef ACE_Guard<LockType> GuardType;
/// Check if socket is closed.
- bool IsClosed (void) const;
+ bool IsClosed(void) const;
/// Close the socket.
- void CloseSocket (void);
+ void CloseSocket(void);
/// Get address of connected peer.
- const std::string& GetRemoteAddress (void) const;
+ const std::string& GetRemoteAddress(void) const;
/// Send A packet on the socket, this function is reentrant.
/// @param pct packet to send
@@ -111,57 +111,60 @@ class WorldSocket : public WorldHandler
int SendPacket(const WorldPacket& pct);
/// Add reference to this object.
- long AddReference (void);
+ long AddReference(void);
/// Remove reference to this object.
- long RemoveReference (void);
+ long RemoveReference(void);
/// things called by ACE framework.
/// Called on open, the void* is the acceptor.
- virtual int open (void *);
+ virtual int open(void *);
/// Called on failures inside of the acceptor, don't call from your code.
- virtual int close (u_long);
+ virtual int close(u_long);
/// Called when we can read from the socket.
- virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE);
+ virtual int handle_input(ACE_HANDLE = ACE_INVALID_HANDLE);
/// Called when the socket can write.
- virtual int handle_output (ACE_HANDLE = ACE_INVALID_HANDLE);
+ virtual int handle_output(ACE_HANDLE = ACE_INVALID_HANDLE);
/// Called when connection is closed or error happens.
- virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
+ virtual int handle_close(ACE_HANDLE = ACE_INVALID_HANDLE,
ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
/// Called by WorldSocketMgr/ReactorRunnable.
- int Update (void);
+ int Update(void);
private:
/// Helper functions for processing incoming data.
- int handle_input_header (void);
- int handle_input_payload (void);
- int handle_input_missing_data (void);
+ int handle_input_header(void);
+ int handle_input_payload(void);
+ int handle_input_missing_data(void);
/// Help functions to mark/unmark the socket for output.
/// @param g the guard is for m_OutBufferLock, the function will release it
- int cancel_wakeup_output (GuardType& g);
- int schedule_wakeup_output (GuardType& g);
+ int cancel_wakeup_output(GuardType& g);
+ int schedule_wakeup_output(GuardType& g);
/// Drain the queue if its not empty.
- int handle_output_queue (GuardType& g);
+ int handle_output_queue(GuardType& g);
/// process one incoming packet.
/// @param new_pct received packet, note that you need to delete it.
- int ProcessIncoming (WorldPacket* new_pct);
+ int ProcessIncoming(WorldPacket* new_pct);
/// Called by ProcessIncoming() on CMSG_AUTH_SESSION.
- int HandleAuthSession (WorldPacket& recvPacket);
+ int HandleAuthSession(WorldPacket& recvPacket);
/// Called by ProcessIncoming() on CMSG_PING.
- int HandlePing (WorldPacket& recvPacket);
+ int HandlePing(WorldPacket& recvPacket);
+
+ int HandleSendAuthSession();
private:
+ void SendAuthResponseError(uint8);
/// Time in which the last ping was received
ACE_Time_Value m_LastPingTime;
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 05da36d2ccc..e440b2a0fbd 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -992,7 +992,10 @@ void AuraEffect::PeriodicTick(AuraApplication * aurApp, Unit* caster) const
void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
{
- // TODO: effect script handlers here
+ bool prevented = GetBase()->CallScriptEffectProcHandlers(const_cast<AuraEffect const*>(this), const_cast<AuraApplication const*>(aurApp), eventInfo);
+ if (prevented)
+ return;
+
switch (GetAuraType())
{
case SPELL_AURA_PROC_TRIGGER_SPELL:
@@ -1013,6 +1016,8 @@ void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
default:
break;
}
+
+ GetBase()->CallScriptAfterEffectProcHandlers(const_cast<AuraEffect const*>(this), const_cast<AuraApplication const*>(aurApp), eventInfo);
}
void AuraEffect::CleanupTriggeredSpells(Unit* target)
@@ -1572,7 +1577,7 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app
// call functions which may have additional effects after chainging state of unit
// phase auras normally not expected at BG but anyway better check
- if (apply && (mode & AURA_EFFECT_HANDLE_REAL))
+ if (apply)
{
// drop flag at invisibiliy in bg
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 24a83c7990c..a41d25eae09 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1940,9 +1940,12 @@ void Aura::AddProcCooldown(uint32 /*msec*/)
//m_procCooldown = time(NULL) + msec;
}
-void Aura::PrepareProcToTrigger()
+void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo)
{
- // TODO: allow scripts to prevent charge drop/cooldown
+ bool prepare = CallScriptPrepareProcHandlers(aurApp, eventInfo);
+ if (!prepare)
+ return;
+
// take one charge, aura expiration will be handled in Aura::TriggerProcOnEvent (if needed)
if (IsUsingCharges())
{
@@ -1981,14 +1984,18 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI
return false;
// do checks using conditions table
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, GetSpellInfo()->Id);
+ ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, GetId());
ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget());
if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
return false;
+ // AuraScript Hook
+ bool check = const_cast<Aura*>(this)->CallScriptCheckProcHandlers(aurApp, eventInfo);
+ if (!check)
+ return false;
+
// TODO:
- // - add DoCheckProc() AuraScript hook
- // to allow additional requirements for procs
+ // do allow additional requirements for procs
// this is needed because this is the last moment in which you can prevent aura charge drop on proc
// and possibly a way to prevent default checks (if there're going to be any)
@@ -2052,14 +2059,14 @@ float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& event
void Aura::TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo)
{
- // TODO: OnProc hook here
+ CallScriptProcHandlers(const_cast<AuraApplication const*>(aurApp), eventInfo);
+
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (aurApp->HasEffect(i))
- // TODO: OnEffectProc hook here (allowing prevention of selected effects)
+ // OnEffectProc / AfterEffectProc hooks handled in AuraEffect::HandleProc()
GetEffect(i)->HandleProc(aurApp, eventInfo);
- // TODO: AfterEffectProc hook here
- // TODO: AfterProc hook here
+ CallScriptAfterProcHandlers(const_cast<AuraApplication const*>(aurApp), eventInfo);
// Remove aura if we've used last charge to proc
if (IsUsingCharges() && !GetCharges())
@@ -2355,6 +2362,95 @@ void Aura::CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication con
}
}
+bool Aura::CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
+{
+ for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_PROC, aurApp);
+ std::list<AuraScript::CheckProcHandler>::iterator hookItrEnd = (*scritr)->DoCheckProc.end(), hookItr = (*scritr)->DoCheckProc.begin();
+ for (; hookItr != hookItrEnd; ++hookItr)
+ if (!(*hookItr).Call(*scritr, eventInfo))
+ return false;
+ (*scritr)->_FinishScriptCall();
+ }
+ return true;
+}
+
+bool Aura::CallScriptPrepareProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
+{
+ bool prepare = true;
+ for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_PREPARE_PROC, aurApp);
+ std::list<AuraScript::AuraProcHandler>::iterator effEndItr = (*scritr)->DoPrepareProc.end(), effItr = (*scritr)->DoPrepareProc.begin();
+ for (; effItr != effEndItr; ++effItr)
+ (*effItr).Call(*scritr, eventInfo);
+
+ if (prepare && (*scritr)->_IsDefaultActionPrevented())
+ prepare = false;
+ (*scritr)->_FinishScriptCall();
+ }
+ return prepare;
+}
+
+void Aura::CallScriptProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
+{
+ for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_PROC, aurApp);
+ std::list<AuraScript::AuraProcHandler>::iterator hookItrEnd = (*scritr)->OnProc.end(), hookItr = (*scritr)->OnProc.begin();
+ for (; hookItr != hookItrEnd; ++hookItr)
+ (*hookItr).Call(*scritr, eventInfo);
+ (*scritr)->_FinishScriptCall();
+ }
+}
+
+void Aura::CallScriptAfterProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
+{
+ for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_AFTER_PROC, aurApp);
+ std::list<AuraScript::AuraProcHandler>::iterator hookItrEnd = (*scritr)->AfterProc.end(), hookItr = (*scritr)->AfterProc.begin();
+ for (; hookItr != hookItrEnd; ++hookItr)
+ (*hookItr).Call(*scritr, eventInfo);
+ (*scritr)->_FinishScriptCall();
+ }
+}
+
+bool Aura::CallScriptEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo)
+{
+ bool preventDefault = false;
+ for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_PROC, aurApp);
+ std::list<AuraScript::EffectProcHandler>::iterator effEndItr = (*scritr)->OnEffectProc.end(), effItr = (*scritr)->OnEffectProc.begin();
+ for (; effItr != effEndItr; ++effItr)
+ {
+ if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
+ (*effItr).Call(*scritr, aurEff, eventInfo);
+ }
+ if (!preventDefault)
+ preventDefault = (*scritr)->_IsDefaultActionPrevented();
+ (*scritr)->_FinishScriptCall();
+ }
+ return preventDefault;
+}
+
+void Aura::CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo)
+{
+ for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC, aurApp);
+ std::list<AuraScript::EffectProcHandler>::iterator effEndItr = (*scritr)->AfterEffectProc.end(), effItr = (*scritr)->AfterEffectProc.begin();
+ for (; effItr != effEndItr; ++effItr)
+ {
+ if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
+ (*effItr).Call(*scritr, aurEff, eventInfo);
+ }
+ (*scritr)->_FinishScriptCall();
+ }
+}
+
UnitAura::UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, uint64 casterGUID)
: Aura(spellproto, owner, caster, castItem, casterGUID)
{
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 88ebee18981..bd351548255 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -194,7 +194,7 @@ class Aura
void AddProcCooldown(uint32 msec);
bool IsUsingCharges() const { return m_isUsingCharges; }
void SetUsingCharges(bool val) { m_isUsingCharges = val; }
- void PrepareProcToTrigger();
+ void PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo);
bool IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) const;
float CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const;
void TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo);
@@ -218,6 +218,13 @@ class Aura
void CallScriptEffectManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented);
void CallScriptEffectAfterManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount);
void CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & splitAmount);
+ // Spell Proc Hooks
+ bool CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
+ bool CallScriptPrepareProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
+ void CallScriptProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
+ void CallScriptAfterProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo);
+ bool CallScriptEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo);
+ void CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo);
std::list<AuraScript*> m_loadedScripts;
private:
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 582f13284bb..b258f01ccd5 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3633,6 +3633,8 @@ void SpellMgr::LoadDbcDataCorrections()
case 49345: // Call Emerald Drake
spellInfo->Effect[1] = 0;
break;
+ case 24314: // Threatening Gaze
+ spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CAST | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_JUMP;
default:
break;
}
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index c29b08242a0..89ed223545f 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -470,7 +470,7 @@ WorldLocation* SpellScript::GetHitDest()
{
if (!IsInEffectHook())
{
- sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u`: function SpellScript::GetHitGObj was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
+ sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u`: function SpellScript::GetHitDest was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
return NULL;
}
return m_spell->destTarget;
@@ -679,6 +679,30 @@ bool AuraScript::_Validate(SpellInfo const* entry)
if (!(*itr).GetAffectedEffectsMask(entry))
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectSplit` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+ for (std::list<CheckProcHandler>::iterator itr = DoCheckProc.begin(); itr != DoCheckProc.end(); ++itr)
+ if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
+ sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `DoCheckProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
+
+ for (std::list<AuraProcHandler>::iterator itr = DoPrepareProc.begin(); itr != DoPrepareProc.end(); ++itr)
+ if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
+ sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `DoPrepareProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
+
+ for (std::list<AuraProcHandler>::iterator itr = OnProc.begin(); itr != OnProc.end(); ++itr)
+ if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
+ sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `OnProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
+
+ for (std::list<AuraProcHandler>::iterator itr = AfterProc.begin(); itr != AfterProc.end(); ++itr)
+ if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
+ sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `AfterProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
+
+ for (std::list<EffectProcHandler>::iterator itr = OnEffectProc.begin(); itr != OnEffectProc.end(); ++itr)
+ if (!(*itr).GetAffectedEffectsMask(entry))
+ sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectProc` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+
+ for (std::list<EffectProcHandler>::iterator itr = AfterEffectProc.begin(); itr != AfterEffectProc.end(); ++itr)
+ if (!(*itr).GetAffectedEffectsMask(entry))
+ sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `AfterEffectProc` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+
return _SpellScript::_Validate(entry);
}
@@ -818,6 +842,37 @@ void AuraScript::EffectSplitHandler::Call(AuraScript* auraScript, AuraEffect* au
(auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, splitAmount);
}
+AuraScript::CheckProcHandler::CheckProcHandler(AuraCheckProcFnType handlerScript)
+{
+ _HandlerScript = handlerScript;
+}
+
+bool AuraScript::CheckProcHandler::Call(AuraScript* auraScript, ProcEventInfo& eventInfo)
+{
+ return (auraScript->*_HandlerScript)(eventInfo);
+}
+
+AuraScript::AuraProcHandler::AuraProcHandler(AuraProcFnType handlerScript)
+{
+ _HandlerScript = handlerScript;
+}
+
+void AuraScript::AuraProcHandler::Call(AuraScript* auraScript, ProcEventInfo& eventInfo)
+{
+ (auraScript->*_HandlerScript)(eventInfo);
+}
+
+AuraScript::EffectProcHandler::EffectProcHandler(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName)
+ : AuraScript::EffectBase(effIndex, effName)
+{
+ _EffectHandlerScript = effectHandlerScript;
+}
+
+void AuraScript::EffectProcHandler::Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+{
+ (auraScript->*_EffectHandlerScript)(aurEff, eventInfo);
+}
+
bool AuraScript::_Load(Aura* aura)
{
m_aura = aura;
@@ -853,6 +908,8 @@ bool AuraScript::_IsDefaultActionPrevented()
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
case AURA_SCRIPT_HOOK_EFFECT_ABSORB:
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
+ case AURA_SCRIPT_HOOK_PREPARE_PROC:
+ case AURA_SCRIPT_HOOK_EFFECT_PROC:
return m_defaultActionPrevented;
default:
ASSERT(false && "AuraScript::_IsDefaultActionPrevented is called in a wrong place");
@@ -869,6 +926,8 @@ void AuraScript::PreventDefaultAction()
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
case AURA_SCRIPT_HOOK_EFFECT_ABSORB:
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
+ case AURA_SCRIPT_HOOK_PREPARE_PROC:
+ case AURA_SCRIPT_HOOK_EFFECT_PROC:
m_defaultActionPrevented = true;
break;
default:
@@ -1051,6 +1110,12 @@ Unit* AuraScript::GetTarget() const
case AURA_SCRIPT_HOOK_EFFECT_MANASHIELD:
case AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD:
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
+ case AURA_SCRIPT_HOOK_CHECK_PROC:
+ case AURA_SCRIPT_HOOK_PREPARE_PROC:
+ case AURA_SCRIPT_HOOK_PROC:
+ case AURA_SCRIPT_HOOK_AFTER_PROC:
+ case AURA_SCRIPT_HOOK_EFFECT_PROC:
+ case AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC:
return m_auraApplication->GetTarget();
default:
sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u` AuraScript::GetTarget called in a hook in which the call won't have effect!", m_scriptName->c_str(), m_scriptSpellId);
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 5791c701c07..6f1df2560dc 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -428,14 +428,22 @@ enum AuraScriptHookType
AURA_SCRIPT_HOOK_EFFECT_SPLIT,
AURA_SCRIPT_HOOK_CHECK_AREA_TARGET,
AURA_SCRIPT_HOOK_DISPEL,
- AURA_SCRIPT_HOOK_AFTER_DISPEL
+ AURA_SCRIPT_HOOK_AFTER_DISPEL,
+ // Spell Proc Hooks
+ AURA_SCRIPT_HOOK_CHECK_PROC,
+ AURA_SCRIPT_HOOK_PREPARE_PROC,
+ AURA_SCRIPT_HOOK_PROC,
+ AURA_SCRIPT_HOOK_EFFECT_PROC,
+ AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC,
+ AURA_SCRIPT_HOOK_AFTER_PROC,
/*AURA_SCRIPT_HOOK_APPLY,
AURA_SCRIPT_HOOK_REMOVE, */
};
+/*
#define HOOK_AURA_EFFECT_START HOOK_AURA_EFFECT_APPLY
#define HOOK_AURA_EFFECT_END HOOK_AURA_EFFECT_CALC_SPELLMOD + 1
#define HOOK_AURA_EFFECT_COUNT HOOK_AURA_EFFECT_END - HOOK_AURA_EFFECT_START
-
+*/
class AuraScript : public _SpellScript
{
// internal use classes & functions
@@ -453,6 +461,9 @@ class AuraScript : public _SpellScript
typedef void(CLASSNAME::*AuraEffectCalcSpellModFnType)(AuraEffect const*, SpellModifier* &); \
typedef void(CLASSNAME::*AuraEffectAbsorbFnType)(AuraEffect*, DamageInfo &, uint32 &); \
typedef void(CLASSNAME::*AuraEffectSplitFnType)(AuraEffect*, DamageInfo &, uint32 &); \
+ typedef bool(CLASSNAME::*AuraCheckProcFnType)(ProcEventInfo&); \
+ typedef void(CLASSNAME::*AuraProcFnType)(ProcEventInfo&); \
+ typedef void(CLASSNAME::*AuraEffectProcFnType)(AuraEffect const*, ProcEventInfo&); \
AURASCRIPT_FUNCTION_TYPE_DEFINES(AuraScript)
@@ -552,6 +563,30 @@ class AuraScript : public _SpellScript
private:
AuraEffectSplitFnType pEffectHandlerScript;
};
+ class CheckProcHandler
+ {
+ public:
+ CheckProcHandler(AuraCheckProcFnType handlerScript);
+ bool Call(AuraScript* auraScript, ProcEventInfo& eventInfo);
+ private:
+ AuraCheckProcFnType _HandlerScript;
+ };
+ class AuraProcHandler
+ {
+ public:
+ AuraProcHandler(AuraProcFnType handlerScript);
+ void Call(AuraScript* auraScript, ProcEventInfo& eventInfo);
+ private:
+ AuraProcFnType _HandlerScript;
+ };
+ class EffectProcHandler : public EffectBase
+ {
+ public:
+ EffectProcHandler(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName);
+ void Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo);
+ private:
+ AuraEffectProcFnType _EffectHandlerScript;
+ };
#define AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
class CheckAreaTargetFunction : public AuraScript::CheckAreaTargetHandler { public: CheckAreaTargetFunction(AuraCheckAreaTargetFnType _pHandlerScript) : AuraScript::CheckAreaTargetHandler((AuraScript::AuraCheckAreaTargetFnType)_pHandlerScript) {} }; \
@@ -565,6 +600,9 @@ class AuraScript : public _SpellScript
class EffectAbsorbFunction : public AuraScript::EffectAbsorbHandler { public: EffectAbsorbFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectAbsorbHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \
class EffectManaShieldFunction : public AuraScript::EffectManaShieldHandler { public: EffectManaShieldFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectManaShieldHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \
class EffectSplitFunction : public AuraScript::EffectSplitHandler { public: EffectSplitFunction(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectSplitHandler((AuraScript::AuraEffectSplitFnType)_pEffectHandlerScript, _effIndex) {} }; \
+ class CheckProcHandlerFunction : public AuraScript::CheckProcHandler { public: CheckProcHandlerFunction(AuraCheckProcFnType handlerScript) : AuraScript::CheckProcHandler((AuraScript::AuraCheckProcFnType)handlerScript) {} }; \
+ class AuraProcHandlerFunction : public AuraScript::AuraProcHandler { public: AuraProcHandlerFunction(AuraProcFnType handlerScript) : AuraScript::AuraProcHandler((AuraScript::AuraProcFnType)handlerScript) {} }; \
+ class EffectProcHandlerFunction : public AuraScript::EffectProcHandler { public: EffectProcHandlerFunction(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName) : AuraScript::EffectProcHandler((AuraScript::AuraEffectProcFnType)effectHandlerScript, effIndex, effName) {} }; \
#define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)
@@ -695,6 +733,36 @@ class AuraScript : public _SpellScript
HookList<EffectSplitHandler> OnEffectSplit;
#define AuraEffectSplitFn(F, I) EffectSplitFunction(&F, I)
+ // executed when aura checks if it can proc
+ // example: DoCheckProc += AuraCheckProcFn(class::function);
+ // where function is: bool function (ProcEventInfo& eventInfo);
+ HookList<CheckProcHandler> DoCheckProc;
+ #define AuraCheckProcFn(F) CheckProcHandlerFunction(&F)
+
+ // executed before aura procs (possibility to prevent charge drop/cooldown)
+ // example: DoPrepareProc += AuraProcFn(class::function);
+ // where function is: void function (ProcEventInfo& eventInfo);
+ HookList<AuraProcHandler> DoPrepareProc;
+ // executed when aura procs
+ // example: OnProc += AuraProcFn(class::function);
+ // where function is: void function (ProcEventInfo& eventInfo);
+ HookList<AuraProcHandler> OnProc;
+ // executed after aura proced
+ // example: AfterProc += AuraProcFn(class::function);
+ // where function is: void function (ProcEventInfo& eventInfo);
+ HookList<AuraProcHandler> AfterProc;
+ #define AuraProcFn(F) AuraProcHandlerFunction(&F)
+
+ // executed when aura effect procs
+ // example: OnEffectProc += AuraEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
+ // where function is: void function (AuraEffect const* aurEff, ProcEventInfo& procInfo);
+ HookList<EffectProcHandler> OnEffectProc;
+ // executed after aura effect proced
+ // example: AfterEffectProc += AuraEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
+ // where function is: void function (AuraEffect const* aurEff, ProcEventInfo& procInfo);
+ HookList<EffectProcHandler> AfterEffectProc;
+ #define AuraEffectProcFn(F, I, N) EffectProcHandlerFunction(&F, I, N)
+
// AuraScript interface - hook/effect execution manipulators
// prevents default action of a hook from being executed (works only while called in a hook which default action can be prevented)
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 068bca2692f..2536ad6f0b9 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1781,7 +1781,9 @@ void World::SetInitialWorldSettings()
uint32 startupDuration = GetMSTimeDiffToNow(startupBegin);
sLog->outInfo(LOG_FILTER_WORLDSERVER, "World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000));
- sLog->EnableDBAppenders();
+
+ if (uint32 realmId = ConfigMgr::GetIntDefault("RealmID", 0)) // 0 reserved for auth
+ sLog->SetRealmId(realmId);
}
void World::DetectDBCLang()
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index 8679e288282..7ccd5ed1177 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -33,6 +33,42 @@ EndScriptData */
#include "Player.h"
#include "Pet.h"
+struct NpcFlagText
+{
+ uint32 flag;
+ int32 text;
+};
+
+#define NPCFLAG_COUNT 24
+
+const NpcFlagText npcFlagTexts[NPCFLAG_COUNT] =
+{
+ { UNIT_NPC_FLAG_AUCTIONEER, LANG_NPCINFO_AUCTIONEER },
+ { UNIT_NPC_FLAG_BANKER, LANG_NPCINFO_BANKER },
+ { UNIT_NPC_FLAG_BATTLEMASTER, LANG_NPCINFO_BATTLEMASTER },
+ { UNIT_NPC_FLAG_FLIGHTMASTER, LANG_NPCINFO_FLIGHTMASTER },
+ { UNIT_NPC_FLAG_GOSSIP, LANG_NPCINFO_GOSSIP },
+ { UNIT_NPC_FLAG_GUILD_BANKER, LANG_NPCINFO_GUILD_BANKER },
+ { UNIT_NPC_FLAG_INNKEEPER, LANG_NPCINFO_INNKEEPER },
+ { UNIT_NPC_FLAG_PETITIONER, LANG_NPCINFO_PETITIONER },
+ { UNIT_NPC_FLAG_PLAYER_VEHICLE, LANG_NPCINFO_PLAYER_VEHICLE },
+ { UNIT_NPC_FLAG_QUESTGIVER, LANG_NPCINFO_QUESTGIVER },
+ { UNIT_NPC_FLAG_REPAIR, LANG_NPCINFO_REPAIR },
+ { UNIT_NPC_FLAG_SPELLCLICK, LANG_NPCINFO_SPELLCLICK },
+ { UNIT_NPC_FLAG_SPIRITGUIDE, LANG_NPCINFO_SPIRITGUIDE },
+ { UNIT_NPC_FLAG_SPIRITHEALER, LANG_NPCINFO_SPIRITHEALER },
+ { UNIT_NPC_FLAG_STABLEMASTER, LANG_NPCINFO_STABLEMASTER },
+ { UNIT_NPC_FLAG_TABARDDESIGNER, LANG_NPCINFO_TABARDDESIGNER },
+ { UNIT_NPC_FLAG_TRAINER, LANG_NPCINFO_TRAINER },
+ { UNIT_NPC_FLAG_TRAINER_CLASS, LANG_NPCINFO_TRAINER_CLASS },
+ { UNIT_NPC_FLAG_TRAINER_PROFESSION, LANG_NPCINFO_TRAINER_PROFESSION },
+ { UNIT_NPC_FLAG_VENDOR, LANG_NPCINFO_VENDOR },
+ { UNIT_NPC_FLAG_VENDOR_AMMO, LANG_NPCINFO_VENDOR_AMMO },
+ { UNIT_NPC_FLAG_VENDOR_FOOD, LANG_NPCINFO_VENDOR_FOOD },
+ { UNIT_NPC_FLAG_VENDOR_POISON, LANG_NPCINFO_VENDOR_POISON },
+ { UNIT_NPC_FLAG_VENDOR_REAGENT, LANG_NPCINFO_VENDOR_REAGENT }
+};
+
class npc_commandscript : public CommandScript
{
public:
@@ -619,11 +655,9 @@ public:
handler->PSendSysMessage(LANG_NPCINFO_POSITION, float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
handler->PSendSysMessage(LANG_NPCINFO_AIINFO, target->GetAIName().c_str(), target->GetScriptName().c_str());
- if (npcflags & UNIT_NPC_FLAG_VENDOR)
- handler->SendSysMessage(LANG_NPCINFO_VENDOR);
-
- if (npcflags & UNIT_NPC_FLAG_TRAINER)
- handler->SendSysMessage(LANG_NPCINFO_TRAINER);
+ for (uint8 i = 0; i < NPCFLAG_COUNT; i++)
+ if (npcflags & npcFlagTexts[i].flag)
+ handler->PSendSysMessage(npcFlagTexts[i].text, npcFlagTexts[i].flag);
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
index b0a2d48d053..19660cec4af 100644
--- a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
+++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
@@ -64,6 +64,12 @@ enum eMisc
KIRTONOS_PATH = 105061
};
+Position const PosMove[2] =
+{
+ { 299.4884f, 92.76137f, 105.6335f, 0.0f },
+ { 314.8673f, 90.30210f, 101.6459f, 0.0f }
+};
+
class boss_kirtonos_the_herald : public CreatureScript
{
public: boss_kirtonos_the_herald() : CreatureScript("boss_kirtonos_the_herald") { }
@@ -74,15 +80,11 @@ class boss_kirtonos_the_herald : public CreatureScript
void Reset()
{
- _introEvent = 0;
- _introTimer = 0;
_Reset();
}
void EnterCombat(Unit* /*who*/)
{
- _introTimer = 0;
- _introEvent = 0;
events.ScheduleEvent(EVENT_SWOOP, urand(8000, 8000));
events.ScheduleEvent(EVENT_WING_FLAP, urand(15000, 15000));
events.ScheduleEvent(EVENT_PIERCE_ARMOR, urand(18000, 18000));
@@ -120,12 +122,10 @@ class boss_kirtonos_the_herald : public CreatureScript
void IsSummonedBy(Unit* /*summoner*/)
{
+ events.ScheduleEvent(INTRO_1, 500);
me->SetDisableGravity(true);
me->SetReactState(REACT_PASSIVE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
- _introEvent = INTRO_1;
- _introTimer = 1;
- _currentPoint = 0;
Talk(EMOTE_SUMMONED);
}
@@ -138,68 +138,58 @@ class boss_kirtonos_the_herald : public CreatureScript
{
if (type == WAYPOINT_MOTION_TYPE && id == POINT_KIRTONOS_LAND)
{
- _introTimer = 1500;
- _introEvent = INTRO_2;
+ events.ScheduleEvent(INTRO_2, 1500);
}
}
void UpdateAI(uint32 const diff)
{
- if (_introEvent)
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent() && !UpdateVictim())
{
- if (_introTimer <= diff)
+ switch (eventId)
{
- switch (_introEvent)
- {
- case INTRO_1:
- me->GetMotionMaster()->MovePath(KIRTONOS_PATH, false);
- _introEvent = 0;
- break;
- case INTRO_2:
- me->GetMotionMaster()->MovePoint(0, 299.4884f, 92.76137f, 105.6335f);
- _introTimer = 1000;
- _introEvent = INTRO_3;
- break;
- case INTRO_3:
- if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_GATE_KIRTONOS)))
- gate->SetGoState(GO_STATE_READY);
- me->SetFacingTo(0.01745329f);
- _introTimer = 3000;
- _introEvent = INTRO_4;
- break;
- case INTRO_4:
- if (GameObject* brazier = me->GetMap()->GetGameObject(instance->GetData64(GO_BRAZIER_OF_THE_HERALD)))
- brazier->SetGoState(GO_STATE_READY);
- me->SetWalk(true);
- me->SetDisableGravity(false);
- DoCast(me, SPELL_KIRTONOS_TRANSFORM);
- me->SetCanFly(false);
- _introTimer = 1000;
- _introEvent = INTRO_5;
- break;
- case INTRO_5:
- me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_KIRTONOS_STAFF));
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
- me->SetReactState(REACT_AGGRESSIVE);
- _introTimer = 5000;
- _introEvent = INTRO_6;
- case INTRO_6:
- me->GetMotionMaster()->MovePoint(0, 314.8673f, 90.3021f, 101.6459f);
- _introTimer = 0;
- _introEvent = 0;
+ case INTRO_1:
+ me->GetMotionMaster()->MovePath(KIRTONOS_PATH, false);
+ break;
+ case INTRO_2:
+ me->GetMotionMaster()->MovePoint(0, PosMove[0]);
+ events.ScheduleEvent(INTRO_3, 1000);
+ break;
+ case INTRO_3:
+ if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_GATE_KIRTONOS)))
+ gate->SetGoState(GO_STATE_READY);
+ me->SetFacingTo(0.01745329f);
+ events.ScheduleEvent(INTRO_4, 3000);
+ break;
+ case INTRO_4:
+ if (GameObject* brazier = me->GetMap()->GetGameObject(instance->GetData64(GO_BRAZIER_OF_THE_HERALD)))
+ brazier->SetGoState(GO_STATE_READY);
+ me->SetWalk(true);
+ me->SetDisableGravity(false);
+ DoCast(me, SPELL_KIRTONOS_TRANSFORM);
+ me->SetCanFly(false);
+ events.ScheduleEvent(INTRO_5, 1000);
+ break;
+ case INTRO_5:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
+ me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_KIRTONOS_STAFF));
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ events.ScheduleEvent(INTRO_6, 5000);
+ break;
+ case INTRO_6:
+ me->GetMotionMaster()->MovePoint(0, PosMove[1]);
+ break;
+ default:
break;
- }
}
- else
- _introTimer -= diff;
}
if (!UpdateVictim())
return;
- events.Update(diff);
-
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
@@ -257,11 +247,6 @@ class boss_kirtonos_the_herald : public CreatureScript
DoMeleeAttackIfReady();
}
-
- private:
- uint8 _introEvent;
- uint32 _introTimer;
- uint32 _currentPoint;
};
CreatureAI* GetAI(Creature* creature) const
@@ -280,6 +265,11 @@ enum Brazier_Of_The_Herald
SOUND_SCREECH = 557
};
+Position const PosSummon[1] =
+{
+ { 315.028f, 70.53845f, 102.1496f, 0.3859715f }
+};
+
class go_brazier_of_the_herald : public GameObjectScript
{
public:
@@ -289,7 +279,7 @@ class go_brazier_of_the_herald : public GameObjectScript
{
go->UseDoorOrButton();
go->PlayDirectSound(SOUND_SCREECH, 0);
- player->SummonCreature(NPC_KIRTONOS, 315.028f, 70.53845f, 102.1496f, 0.3859715f, TEMPSUMMON_DEAD_DESPAWN, 900000);
+ player->SummonCreature(NPC_KIRTONOS, PosSummon[0], TEMPSUMMON_DEAD_DESPAWN, 900000);
return true;
}
};
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
index 1334d587464..51aab7c20d0 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
@@ -79,11 +79,7 @@ class boss_arlokk : public CreatureScript
struct boss_arlokkAI : public BossAI
{
- boss_arlokkAI(Creature* creature) : BossAI(creature, DATA_ARLOKK) {}
-
- uint32 summonCount;
- // Unit* markedTarget;
- uint64 markedTargetGUID;
+ boss_arlokkAI(Creature* creature) : BossAI(creature, DATA_ARLOKK) { }
void Reset()
{
@@ -113,13 +109,15 @@ class boss_arlokk : public CreatureScript
void JustReachedHome()
{
- if (instance)
- instance->SetData(DATA_ARLOKK, NOT_STARTED);
+ instance->SetBossState(DATA_ARLOKK, NOT_STARTED);
me->DespawnOrUnsummon();
}
void DoSummonPhanters()
{
+ if (summonCount > 30)
+ return;
+
if (markedTargetGUID)
Talk(SAY_FEAST_PANTHER, markedTargetGUID);
me->SummonCreature(NPC_ZULIAN_PROWLER, PosSummonProwlers[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
@@ -152,7 +150,8 @@ class boss_arlokk : public CreatureScript
events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 15000, 0, PHASE_ONE);
break;
case EVENT_MARK:
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_MARK);
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(target, SPELL_MARK);
events.ScheduleEvent(EVENT_MARK, 15000, 0, PHASE_ONE);
break;
case EVENT_CLEAVE:
@@ -164,8 +163,7 @@ class boss_arlokk : public CreatureScript
events.ScheduleEvent(EVENT_GOUGE, urand(17000, 27000), 0, PHASE_TWO);
break;
case EVENT_SUMMON:
- if (summonCount <= 30)
- DoSummonPhanters();
+ DoSummonPhanters();
events.ScheduleEvent(EVENT_SUMMON, 5000);
break;
case EVENT_VANISH:
@@ -176,21 +174,21 @@ class boss_arlokk : public CreatureScript
events.ScheduleEvent(EVENT_VISIBLE, 6000);
break;
case EVENT_VISIBLE:
- {
- me->SetDisplayId(MODEL_ID_PANTHER);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- const CreatureTemplate* cinfo = me->GetCreatureTemplate();
- me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
- me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
- me->UpdateDamagePhysical(BASE_ATTACK);
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- AttackStart(target);
- events.ScheduleEvent(EVENT_VANISH, 39000);
- events.ScheduleEvent(EVENT_CLEAVE, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_GOUGE, 14000, 0, PHASE_TWO);
- events.SetPhase(PHASE_TWO);
- break;
- }
+ {
+ me->SetDisplayId(MODEL_ID_PANTHER);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ const CreatureTemplate* cinfo = me->GetCreatureTemplate();
+ me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
+ me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
+ me->UpdateDamagePhysical(BASE_ATTACK);
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ AttackStart(target);
+ events.ScheduleEvent(EVENT_VANISH, 39000);
+ events.ScheduleEvent(EVENT_CLEAVE, 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_GOUGE, 14000, 0, PHASE_TWO);
+ events.SetPhase(PHASE_TWO);
+ break;
+ }
default:
break;
}
@@ -198,11 +196,15 @@ class boss_arlokk : public CreatureScript
DoMeleeAttackIfReady();
}
+
+ private:
+ uint32 summonCount;
+ uint64 markedTargetGUID;
};
CreatureAI* GetAI(Creature* creature) const
{
- return new boss_arlokkAI(creature);
+ return GetZulGurubAI<boss_arlokkAI>(creature);
}
};
@@ -214,9 +216,9 @@ class go_gong_of_bethekk : public GameObjectScript
{
if (InstanceScript* instance = go->GetInstanceScript())
{
- if (instance->GetData(DATA_ARLOKK) == DONE || instance->GetData(DATA_ARLOKK) == IN_PROGRESS)
+ if (instance->GetBossState(DATA_ARLOKK) == DONE || instance->GetBossState(DATA_ARLOKK) == IN_PROGRESS)
return true;
- instance->SetData(DATA_ARLOKK, IN_PROGRESS);
+ instance->SetBossState(DATA_ARLOKK, IN_PROGRESS);
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp
index 8003f4a1ed7..68aac7547df 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp
@@ -90,15 +90,15 @@ class boss_hakkar : public CreatureScript
events.ScheduleEvent(EVENT_CAUSE_INSANITY, 17000);
events.ScheduleEvent(EVENT_WILL_OF_HAKKAR, 17000);
events.ScheduleEvent(EVENT_ENRAGE, 600000);
- if (instance->GetData(DATA_JEKLIK) != DONE)
+ if (instance->GetBossState(DATA_JEKLIK) != DONE)
events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, 4000);
- if (instance->GetData(DATA_VENOXIS) != DONE)
+ if (instance->GetBossState(DATA_VENOXIS) != DONE)
events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, 7000);
- if (instance->GetData(DATA_MARLI) != DONE)
+ if (instance->GetBossState(DATA_MARLI) != DONE)
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000);
- if (instance->GetData(DATA_THEKAL) != DONE)
+ if (instance->GetBossState(DATA_THEKAL) != DONE)
events.ScheduleEvent(EVENT_ASPECT_OF_THEKAL, 8000);
- if (instance->GetData(DATA_ARLOKK) != DONE)
+ if (instance->GetBossState(DATA_ARLOKK) != DONE)
events.ScheduleEvent(EVENT_ASPECT_OF_ARLOKK, 18000);
Talk(SAY_AGGRO);
}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp
index 7f19962e719..dc02c895327 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp
@@ -271,7 +271,7 @@ class mob_batrider : public CreatureScript
{
if (instance)
{
- if (instance->GetData(DATA_JEKLIK) == DONE)
+ if (instance->GetBossState(DATA_JEKLIK) == DONE)
{
me->setDeathState(JUST_DIED);
me->RemoveCorpse();
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
index 258dda26c11..e402480609b 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
@@ -25,6 +25,9 @@ EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "Spell.h"
+#include "SpellAuras.h"
+#include "SpellScript.h"
#include "zulgurub.h"
enum Says
@@ -32,23 +35,73 @@ enum Says
SAY_AGGRO = 0,
SAY_DING_KILL = 1,
SAY_WATCH = 2,
- SAY_WATCH_WHISPER = 3, // is this text for real? easter egg?
+ SAY_WATCH_WHISPER = 3,
+ SAY_OHGAN_DEAD = 4,
SAY_GRATS_JINDO = 0,
};
enum Spells
{
- SPELL_CHARGE = 24408,
- SPELL_CLEAVE = 7160,
+ SPELL_CHARGE = 24408, // seen
+ SPELL_OVERPOWER = 24407, // Seen
SPELL_FEAR = 29321,
- SPELL_WHIRLWIND = 15589,
- SPELL_MORTAL_STRIKE = 16856,
- SPELL_ENRAGE = 24318,
- SPELL_WATCH = 24314,
- SPELL_LEVEL_UP = 24312,
- SPELL_SWIFT_ORANGE_RAPTOR = 23243,
- // Ohgans Spell
- SPELL_SUNDERARMOR = 24317
+ SPELL_WHIRLWIND = 13736, // Triggers 15589
+ SPELL_MORTAL_STRIKE = 16856, // Seen
+ SPELL_FRENZY = 24318, // seen
+ SPELL_WATCH = 24314, // seen 24315, 24316
+ SPELL_WATCH_CHARGE = 24315, // Triggers 24316
+ SPELL_LEVEL_UP = 24312 //
+};
+
+enum Events
+{
+ EVENT_CHECK_SPEAKER = 1,
+ EVENT_CHECK_START = 2,
+ EVENT_STARTED = 3,
+ EVENT_OVERPOWER = 4,
+ EVENT_MORTAL_STRIKE = 5,
+ EVENT_WHIRLWIND = 6,
+ EVENT_CHECK_OHGAN = 7,
+ EVENT_WATCH_PLAYER = 8,
+ EVENT_CHARGE_PLAYER = 9
+};
+
+enum Misc
+{
+ MODEL_OHGAN_MOUNT = 15271,
+ PATH_MANDOKIR = 492861,
+ POINT_MANDOKIR_END = 24,
+ CHAINED_SPIRT_COUNT = 20
+};
+
+Position const PosSummonChainedSpirits[CHAINED_SPIRT_COUNT] =
+{
+ { -12167.17f, -1979.330f, 133.0992f, 2.268928f },
+ { -12262.74f, -1953.394f, 133.5496f, 0.593412f },
+ { -12176.89f, -1983.068f, 133.7841f, 2.129302f },
+ { -12226.45f, -1977.933f, 132.7982f, 1.466077f },
+ { -12204.74f, -1890.431f, 135.7569f, 4.415683f },
+ { -12216.70f, -1891.806f, 136.3496f, 4.677482f },
+ { -12236.19f, -1892.034f, 134.1041f, 5.044002f },
+ { -12248.24f, -1893.424f, 134.1182f, 5.270895f },
+ { -12257.36f, -1897.663f, 133.1484f, 5.462881f },
+ { -12265.84f, -1903.077f, 133.1649f, 5.654867f },
+ { -12158.69f, -1972.707f, 133.8751f, 2.408554f },
+ { -12178.82f, -1891.974f, 134.1786f, 3.944444f },
+ { -12193.36f, -1890.039f, 135.1441f, 4.188790f },
+ { -12275.59f, -1932.845f, 134.9017f, 0.174533f },
+ { -12273.51f, -1941.539f, 136.1262f, 0.314159f },
+ { -12247.02f, -1963.497f, 133.9476f, 0.872665f },
+ { -12238.68f, -1969.574f, 133.6273f, 1.134464f },
+ { -12192.78f, -1982.116f, 132.6966f, 1.919862f },
+ { -12210.81f, -1979.316f, 133.8700f, 1.797689f },
+ { -12283.51f, -1924.839f, 133.5170f, 0.069813f }
+};
+
+Position const PosMandokir[2] =
+{
+ { -12167.8f, -1927.25f, 153.73f, 3.76991f },
+ { -12197.86f, -1949.392f, 130.2745f, 0.0f }
};
class boss_mandokir : public CreatureScript
@@ -57,298 +110,319 @@ class boss_mandokir : public CreatureScript
struct boss_mandokirAI : public BossAI
{
- boss_mandokirAI(Creature* creature) : BossAI(creature, DATA_MANDOKIR) {}
-
- uint32 KillCount;
- uint32 Watch_Timer;
- uint32 TargetInRange;
- uint32 Cleave_Timer;
- uint32 Whirlwind_Timer;
- uint32 Fear_Timer;
- uint32 MortalStrike_Timer;
- uint32 Check_Timer;
- float targetX;
- float targetY;
- float targetZ;
-
- InstanceScript* instance;
-
- bool endWatch;
- bool someWatched;
- bool RaptorDead;
- bool CombatStart;
- bool SpeakerDead;
-
- uint64 WatchTarget;
+ boss_mandokirAI(Creature* creature) : BossAI(creature, DATA_MANDOKIR) { }
void Reset()
{
- KillCount = 0;
- Watch_Timer = 33000;
- Cleave_Timer = 7000;
- Whirlwind_Timer = 20000;
- Fear_Timer = 1000;
- MortalStrike_Timer = 1000;
- Check_Timer = 1000;
-
- targetX = 0.0f;
- targetY = 0.0f;
- targetZ = 0.0f;
- TargetInRange = 0;
-
- WatchTarget = 0;
-
- someWatched = false;
- endWatch = false;
- RaptorDead = false;
- CombatStart = false;
- SpeakerDead = false;
-
- DoCast(me, 23243);
+ if (me->GetPositionZ() > 140.0f)
+ {
+ _Reset();
+ killCount = 0;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
+ events.ScheduleEvent(EVENT_CHECK_START, 1000);
+ if (Creature* speaker = Creature::GetCreature(*me, instance->GetData64(NPC_VILEBRANCH_SPEAKER)))
+ if (!speaker->isAlive())
+ speaker->Respawn(true);
+ }
+ summons.DespawnAll();
+ me->Mount(MODEL_OHGAN_MOUNT);
}
void JustDied(Unit* /*killer*/)
{
- _JustDied();
+ // Do not want to unsummon Ohgan
+ for (int i = 0; i < CHAINED_SPIRT_COUNT; ++i)
+ if (Creature* unsummon = Creature::GetCreature(*me, chainedSpirtGUIDs[i]))
+ unsummon->DespawnOrUnsummon();
+ instance->SetBossState(DATA_MANDOKIR, DONE);
+ instance->SaveToDB();
}
- void KilledUnit(Unit* victim)
+ void EnterCombat(Unit* /*who*/)
{
- if (victim->GetTypeId() == TYPEID_PLAYER)
+ _EnterCombat();
+ events.ScheduleEvent(EVENT_OVERPOWER, urand(7000, 9000));
+ events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(12000, 18000));
+ events.ScheduleEvent(EVENT_WHIRLWIND, urand(24000, 30000));
+ events.ScheduleEvent(EVENT_CHECK_OHGAN, 1000);
+ events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(13000, 15000));
+ events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(33000, 38000));
+ me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
+ Talk(SAY_AGGRO);
+ me->Dismount();
+ // Summon Ohgan (Spell missing) TEMP HACK
+ me->SummonCreature(NPC_OHGAN, me->GetPositionX()-3, me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 35000);
+ // Summon Chained Spirits
+ for (int i = 0; i < CHAINED_SPIRT_COUNT; ++i)
{
- ++KillCount;
-
- if (KillCount == 3)
- {
- Talk(SAY_DING_KILL);
-
- if (instance)
- {
- uint64 JindoGUID = instance->GetData64(DATA_JINDO);
- if (JindoGUID)
- {
- if (Creature* jTemp = Creature::GetCreature(*me, JindoGUID))
- {
- if (jTemp->isAlive())
- jTemp->AI()->Talk(SAY_GRATS_JINDO);
- }
- }
- }
- DoCast(me, SPELL_LEVEL_UP, true);
- KillCount = 0;
- }
+ Creature* chainedSpirt = me->SummonCreature(NPC_CHAINED_SPIRT, PosSummonChainedSpirits[i], TEMPSUMMON_CORPSE_DESPAWN);
+ chainedSpirtGUIDs[i] = chainedSpirt->GetGUID();
}
+ DoZoneInCombat();
}
- void EnterCombat(Unit* /*who*/)
+ void KilledUnit(Unit* victim)
{
- _EnterCombat();
- Talk(SAY_AGGRO);
+ if (victim->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if (++killCount == 3)
+ {
+ Talk(SAY_DING_KILL);
+ if (Creature* jindo = Creature::GetCreature(*me, instance->GetData64(DATA_JINDO)))
+ if (jindo->isAlive())
+ jindo->AI()->Talk(SAY_GRATS_JINDO);
+ DoCast(me, SPELL_LEVEL_UP, true);
+ killCount = 0;
+ }
}
- void UpdateAI(const uint32 diff)
+ void MovementInform(uint32 type, uint32 id)
{
- if (!SpeakerDead)
+ if (type == WAYPOINT_MOTION_TYPE)
{
- if (!me->FindNearestCreature(NPC_SPEAKER, 100.0f, true))
+ me->SetWalk(false);
+ if (id == POINT_MANDOKIR_END)
{
- me->GetMotionMaster()->MovePoint(0, -12196.3f, -1948.37f, 130.36f);
- SpeakerDead = true;
+ me->SetHomePosition(PosMandokir[0]);
+ instance->SetBossState(DATA_MANDOKIR, NOT_STARTED);
+ me->DespawnOrUnsummon(6000); // No idea how to respawn on wipe.
}
}
+ }
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE && SpeakerDead)
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ void UpdateAI(uint32 const diff)
+ {
+ events.Update(diff);
if (!UpdateVictim())
- return;
-
- if (me->getVictim() && me->isAlive())
{
- if (!CombatStart)
+ if (instance->GetBossState(DATA_MANDOKIR) == NOT_STARTED || instance->GetBossState(DATA_MANDOKIR) == SPECIAL)
{
- //At combat Start Mandokir is mounted so we must unmount it first
- me->Dismount();
-
- //And summon his raptor
- me->SummonCreature(14988, me->getVictim()->GetPositionX(), me->getVictim()->GetPositionY(), me->getVictim()->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 35000);
- CombatStart = true;
- }
-
- if (Watch_Timer <= diff) //Every 20 Sec Mandokir will check this
- {
- if (WatchTarget) //If someone is watched and If the Position of the watched target is different from the one stored, or are attacking, mandokir will charge him
+ while (uint32 eventId = events.ExecuteEvent())
{
- Unit* unit = Unit::GetUnit(*me, WatchTarget);
-
- if (unit && (
- targetX != unit->GetPositionX() ||
- targetY != unit->GetPositionY() ||
- targetZ != unit->GetPositionZ() ||
- unit->isInCombat()))
+ switch (eventId)
{
- if (me->IsWithinMeleeRange(unit))
- {
- DoCast(unit, 24316);
- }
- else
- {
- DoCast(unit, SPELL_CHARGE);
- //me->SendMonsterMove(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), 0, true, 1);
- AttackStart(unit);
- }
+ case EVENT_CHECK_START:
+ if (instance->GetBossState(DATA_MANDOKIR) == SPECIAL)
+ {
+ me->GetMotionMaster()->MovePoint(0, PosMandokir[1].m_positionX, PosMandokir[1].m_positionY, PosMandokir[1].m_positionZ);
+ events.ScheduleEvent(EVENT_STARTED, 6000);
+ }
+ else
+ events.ScheduleEvent(EVENT_CHECK_START, 1000);
+ break;
+ case EVENT_STARTED:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
+ me->GetMotionMaster()->MovePath(PATH_MANDOKIR, false);
+ break;
+ default:
+ break;
}
}
- someWatched = false;
- Watch_Timer = 20000;
- } else Watch_Timer -= diff;
-
- if ((Watch_Timer < 8000) && !someWatched) //8 sec(cast time + expire time) before the check for the watch effect mandokir will cast watch debuff on a random target
- {
- if (Unit* p = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- Talk(SAY_WATCH, p->GetGUID());
- DoCast(p, SPELL_WATCH);
- WatchTarget = p->GetGUID();
- someWatched = true;
- endWatch = true;
- }
}
+ return;
+ }
- if ((Watch_Timer < 1000) && endWatch) //1 sec before the debuf expire, store the target position
- {
- Unit* unit = Unit::GetUnit(*me, WatchTarget);
- if (unit)
- {
- targetX = unit->GetPositionX();
- targetY = unit->GetPositionY();
- targetZ = unit->GetPositionZ();
- }
- endWatch = false;
- }
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (!someWatched)
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- //Cleave
- if (Cleave_Timer <= diff)
- {
- DoCast(me->getVictim(), SPELL_CLEAVE);
- Cleave_Timer = 7000;
- } else Cleave_Timer -= diff;
-
- //Whirlwind
- if (Whirlwind_Timer <= diff)
- {
+ case EVENT_OVERPOWER:
+ DoCastVictim(SPELL_OVERPOWER, true);
+ events.ScheduleEvent(EVENT_OVERPOWER, urand(6000, 12000));
+ break;
+ case EVENT_MORTAL_STRIKE:
+ if (me->getVictim() && me->getVictim()->HealthBelowPct(50))
+ DoCastVictim(SPELL_MORTAL_STRIKE, true);
+ events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(12000, 18000));
+ break;
+ case EVENT_WHIRLWIND:
DoCast(me, SPELL_WHIRLWIND);
- Whirlwind_Timer = 18000;
- } else Whirlwind_Timer -= diff;
-
- //If more then 3 targets in melee range mandokir will cast fear
- if (Fear_Timer <= diff)
- {
- TargetInRange = 0;
-
- std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
- for (; i != me->getThreatManager().getThreatList().end(); ++i)
+ events.ScheduleEvent(EVENT_WHIRLWIND, urand(22000, 26000));
+ break;
+ case EVENT_CHECK_OHGAN:
+ if (instance->GetBossState(DATA_OHGAN) == DONE)
{
- Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid());
- if (unit && me->IsWithinMeleeRange(unit))
- ++TargetInRange;
+ DoCast(me, SPELL_FRENZY);
+ Talk(SAY_OHGAN_DEAD);
}
-
- if (TargetInRange > 3)
- DoCast(me->getVictim(), SPELL_FEAR);
-
- Fear_Timer = 4000;
- } else Fear_Timer -=diff;
-
- //Mortal Strike if target below 50% hp
- if (me->getVictim() && me->getVictim()->HealthBelowPct(50))
- {
- if (MortalStrike_Timer <= diff)
- {
- DoCast(me->getVictim(), SPELL_MORTAL_STRIKE);
- MortalStrike_Timer = 15000;
- } else MortalStrike_Timer -= diff;
- }
- }
- //Checking if Ohgan is dead. If yes Mandokir will enrage.
- if (Check_Timer <= diff)
- {
- if (instance)
- {
- if (instance->GetData(DATA_OHGAN) == DONE)
+ else
+ events.ScheduleEvent(EVENT_CHECK_OHGAN, 1000);
+ break;
+ case EVENT_WATCH_PLAYER:
+ if (Unit* player = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
- if (!RaptorDead)
- {
- DoCast(me, SPELL_ENRAGE);
- RaptorDead = true;
- }
+ DoCast(player, SPELL_WATCH);
+ Talk(SAY_WATCH, player->GetGUID());
}
- }
-
- Check_Timer = 1000;
- } else Check_Timer -= diff;
-
- DoMeleeAttackIfReady();
+ events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(12000, 15000));
+ break;
+ case EVENT_CHARGE_PLAYER:
+ DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true), SPELL_CHARGE);
+ events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(22000, 30000));
+ break;
+ default:
+ break;
+ }
}
+
+ DoMeleeAttackIfReady();
}
+
+ private:
+ uint8 killCount;
+ uint64 chainedSpirtGUIDs[CHAINED_SPIRT_COUNT];
};
CreatureAI* GetAI(Creature* creature) const
{
- return new boss_mandokirAI(creature);
+ return GetZulGurubAI<boss_mandokirAI>(creature);
}
};
// Ohgan
+
+enum OhganSpells
+{
+ SPELL_SUNDERARMOR = 24317
+};
+
class mob_ohgan : public CreatureScript
{
public: mob_ohgan() : CreatureScript("mob_ohgan") {}
struct mob_ohganAI : public ScriptedAI
{
- mob_ohganAI(Creature* creature) : ScriptedAI(creature)
+ mob_ohganAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { }
+
+ void Reset()
{
- instance = creature->GetInstanceScript();
+ SunderArmor_Timer = 5000;
}
+ void EnterCombat(Unit* /*who*/) {}
+
+ void JustDied(Unit* /*killer*/)
+ {
+ instance->SetBossState(DATA_OHGAN, DONE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ // Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (SunderArmor_Timer <= diff)
+ {
+ DoCastVictim(SPELL_SUNDERARMOR, true);
+ SunderArmor_Timer = urand(10000, 15000);
+ } else SunderArmor_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
uint32 SunderArmor_Timer;
InstanceScript* instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetZulGurubAI<mob_ohganAI>(creature);
+ }
+};
+
+enum VilebranchSpells
+{
+ SPELL_DEMORALIZING_SHOUT = 13730,
+ SPELL_CLEAVE = 15284
+};
+
+class mob_vilebranch_speaker : public CreatureScript
+{
+ public: mob_vilebranch_speaker() : CreatureScript("mob_vilebranch_speaker") {}
+
+ struct mob_vilebranch_speakerAI : public ScriptedAI
+ {
+ mob_vilebranch_speakerAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { }
void Reset()
{
- SunderArmor_Timer = 5000;
+ demoralizing_Shout_Timer = urand (2000, 4000);
+ cleave_Timer = urand (5000, 8000);
}
void EnterCombat(Unit* /*who*/) {}
void JustDied(Unit* /*killer*/)
{
- if (instance)
- instance->SetData(DATA_OHGAN, DONE);
+ instance->SetBossState(DATA_MANDOKIR, SPECIAL);
}
- void UpdateAI (const uint32 diff)
+ void UpdateAI(const uint32 diff)
{
- //Return since we have no target
+ // Return since we have no target
if (!UpdateVictim())
return;
- //SunderArmor_Timer
- if (SunderArmor_Timer <= diff)
+ if (demoralizing_Shout_Timer <= diff)
{
- DoCast(me->getVictim(), SPELL_SUNDERARMOR);
- SunderArmor_Timer = urand(10000, 15000);
- } else SunderArmor_Timer -= diff;
+ DoCast(me, SPELL_DEMORALIZING_SHOUT);
+ demoralizing_Shout_Timer = urand(22000, 30000);
+ } else demoralizing_Shout_Timer -= diff;
+
+ if (cleave_Timer <= diff)
+ {
+ DoCastVictim(SPELL_CLEAVE, true);
+ cleave_Timer = urand(6000, 9000);
+ } else cleave_Timer -= diff;
DoMeleeAttackIfReady();
}
+
+ private:
+ uint32 demoralizing_Shout_Timer;
+ uint32 cleave_Timer;
+ InstanceScript* instance;
};
CreatureAI* GetAI(Creature* creature) const
{
- return new mob_ohganAI(creature);
+ return new mob_vilebranch_speakerAI(creature);
+ }
+};
+
+class spell_threatening_gaze : public SpellScriptLoader
+{
+ public:
+ spell_threatening_gaze() : SpellScriptLoader("spell_threatening_gaze") { }
+
+ class spell_threatening_gaze_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_threatening_gaze_AuraScript);
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ if(Unit* target = GetTarget())
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH)
+ caster->CastSpell(target, SPELL_WATCH_CHARGE);
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_threatening_gaze_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_threatening_gaze_AuraScript();
}
};
@@ -356,5 +430,6 @@ void AddSC_boss_mandokir()
{
new boss_mandokir();
new mob_ohgan();
+ new mob_vilebranch_speaker();
+ new spell_threatening_gaze();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp
index ab45162fc35..61eb695719a 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp
@@ -113,7 +113,7 @@ class boss_thekal : public CreatureScript
void JustReachedHome()
{
if (instance)
- instance->SetData(DATA_THEKAL, NOT_STARTED);
+ instance->SetBossState(DATA_THEKAL, NOT_STARTED);
}
void UpdateAI(uint32 const diff)
@@ -167,7 +167,7 @@ class boss_thekal : public CreatureScript
{
if (instance)
{
- if (instance->GetData(DATA_LORKHAN) == SPECIAL)
+ if (instance->GetBossState(DATA_LORKHAN) == SPECIAL)
{
//Resurrect LorKhan
if (Unit* pLorKhan = Unit::GetUnit(*me, instance->GetData64(DATA_LORKHAN)))
@@ -180,7 +180,7 @@ class boss_thekal : public CreatureScript
}
}
- if (instance->GetData(DATA_ZATH) == SPECIAL)
+ if (instance->GetBossState(DATA_ZATH) == SPECIAL)
{
//Resurrect Zath
if (Unit* pZath = Unit::GetUnit(*me, instance->GetData64(DATA_ZATH)))
@@ -189,7 +189,7 @@ class boss_thekal : public CreatureScript
pZath->setFaction(14);
pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
pZath->SetFullHealth();
- instance->SetData(DATA_ZATH, DONE);
+ instance->SetBossState(DATA_ZATH, DONE);
}
}
}
@@ -241,7 +241,7 @@ class boss_thekal : public CreatureScript
me->SetStandState(UNIT_STAND_STATE_SLEEP);
me->AttackStop();
if (instance)
- instance->SetData(DATA_THEKAL, SPECIAL);
+ instance->SetBossState(DATA_THEKAL, SPECIAL);
WasDead=true;
}
}
@@ -288,7 +288,7 @@ class mob_zealot_lorkhan : public CreatureScript
FakeDeath = false;
if (instance)
- instance->SetData(DATA_LORKHAN, NOT_STARTED);
+ instance->SetBossState(DATA_LORKHAN, NOT_STARTED);
me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
@@ -356,7 +356,7 @@ class mob_zealot_lorkhan : public CreatureScript
{
if (instance)
{
- if (instance->GetData(DATA_THEKAL) == SPECIAL)
+ if (instance->GetBossState(DATA_THEKAL) == SPECIAL)
{
//Resurrect Thekal
if (Unit* pThekal = Unit::GetUnit(*me, instance->GetData64(DATA_THEKAL)))
@@ -368,7 +368,7 @@ class mob_zealot_lorkhan : public CreatureScript
}
}
- if (instance->GetData(DATA_ZATH) == SPECIAL)
+ if (instance->GetBossState(DATA_ZATH) == SPECIAL)
{
//Resurrect Zath
if (Unit* pZath = Unit::GetUnit(*me, instance->GetData64(DATA_ZATH)))
@@ -395,7 +395,7 @@ class mob_zealot_lorkhan : public CreatureScript
me->AttackStop();
if (instance)
- instance->SetData(DATA_LORKHAN, SPECIAL);
+ instance->SetBossState(DATA_LORKHAN, SPECIAL);
FakeDeath = true;
}
@@ -450,7 +450,7 @@ class mob_zealot_zath : public CreatureScript
FakeDeath = false;
if (instance)
- instance->SetData(DATA_ZATH, NOT_STARTED);
+ instance->SetBossState(DATA_ZATH, NOT_STARTED);
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
@@ -509,7 +509,7 @@ class mob_zealot_zath : public CreatureScript
{
if (instance)
{
- if (instance->GetData(DATA_LORKHAN) == SPECIAL)
+ if (instance->GetBossState(DATA_LORKHAN) == SPECIAL)
{
//Resurrect LorKhan
if (Unit* pLorKhan = Unit::GetUnit(*me, instance->GetData64(DATA_LORKHAN)))
@@ -521,7 +521,7 @@ class mob_zealot_zath : public CreatureScript
}
}
- if (instance->GetData(DATA_THEKAL) == SPECIAL)
+ if (instance->GetBossState(DATA_THEKAL) == SPECIAL)
{
//Resurrect Thekal
if (Unit* pThekal = Unit::GetUnit(*me, instance->GetData64(DATA_THEKAL)))
@@ -548,7 +548,7 @@ class mob_zealot_zath : public CreatureScript
me->AttackStop();
if (instance)
- instance->SetData(DATA_ZATH, SPECIAL);
+ instance->SetBossState(DATA_ZATH, SPECIAL);
FakeDeath = true;
}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp
index b997d277c95..19a2ba39578 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp
@@ -29,7 +29,7 @@ EndScriptData */
class instance_zulgurub : public InstanceMapScript
{
- public: instance_zulgurub(): InstanceMapScript("instance_zulgurub", 309) {}
+ public: instance_zulgurub(): InstanceMapScript(ZGScriptName, 309) {}
struct instance_zulgurub_InstanceMapScript : public InstanceScript
{
@@ -38,24 +38,18 @@ class instance_zulgurub : public InstanceMapScript
SetBossNumber(EncounterCount);
}
- //If all High Priest bosses were killed. Lorkhan, Zath and Ohgan are added too.
- //Storing Lorkhan, Zath and Thekal because we need to cast on them later. Jindo is needed for healfunction too.
- uint64 LorKhanGUID;
- uint64 ZathGUID;
- uint64 ThekalGUID;
- uint64 JindoGUID;
-
void Initialize()
{
- LorKhanGUID = 0;
- ZathGUID = 0;
- ThekalGUID = 0;
- JindoGUID = 0;
+ ZealotLorkhanGUID = 0;
+ ZealotZathGUID = 0;
+ HighPriestTekalGUID = 0;
+ JindoTheHexxerGUID = 0;
+ VilebranchSpeakerGUID = 0;
}
bool IsEncounterInProgress() const
{
- //not active in Zul'Gurub
+ // not active in Zul'Gurub
return false;
}
@@ -63,78 +57,44 @@ class instance_zulgurub : public InstanceMapScript
{
switch (creature->GetEntry())
{
- case NPC_ZEALOT_LORKHAN: LorKhanGUID = creature->GetGUID(); break;
- case NPC_ZEALOT_ZATH: ZathGUID = creature->GetGUID(); break;
- case NPC_HIGH_PRIEST_THEKAL: ThekalGUID = creature->GetGUID(); break;
- case NPC_JINDO_THE_HEXXER: JindoGUID = creature->GetGUID(); break;
- }
- }
-
- bool SetBossState(uint32 type, EncounterState state)
- {
- if (!InstanceScript::SetBossState(type, state))
- return false;
-
- switch (type)
- {
- case DATA_JEKLIK:
- case DATA_VENOXIS:
- case DATA_MARLI:
- case DATA_ARLOKK:
- case DATA_HAKKAR:
- case DATA_MANDOKIR:
- case DATA_JINDO:
- case DATA_GAHZRANKA:
- case DATA_EDGE_OF_MADNESS:
- case DATA_THEKAL:
- case DATA_LORKHAN:
- case DATA_ZATH:
- case DATA_OHGAN:
+ case NPC_ZEALOT_LORKHAN:
+ ZealotLorkhanGUID = creature->GetGUID();
break;
- default:
+ case NPC_ZEALOT_ZATH:
+ ZealotZathGUID = creature->GetGUID();
break;
- }
-
- return true;
- }
-
- uint32 GetData(uint32 type) const
- {
- switch (type)
- {
- case DATA_JEKLIK: return GetBossState(DATA_JEKLIK);
- case DATA_VENOXIS: return GetBossState(DATA_VENOXIS);
- case DATA_MARLI: return GetBossState(DATA_MARLI);
- case DATA_ARLOKK: return GetBossState(DATA_ARLOKK);
- case DATA_HAKKAR: return GetBossState(DATA_HAKKAR);
- case DATA_MANDOKIR: return GetBossState(DATA_MANDOKIR);
- case DATA_JINDO: return GetBossState(DATA_JINDO);
- case DATA_GAHZRANKA: return GetBossState(DATA_GAHZRANKA);
- case DATA_EDGE_OF_MADNESS: return GetBossState(DATA_EDGE_OF_MADNESS);
- case DATA_THEKAL: return GetBossState(DATA_THEKAL);
- case DATA_LORKHAN: return GetBossState(DATA_LORKHAN);
- case DATA_ZATH: return GetBossState(DATA_ZATH);
- case DATA_OHGAN: return GetBossState(DATA_OHGAN);
+ case NPC_HIGH_PRIEST_THEKAL:
+ HighPriestTekalGUID = creature->GetGUID();
+ break;
+ case NPC_JINDO_THE_HEXXER:
+ JindoTheHexxerGUID = creature->GetGUID();
break;
- default:
+ case NPC_VILEBRANCH_SPEAKER:
+ VilebranchSpeakerGUID = creature->GetGUID();
break;
+ case NPC_MANDOKIR:
+ if (GetBossState(DATA_MANDOKIR) == DONE)
+ creature->DespawnOrUnsummon();
+ break;
+ }
}
- return 0;
- }
-
uint64 GetData64(uint32 uiData) const
{
switch (uiData)
{
case DATA_LORKHAN:
- return LorKhanGUID;
+ return ZealotLorkhanGUID;
+ break;
case DATA_ZATH:
- return ZathGUID;
+ return ZealotZathGUID;
+ break;
case DATA_THEKAL:
- return ThekalGUID;
+ return HighPriestTekalGUID;
+ break;
case DATA_JINDO:
- return JindoGUID;
+ return JindoTheHexxerGUID;
+ break;
}
return 0;
}
@@ -181,6 +141,15 @@ class instance_zulgurub : public InstanceMapScript
OUT_LOAD_INST_DATA_COMPLETE;
}
+ private:
+ //If all High Priest bosses were killed. Lorkhan, Zath and Ohgan are added too.
+ //Storing Lorkhan, Zath and Thekal because we need to cast on them later. Jindo is needed for healfunction too.
+
+ uint64 ZealotLorkhanGUID;
+ uint64 ZealotZathGUID;
+ uint64 HighPriestTekalGUID;
+ uint64 JindoTheHexxerGUID;
+ uint64 VilebranchSpeakerGUID;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
index 2544e4f4d5f..34680447cd7 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
@@ -20,6 +20,8 @@
uint32 const EncounterCount = 13;
+#define ZGScriptName "instance_zulgurub"
+
enum DataTypes
{
DATA_JEKLIK = 0, // Main boss
@@ -45,9 +47,22 @@ enum CreatureIds
NPC_JINDO_THE_HEXXER = 11380,
NPC_NIGHTMARE_ILLUSION = 15163,
NPC_ZULIAN_PROWLER = 15101,
- NPC_SPEAKER = 11391,
+ NPC_VILEBRANCH_SPEAKER = 11391,
NPC_SHADE_OF_JINDO = 14986,
- NPC_SACRIFICED_TROLL = 14826
+ NPC_SACRIFICED_TROLL = 14826,
+ NPC_OHGAN = 14988,
+ NPC_CHAINED_SPIRT = 15117,
+ NPC_MANDOKIR = 11382
};
+template<class AI>
+CreatureAI* GetZulGurubAI(Creature* creature)
+{
+ if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
+ if (instance->GetInstanceScript())
+ if (instance->GetScriptId() == sObjectMgr->GetScriptId(ZGScriptName))
+ return new AI(creature);
+ return NULL;
+}
+
#endif
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
index 7f8108e5e71..6039e01b901 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
@@ -359,7 +359,7 @@ class boss_halion : public CreatureScript
if (Creature* twilightHalion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TWILIGHT_HALION)))
if (twilightHalion->isAlive())
twilightHalion->Kill(twilightHalion);
-
+
if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HALION_CONTROLLER)))
if (controller->isAlive())
controller->Kill(controller);
diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
index f3afc03e68a..7db2ae4707b 100644
--- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp
+++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
@@ -1033,6 +1033,102 @@ public:
}
};
+/*######
+## Quest: Reconnaissance Flight (12671)
+######*/
+enum ReconnaissanceFlight
+{
+ NPC_PLANE = 28710, // Vic's Flying Machine
+ NPC_PILOT = 28646,
+
+ VIC_SAY_0 = 0,
+ VIC_SAY_1 = 1,
+ VIC_SAY_2 = 2,
+ VIC_SAY_3 = 3,
+ VIC_SAY_4 = 4,
+ VIC_SAY_5 = 5,
+ VIC_SAY_6 = 6,
+ PLANE_EMOTE = 0,
+
+ AURA_ENGINE = 52255, // Engine on Fire
+
+ SPELL_LAND = 52226, // Land Flying Machine
+ SPELL_CREDIT = 53328 // Land Flying Machine Credit
+};
+
+class npc_vics_flying_machine : public CreatureScript
+{
+public:
+ npc_vics_flying_machine() : CreatureScript("npc_vics_flying_machine") { }
+
+ struct npc_vics_flying_machineAI : public VehicleAI
+ {
+ npc_vics_flying_machineAI(Creature* creature) : VehicleAI(creature) {}
+
+ void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply)
+ {
+ if (apply && passenger->GetTypeId() == TYPEID_PLAYER)
+ me->GetMotionMaster()->MovePath(NPC_PLANE, false);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != WAYPOINT_MOTION_TYPE)
+ return;
+
+ if (Creature* pilot = GetClosestCreatureWithEntry(me, NPC_PILOT, 10))
+ switch (id)
+ {
+ case 5:
+ pilot->AI()->Talk(VIC_SAY_0);
+ break;
+ case 11:
+ pilot->AI()->Talk(VIC_SAY_1);
+ break;
+ case 12:
+ pilot->AI()->Talk(VIC_SAY_2);
+ break;
+ case 14:
+ pilot->AI()->Talk(VIC_SAY_3);
+ break;
+ case 15:
+ pilot->AI()->Talk(VIC_SAY_4);
+ break;
+ case 17:
+ pilot->AI()->Talk(VIC_SAY_5);
+ break;
+ case 21:
+ pilot->AI()->Talk(VIC_SAY_6);
+ break;
+ case 25:
+ me->AI()->Talk(PLANE_EMOTE);
+ me->AI()->DoCast(AURA_ENGINE);
+ break;
+ }
+ }
+
+ void SpellHit(Unit* /*caster*/, SpellInfo const* spell)
+ {
+ if (spell->Id == SPELL_LAND)
+ {
+ Unit* passenger = me->GetVehicleKit()->GetPassenger(1); // player should be on seat 1
+ if (passenger && passenger->GetTypeId() == TYPEID_PLAYER)
+ {
+ passenger->CastSpell(passenger, SPELL_CREDIT, true);
+ passenger->ExitVehicle();
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 /*diff*/) {}
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_vics_flying_machineAI(creature);
+ }
+};
+
void AddSC_sholazar_basin()
{
new npc_injured_rainspeaker_oracle();
@@ -1045,4 +1141,5 @@ void AddSC_sholazar_basin()
new spell_q12620_the_lifewarden_wrath();
new spell_q12589_shoot_rjr();
new npc_haiphoon();
+ new npc_vics_flying_machine();
}
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index cfbd4b2bc45..1c2410b8b53 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -374,7 +374,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_GROUP_DIFFICULTY, "UPDATE groups SET difficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GROUP_RAID_DIFFICULTY, "UPDATE groups SET raiddifficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ALL_GM_TICKETS, "TRUNCATE TABLE gm_tickets", CONNECTION_ASYNC);
- PrepareStatement(CHAR_DEL_INVALID_SPELL, "DELETE FROM character_talent WHERE spell = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_INVALID_SPELL_TALENTS, "DELETE FROM character_talent WHERE spell = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_INVALID_SPELL_SPELLS, "DELETE FROM character_spell WHERE spell = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_DELETE_INFO, "UPDATE characters SET deleteInfos_Name = name, deleteInfos_Account = account, deleteDate = UNIX_TIMESTAMP(), name = '', account = 0 WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UDP_RESTORE_DELETE_INFO, "UPDATE characters SET name = ?, account = ?, deleteDate = NULL, deleteInfos_Name = NULL, deleteInfos_Account = NULL WHERE deleteDate IS NOT NULL AND guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ZONE, "UPDATE characters SET zone = ? WHERE guid = ?", CONNECTION_ASYNC);
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index bfa7bc48cf5..e4728e19934 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -315,7 +315,8 @@ enum CharacterDatabaseStatements
CHAR_UPD_GROUP_MEMBER_FLAG,
CHAR_UPD_GROUP_DIFFICULTY,
CHAR_UPD_GROUP_RAID_DIFFICULTY,
- CHAR_DEL_INVALID_SPELL,
+ CHAR_DEL_INVALID_SPELL_SPELLS,
+ CHAR_DEL_INVALID_SPELL_TALENTS,
CHAR_UPD_DELETE_INFO,
CHAR_UDP_RESTORE_DELETE_INFO,
CHAR_UPD_ZONE,
diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp
index f2f5da53dae..1d215e1212e 100644
--- a/src/server/shared/Logging/Appender.cpp
+++ b/src/server/shared/Logging/Appender.cpp
@@ -73,10 +73,7 @@ void Appender::setLogLevel(LogLevel _level)
void Appender::write(LogMessage& message)
{
if (!level || level > message.level)
- {
- //fprintf(stderr, "Appender::write: Appender %s, Level %s. Msg %s Level %s Type %s WRONG LEVEL MASK\n", getName().c_str(), getLogLevelString(level), message.text.c_str(), getLogLevelString(message.level), getLogFilterTypeString(message.type)); // DEBUG - RemoveMe
return;
- }
message.prefix.clear();
if (flags & APPENDER_FLAGS_PREFIX_TIMESTAMP)
@@ -222,5 +219,6 @@ char const* Appender::getLogFilterTypeString(LogFilterType type)
default:
break;
}
+
return "???";
}
diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h
index 6a0f0bdac26..a8854a8abc6 100644
--- a/src/server/shared/Logging/Appender.h
+++ b/src/server/shared/Logging/Appender.h
@@ -143,7 +143,7 @@ class Appender
static const char* getLogFilterTypeString(LogFilterType type);
private:
- virtual void _write(LogMessage& /*message*/) = 0;
+ virtual void _write(LogMessage const& /*message*/) = 0;
uint8 id;
std::string name;
diff --git a/src/server/shared/Logging/AppenderConsole.cpp b/src/server/shared/Logging/AppenderConsole.cpp
index d0af761188c..a1212bd135b 100644
--- a/src/server/shared/Logging/AppenderConsole.cpp
+++ b/src/server/shared/Logging/AppenderConsole.cpp
@@ -154,7 +154,7 @@ void AppenderConsole::ResetColor(bool stdout_stream)
#endif
}
-void AppenderConsole::_write(LogMessage& message)
+void AppenderConsole::_write(LogMessage const& message)
{
bool stdout_stream = message.level == LOG_LEVEL_ERROR || message.level == LOG_LEVEL_FATAL;
diff --git a/src/server/shared/Logging/AppenderConsole.h b/src/server/shared/Logging/AppenderConsole.h
index 3319c84e887..6f3fcca901c 100644
--- a/src/server/shared/Logging/AppenderConsole.h
+++ b/src/server/shared/Logging/AppenderConsole.h
@@ -51,7 +51,7 @@ class AppenderConsole: public Appender
private:
void SetColor(bool stdout_stream, ColorTypes color);
void ResetColor(bool stdout_stream);
- void _write(LogMessage& message);
+ void _write(LogMessage const& message);
bool _colored;
ColorTypes _colors[MaxLogLevels];
};
diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp
index 86677eeedd8..ae5fc17de73 100644
--- a/src/server/shared/Logging/AppenderDB.cpp
+++ b/src/server/shared/Logging/AppenderDB.cpp
@@ -18,8 +18,8 @@
#include "AppenderDB.h"
#include "Database/DatabaseEnv.h"
-AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level, uint32 realmId)
- : Appender(id, name, APPENDER_DB, level), realm(realmId), enable(false)
+AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level)
+ : Appender(id, name, APPENDER_DB, level), realmId(0), enabled(false)
{
}
@@ -27,10 +27,11 @@ AppenderDB::~AppenderDB()
{
}
-void AppenderDB::_write(LogMessage& message)
+void AppenderDB::_write(LogMessage const& message)
{
- if (!enable)
+ if (!enabled)
return;
+
switch (message.type)
{
case LOG_FILTER_SQL:
@@ -40,7 +41,7 @@ void AppenderDB::_write(LogMessage& message)
default:
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_LOG);
stmt->setUInt64(0, message.mtime);
- stmt->setUInt32(1, realm);
+ stmt->setUInt32(1, realmId);
stmt->setUInt8(2, uint8(message.type));
stmt->setUInt8(3, uint8(message.level));
stmt->setString(4, message.text);
@@ -49,7 +50,8 @@ void AppenderDB::_write(LogMessage& message)
}
}
-void AppenderDB::setEnable(bool _enable)
+void AppenderDB::setRealmId(uint32 _realmId)
{
- enable = _enable;
+ enabled = true;
+ realmId = _realmId;
}
diff --git a/src/server/shared/Logging/AppenderDB.h b/src/server/shared/Logging/AppenderDB.h
index 5ab9a1ee423..f9dde0a1e82 100644
--- a/src/server/shared/Logging/AppenderDB.h
+++ b/src/server/shared/Logging/AppenderDB.h
@@ -23,14 +23,15 @@
class AppenderDB: public Appender
{
public:
- AppenderDB(uint8 _id, std::string const& _name, LogLevel level, uint32 realmId);
+ AppenderDB(uint8 _id, std::string const& _name, LogLevel level);
~AppenderDB();
- void setEnable(bool enable);
+
+ void setRealmId(uint32 realmId);
private:
- uint32 realm;
- bool enable;
- void _write(LogMessage& message);
+ uint32 realmId;
+ bool enabled;
+ void _write(LogMessage const& message);
};
#endif
diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp
index 7b0bac03d03..8189237bb4e 100644
--- a/src/server/shared/Logging/AppenderFile.cpp
+++ b/src/server/shared/Logging/AppenderFile.cpp
@@ -39,7 +39,7 @@ AppenderFile::~AppenderFile()
}
}
-void AppenderFile::_write(LogMessage& message)
+void AppenderFile::_write(LogMessage const& message)
{
if (dynamicName)
{
@@ -70,5 +70,6 @@ FILE* AppenderFile::OpenFile(std::string const &filename, std::string const &mod
newName.append(LogMessage::getTimeStr(time(NULL)));
rename(filename.c_str(), newName.c_str()); // no error handling... if we couldn't make a backup, just ignore
}
+
return fopen((logDir + filename).c_str(), mode.c_str());
}
diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h
index 934370d70b4..a3fe285cc7d 100644
--- a/src/server/shared/Logging/AppenderFile.h
+++ b/src/server/shared/Logging/AppenderFile.h
@@ -28,7 +28,7 @@ class AppenderFile: public Appender
FILE* OpenFile(std::string const& _name, std::string const& _mode, bool _backup);
private:
- void _write(LogMessage& message);
+ void _write(LogMessage const& message);
FILE* logfile;
std::string filename;
std::string logDir;
diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp
index 60320d049ac..96c72b5eb74 100644
--- a/src/server/shared/Logging/Log.cpp
+++ b/src/server/shared/Logging/Log.cpp
@@ -31,7 +31,6 @@
Log::Log() : worker(NULL)
{
- SetRealmID(0);
m_logsTimestamp = "_" + GetTimestampStr();
LoadFromConfig();
}
@@ -154,7 +153,7 @@ void Log::CreateAppenderFromConfig(const char* name)
case APPENDER_DB:
{
uint8 id = NextAppenderId();
- appenders[id] = new AppenderDB(id, name, level, realm);
+ appenders[id] = new AppenderDB(id, name, level);
break;
}
default:
@@ -265,13 +264,6 @@ void Log::ReadLoggersFromConfig()
loggers[LOG_FILTER_GENERAL].Create("root", LOG_FILTER_GENERAL, LOG_LEVEL_DISABLED);
}
-void Log::EnableDBAppenders()
-{
- for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
- if (it->second && it->second->getType() == APPENDER_DB)
- ((AppenderDB *)it->second)->setEnable(true);
-}
-
void Log::vlog(LogFilterType filter, LogLevel level, char const* str, va_list argptr)
{
char text[MAX_QUERY_LEN];
@@ -281,12 +273,16 @@ void Log::vlog(LogFilterType filter, LogLevel level, char const* str, va_list ar
void Log::write(LogMessage* msg)
{
+ if (loggers.empty())
+ return;
+
+ msg->text.append("\n");
+ Logger* logger = GetLoggerByType(msg->type);
+
if (worker)
- {
- msg->text.append("\n");
- Logger* logger = GetLoggerByType(msg->type);
worker->enqueue(new LogOperation(logger, msg));
- }
+ else
+ logger->write(*msg);
}
std::string Log::GetTimestampStr()
@@ -463,9 +459,11 @@ void Log::outCommand(uint32 account, const char * str, ...)
write(msg);
}
-void Log::SetRealmID(uint32 id)
+void Log::SetRealmId(uint32 id)
{
- realm = id;
+ for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
+ if (it->second && it->second->getType() == APPENDER_DB)
+ ((AppenderDB *)it->second)->setRealmId(id);
}
void Log::Close()
@@ -484,7 +482,10 @@ void Log::Close()
void Log::LoadFromConfig()
{
Close();
- worker = new LogWorker();
+
+ if (ConfigMgr::GetBoolDefault("Log.Async.Enable", false))
+ worker = new LogWorker();
+
AppenderId = 0;
m_logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
if (!m_logsDir.empty())
diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h
index 6d6cfe715e8..46aaea4bad1 100644
--- a/src/server/shared/Logging/Log.h
+++ b/src/server/shared/Logging/Log.h
@@ -52,12 +52,11 @@ class Log
void outError(LogFilterType f, char const* str, ...) ATTR_PRINTF(3, 4);
void outFatal(LogFilterType f, char const* str, ...) ATTR_PRINTF(3, 4);
- void EnableDBAppenders();
void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4);
void outCharDump(char const* str, uint32 account_id, uint32 guid, char const* name);
static std::string GetTimestampStr();
- void SetRealmID(uint32 id);
+ void SetRealmId(uint32 id);
private:
void vlog(LogFilterType f, LogLevel level, char const* str, va_list argptr);
@@ -78,7 +77,6 @@ class Log
std::string m_logsDir;
std::string m_logsTimestamp;
- uint32 realm;
LogWorker* worker;
};
diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp
index fe872c1977f..56dd64bc45a 100644
--- a/src/server/worldserver/Master.cpp
+++ b/src/server/worldserver/Master.cpp
@@ -438,8 +438,6 @@ bool Master::_StartDB()
}
sLog->outInfo(LOG_FILTER_WORLDSERVER, "Realm running as realm ID %d", realmID);
- sLog->SetRealmID(realmID);
-
///- Clean the database before starting
ClearOnlineAccounts();
diff --git a/src/server/worldserver/RemoteAccess/RASocket.cpp b/src/server/worldserver/RemoteAccess/RASocket.cpp
index 95fdad9ad44..e0f4e7f0de6 100644
--- a/src/server/worldserver/RemoteAccess/RASocket.cpp
+++ b/src/server/worldserver/RemoteAccess/RASocket.cpp
@@ -71,7 +71,7 @@ int RASocket::send(const std::string& line)
ssize_t n = peer().send(line.c_str(), line.length());
#endif // MSG_NOSIGNAL
- return n == line.length() ? 0 : -1;
+ return n == ssize_t(line.length()) ? 0 : -1;
}
int RASocket::recv_line(ACE_Message_Block& buffer)
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 68cf3994e3b..505a65771fa 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2824,4 +2824,12 @@ Logger.Opcodes=41,6,Console Server
Loggers=Root Chat DBErrors GM RA Warden Character Load WorldServer Opcodes
#
+# Log.Async.Enable
+# Description: Enables asyncronous message logging.
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+Log.Async.Enable = 0
+
+#
###################################################################################################