aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/2016_01_07_01_world.sql2
-rw-r--r--sql/updates/world/2016_01_07_02_world.sql2
-rw-r--r--sql/updates/world/2016_01_08_00_world.sql18
-rw-r--r--sql/updates/world/2016_01_08_01_world.sql52
-rw-r--r--sql/updates/world/2016_01_08_02_world.sql35
-rw-r--r--sql/updates/world/2016_01_08_03_world.sql3
-rw-r--r--sql/updates/world/2016_01_09_00_world.sql16
-rw-r--r--sql/updates/world/2016_01_10_00_world.sql3
-rw-r--r--sql/updates/world/2016_01_10_01_world.sql2
-rw-r--r--sql/updates/world/2016_01_10_02_world.sql6
-rw-r--r--sql/updates/world/2016_01_10_03_world.sql2
-rw-r--r--sql/updates/world/2016_01_10_04_world.sql11
-rw-r--r--sql/updates/world/2016_01_10_05_world335.sql21
-rw-r--r--sql/updates/world/2016_01_12_00_world.sql (renamed from sql/updates/world/2016_01_07_npc_taxi.sql)0
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h5
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.cpp16
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.h15
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp28
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h6
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.h5
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp78
-rw-r--r--src/server/game/Entities/Player/Player.h16
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp6
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp5
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp7
-rw-r--r--src/server/game/Spells/Spell.cpp21
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp1
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp1
-rw-r--r--src/server/scripts/Outland/zone_shadowmoon_valley.cpp4
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp306
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp39
-rw-r--r--src/server/worldserver/worldserver.conf.dist40
35 files changed, 746 insertions, 31 deletions
diff --git a/sql/updates/world/2016_01_07_01_world.sql b/sql/updates/world/2016_01_07_01_world.sql
new file mode 100644
index 00000000000..4a15aa405ec
--- /dev/null
+++ b/sql/updates/world/2016_01_07_01_world.sql
@@ -0,0 +1,2 @@
+--
+DELETE FROM `creature` WHERE `id`=22972;
diff --git a/sql/updates/world/2016_01_07_02_world.sql b/sql/updates/world/2016_01_07_02_world.sql
new file mode 100644
index 00000000000..7724b42ac9d
--- /dev/null
+++ b/sql/updates/world/2016_01_07_02_world.sql
@@ -0,0 +1,2 @@
+-- fix a start-up warning
+UPDATE `creature` SET `spawndist`=0 WHERE `guid` IN (79007,79008,79009);
diff --git a/sql/updates/world/2016_01_08_00_world.sql b/sql/updates/world/2016_01_08_00_world.sql
new file mode 100644
index 00000000000..55ed3ddf336
--- /dev/null
+++ b/sql/updates/world/2016_01_08_00_world.sql
@@ -0,0 +1,18 @@
+UPDATE `creature_template` SET
+`spell1` = 62225, -- Claw
+`spell2` = 47480, -- Thrash
+`spell3` = 47481, -- Gnaw
+`spell4` = 47482, -- Leap
+`spell5` = 47484, -- Huddle
+`spell6` = 47496 -- Explode
+WHERE `entry` = 30230;
+
+DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_dk_raise_ally_initial', 'spell_dk_raise_ally', 'spell_dk_ghoul_thrash');
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(61999, 'spell_dk_raise_ally_initial'),
+(46619, 'spell_dk_raise_ally'),
+(47480, 'spell_dk_ghoul_thrash');
+
+DELETE FROM `spell_dbc` WHERE `Id`=62214;
+INSERT INTO `spell_dbc` (`Id`,`Attributes`,`AttributesEx`,`AttributesEx2`,`AttributesEx3`,`AttributesEx4`,`AttributesEx5`,`AttributesEx6`,`DurationIndex`,`RangeIndex`,`Effect1`,`EffectImplicitTargetA1`,`EffectApplyAuraName1`,`Comment`) VALUES
+(62214,0xA9800100,0x10000420,0x10084005,0x00130000,0x00800080,0x00060008,0x00001404,21,13,6,25,279,'Mirror Name');
diff --git a/sql/updates/world/2016_01_08_01_world.sql b/sql/updates/world/2016_01_08_01_world.sql
new file mode 100644
index 00000000000..ebf4560d326
--- /dev/null
+++ b/sql/updates/world/2016_01_08_01_world.sql
@@ -0,0 +1,52 @@
+--
+SET @Oguid :=6008;
+DELETE FROM `gameobject` WHERE `id`=186487;
+INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES
+(@Oguid, 186487, 571, 1, 1, 2821.75, -3603.67, 245.555, 3.49556, 0, 0, 0.984379, -0.176061, -300, 0, 1);
+
+SET @CGUID := 76053;
+DELETE FROM `creature_template_addon` WHERE `entry` IN (24029);
+INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES
+(24029, 0, 0x0, 0x1, 12544); -- Wyrmcaller Vile - Frost Armor
+
+DELETE FROM `creature_addon` WHERE `guid` IN (@CGUID+5);
+INSERT INTO `creature_addon` (`guid`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES
+(@CGUID+5, 0, 0x0, 0x1, 43570); -- Invisible Stalker (Floating) - Frost State
+
+DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN(43568,43569);
+INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES
+(43568, 34872, 1, 'Frost Strike'),
+(43569, 34872, 1, 'Frost trigger ');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN(43568);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13,1,43568,0,0,31,0,3,15214,0,0,0,0,'',"Spell 'Frost Strike' Effect 0 can hit 'Invisible Stalker'");
+
+DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID AND @CGUID+8;
+INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `MovementType`) VALUES
+(@CGUID, 15214, 571, 1, 1, 2842.762, -3599.551, 247.2563, 1.658063, 120, 0, 0), -- Invisible Stalker (Area: -Unknown-)
+(@CGUID+1, 15214, 571, 1, 1, 2807.391, -3586.93, 247.6916, 3.455752, 120, 0, 0), -- Invisible Stalker (Area: -Unknown-)
+(@CGUID+2, 15214, 571, 1, 1, 2833.016, -3621.016, 247.373, 1.850049, 120, 0, 0), -- Invisible Stalker (Area: -Unknown-)
+(@CGUID+3, 23033, 571, 1, 1, 2831.685, -3611.948, 257.9287, 0.2479207, 120, 0, 0), -- Invisible Stalker (Floating) (Area: -Unknown-) (Auras: 43570 - Frost State)
+(@CGUID+4, 23033, 571, 1, 1, 2832.849, -3638.875, 246.9362, 0.5235988, 120, 0, 0), -- Invisible Stalker (Floating) (Area: -Unknown-)
+(@CGUID+5, 23033, 571, 1, 1, 2820.243, -3602.598, 261.4395, 6.161012, 120, 0, 0), -- Invisible Stalker (Floating) (Area: -Unknown-)
+(@CGUID+6, 23033, 571, 1, 1, 2855.824, -3596.345, 248.4855, 5.131268, 120, 0, 0), -- Invisible Stalker (Floating) (Area: -Unknown-)
+(@CGUID+7, 24029, 571, 1, 1, 2820.328, -3602.552, 247.9988, 3.665191, 120, 0, 0), -- Wyrmcaller Vile (Area: -Unknown-) (Auras: 12544 - Frost Armor)
+(@CGUID+8, 23033, 571, 1, 1, 2818.341, -3604.437, 252.666, 3.845377, 120, 0, 0); -- Invisible Stalker (Floating) (Area: -Unknown-)
+
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=24029;
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN (24029,-106031,-@CGUID,-(@CGUID+1),-(@CGUID+2),-(@CGUID+5),-(@CGUID+8)) AND `source_type`=0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@CGUID*100,@CGUID*100+1) AND `source_type`=9;
+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
+(24029,0,0,0,1,0,100,1,0,0,3000,3000,11,43576,2,0,0,0,0,1,0,0,0,0,0,0,0,'Wyrmcaller Vile - OOC - Cast \'Frost Power\''),
+(24029,0,1,0,0,0,100,0,0,0,4000,4000,11,9672,0,0,0,0,0,2,0,0,0,0,0,0,0,'Wyrmcaller Vile - IC - Cast \'Frostbolt\''),
+(24029,0,2,0,0,0,100,0,0,0,6000,10000,11,15532,0,0,0,0,0,2,0,0,0,0,0,0,0,'Wyrmcaller Vile - IC - Cast \'Frost Nova\''),
+(24029,0,3,0,1,0,100,0,0,0,3000,3000,45,0,1,0,0,0,0,19,23033,10,0,0,0,0,0,'Wyrmcaller Vile - OOC - Cast \'Set Data\''),
+(-106031,0,0,0,8,0,100,0,43568,0,0,0,80,@CGUID*100,0,0,0,0,0,1,0,0,0,0,0,0,0,'Invisible Stalker - On SpellHit \'Frost Strike\' - Call ActionList'),
+(-@CGUID,0,0,0,8,0,100,0,43568,0,0,0,80,@CGUID*100,0,0,0,0,0,1,0,0,0,0,0,0,0,'Invisible Stalker - On SpellHit \'Frost Strike\' - Call ActionList'),
+(-(@CGUID+1),0,0,0,8,0,100,0,43568,0,0,0,80,@CGUID*100,0,0,0,0,0,1,0,0,0,0,0,0,0,'Invisible Stalker - On SpellHit \'Frost Strike\' - Call ActionList'),
+(-(@CGUID+2),0,0,0,8,0,100,0,43568,0,0,0,80,@CGUID*100+1,0,0,0,0,0,1,0,0,0,0,0,0,0,'Invisible Stalker - On SpellHit \'Frost Strike\' - Call ActionList'),
+(@CGUID*100,9,0,0,0,0,100,0,2400,2400,0,0,11,43569,2,0,0,0,0,19,23033,19,0,0,0,0,0,'Invisible Stalker - Action list - Cast \'Frost\''),
+(@CGUID*100+1,9,0,0,0,0,100,0,2400,2400,0,0,11,43569,2,0,0,0,0,10,@CGUID+4,23033,0,0,0,0,0,'Invisible Stalker - Action list - Cast \'Frost\''),
+(-(@CGUID+5),0,0,0,1,0,100,0,0,0,5000,7000,11,43591,2,0,0,0,0,19,24029,16,0,0,0,0,0,'Invisible Stalker - OOC - Cast \'Soul Siphon\''),
+(-(@CGUID+8),0,0,0,38,0,100,0,0,1,0,0,11,43568,2,0,0,0,0,1,0,0,0,0,0,0,0,'Invisible Stalker - On data set - Cast \'Frost Strike\'');
diff --git a/sql/updates/world/2016_01_08_02_world.sql b/sql/updates/world/2016_01_08_02_world.sql
new file mode 100644
index 00000000000..28e55dfba3b
--- /dev/null
+++ b/sql/updates/world/2016_01_08_02_world.sql
@@ -0,0 +1,35 @@
+--
+DELETE FROM `creature_formations` WHERE `leaderGUID`=79010;
+INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
+(79010, 79010, 0, 0, 2, 0, 0),
+(79010, 79012, 6, 360, 2, 0, 0);
+
+-- Pathing for Entry: 22987 'TDB FORMAT'
+SET @NPC := 79010;
+SET @PATH := @NPC * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-3376.641,`position_y`=3642.897,`position_z`=285.1084 WHERE `guid`=@NPC;
+DELETE FROM `creature_addon` WHERE `guid`=@NPC;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,-3376.641,3642.897,285.1084,0,0,0,0,100,0), -- 00:15:15
+(@PATH,2,-3372.496,3645.907,284.7475,0,0,0,0,100,0), -- 00:15:16
+(@PATH,3,-3376.866,3642.62,285.2078,0,0,0,0,100,0), -- 00:15:22
+(@PATH,4,-3381.402,3626.403,279.4974,0,0,0,0,100,0), -- 00:15:26
+(@PATH,5,-3382.558,3624.162,278.2544,0,0,0,0,100,0), -- 00:15:31
+(@PATH,6,-3385.898,3620.779,276.7867,0,0,0,0,100,0), -- 00:15:33
+(@PATH,7,-3389.558,3619.429,276.3516,0,0,0,0,100,0), -- 00:15:35
+(@PATH,8,-3393.407,3613.085,276.4259,0,0,0,0,100,0), -- 00:15:38
+(@PATH,9,-3390.018,3604.891,276.2281,0,0,0,0,100,0), -- 00:15:41
+(@PATH,10,-3397.005,3597.193,277.0055,0,0,0,0,100,0), -- 00:15:44
+(@PATH,11,-3393.93,3598.741,276.5433,0,0,0,0,100,0), -- 00:15:48
+(@PATH,12,-3390.969,3600.254,276.3882,0,0,0,0,100,0), -- 00:15:50
+(@PATH,13,-3389.908,3605.303,276.3074,0,0,0,0,100,0), -- 00:15:51
+(@PATH,14,-3390.732,3618.796,276.4376,0,0,0,0,100,0), -- 00:15:55
+(@PATH,15,-3384.879,3620.886,277.2273,0,0,0,0,100,0), -- 00:15:58
+(@PATH,16,-3382.095,3624.67,278.3322,0,0,0,0,100,0), -- 00:16:01
+(@PATH,17,-3381.752,3635.601,284.2187,0,0,0,0,100,0), -- 00:16:03
+(@PATH,18,-3379.75,3638.496,285.585,0,0,0,0,100,0), -- 00:16:08
+(@PATH,19,-3376.617,3642.928,285.1052,0,0,0,0,100,0), -- 00:16:12
+(@PATH,20,-3372.458,3645.933,284.7447,0,0,0,0,100,0); -- 00:16:13
+-- 0x1C011842401672C000002500008BC617 .go -3376.641 3642.897 285.1084
diff --git a/sql/updates/world/2016_01_08_03_world.sql b/sql/updates/world/2016_01_08_03_world.sql
new file mode 100644
index 00000000000..2899c6e06eb
--- /dev/null
+++ b/sql/updates/world/2016_01_08_03_world.sql
@@ -0,0 +1,3 @@
+--
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=25968;
+DELETE FROM `creature` WHERE `id`=25801;
diff --git a/sql/updates/world/2016_01_09_00_world.sql b/sql/updates/world/2016_01_09_00_world.sql
new file mode 100644
index 00000000000..534e17ccb00
--- /dev/null
+++ b/sql/updates/world/2016_01_09_00_world.sql
@@ -0,0 +1,16 @@
+--
+-- Enable Landmine Knockback Achievement by removing it from disables
+DELETE FROM `disables` WHERE `sourceType`= 4 AND `entry`= 5258;
+
+-- Insert missing Landmine Knockback Achievement criteria data
+DELETE FROM `achievement_criteria_data` WHERE `criteria_id`= 5258;
+INSERT INTO `achievement_criteria_data` (`criteria_id`, `type`, `value1`, `value2`, `ScriptName`) VALUES
+(5258,0,57064,0,'');
+
+-- Update description for the linked spells 54355 and 54402
+UPDATE `spell_linked_spell` SET `comment`= 'Trigger Detonation with Land Mine Knockback' WHERE `spell_trigger` = 54355;
+
+-- Insert spell script name for spell 57099
+DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_gen_landmine_knockback_achievement';
+INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
+(57099,'spell_gen_landmine_knockback_achievement');
diff --git a/sql/updates/world/2016_01_10_00_world.sql b/sql/updates/world/2016_01_10_00_world.sql
new file mode 100644
index 00000000000..83ed21c8489
--- /dev/null
+++ b/sql/updates/world/2016_01_10_00_world.sql
@@ -0,0 +1,3 @@
+--
+UPDATE `creature_text` SET `text`='Windroc Matriarch lets loose a terrifying shriek.', `BroadcastTextId`=16149 WHERE `entry`=19055;
+UPDATE `smart_scripts` SET `action_type`=49, `action_param1`=0 WHERE `entryorguid`=1905500 AND `id`=3;
diff --git a/sql/updates/world/2016_01_10_01_world.sql b/sql/updates/world/2016_01_10_01_world.sql
new file mode 100644
index 00000000000..c79c157a1a1
--- /dev/null
+++ b/sql/updates/world/2016_01_10_01_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `creature_template` SET `unit_flags`=32832 WHERE `entry`= 18689;
diff --git a/sql/updates/world/2016_01_10_02_world.sql b/sql/updates/world/2016_01_10_02_world.sql
new file mode 100644
index 00000000000..eca8ef07849
--- /dev/null
+++ b/sql/updates/world/2016_01_10_02_world.sql
@@ -0,0 +1,6 @@
+--
+UPDATE `creature_template` SET `AIName`='SmartAI', `ScriptName`='' WHERE `entry`=25623;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=25623 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
+(25623, 0, 0, 0, 0, 0, 100, 0, 3000, 5000, 4000, 6000, 11, 54185, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Harvest Collector - IC - Cast Claw Slash'),
+(25623, 0, 1, 0, 8, 0, 100, 0, 47166, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Harvest Collector - On spell hit - Despawn');
diff --git a/sql/updates/world/2016_01_10_03_world.sql b/sql/updates/world/2016_01_10_03_world.sql
new file mode 100644
index 00000000000..5ac352ffe10
--- /dev/null
+++ b/sql/updates/world/2016_01_10_03_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `smart_scripts` SET `action_param6`=2 WHERE `entryorguid`=-96556 AND `id`=0 AND `source_type`=0;
diff --git a/sql/updates/world/2016_01_10_04_world.sql b/sql/updates/world/2016_01_10_04_world.sql
new file mode 100644
index 00000000000..da6eed191ad
--- /dev/null
+++ b/sql/updates/world/2016_01_10_04_world.sql
@@ -0,0 +1,11 @@
+--
+DELETE FROM `instance_template` WHERE `map` = 169;
+INSERT INTO `instance_template` (`map`, `parent`, `script`, `allowMount`) VALUES
+(169, 0, '', 0);
+
+DELETE FROM `game_tele` WHERE `id` IN (1425, 1426, 1427, 1428);
+INSERT INTO `game_tele` (`id`, `position_x`, `position_y`, `position_z`, `orientation`, `map`, `name`) VALUES
+(1425, -366.091, 3097.86, 92.317, 0.0487625, 169, 'EmeraldDream'),
+(1426, 2781.566406, 3006.763184, 23.221882, 0.5, 169, 'EmeraldStatue'),
+(1427, -2128.12, -1005.89, 132.213, 0.5, 169, 'VerdantFields'),
+(1428, 2732.93, -3319.63, 101.284, 0.5, 169, 'EmeraldForest');
diff --git a/sql/updates/world/2016_01_10_05_world335.sql b/sql/updates/world/2016_01_10_05_world335.sql
new file mode 100644
index 00000000000..468e9c6dc17
--- /dev/null
+++ b/sql/updates/world/2016_01_10_05_world335.sql
@@ -0,0 +1,21 @@
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` in(19,20) AND `SourceId` in(5066,5090,5091,5093,5094,5095,10373,10374);
+
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(19, 0, 5066, 0, 0, 14, 0, 5092, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(20, 0, 5066, 0, 0, 14, 0, 5092, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(19, 0, 5090, 0, 0, 14, 0, 5092, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(20, 0, 5090, 0, 0, 14, 0, 5092, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(19, 0, 5091, 0, 0, 14, 0, 5092, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(20, 0, 5091, 0, 0, 14, 0, 5092, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(19, 0, 5093, 0, 0, 14, 0, 5096, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(20, 0, 5093, 0, 0, 14, 0, 5096, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(19, 0, 5094, 0, 0, 14, 0, 5096, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(20, 0, 5094, 0, 0, 14, 0, 5096, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(19, 0, 5095, 0, 0, 14, 0, 5096, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(20, 0, 5095, 0, 0, 14, 0, 5096, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(19, 0, 10373, 0, 0, 14, 0, 5092, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(20, 0, 10373, 0, 0, 14, 0, 5092, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(19, 0, 10374, 0, 0, 14, 0, 5096, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)'),
+(20, 0, 10374, 0, 0, 14, 0, 5096, 0, 0, 0, 0, 0, '', 'Call to Arms: The Plaguelands (Breadcrumb)');
+
+UPDATE `quest_template_addon` SET `NextQuestID`=0 WHERE `ID` in(5066,5090,5091,5093,5094,5095,10373,10374);
diff --git a/sql/updates/world/2016_01_07_npc_taxi.sql b/sql/updates/world/2016_01_12_00_world.sql
index 8ed4099450b..8ed4099450b 100644
--- a/sql/updates/world/2016_01_07_npc_taxi.sql
+++ b/sql/updates/world/2016_01_12_00_world.sql
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index 11fbc2f77b6..e8b89a813b5 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -209,7 +209,7 @@ class SmartScript
if (lookupRoot)
{
- if (!meOrigGUID)
+ if (!meOrigGUID.IsEmpty())
{
if (Creature* m = ObjectAccessor::GetCreature(*lookupRoot, meOrigGUID))
{
@@ -217,7 +217,8 @@ class SmartScript
go = NULL;
}
}
- if (!goOrigGUID)
+
+ if (!goOrigGUID.IsEmpty())
{
if (GameObject* o = ObjectAccessor::GetGameObject(*lookupRoot, goOrigGUID))
{
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
index 4c4a3d8028f..e1ba9a64191 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
@@ -242,6 +242,22 @@ void AuctionBotConfig::GetConfigFromFile()
SetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL, "AuctionHouseBot.Class.TradeGood.ItemLevel.Max", 0);
SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL, "AuctionHouseBot.Class.Container.ItemLevel.Min", 0);
SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL, "AuctionHouseBot.Class.Container.ItemLevel.Max", 0);
+
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONSUMABLE, "AuctionHouseBot.Class.RandomStackRatio.Consumable", 20);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONTAINER, "AuctionHouseBot.Class.RandomStackRatio.Container", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_WEAPON, "AuctionHouseBot.Class.RandomStackRatio.Weapon", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GEM, "AuctionHouseBot.Class.RandomStackRatio.Gem", 20);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_ARMOR, "AuctionHouseBot.Class.RandomStackRatio.Armor", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_REAGENT, "AuctionHouseBot.Class.RandomStackRatio.Reagent", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_PROJECTILE, "AuctionHouseBot.Class.RandomStackRatio.Projectile", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_TRADEGOOD, "AuctionHouseBot.Class.RandomStackRatio.TradeGood", 50);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GENERIC, "AuctionHouseBot.Class.RandomStackRatio.Generic", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_RECIPE, "AuctionHouseBot.Class.RandomStackRatio.Recipe", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUIVER, "AuctionHouseBot.Class.RandomStackRatio.Quiver", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUEST, "AuctionHouseBot.Class.RandomStackRatio.Quest", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_KEY, "AuctionHouseBot.Class.RandomStackRatio.Key", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_MISC, "AuctionHouseBot.Class.RandomStackRatio.Misc", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GLYPH, "AuctionHouseBot.Class.RandomStackRatio.Glyph", 0);
}
char const* AuctionBotConfig::GetHouseTypeName(AuctionHouseType houseType)
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.h b/src/server/game/AuctionHouseBot/AuctionHouseBot.h
index 63641fc7da2..87f76a17dcc 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBot.h
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.h
@@ -137,6 +137,21 @@ enum AuctionBotConfigUInt32Values
CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL,
CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL,
CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONSUMABLE,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONTAINER,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_WEAPON,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GEM,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_ARMOR,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_REAGENT,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_PROJECTILE,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_TRADEGOOD,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GENERIC,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_RECIPE,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUIVER,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUEST,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_KEY,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_MISC,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GLYPH,
CONFIG_UINT32_AHBOT_UINT32_COUNT
};
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
index bcecc20c41a..5acb56b5173 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
@@ -533,6 +533,23 @@ void AuctionBotSeller::LoadItemsQuantity(SellerConfiguration& config)
config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_GLYPH, 0);
// ============================================================================================
+ // Set Stack Quantities
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONSUMABLE));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONTAINER));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_WEAPON));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GEM));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_ARMOR));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_REAGENT, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_REAGENT));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_PROJECTILE));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_TRADEGOOD));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_GENERIC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GENERIC));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_RECIPE));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUIVER));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUEST));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_KEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_KEY));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_MISC));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_GLYPH, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GLYPH));
+
// Set the best value to get nearest amount of items wanted
for (uint32 j = 0; j < MAX_AUCTION_QUALITY; ++j)
{
@@ -719,6 +736,15 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf
bidp = urand(basePrice - range, basePrice + range) + 1;
}
+// Determines the stack size to use for the item
+uint32 AuctionBotSeller::GetStackSizeForItem(ItemTemplate const* itemProto, SellerConfiguration& config) const
+{
+ if (config.GetRandomStackRatioPerClass(ItemClass(itemProto->Class)) > urand(0, 99))
+ return urand(1, itemProto->GetMaxStackSize());
+ else
+ return 1;
+}
+
// Determine the multiplier for the sell price of any weapon without a buy price.
uint32 AuctionBotSeller::GetSellModifier(ItemTemplate const* prototype)
{
@@ -952,7 +978,7 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config)
continue;
}
- uint32 stackCount = urand(1, prototype->GetMaxStackSize());
+ uint32 stackCount = GetStackSizeForItem(prototype, config);
Item* item = Item::CreateItem(itemId, stackCount);
if (!item)
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
index 4f293e03d9a..dd82b0f3dda 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
@@ -33,12 +33,13 @@ typedef std::vector<std::vector<uint32>> AllItemsArray;
struct SellerItemClassInfo
{
- SellerItemClassInfo(): AmountOfItems(0), MissItems(0), Quantity(0), PriceRatio(0) {}
+ SellerItemClassInfo(): AmountOfItems(0), MissItems(0), Quantity(0), PriceRatio(0), RandomStackRatio(100) {}
uint32 AmountOfItems;
uint32 MissItems;
uint32 Quantity;
uint32 PriceRatio;
+ uint32 RandomStackRatio;
};
struct SellerItemInfo
@@ -102,6 +103,8 @@ public:
uint32 GetPriceRatioPerQuality(AuctionQuality quality) const { return _ItemInfo[quality].PriceRatio; }
void SetPriceRatioPerClass(ItemClass item, uint32 value) { _ItemInfo[0].ItemClassInfos[item].PriceRatio = value; }
uint32 GetPriceRatioPerClass(ItemClass item) const { return _ItemInfo[0].ItemClassInfos[item].PriceRatio; }
+ void SetRandomStackRatioPerClass(ItemClass item, uint32 value) { _ItemInfo[0].ItemClassInfos[item].RandomStackRatio = value; }
+ uint32 GetRandomStackRatioPerClass(ItemClass item) const { return _ItemInfo[0].ItemClassInfos[item].RandomStackRatio; }
private:
AuctionHouseType _houseType;
@@ -139,6 +142,7 @@ private:
uint32 SetStat(SellerConfiguration& config);
bool GetItemsToSell(SellerConfiguration& config, ItemsToSellArray& itemsToSellArray, AllItemsArray const& addedItem);
void SetPricesOfItem(ItemTemplate const* itemProto, SellerConfiguration& config, uint32& buyp, uint32& bidp, uint32 stackcnt);
+ uint32 GetStackSizeForItem(ItemTemplate const* itemProto, SellerConfiguration& config) const;
void LoadItemsQuantity(SellerConfiguration& config);
static uint32 GetBuyModifier(ItemTemplate const* prototype);
static uint32 GetSellModifier(ItemTemplate const* itemProto);
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index afca851974a..6d058f405a8 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -72,9 +72,10 @@ class Minion : public TempSummon
Unit* GetOwner() const { return m_owner; }
float GetFollowAngle() const override { return m_followAngle; }
void SetFollowAngle(float angle) { m_followAngle = angle; }
- bool IsPetGhoul() const {return GetEntry() == 26125;} // Ghoul may be guardian or pet
- bool IsSpiritWolf() const {return GetEntry() == 29264;} // Spirit wolf from feral spirits
+ bool IsPetGhoul() const { return GetEntry() == 26125; } // Ghoul may be guardian or pet
+ bool IsSpiritWolf() const { return GetEntry() == 29264; } // Spirit wolf from feral spirits
bool IsGuardianPet() const;
+ bool IsRisenAlly() const { return GetEntry() == 30230; }
protected:
Unit* const m_owner;
float m_followAngle;
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 9aabed67243..6f0b9f89e44 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1803,6 +1803,8 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, bool triggered /*= true
if (Unit* owner = GetOwner())
{
trigger->setFaction(owner->getFaction());
+ if (owner->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE))
+ trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
// needed for GO casts for proper target validation checks
trigger->SetOwnerGUID(owner->GetGUID());
trigger->CastSpell(target ? target : trigger, spellInfo, triggered, nullptr, nullptr, owner->GetGUID());
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 52291cb6bf5..4fdf25e41c3 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1242,6 +1242,9 @@ void Player::Update(uint32 p_time)
if (charmer->GetTypeId() == TYPEID_UNIT && charmer->IsAlive())
UpdateCharmedAI();
+ if (GetAI() && IsAIEnabled)
+ GetAI()->UpdateAI(p_time);
+
// Update items that have just a limited lifetime
if (now > m_Last_tick)
UpdateItemDuration(uint32(now - m_Last_tick));
@@ -1476,8 +1479,8 @@ void Player::Update(uint32 p_time)
_pendingBindTimer -= p_time;
}
- // not auto-free ghost from body in instances
- if (m_deathTimer > 0 && !GetBaseMap()->Instanceable() && !HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
+ // not auto-free ghost from body in instances or if its affected by risen ally
+ if (m_deathTimer > 0 && !GetBaseMap()->Instanceable() && !HasAuraType(SPELL_AURA_PREVENT_RESURRECTION) && !IsGhouled())
{
if (p_time >= m_deathTimer)
{
@@ -2157,7 +2160,7 @@ bool Player::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) co
return true;
if (spellInfo->Effects[index].IsEffect(SPELL_EFFECT_ATTACK_ME))
return true;
-
+
return Unit::IsImmunedToSpellEffect(spellInfo, index);
}
@@ -4731,6 +4734,32 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
}
}
+void Player::SendGhoulResurrectRequest(Player* target)
+{
+ target->m_ghoulResurrectPlayerGUID = GetGUID();
+
+ WorldPacket data(SMSG_RESURRECT_REQUEST, 8 + 4 + 1 + 1);
+ data << uint64(GetGUID());
+ data << uint32(0);
+ data << uint8(0);
+ data << uint8(0);
+ target->GetSession()->SendPacket(&data);
+}
+
+void Player::GhoulResurrect()
+{
+ CastSpell(this, 46619 /*SPELL_DK_RAISE_ALLY*/, true, nullptr, nullptr, m_ghoulResurrectPlayerGUID);
+
+ m_ghoulResurrectPlayerGUID = ObjectGuid::Empty;
+}
+
+void Player::RemoveGhoul()
+{
+ if (IsGhouled())
+ if (Creature* ghoul = ObjectAccessor::GetCreature(*this, m_ghoulResurrectGhoulGUID))
+ ghoul->DespawnOrUnsummon(); // Raise Ally aura will handle unauras
+}
+
void Player::KillPlayer()
{
if (IsFlying() && !GetTransport())
@@ -18682,7 +18711,7 @@ bool Player::CheckInstanceValidity(bool /*isLogin*/)
// game masters' instances are always valid
if (IsGameMaster())
return true;
-
+
// non-instances are always valid
Map* map = GetMap();
if (!map || !map->IsDungeon())
@@ -20156,6 +20185,12 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
void Player::StopCastingCharm()
{
+ if (IsGhouled())
+ {
+ RemoveGhoul();
+ return;
+ }
+
Unit* charm = GetCharm();
if (!charm)
return;
@@ -21508,6 +21543,14 @@ void Player::setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, flo
m_resurrectHealth = health;
m_resurrectMana = mana;
}
+
+void Player::clearResurrectRequestData()
+{
+ setResurrectRequestData(ObjectGuid::Empty, 0, 0.0f, 0.0f, 0.0f, 0, 0);
+
+ m_ghoulResurrectPlayerGUID = ObjectGuid::Empty;
+ m_ghoulResurrectGhoulGUID = ObjectGuid::Empty;
+}
//slot to be excluded while counting
bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot)
{
@@ -23410,6 +23453,8 @@ uint32 Player::GetBaseWeaponSkillValue(WeaponAttackType attType) const
void Player::ResurrectUsingRequestData()
{
+ RemoveGhoul();
+
/// Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse
TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());
@@ -23854,6 +23899,31 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
//WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
//GetSession()->SendPacket(&data);
}
+
+ // HACK: Make sure update for PLAYER_FARSIGHT is received before SMSG_PET_SPELLS to properly hide "Release spirit" dialog
+ if (target->GetTypeId() == TYPEID_UNIT && static_cast<Unit*>(target)->HasUnitTypeMask(UNIT_MASK_MINION) && static_cast<Minion*>(target)->IsRisenAlly())
+ {
+ if (apply)
+ {
+ UpdateDataMapType update_players;
+ BuildUpdate(update_players);
+ WorldPacket packet;
+ for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
+ {
+ iter->second.BuildPacket(&packet);
+ iter->first->GetSession()->SendPacket(&packet);
+ packet.clear();
+ }
+ }
+ else
+ {
+ m_deathTimer = 6 * MINUTE * IN_MILLISECONDS;
+
+ // Reset "Release spirit" timer clientside
+ WorldPacket data(SMSG_FORCED_DEATH_UPDATE);
+ SendDirectMessage(&data);
+ }
+ }
}
WorldObject* Player::GetViewpoint() const
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 32a4fec27f2..e7af827e9c7 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1576,7 +1576,7 @@ class Player : public Unit, public GridObject<Player>
void UpdatePotionCooldown(Spell* spell = NULL);
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana);
- void clearResurrectRequestData() { setResurrectRequestData(ObjectGuid::Empty, 0, 0.0f, 0.0f, 0.0f, 0, 0); }
+ void clearResurrectRequestData();
bool isResurrectRequestedBy(ObjectGuid guid) const { return !m_resurrectGUID.IsEmpty() && m_resurrectGUID == guid; }
bool isResurrectRequested() const { return !m_resurrectGUID.IsEmpty(); }
void ResurrectUsingRequestData();
@@ -1770,6 +1770,15 @@ class Player : public Unit, public GridObject<Player>
void ResurrectPlayer(float restore_percent, bool applySickness = false);
void BuildPlayerRepop();
void RepopAtGraveyard();
+ void SendGhoulResurrectRequest(Player* target);
+ bool IsValidGhoulResurrectRequest(ObjectGuid guid)
+ {
+ return !m_ghoulResurrectPlayerGUID.IsEmpty() && m_ghoulResurrectPlayerGUID == guid;
+ }
+ void GhoulResurrect();
+ void SetGhoulResurrectGhoulGUID(ObjectGuid guid) { m_ghoulResurrectGhoulGUID = guid; }
+ ObjectGuid GetGhoulResurrectGhoulGUID() { return m_ghoulResurrectGhoulGUID; }
+ void RemoveGhoul();
void DurabilityLossAll(double percent, bool inventory);
void DurabilityLoss(Item* item, double percent);
@@ -2403,6 +2412,9 @@ class Player : public Unit, public GridObject<Player>
float m_resurrectX, m_resurrectY, m_resurrectZ;
uint32 m_resurrectHealth, m_resurrectMana;
+ ObjectGuid m_ghoulResurrectPlayerGUID;
+ ObjectGuid m_ghoulResurrectGhoulGUID;
+
WorldSession* m_session;
typedef std::list<Channel*> JoinedChannelsList;
@@ -2502,7 +2514,7 @@ class Player : public Unit, public GridObject<Player>
bool IsHasDelayedTeleport() const { return m_bHasDelayedTeleport; }
void SetDelayedTeleportFlag(bool setting) { m_bHasDelayedTeleport = setting; }
void ScheduleDelayedOperation(uint32 operation) { if (operation < DELAYED_END) m_DelayedOperations |= operation; }
-
+
bool IsInstanceLoginGameMasterException() const;
MapReference m_mapRef;
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index 775a3c96c46..a8e13a9f7db 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -499,7 +499,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness
UpdateSpellDamageAndHealingBonus();
- if (pet && pet->IsPetGhoul()) // At melee attack power change for DK pet
+ if (pet && (pet->IsPetGhoul() || pet->IsRisenAlly())) // At melee attack power change for DK pet
pet->UpdateAttackPowerAndDamage();
if (guardian && guardian->IsSpiritWolf()) // At melee attack power change for Shaman feral spirit
@@ -1113,7 +1113,7 @@ bool Guardian::UpdateStats(Stats stat)
Unit* owner = GetOwner();
// Handle Death Knight Glyphs and Talents
float mod = 0.75f;
- if (IsPetGhoul() && (stat == STAT_STAMINA || stat == STAT_STRENGTH))
+ if ((IsPetGhoul() || IsRisenAlly()) && (stat == STAT_STAMINA || stat == STAT_STRENGTH))
{
if (stat == STAT_STAMINA)
mod = 0.3f; // Default Owner's Stamina scale
@@ -1329,7 +1329,7 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod;
SetBonusDamage(int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod));
}
- else if (IsPetGhoul()) //ghouls benefit from deathknight's attack power (may be summon pet or not)
+ else if (IsPetGhoul() || IsRisenAlly()) //ghouls benefit from deathknight's attack power (may be summon pet or not)
{
bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.22f;
SetBonusDamage(int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.1287f));
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index fcd2535dad9..261f4faf1a8 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -9395,7 +9395,7 @@ void Unit::SetMinion(Minion *minion, bool apply)
minion->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
// Ghoul pets have energy instead of mana (is anywhere better place for this code?)
- if (minion->IsPetGhoul())
+ if (minion->IsPetGhoul() || minion->IsRisenAlly())
minion->setPowerType(POWER_ENERGY);
// Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again
@@ -13625,6 +13625,9 @@ void Unit::RemoveFromWorld()
RemoveAreaAurasDueToLeaveWorld();
+ if (IsCharmed())
+ RemoveCharmedBy(nullptr);
+
if (GetCharmerGUID())
{
TC_LOG_FATAL("entities.unit", "Unit %u has charmer guid when removed from world", GetEntry());
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 8fc93f24351..90d312f422a 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1598,6 +1598,7 @@ class Unit : public WorldObject
bool IsAlive() const { return (m_deathState == ALIVE); }
bool isDying() const { return (m_deathState == JUST_DIED); }
bool isDead() const { return (m_deathState == DEAD || m_deathState == CORPSE); }
+ bool IsGhouled() const { return HasAura(46619 /*SPELL_DK_RAISE_ALLY*/); }
DeathState getDeathState() const { return m_deathState; }
virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index e4ee057d6ea..758d5af83f7 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -71,6 +71,7 @@ void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData)
}
//this is spirit release confirm?
+ GetPlayer()->RemoveGhoul();
GetPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
GetPlayer()->BuildPlayerRepop();
GetPlayer()->RepopAtGraveyard();
@@ -776,6 +777,12 @@ void WorldSession::HandleResurrectResponseOpcode(WorldPacket& recvData)
return;
}
+ if (GetPlayer()->IsValidGhoulResurrectRequest(guid))
+ {
+ GetPlayer()->GhoulResurrect();
+ return;
+ }
+
if (!GetPlayer()->isResurrectRequestedBy(guid))
return;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index cb573f4ec3d..aed7c0db043 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2359,7 +2359,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
// Do healing and triggers
if (m_healing > 0)
{
- bool crit = caster->IsSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
+ bool crit = target->crit;
uint32 addhealth = m_healing;
if (crit)
{
@@ -2384,7 +2384,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
// Add bonuses and fill damageInfo struct
- caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
+ caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
// Send log damage message to client
@@ -4207,21 +4207,16 @@ void Spell::SendResurrectRequest(Player* target)
{
// get resurrector name for creature resurrections, otherwise packet will be not accepted
// for player resurrections the name is looked up by guid
- std::string const sentName(m_caster->GetTypeId() == TYPEID_PLAYER
- ? ""
- : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
+ std::string const sentName(m_caster->GetTypeId() == TYPEID_PLAYER ?
+ "" : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
- WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+sentName.size()+1+1+1+4));
+ WorldPacket data(SMSG_RESURRECT_REQUEST, 8 + 4 + sentName.size() + 1 + 1 + 1);
data << uint64(m_caster->GetGUID());
data << uint32(sentName.size() + 1);
-
data << sentName;
- data << uint8(0); // null terminator
-
- data << uint8(m_caster->GetTypeId() == TYPEID_PLAYER ? 0 : 1); // "you'll be afflicted with resurrection sickness"
+ data << uint8(m_caster->IsSpiritHealer()); // "you'll be afflicted with resurrection sickness"
// override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
- if (m_spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_RESURRECTION_TIMER))
- data << uint32(0);
+ data << uint8(!m_spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_RESURRECTION_TIMER));
target->GetSession()->SendPacket(&data);
}
@@ -5512,7 +5507,7 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
// dead owner (pets still alive when owners ressed?)
if (Unit* owner = m_caster->GetCharmerOrOwner())
- if (!owner->IsAlive())
+ if (!owner->IsAlive() && !owner->IsGhouled())
return SPELL_FAILED_CASTER_DEAD;
if (!target && m_targets.GetUnitTarget())
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index fd9247bd778..6ae509af443 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -1362,7 +1362,7 @@ public:
int32 level = atol(levelStr);
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
index 1de3884664b..66806920e77 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
@@ -135,6 +135,7 @@ class boss_lord_marrowgar : public CreatureScript
_boneStormDuration = RAID_MODE<uint32>(20000, 30000, 20000, 30000);
_baseSpeed = creature->GetSpeedRate(MOVE_RUN);
_coldflameLastPos.Relocate(creature);
+ _introDone = false;
_boneSlice = false;
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index 31dd7de96ca..fafe3113835 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -236,6 +236,7 @@ class boss_professor_putricide : public CreatureScript
summons.DespawnAll();
SetPhase(PHASE_COMBAT_1);
_experimentState = EXPERIMENT_STATE_OOZE;
+ me->SetReactState(REACT_DEFENSIVE);
me->SetWalk(false);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
index 7f5d2b95dc0..7ea87a3c0c4 100644
--- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
@@ -560,6 +560,10 @@ public:
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
} else PoisonTimer -= diff;
}
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
}
};
};
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 59caf4b7f7b..3cea620559a 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -22,6 +22,7 @@
*/
#include "Player.h"
+#include "UnitAI.h"
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
@@ -63,7 +64,10 @@ enum DeathKnightSpells
SPELL_DK_UNHOLY_PRESENCE = 48265,
SPELL_DK_UNHOLY_PRESENCE_TRIGGERED = 49772,
SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189,
- SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284
+ SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284,
+ SPELL_DK_RAISE_ALLY_INITIAL = 61999,
+ SPELL_DK_RAISE_ALLY = 46619,
+ SPELL_DK_GHOUL_THRASH = 47480
};
enum DeathKnightSpellIcons
@@ -1699,6 +1703,303 @@ public:
}
};
+enum RaiseAllyMisc
+{
+ TEXT_RISE_ALLY = 33055,
+
+ SPELL_DK_RISEN_GHOUL_SELF_STUN = 47466,
+ SPELL_DK_RISEN_GHOUL_SPAWN__IN = 47448,
+ SPELL_DK_SUMMON_HEAL = 36492,
+ SPELL_DK_DEATH_KNIGHT_RUNE_WEAPON_SCALING_02 = 51906,
+ SPELL_DK_DEATH_KNIGHT_PET_SCALING_01 = 54566,
+ SPELL_DK_DEATH_KNIGHT_PET_SCALING_03 = 61697,
+ SPELL_DK_MIRROR_NAME = 62224,
+ SPELL_DK_MIRROR_NAME_TRIGGERED = 62214,
+ SPELL_DK_PET_SCALING___MASTER_SPELL_03___INTELLECT_SPIRIT_RESILIENCE = 67557,
+ SPELL_DK_PET_SCALING___MASTER_SPELL_06___SPELL_HIT_EXPERTISE_SPELL_PENETRATION = 67561,
+
+ SPELL_GHOUL_FRENZY = 62218,
+
+ NPC_RISEN_ALLY = 30230
+};
+
+// 61999 - Raise Ally Initial
+class spell_dk_raise_ally_initial : public SpellScriptLoader
+{
+public:
+ spell_dk_raise_ally_initial() : SpellScriptLoader("spell_dk_raise_ally_initial") { }
+
+ class spell_dk_raise_ally_initial_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dk_raise_ally_initial_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY_INITIAL))
+ return false;
+ return true;
+ }
+
+ SpellCastResult CheckCast()
+ {
+ // Raise Ally cannot be casted on alive players
+ Unit* target = GetExplTargetUnit();
+ if (!target)
+ return SPELL_FAILED_NO_VALID_TARGETS;
+ if (target->IsAlive())
+ return SPELL_FAILED_TARGET_NOT_DEAD;
+ if (Player* playerCaster = GetCaster()->ToPlayer())
+ if (playerCaster->InArena())
+ return SPELL_FAILED_NOT_IN_ARENA;
+ if (target->IsGhouled())
+ return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
+
+ return SPELL_CAST_OK;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Player* caster = GetCaster()->ToPlayer();
+ Player* target = GetHitPlayer();
+ if (caster && target)
+ caster->SendGhoulResurrectRequest(target);
+ }
+
+ void Register() override
+ {
+ OnCheckCast += SpellCheckCastFn(spell_dk_raise_ally_initial_SpellScript::CheckCast);
+ OnEffectHitTarget += SpellEffectFn(spell_dk_raise_ally_initial_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_dk_raise_ally_initial_SpellScript();
+ }
+};
+
+class player_ghoulAI : public PlayerAI
+{
+ public:
+ player_ghoulAI(Player* player, ObjectGuid ghoulGUID) : PlayerAI(player), _ghoulGUID(ghoulGUID) { }
+
+ void UpdateAI(uint32 /*diff*/) override
+ {
+ if (Creature* ghoul = ObjectAccessor::GetCreature(*me, _ghoulGUID))
+ {
+ if (!ghoul->IsAlive())
+ me->RemoveAura(SPELL_DK_RAISE_ALLY);
+ }
+ else
+ me->RemoveAura(SPELL_DK_RAISE_ALLY);
+ }
+
+ private:
+ ObjectGuid _ghoulGUID;
+};
+
+// 46619 - Raise Ally
+class spell_dk_raise_ally : public SpellScriptLoader
+{
+public:
+ spell_dk_raise_ally() : SpellScriptLoader("spell_dk_raise_ally") { }
+
+ class spell_dk_raise_ally_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dk_raise_ally_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY))
+ return false;
+ return true;
+ }
+
+ void SendText()
+ {
+ Player* caster = GetCaster()->ToPlayer();
+ Unit* original = GetOriginalCaster();
+ if (caster && original)
+ original->Whisper(TEXT_RISE_ALLY, caster, true);
+ }
+
+ void HandleSummon(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+
+ Unit* caster = GetCaster();
+ Unit* originalCaster = GetOriginalCaster();
+ if (!originalCaster)
+ return;
+
+ uint32 entry = uint32(GetSpellInfo()->Effects[effIndex].MiscValue);
+
+ //! HACK - StatSystem needs further develop to enable update on Puppet stats
+ // Using same summon properties as Raise Dead 46585 (Guardian) - EffectMiscValueB = 829
+ SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(829);
+
+ uint32 duration = uint32(GetSpellInfo()->GetDuration());
+ Position pos = caster->GetPosition();
+
+ TempSummon* summon = originalCaster->GetMap()->SummonCreature(entry, pos, properties, duration, originalCaster, GetSpellInfo()->Id);
+ if (!summon)
+ return;
+
+ //! Leaving this here as it's necessary if statsystem problem is solved
+ /*
+ Default SUMMON_CATEGORY_PUPPET behaviour sets possesor as originalCaster,
+ in this case we need caster as possesor and originalCaster as owner
+ */
+ //summon->RemoveCharmedBy(NULL);
+
+ summon->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
+
+ summon->CastSpell(summon, SPELL_DK_RISEN_GHOUL_SELF_STUN, true);
+ summon->CastSpell(summon, SPELL_DK_RISEN_GHOUL_SPAWN__IN, true);
+ summon->CastSpell(summon, SPELL_DK_SUMMON_HEAL, true);
+ summon->CastSpell(caster, SPELL_DK_MIRROR_NAME, true);
+ caster->CastSpell(summon, SPELL_DK_MIRROR_NAME_TRIGGERED, true);
+ summon->CastSpell(summon, SPELL_DK_DEATH_KNIGHT_RUNE_WEAPON_SCALING_02, true);
+ summon->CastSpell(summon, SPELL_DK_DEATH_KNIGHT_PET_SCALING_01, true);
+ summon->CastSpell(summon, SPELL_DK_DEATH_KNIGHT_PET_SCALING_03, true);
+ summon->CastSpell(summon, SPELL_DK_PET_SCALING___MASTER_SPELL_03___INTELLECT_SPIRIT_RESILIENCE, true);
+ summon->CastSpell(summon, SPELL_DK_PET_SCALING___MASTER_SPELL_06___SPELL_HIT_EXPERTISE_SPELL_PENETRATION, true);
+
+ // SMSG_POWER_UPDATE is sent
+ summon->SetMaxPower(POWER_ENERGY, 100);
+
+ if (Player* player = GetCaster()->ToPlayer())
+ player->SetGhoulResurrectGhoulGUID(summon->GetGUID());
+ }
+
+ void Register() override
+ {
+ AfterHit += SpellHitFn(spell_dk_raise_ally_SpellScript::SendText);
+ OnEffectHit += SpellEffectFn(spell_dk_raise_ally_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_dk_raise_ally_SpellScript();
+ }
+
+ class spell_dk_raise_ally_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_raise_ally_AuraScript);
+
+ public:
+ spell_dk_raise_ally_AuraScript()
+ {
+ oldAI = nullptr;
+ oldAIState = false;
+ }
+
+ private:
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY))
+ return false;
+ return true;
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Player* player = GetTarget()->ToPlayer();
+ if (!player || player->GetGhoulResurrectGhoulGUID().IsEmpty())
+ return;
+
+ oldAI = player->GetAI();
+ oldAIState = player->IsAIEnabled;
+ player->SetAI(new player_ghoulAI(player, player->GetGhoulResurrectGhoulGUID()));
+ player->IsAIEnabled = true;
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Player* player = GetTarget()->ToPlayer();
+ if (!player)
+ return;
+
+ player->IsAIEnabled = oldAIState;
+ UnitAI* thisAI = player->GetAI();
+ player->SetAI(oldAI);
+ delete thisAI;
+
+ // Dismiss ghoul if necessary
+ if (Creature* ghoul = ObjectAccessor::GetCreature(*player, player->GetGhoulResurrectGhoulGUID()))
+ {
+ ghoul->RemoveCharmedBy(nullptr);
+ ghoul->DespawnOrUnsummon(1000);
+ }
+
+ player->SetGhoulResurrectGhoulGUID(ObjectGuid::Empty);
+ player->RemoveAura(SPELL_GHOUL_FRENZY);
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_dk_raise_ally_AuraScript::OnApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_dk_raise_ally_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+
+ UnitAI* oldAI;
+ bool oldAIState;
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_dk_raise_ally_AuraScript();
+ }
+};
+
+// 47480 - Thrash
+class spell_dk_ghoul_thrash : public SpellScriptLoader
+{
+public:
+ spell_dk_ghoul_thrash() : SpellScriptLoader("spell_dk_ghoul_thrash") { }
+
+ class spell_dk_ghoul_thrash_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dk_ghoul_thrash_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_GHOUL_THRASH))
+ return false;
+ return true;
+ }
+
+ void CalcDamage()
+ {
+ if (Aura* aur = GetCaster()->GetAura(SPELL_GHOUL_FRENZY))
+ {
+ int32 damage = GetHitDamage();
+ damage += int32(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK) * 0.05f * aur->GetStackAmount());
+ aur->Remove();
+ SetHitDamage(damage);
+ }
+
+ /*
+ Also remove aura from charmer
+ SPELL_GHOUL_FRENZY (62218) - Targets (1, 27) (TARGET_UNIT_CASTER, TARGET_UNIT_MASTER)
+ */
+ if (Unit* charmer = GetCaster()->GetCharmer())
+ charmer->RemoveAura(SPELL_GHOUL_FRENZY);
+ }
+
+ void Register() override
+ {
+ OnHit += SpellHitFn(spell_dk_ghoul_thrash_SpellScript::CalcDamage);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_dk_ghoul_thrash_SpellScript();
+ }
+};
+
void AddSC_deathknight_spell_scripts()
{
new spell_dk_anti_magic_shell_raid();
@@ -1729,4 +2030,7 @@ void AddSC_deathknight_spell_scripts()
new spell_dk_vampiric_blood();
new spell_dk_will_of_the_necropolis();
new spell_dk_death_grip_initial();
+ new spell_dk_raise_ally_initial();
+ new spell_dk_raise_ally();
+ new spell_dk_ghoul_thrash();
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index c66abf72528..5c3ee1d7f4a 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -4120,6 +4120,44 @@ public:
}
};
+enum LandmineKnockbackAchievement
+{
+ SPELL_LANDMINE_KNOCKBACK_ACHIEVEMENT = 57064
+};
+
+class spell_gen_landmine_knockback_achievement : public SpellScriptLoader
+{
+public:
+ spell_gen_landmine_knockback_achievement() : SpellScriptLoader("spell_gen_landmine_knockback_achievement") { }
+
+ class spell_gen_landmine_knockback_achievement_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_landmine_knockback_achievement_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Player* target = GetHitPlayer())
+ {
+ Aura const* aura = GetHitAura();
+ if (!aura || aura->GetStackAmount() < 10)
+ return;
+
+ target->CastSpell(target, SPELL_LANDMINE_KNOCKBACK_ACHIEVEMENT, true);
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_landmine_knockback_achievement_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_gen_landmine_knockback_achievement_SpellScript();
+ }
+};
+
void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
@@ -4205,4 +4243,5 @@ void AddSC_generic_spell_scripts()
new spell_gen_gm_freeze();
new spell_gen_stand();
new spell_gen_mixology_bonus();
+ new spell_gen_landmine_knockback_achievement();
}
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 840b819fe99..5b07dde22bb 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -3190,6 +3190,46 @@ AuctionHouseBot.forceIncludeItems = ""
AuctionHouseBot.forceExcludeItems = ""
#
+# AuctionHouseBot.Class.RandomStackRatio.*
+# Description: Used to determine how often a stack of the class will be single or randomly-size stacked when posted
+# Value needs to be between 0 and 100, no decimal. Anything higher than 100 will be treated as 100
+# Examples: 100 = stacks will always be random in size
+# 50 = half the time the stacks are random, the other half being single stack
+# 0 = stacks will always single size
+# Default: Consumable: 20 (20% random stack size, 80% single stack size)
+# Container: 0 (100% single stack size)
+# Weapon: 0 (100% single stack size)
+# Gem: 20 (20% random stack size, 80% single stack size)
+# Armor: 0 (100% single stack size)
+# Reagent: 100 (100% random stack size)
+# Projectile: 100 (100% random stack size)
+# TradeGood: 50 (50% random stack size, 50% single stack size)
+# Generic: 100 (100% random stack size)
+# Recipe: 0 (100% single stack size)
+# Quiver: 0 (100% single stack size)
+# Quest: 100 (100% random stack size)
+# Key: 100 (100% random stack size)
+# Misc: 100 (100% random stack size)
+# Glyph: 0 (100% single stack size)
+#
+
+AuctionHouseBot.Class.RandomStackRatio.Consumable = 20
+AuctionHouseBot.Class.RandomStackRatio.Container = 0
+AuctionHouseBot.Class.RandomStackRatio.Weapon = 0
+AuctionHouseBot.Class.RandomStackRatio.Gem = 20
+AuctionHouseBot.Class.RandomStackRatio.Armor = 0
+AuctionHouseBot.Class.RandomStackRatio.Reagent = 100
+AuctionHouseBot.Class.RandomStackRatio.Projectile = 100
+AuctionHouseBot.Class.RandomStackRatio.TradeGood = 50
+AuctionHouseBot.Class.RandomStackRatio.Generic = 100
+AuctionHouseBot.Class.RandomStackRatio.Recipe = 0
+AuctionHouseBot.Class.RandomStackRatio.Quiver = 0
+AuctionHouseBot.Class.RandomStackRatio.Quest = 100
+AuctionHouseBot.Class.RandomStackRatio.Key = 100
+AuctionHouseBot.Class.RandomStackRatio.Misc = 100
+AuctionHouseBot.Class.RandomStackRatio.Glyph = 0
+
+#
###################################################################################################
###################################################################################################