diff --git a/data/sql/updates/pending_db_character/rev_1719945200692175000.sql b/data/sql/updates/db_characters/2024_07_05_00.sql
similarity index 56%
rename from data/sql/updates/pending_db_character/rev_1719945200692175000.sql
rename to data/sql/updates/db_characters/2024_07_05_00.sql
index 93b01738b..4a7e9e03c 100644
--- a/data/sql/updates/pending_db_character/rev_1719945200692175000.sql
+++ b/data/sql/updates/db_characters/2024_07_05_00.sql
@@ -1,3 +1,4 @@
+-- DB update 2024_01_20_00 -> 2024_07_05_00
--
ALTER TABLE `character_homebind`
diff --git a/data/sql/updates/db_world/2024_07_04_00.sql b/data/sql/updates/db_world/2024_07_04_00.sql
new file mode 100644
index 000000000..fd521f81e
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_04_00.sql
@@ -0,0 +1,2 @@
+-- DB update 2024_07_02_00 -> 2024_07_04_00
+UPDATE `gameobject` SET `position_x` = -11102.743, `position_y` = -1848.9752, `position_z` = 221.06969, `orientation` = 5.393069, `rotation2` = -0.43051052, `rotation3` = 0.90258557 WHERE `guid` = 56429 AND `id` = 185119;
diff --git a/data/sql/updates/db_world/2024_07_04_01.sql b/data/sql/updates/db_world/2024_07_04_01.sql
new file mode 100644
index 000000000..863d045ca
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_04_01.sql
@@ -0,0 +1,3 @@
+-- DB update 2024_07_04_00 -> 2024_07_04_01
+--
+UPDATE `creature_template` SET `flags_extra` = `flags_extra` | 128 WHERE `entry` = 8611;
diff --git a/data/sql/updates/db_world/2024_07_04_02.sql b/data/sql/updates/db_world/2024_07_04_02.sql
new file mode 100644
index 000000000..7c27ae5bd
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_04_02.sql
@@ -0,0 +1,33 @@
+-- DB update 2024_07_04_01 -> 2024_07_04_02
+DELETE FROM `gossip_menu` WHERE `MenuID` = 7175;
+INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES
+(7175, 8454),
+(7175, 8455);
+DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 14) AND (`SourceGroup` IN (7175));
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `Comment`) VALUES
+(14, 7175, 8455, 0, 0, 5, 0, 529, 240, 0, 0, 'Player for which gossip text is shown has at least reputation Friendly, Honored, Revered, Exalted to faction 529');
+
+DELETE FROM `gossip_menu_option` WHERE `MenuID` = 7175;
+INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
+(7175, 0, 0, 'I am diseased. Please cure me, medic.', 12154, 1, 1, 0, 0, 0, 0, NULL, 0, 0);
+
+DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` IN (7175));
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `Comment`) VALUES
+(15, 7175, 0, 0, 0, 1, 0, 12541, 0, 0, 0, 'Player for which gossip text is shown has aura of spell Ghoul Rot (Ghoul Rot12541), effect EFFECT_0'),
+(15, 7175, 0, 0, 1, 1, 0, 3427, 0, 0, 0, 'Player for which gossip text is shown has aura of spell Infected Wound (3427), effect EFFECT_0'),
+(15, 7175, 0, 0, 2, 1, 0, 16449, 0, 0, 0, 'Player for which gossip text is shown has aura of spell Maggot Slime (16449), effect EFFECT_0');
+
+-- Argent Medic smart ai
+SET @ENTRY := 16284;
+UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY;
+DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY;
+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
+(@ENTRY, 0, 0, 0, 2, 0, 100, 1, 0, 15, 0, 0, 25, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Argent Medic - Self: Flee for assist'),
+(@ENTRY, 0, 1, 0, 25, 0, 100, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Argent Medic - On reset - Set event phase to phase 1'),
+(@ENTRY, 0, 2, 0, 62, 0, 100, 512, 7175, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Player - On gossip action 0 from menu 7175 selected - Gossip player: Close gossip'),
+(@ENTRY, 0, 3, 4, 62, 1, 100, 512, 7175, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Player - On gossip action 0 from menu 7175 selected - Set event phase to phase 2'),
+(@ENTRY, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 11, 28133, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Player - On gossip action 0 from menu 7175 selected - Self: Cast spell Cure Disease (28133) on Gossip player'),
+(@ENTRY, 0, 5, 0, 31, 0, 100, 0, 28133, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Argent Medic - On spell Cure Disease (28133) hit a target - Set event phase to phase 1');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 16284 AND `SourceId` = 0;
+
diff --git a/data/sql/updates/db_world/2024_07_04_03.sql b/data/sql/updates/db_world/2024_07_04_03.sql
new file mode 100644
index 000000000..1ef76fb66
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_04_03.sql
@@ -0,0 +1,14 @@
+-- DB update 2024_07_04_02 -> 2024_07_04_03
+--
+-- Razuvious
+DELETE FROM `creature_text` WHERE `CreatureID` = 16061 AND `GroupID` IN (4, 5);
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(16061, 4, 0, 'Pathetic...', 12, 0, 100, 5, 0, 0, 27865, 0, 'Razuvious SAY_PATHETIC'),
+(16061, 5, 0, 'Start doing something before I replace that target dummy with you and begin a warm up session of my own!', 12, 0, 100, 5, 0, 0, 13136, 0, 'Razuvious SAY_TARGET_DUMMY');
+
+-- Death Knight Understudy
+DELETE FROM `creature_text` WHERE `CreatureID` = 16803;
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(16803, 0, 0, 'Sir, student requests that you beat him for his lack of understanding!', 12, 0, 100, 1, 0, 0, 13140, 0, 'Death Knight Understudy SAY_BEAT_ME'),
+(16803, 0, 1, 'I am unworthy, master!', 12, 0, 100, 1, 0, 0, 13138, 0, 'Death Knight Understudy SAY_UNWORTHY'),
+(16803, 0, 2, 'Student is worthless, master! Student apologizes for his deficiency!', 12, 0, 100, 1, 0, 0, 13137, 0, 'Death Knight Understudy SAY_WORTHLESS');
diff --git a/data/sql/updates/db_world/2024_07_04_04.sql b/data/sql/updates/db_world/2024_07_04_04.sql
new file mode 100644
index 000000000..aded22c2c
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_04_04.sql
@@ -0,0 +1,15 @@
+-- DB update 2024_07_04_03 -> 2024_07_04_04
+--
+DELETE FROM `waypoint_data` WHERE `id` IN (2357601, 2357602, 2357603);
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(2357601, 1, -52.642, 1419.357, 27.31, NULL, 0, 1, 0, 100, 0),
+(2357602, 1, -69.908, 1419.721, 27.31, NULL, 0, 1, 0, 100, 0),
+(2357602, 2, -79.929, 1395.958, 27.31, NULL, 0, 1, 0, 100, 0),
+(2357602, 3, -80.072, 1374.555, 40.87, NULL, 0, 1, 0, 100, 0),
+(2357603, 1, -80.072, 1314.398, 40.87, NULL, 0, 1, 0, 100, 0),
+(2357603, 2, -80.072, 1295.775, 48.60, NULL, 0, 1, 0, 100, 0);
+
+DELETE FROM `creature_text` WHERE `CreatureID` = 23576 AND `GroupID` IN (14, 15);
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(23576, 14, 0, 'Mua-ha-ha!', 14, 0, 100, 0, 0, 0, 22145, 1, 'Nalorakk - RUN AWAY'),
+(23576, 15, 0, '%s transforms into a bear!', 16, 0, 100, 0, 0, 0, 24263, 1, 'Nalorakk - EMOTE BEAR');
diff --git a/data/sql/updates/db_world/2024_07_04_05.sql b/data/sql/updates/db_world/2024_07_04_05.sql
new file mode 100644
index 000000000..f34250d85
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_04_05.sql
@@ -0,0 +1,11 @@
+-- DB update 2024_07_04_04 -> 2024_07_04_05
+-- Shattrath Daily Normal/Heroic holograms
+UPDATE `creature_template` SET `ScriptName` = 'npc_shattrath_daily_quest' WHERE `entry` IN (24410,24854);
+
+UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24369;
+DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24369);
+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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(24369, 0, 0, 1, 1, 0, 100, 1, 0, 0, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 79464, 24854, 0, 0, 0, 0, 0, 0, 'Wind Trader Zhareem - Out of Combat - Do Action ID 1 (No Repeat)'),
+(24369, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 79462, 24410, 0, 0, 0, 0, 0, 0, 'Wind Trader Zhareem - Out of Combat - Do Action ID 1 (No Repeat)'),
+(24369, 0, 2, 3, 101, 0, 100, 0, 1, 30, 60000, 60000, 60000, 0, 223, 1, 0, 0, 0, 0, 0, 10, 79464, 24854, 0, 0, 0, 0, 0, 0, 'Wind Trader Zhareem - On 1 or More Players in Range - Do Action ID 1'),
+(24369, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 79462, 24410, 0, 0, 0, 0, 0, 0, 'Wind Trader Zhareem - On 1 or More Players in Range - Do Action ID 1');
diff --git a/data/sql/updates/db_world/2024_07_04_06.sql b/data/sql/updates/db_world/2024_07_04_06.sql
new file mode 100644
index 000000000..c67e8bc1e
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_04_06.sql
@@ -0,0 +1,5 @@
+-- DB update 2024_07_04_05 -> 2024_07_04_06
+--
+DELETE FROM `spell_custom_attr` WHERE `spell_id` = 38510;
+INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES
+(38510, 2147483648);
diff --git a/data/sql/updates/db_world/2024_07_05_00.sql b/data/sql/updates/db_world/2024_07_05_00.sql
new file mode 100644
index 000000000..b917c5e87
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_05_00.sql
@@ -0,0 +1,5 @@
+-- DB update 2024_07_04_06 -> 2024_07_05_00
+--
+DELETE FROM `spell_script_names` WHERE `spell_id` = 38929;
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(38929, 'spell_item_fel_mana_potion');
diff --git a/data/sql/updates/db_world/2024_07_05_01.sql b/data/sql/updates/db_world/2024_07_05_01.sql
new file mode 100644
index 000000000..a05420758
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_05_01.sql
@@ -0,0 +1,26 @@
+-- DB update 2024_07_05_00 -> 2024_07_05_01
+--
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1367 AND `source_type` = 0 AND `id` = 1;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1367 AND `source_type` = 0 AND `id` = 3;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1367 AND `source_type` = 0 AND `id` = 5;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1368 AND `source_type` = 0 AND `id` = 1;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1368 AND `source_type` = 0 AND `id` = 3;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1371 AND `source_type` = 0 AND `id` = 2;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1371 AND `source_type` = 0 AND `id` = 4;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1414 AND `source_type` = 0 AND `id` = 4;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1415 AND `source_type` = 0 AND `id` = 3;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2470 AND `source_type` = 0 AND `id` = 0;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 137300 AND `source_type` = 9 AND `id` = 20;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 137300 AND `source_type` = 9 AND `id` = 19;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1043900 AND `source_type` = 9 AND `id` = 2;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2129100 AND `source_type` = 9 AND `id` = 1;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2129100 AND `source_type` = 9 AND `id` = 13;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711300 AND `source_type` = 9 AND `id` = 1;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711300 AND `source_type` = 9 AND `id` = 3;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711400 AND `source_type` = 9 AND `id` = 1;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711400 AND `source_type` = 9 AND `id` = 3;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711500 AND `source_type` = 9 AND `id` = 1;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711500 AND `source_type` = 9 AND `id` = 3;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2731600 AND `source_type` = 9 AND `id` = 2;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2731600 AND `source_type` = 9 AND `id` = 3;
+UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 3019000 AND `source_type` = 9 AND `id` = 13;
diff --git a/data/sql/updates/db_world/2024_07_05_02.sql b/data/sql/updates/db_world/2024_07_05_02.sql
new file mode 100644
index 000000000..2b8ab129c
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_05_02.sql
@@ -0,0 +1,41 @@
+-- DB update 2024_07_05_01 -> 2024_07_05_02
+--
+DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 18870);
+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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(18870, 0, 0, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Reset - Set Event Phase 0'),
+(18870, 0, 1, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 34302, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Respawn - Cast \'Coalesce\''),
+(18870, 0, 2, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Aggro - Set Event Phase 1'),
+(18870, 0, 3, 4, 8, 1, 100, 0, 0, 2, 0, 0, 0, 0, 11, 34336, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Holy\' - Cast \'Damage Reduction: Holy\' (Phase 1)'),
+(18870, 0, 4, 5, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Holy\' - Say Line 1 (Phase 1)'),
+(18870, 0, 5, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Holy\' - Set Event Phase 2 (Phase 1)'),
+(18870, 0, 6, 7, 8, 1, 100, 0, 0, 4, 0, 0, 0, 0, 11, 34333, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Fire\' - Cast \'Damage Reduction: Fire\' (Phase 1)'),
+(18870, 0, 7, 8, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Fire\' - Say Line 2 (Phase 1)'),
+(18870, 0, 8, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Fire\' - Set Event Phase 3 (Phase 1)'),
+(18870, 0, 9, 10, 8, 1, 100, 0, 0, 8, 0, 0, 0, 0, 11, 34335, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Nature\' - Cast \'Damage Reduction: Nature\' (Phase 1)'),
+(18870, 0, 10, 11, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Nature\' - Say Line 3 (Phase 1)'),
+(18870, 0, 11, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Nature\' - Set Event Phase 4 (Phase 1)'),
+(18870, 0, 12, 13, 8, 1, 100, 0, 0, 16, 0, 0, 0, 0, 11, 34334, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Frost\' - Cast \'Damage Reduction: Frost\' (Phase 1)'),
+(18870, 0, 13, 14, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Frost\' - Say Line 4 (Phase 1)'),
+(18870, 0, 14, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Frost\' - Set Event Phase 5 (Phase 1)'),
+(18870, 0, 15, 16, 8, 1, 100, 0, 0, 32, 0, 0, 0, 0, 11, 34338, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Shadow\' - Cast \'Damage Reduction: Shadow\' (Phase 1)'),
+(18870, 0, 16, 17, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Shadow\' - Say Line 5 (Phase 1)'),
+(18870, 0, 17, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Shadow\' - Set Event Phase 6 (Phase 1)'),
+(18870, 0, 18, 19, 8, 1, 100, 0, 0, 64, 0, 0, 0, 0, 11, 34331, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Arcane\' - Cast \'Damage Reduction: Arcane\' (Phase 1)'),
+(18870, 0, 19, 20, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Arcane\' - Say Line 6 (Phase 1)'),
+(18870, 0, 20, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Arcane\' - Set Event Phase 7 (Phase 1)'),
+(18870, 0, 21, 0, 106, 0, 100, 0, 9000, 13000, 14000, 18000, 0, 8, 11, 22884, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Hostile in Range - Cast \'Psychic Scream\''),
+(18870, 0, 22, 0, 0, 33, 100, 0, 0, 1000, 3000, 3500, 0, 0, 11, 12471, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Shadow Bolt\' (Phases 1 & 6)'),
+(18870, 0, 23, 0, 0, 2, 100, 0, 0, 1000, 2500, 3000, 0, 0, 11, 15498, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Holy Smite\' (Phase 2)'),
+(18870, 0, 24, 0, 0, 4, 100, 0, 0, 1000, 3000, 3500, 0, 0, 11, 14034, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Fireball\' (Phase 3)'),
+(18870, 0, 25, 0, 0, 8, 100, 0, 0, 1000, 3000, 3500, 0, 0, 11, 12167, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Lightning Bolt\' (Phase 4)'),
+(18870, 0, 26, 0, 0, 16, 100, 0, 0, 1000, 3000, 3500, 0, 0, 11, 15497, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Frostbolt\' (Phase 5)'),
+(18870, 0, 27, 0, 0, 64, 100, 0, 0, 1000, 5000, 6000, 0, 0, 11, 38204, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Arcane Bolt\' (Phase 7)');
+
+DELETE FROM `creature_text` WHERE (`CreatureID` = 18870);
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(18870, 1, 0, '%s absorbs the holy energy of the attack.', 16, 0, 0, 0, 0, 0, 17110, 0, 'Voidshrieker'),
+(18870, 2, 0, '%s absorbs the fire energy of the attack.', 16, 0, 0, 0, 0, 0, 17105, 0, 'Voidshrieker'),
+(18870, 3, 0, '%s absorbs the nature energy of the attack.', 16, 0, 0, 0, 0, 0, 17107, 0, 'Voidshrieker'),
+(18870, 4, 0, '%s absorbs the frost energy of the attack.', 16, 0, 0, 0, 0, 0, 17106, 0, 'Voidshrieker'),
+(18870, 5, 0, '%s absorbs the shadow energy of the attack.', 16, 0, 0, 0, 0, 0, 17108, 0, 'Voidshrieker'),
+(18870, 6, 0, '%s absorbs the arcane energy of the attack.', 16, 0, 0, 0, 0, 0, 17109, 0, 'Voidshrieker');
diff --git a/data/sql/updates/db_world/2024_07_06_00.sql b/data/sql/updates/db_world/2024_07_06_00.sql
new file mode 100644
index 000000000..3b65178a3
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_00.sql
@@ -0,0 +1,10 @@
+-- DB update 2024_07_05_02 -> 2024_07_06_00
+--
+UPDATE `conditions` SET `ConditionTypeOrReference` = 8 WHERE `SourceGroup` = 8234 AND `SourceTypeOrReferenceId` = 15 AND `ConditionTypeOrReference` = 9;
+
+DELETE FROM `gossip_menu_option` WHERE (`MenuID` = 8234);
+INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
+(8234, 0, 0, 'I seem to have misplaced my ring.', 21813, 1, 1, 0, 0, 0, 0, '', 0, 55056),
+(8234, 1, 0, 'I seem to have misplaced my ring.', 21813, 1, 1, 0, 0, 0, 0, '', 0, 55056),
+(8234, 2, 0, 'I seem to have misplaced my ring.', 21813, 1, 1, 0, 0, 0, 0, '', 0, 55056),
+(8234, 3, 0, 'I seem to have misplaced my ring.', 21813, 1, 1, 0, 0, 0, 0, '', 0, 55056);
diff --git a/data/sql/updates/db_world/2024_07_06_01.sql b/data/sql/updates/db_world/2024_07_06_01.sql
new file mode 100644
index 000000000..1fd815d2d
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_01.sql
@@ -0,0 +1,18 @@
+-- DB update 2024_07_06_00 -> 2024_07_06_01
+--
+DELETE FROM `creature_text` WHERE (`CreatureID` = 6240);
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(6240, 0, 0, '%s is demoralized and runs!', 16, 0, 100, 0, 0, 0, 2356, 0, 'Affray Challenger');
+
+UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 6240;
+
+DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 6240);
+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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(6240, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Emote'),
+(6240, 0, 2, 1, 8, 0, 100, 0, 1160, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'),
+(6240, 0, 3, 1, 8, 0, 100, 0, 6190, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'),
+(6240, 0, 4, 1, 8, 0, 100, 0, 11554, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'),
+(6240, 0, 5, 1, 8, 0, 100, 0, 11555, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'),
+(6240, 0, 6, 1, 8, 0, 100, 0, 11556, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'),
+(6240, 0, 7, 1, 8, 0, 100, 0, 25202, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'),
+(6240, 0, 8, 1, 8, 0, 100, 0, 25203, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist');
diff --git a/data/sql/updates/db_world/2024_07_06_02.sql b/data/sql/updates/db_world/2024_07_06_02.sql
new file mode 100644
index 000000000..1c568b645
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_02.sql
@@ -0,0 +1,3 @@
+-- DB update 2024_07_06_01 -> 2024_07_06_02
+--
+DELETE FROM `creature_loot_template` WHERE `Item` = 21314;
diff --git a/data/sql/updates/db_world/2024_07_06_03.sql b/data/sql/updates/db_world/2024_07_06_03.sql
new file mode 100644
index 000000000..02801d8b2
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_03.sql
@@ -0,0 +1,5 @@
+-- DB update 2024_07_06_02 -> 2024_07_06_03
+--
+DELETE FROM `smart_scripts` WHERE (`entryorguid` = 23383) AND (`source_type` = 0) AND (`id` IN (7));
+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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(23383, 0, 7, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Prisoner - On Respawn - Set Reactstate Passive');
diff --git a/data/sql/updates/db_world/2024_07_06_04.sql b/data/sql/updates/db_world/2024_07_06_04.sql
new file mode 100644
index 000000000..c6fe8b15d
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_04.sql
@@ -0,0 +1,3 @@
+-- DB update 2024_07_06_03 -> 2024_07_06_04
+-- RequiredMinRepValue was set to 1
+UPDATE `quest_template_addon` SET `RequiredMinRepValue` = 0 WHERE (`ID` IN (10412, 10414, 10415, 10325, 10326, 10327));
diff --git a/data/sql/updates/db_world/2024_07_06_05.sql b/data/sql/updates/db_world/2024_07_06_05.sql
new file mode 100644
index 000000000..9f83fb107
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_05.sql
@@ -0,0 +1,5 @@
+-- DB update 2024_07_06_04 -> 2024_07_06_05
+--
+DELETE FROM `smart_scripts` WHERE (`entryorguid` = 3395) AND (`source_type` = 0) AND (`id` IN (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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(3395, 0, 0, 0, 1, 0, 100, 1, 4000, 4000, 0, 0, 0, 0, 53, 0, 3395, 0, 0, 600000, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Verog the Dervish - Out of Combat - Start Waypoint Movement (No Repeat)');
diff --git a/data/sql/updates/db_world/2024_07_06_06.sql b/data/sql/updates/db_world/2024_07_06_06.sql
new file mode 100644
index 000000000..3fd7d1a0c
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_06.sql
@@ -0,0 +1,11 @@
+-- DB update 2024_07_06_05 -> 2024_07_06_06
+--
+DELETE FROM `smart_scripts` WHERE (`entryorguid` = 18945) AND (`source_type` = 0) AND (`id` IN (4, 5, 6));
+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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(18945, 0, 4, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 80, 1894500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pit Commander - On Respawn - Run Script'),
+(18945, 0, 5, 0, 21, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pit Commander - On Reached Home - Set Event Phase');
+
+DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 1894500);
+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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(1894500, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 51347, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pit Commander - Actionlist - Cast \'Teleport Visual Only\''),
+(1894500, 9, 1, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 53, 0, 18945, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pit Commander - Actionlist - Start Waypoint Path 18945');
diff --git a/data/sql/updates/db_world/2024_07_06_07.sql b/data/sql/updates/db_world/2024_07_06_07.sql
new file mode 100644
index 000000000..e3f324cda
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_07.sql
@@ -0,0 +1,18 @@
+-- DB update 2024_07_06_06 -> 2024_07_06_07
+--
+DELETE FROM `creature_text` WHERE (`CreatureID` = 22484);
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(22484, 0, 0, '%s gathers the warp chaser\'s blood.', 16, 0, 100, 0, 0, 0, 20371, 0, 'Zeppit - Gather blood');
+
+UPDATE `smart_scripts` SET`target_param2` = 25 WHERE `entryorguid`=18884 AND `source_type`=0 AND `id`=3;
+
+DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 22484);
+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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(22484, 0, 0, 0, 38, 0, 100, 0, 1, 1, 3000, 3000, 0, 0, 69, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Zeppit - On Data Set 1 1 - Move To Invoker'),
+(22484, 0, 1, 0, 34, 0, 100, 0, 8, 1, 0, 0, 0, 0, 80, 2248400, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Zeppit - On Reached Point 1 - Run Script');
+
+DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2248400);
+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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(2248400, 9, 0, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Zeppit - Actionlist - Say Line 0'),
+(2248400, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 39244, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Zeppit - Actionlist - Cast \'Gather Warp Chaser Blood\''),
+(2248400, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Zeppit - Actionlist - Start Follow Owner Or Summoner');
diff --git a/data/sql/updates/db_world/2024_07_06_08.sql b/data/sql/updates/db_world/2024_07_06_08.sql
new file mode 100644
index 000000000..1a7faa883
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_08.sql
@@ -0,0 +1,3 @@
+-- DB update 2024_07_06_07 -> 2024_07_06_08
+--
+UPDATE `creature_template` SET `detection_range` = 55 WHERE `entry` = 22849;
diff --git a/data/sql/updates/db_world/2024_07_06_09.sql b/data/sql/updates/db_world/2024_07_06_09.sql
new file mode 100644
index 000000000..d364f1302
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_09.sql
@@ -0,0 +1,3 @@
+-- DB update 2024_07_06_08 -> 2024_07_06_09
+--
+UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|33554432 WHERE `entry` = 23394;
diff --git a/data/sql/updates/db_world/2024_07_06_10.sql b/data/sql/updates/db_world/2024_07_06_10.sql
new file mode 100644
index 000000000..903d2adcd
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_10.sql
@@ -0,0 +1,3 @@
+-- DB update 2024_07_06_09 -> 2024_07_06_10
+--
+UPDATE `quest_template` SET `AllowableRaces` = 690 WHERE `ID` = 9846;
diff --git a/data/sql/updates/db_world/2024_07_06_11.sql b/data/sql/updates/db_world/2024_07_06_11.sql
new file mode 100644
index 000000000..8a74db700
--- /dev/null
+++ b/data/sql/updates/db_world/2024_07_06_11.sql
@@ -0,0 +1,6 @@
+-- DB update 2024_07_06_10 -> 2024_07_06_11
+DELETE FROM `spell_script_names` WHERE `spell_id` = 31944;
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (31944, 'spell_doomfire');
+
+DELETE FROM `spell_custom_attr` WHERE `spell_id` = 31944;
+INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (31944, 4194304);
diff --git a/src/common/Configuration/Config.cpp b/src/common/Configuration/Config.cpp
index 742777b18..d8665593c 100644
--- a/src/common/Configuration/Config.cpp
+++ b/src/common/Configuration/Config.cpp
@@ -35,6 +35,14 @@ namespace
std::unordered_map _envVarCache;
std::mutex _configLock;
+ std::vector _fatalConfigOptions =
+ {
+ { "RealmID" },
+ { "LoginDatabaseInfo" },
+ { "WorldDatabaseInfo" },
+ { "CharacterDatabaseInfo" },
+ };
+
// Check system configs like *server.conf*
bool IsAppConfig(std::string_view fileName)
{
@@ -388,6 +396,7 @@ T ConfigMgr::GetValueDefault(std::string const& name, T const& def, bool showLog
std::string strValue;
auto const& itr = _configOptions.find(name);
+ bool fatalConfig = false;
bool notFound = itr == _configOptions.end();
auto envVarName = GetEnvVarName(name);
Optional envVar = GetEnvFromCache(name, envVarName);
@@ -406,7 +415,18 @@ T ConfigMgr::GetValueDefault(std::string const& name, T const& def, bool showLog
{
if (showLogs)
{
- LOG_ERROR("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.",
+ for (std::string s : _fatalConfigOptions)
+ if (s == name)
+ {
+ fatalConfig = true;
+ break;
+ }
+
+ if (fatalConfig)
+ LOG_FATAL("server.loading", "> Config:\n\nFATAL ERROR: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable\n\nYour server cannot start without this option!",
+ name, _filename, name, Acore::ToString(def), envVarName);
+ else
+ LOG_WARN("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.",
name, _filename, name, Acore::ToString(def), envVarName);
}
return def;
@@ -435,6 +455,7 @@ template<>
std::string ConfigMgr::GetValueDefault(std::string const& name, std::string const& def, bool showLogs /*= true*/) const
{
auto const& itr = _configOptions.find(name);
+ bool fatalConfig = false;
bool notFound = itr == _configOptions.end();
auto envVarName = GetEnvVarName(name);
Optional envVar = GetEnvFromCache(name, envVarName);
@@ -453,7 +474,18 @@ std::string ConfigMgr::GetValueDefault(std::string const& name, std
{
if (showLogs)
{
- LOG_ERROR("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.",
+ for (std::string s : _fatalConfigOptions)
+ if (s == name)
+ {
+ fatalConfig = true;
+ break;
+ }
+
+ if (fatalConfig)
+ LOG_FATAL("server.loading", "> Config:\n\nFATAL ERROR: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.\n\nYour server cannot start without this option!",
+ name, _filename, name, def, envVarName);
+ else
+ LOG_WARN("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.",
name, _filename, name, def, envVarName);
}
diff --git a/src/common/Logging/enuminfo_LogCommon.cpp b/src/common/Logging/enuminfo_LogCommon.cpp
index e1750cb3f..2e4265563 100644
--- a/src/common/Logging/enuminfo_LogCommon.cpp
+++ b/src/common/Logging/enuminfo_LogCommon.cpp
@@ -15,8 +15,8 @@
* with this program. If not, see .
*/
-#include "Define.h"
#include "LogCommon.h"
+#include "Define.h"
#include "SmartEnum.h"
#include
diff --git a/src/server/database/Database/DatabaseLoader.cpp b/src/server/database/Database/DatabaseLoader.cpp
index a9f0bfcb8..2bee9d683 100644
--- a/src/server/database/Database/DatabaseLoader.cpp
+++ b/src/server/database/Database/DatabaseLoader.cpp
@@ -154,7 +154,7 @@ DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool& pool, std::st
bool DatabaseLoader::Load()
{
if (!_updateFlags)
- LOG_INFO("sql.updates", "Automatic database updates are disabled for all databases!");
+ LOG_WARN("sql.updates", "> AUTOUPDATER: Automatic database updates are disabled for all databases in the config! This is not recommended!");
if (!OpenDatabases())
return false;
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 865415f59..2f9bba321 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -23,6 +23,17 @@
#include "Unit.h"
#include
+#define CAST_AI(a, b) (dynamic_cast(b))
+#define ENSURE_AI(a,b) (EnsureAI(b))
+
+template
+T* EnsureAI(U* ai)
+{
+ T* cast_ai = dynamic_cast(ai);
+ ASSERT(cast_ai);
+ return cast_ai;
+}
+
class Player;
class Quest;
class Unit;
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index be04450d0..f6ed31486 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -25,8 +25,6 @@
#include "InstanceScript.h"
#include "TaskScheduler.h"
-#define CAST_AI(a, b) (dynamic_cast(b))
-
typedef std::list ObjectList;
class InstanceScript;
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index d126a9cfc..d3ec5eb51 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -962,9 +962,9 @@ uint32 SmartAI::GetData(uint32 /*id*/) const
return 0;
}
-void SmartAI::SetData(uint32 id, uint32 value)
+void SmartAI::SetData(uint32 id, uint32 value, Unit* invoker)
{
- GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, nullptr, id, value);
+ GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, invoker, id, value);
}
void SmartAI::SetGUID(ObjectGuid /*guid*/, int32 /*id*/)
@@ -1232,9 +1232,9 @@ void SmartGameObjectAI::Destroyed(Player* player, uint32 eventId)
GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, player, eventId, 0, false, nullptr, me);
}
-void SmartGameObjectAI::SetData(uint32 id, uint32 value)
+void SmartGameObjectAI::SetData(uint32 id, uint32 value, Unit* invoker)
{
- GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, nullptr, id, value);
+ GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, invoker, id, value);
}
void SmartGameObjectAI::SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker)
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index acb52d904..0311590fe 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -159,7 +159,8 @@ public:
uint32 GetData(uint32 id = 0) const override;
// Used in scripts to share variables
- void SetData(uint32 id, uint32 value) override;
+ void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); }
+ void SetData(uint32 id, uint32 value, Unit* invoker);
// Used in scripts to share variables
void SetGUID(ObjectGuid guid, int32 id = 0) override;
@@ -272,7 +273,8 @@ public:
bool QuestAccept(Player* player, Quest const* quest) override;
bool QuestReward(Player* player, Quest const* quest, uint32 opt) override;
void Destroyed(Player* player, uint32 eventId) override;
- void SetData(uint32 id, uint32 value) override;
+ void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); }
+ void SetData(uint32 id, uint32 value, Unit* invoker);
void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker);
void OnGameEvent(bool start, uint16 eventId) override;
void OnStateChanged(uint32 state, Unit* unit) override;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index cabedbe4a..7930317bf 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -63,7 +63,46 @@ SmartScript::SmartScript()
SmartScript::~SmartScript()
{
+}
+bool SmartScript::IsSmart(Creature* c, bool silent) const
+{
+ if (!c)
+ return false;
+
+ bool smart = true;
+ if (!dynamic_cast(c->AI()))
+ smart = false;
+
+ if (!smart && !silent)
+ LOG_ERROR("sql.sql", "SmartScript: Action target Creature(entry: {}) is not using SmartAI, action skipped to prevent crash.", c ? c->GetEntry() : (me ? me->GetEntry() : 0));
+
+ return smart;
+}
+
+bool SmartScript::IsSmart(GameObject* g, bool silent) const
+{
+ if (!g)
+ return false;
+
+ bool smart = true;
+ if (!dynamic_cast(g->AI()))
+ smart = false;
+
+ if (!smart && !silent)
+ LOG_ERROR("sql.sql", "SmartScript: Action target GameObject(entry: {}) is not using SmartGameObjectAI, action skipped to prevent crash.", g ? g->GetEntry() : (go ? go->GetEntry() : 0));
+
+ return smart;
+}
+
+bool SmartScript::IsSmart(bool silent) const
+{
+ if (me)
+ return IsSmart(me, silent);
+ if (go)
+ return IsSmart(go, silent);
+
+ return false;
}
void SmartScript::OnReset()
@@ -1272,22 +1311,29 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
for (WorldObject* target : targets)
{
- Milliseconds despawnDelay(e.action.forceDespawn.delay);
+ if (e.action.forceDespawn.removeObjectFromWorld)
+ {
+ if (e.action.forceDespawn.delay || e.action.forceDespawn.forceRespawnTimer)
+ LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_FORCE_DESPAWN has removeObjectFromWorld set. delay and forceRespawnTimer ignored.");
- // Wait at least one world update tick before despawn, so it doesn't break linked actions.
- if (despawnDelay <= 0ms)
- {
- despawnDelay = 1ms;
+ if (Creature* creature = target->ToCreature())
+ creature->AddObjectToRemoveList();
+ else if (GameObject* go = target->ToGameObject())
+ go->AddObjectToRemoveList();
}
+ else
+ {
+ Milliseconds despawnDelay(e.action.forceDespawn.delay);
- Seconds forceRespawnTimer(e.action.forceDespawn.forceRespawnTimer);
- if (Creature* creature = target->ToCreature())
- {
- creature->DespawnOrUnsummon(despawnDelay, forceRespawnTimer);
- }
- else if (GameObject* go = target->ToGameObject())
- {
- go->DespawnOrUnsummon(despawnDelay, forceRespawnTimer);
+ // Wait at least one world update tick before despawn, so it doesn't break linked actions.
+ if (despawnDelay <= 0ms)
+ despawnDelay = 1ms;
+
+ Seconds forceRespawnTimer(e.action.forceDespawn.forceRespawnTimer);
+ if (Creature* creature = target->ToCreature())
+ creature->DespawnOrUnsummon(despawnDelay, forceRespawnTimer);
+ else if (GameObject* go = target->ToGameObject())
+ go->DespawnOrUnsummon(despawnDelay, forceRespawnTimer);
}
}
@@ -1348,10 +1394,22 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
for (WorldObject* target : targets)
{
- if (IsCreature(target))
- target->ToCreature()->AI()->SetData(e.action.setData.field, e.action.setData.data);
- else if (IsGameObject(target))
- target->ToGameObject()->AI()->SetData(e.action.setData.field, e.action.setData.data);
+ if (Creature* cTarget = target->ToCreature())
+ {
+ CreatureAI* ai = cTarget->AI();
+ if (IsSmart(cTarget))
+ ENSURE_AI(SmartAI, ai)->SetData(e.action.setData.field, e.action.setData.data, me);
+ else
+ ai->SetData(e.action.setData.field, e.action.setData.data);
+ }
+ else if (GameObject* oTarget = target->ToGameObject())
+ {
+ GameObjectAI* ai = oTarget->AI();
+ if (IsSmart(oTarget))
+ ENSURE_AI(SmartGameObjectAI, ai)->SetData(e.action.setData.field, e.action.setData.data, me);
+ else
+ ai->SetData(e.action.setData.field, e.action.setData.data);
+ }
}
break;
}
@@ -1737,60 +1795,61 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
WorldObject* target = nullptr;
- if (e.GetTargetType() == SMART_TARGET_RANDOM_POINT)
+ switch (e.GetTargetType())
{
+ case SMART_TARGET_POSITION:
+ {
+ G3D::Vector3 dest(e.target.x, e.target.y, e.target.z);
+ if (e.action.moveToPos.transport)
+ if (TransportBase* trans = me->GetDirectTransport())
+ trans->CalculatePassengerPosition(dest.x, dest.y, dest.z);
+
+ me->GetMotionMaster()->MovePoint(e.action.moveToPos.pointId, dest.x, dest.y, dest.z, true, true,
+ isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE, e.target.o);
+
+ break;
+ }
+ case SMART_TARGET_RANDOM_POINT:
if (me)
{
float range = (float)e.target.randomPoint.range;
Position srcPos = { e.target.x, e.target.y, e.target.z, e.target.o };
Position randomPoint = me->GetRandomPoint(srcPos, range);
me->GetMotionMaster()->MovePoint(
- e.action.moveToPos.pointId,
- randomPoint.m_positionX,
- randomPoint.m_positionY,
- randomPoint.m_positionZ,
- true,
- true,
- isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE
+ e.action.moveToPos.pointId,
+ randomPoint.m_positionX,
+ randomPoint.m_positionY,
+ randomPoint.m_positionZ,
+ true,
+ true,
+ isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE
);
+
+ break;
}
-
- break;
- }
-
- /*if (e.GetTargetType() == SMART_TARGET_CREATURE_RANGE || e.GetTargetType() == SMART_TARGET_CREATURE_GUID ||
- e.GetTargetType() == SMART_TARGET_CREATURE_DISTANCE || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_RANGE ||
- e.GetTargetType() == SMART_TARGET_GAMEOBJECT_GUID || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_DISTANCE ||
- e.GetTargetType() == SMART_TARGET_CLOSEST_CREATURE || e.GetTargetType() == SMART_TARGET_CLOSEST_GAMEOBJECT ||
- e.GetTargetType() == SMART_TARGET_OWNER_OR_SUMMONER || e.GetTargetType() == SMART_TARGET_ACTION_INVOKER ||
- e.GetTargetType() == SMART_TARGET_CLOSEST_ENEMY || e.GetTargetType() == SMART_TARGET_CLOSEST_FRIENDLY ||
- e.GetTargetType() == SMART_TARGET_SELF || e.GetTargetType() == SMART_TARGET_STORED)) */
- {
- // we want to move to random element
- if (!targets.empty())
- target = Acore::Containers::SelectRandomContainerElement(targets);
- }
-
- if (!target)
- {
- G3D::Vector3 dest(e.target.x, e.target.y, e.target.z);
- if (e.action.moveToPos.transport)
- if (TransportBase* trans = me->GetDirectTransport())
- trans->CalculatePassengerPosition(dest.x, dest.y, dest.z);
-
- me->GetMotionMaster()->MovePoint(e.action.moveToPos.pointId, dest.x, dest.y, dest.z, true, true,
- isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE, e.target.o);
- }
- else // Xinef: we can use dest.x, dest.y, dest.z to make offset
- {
- float x, y, z;
- target->GetPosition(x, y, z);
- if (e.action.moveToPos.ContactDistance > 0)
+ // Can use target floats as offset
+ default:
{
- target->GetNearPoint(me, x, y, z, e.action.moveToPos.ContactDistance, 0, target->GetAngle(me));
+ // we want to move to random element
+ if (targets.empty())
+ return;
+ else
+ target = Acore::Containers::SelectRandomContainerElement(targets);
+
+ float x, y, z;
+ target->GetPosition(x, y, z);
+
+ if (e.action.moveToPos.combatReach)
+ target->GetNearPoint(me, x, y, z, target->GetCombatReach() + e.action.moveToPos.ContactDistance, 0, target->GetAngle(me));
+ else if (e.action.moveToPos.ContactDistance)
+ target->GetNearPoint(me, x, y, z, e.action.moveToPos.ContactDistance, 0, target->GetAngle(me));
+
+ me->GetMotionMaster()->MovePoint(e.action.moveToPos.pointId, x + e.target.x, y + e.target.y, z + e.target.z, true, true, isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE);
+
+ break;
}
- me->GetMotionMaster()->MovePoint(e.action.moveToPos.pointId, x + e.target.x, y + e.target.y, z + e.target.z, true, true, isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE);
}
+
break;
}
case SMART_ACTION_MOVE_TO_POS_TARGET:
@@ -1966,7 +2025,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
else if (GameObject* go = target->ToGameObject())
{
- if (IsSmartGO(go))
+ if (IsSmart(go))
CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
}
}
@@ -2053,7 +2112,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
else if (GameObject* go = target->ToGameObject())
{
- if (IsSmartGO(go))
+ if (IsSmart(go))
CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, id, GetLastInvoker());
}
}
@@ -2077,7 +2136,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
else if (GameObject* go = target->ToGameObject())
{
- if (IsSmartGO(go))
+ if (IsSmart(go))
CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, id, GetLastInvoker());
}
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index b9ab57327..82ac3700d 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -76,6 +76,10 @@ public:
void DoFindFriendlyMissingBuff(std::vector& creatures, float range, uint32 spellid) const;
Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly) const;
+ bool IsSmart(Creature* c, bool silent = false) const;
+ bool IsSmart(GameObject* g, bool silent = false) const;
+ bool IsSmart(bool silent = false) const;
+
void StoreTargetList(ObjectVector const& targets, uint32 id)
{
// insert or replace
@@ -83,35 +87,6 @@ public:
_storedTargets.emplace(id, ObjectGuidVector(targets));
}
- bool IsSmart(Creature* c = nullptr)
- {
- bool smart = true;
- if (c && c->GetAIName() != "SmartAI")
- smart = false;
-
- if (!me || me->GetAIName() != "SmartAI")
- smart = false;
-
- if (!smart)
- LOG_ERROR("sql.sql", "SmartScript: Action target Creature(entry: {}) is not using SmartAI, action skipped to prevent crash.", c ? c->GetEntry() : (me ? me->GetEntry() : 0));
-
- return smart;
- }
-
- bool IsSmartGO(GameObject* g = nullptr)
- {
- bool smart = true;
- if (g && g->GetAIName() != "SmartGameObjectAI")
- smart = false;
-
- if (!go || go->GetAIName() != "SmartGameObjectAI")
- smart = false;
- if (!smart)
- LOG_ERROR("sql.sql", "SmartScript: Action target GameObject(entry: {}) is not using SmartGameObjectAI, action skipped to prevent crash.", g ? g->GetEntry() : (go ? go->GetEntry() : 0));
-
- return smart;
- }
-
ObjectVector const* GetStoredTargetVector(uint32 id, WorldObject const& ref) const
{
auto itr = _storedTargets.find(id);
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index 1f2c3ae9b..a3d759a6d 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -346,6 +346,7 @@ void SmartAIMgr::LoadSmartAIFromDB()
case SMART_EVENT_TRANSPORT_ADDCREATURE:
case SMART_EVENT_NEAR_PLAYERS:
case SMART_EVENT_SUMMONED_UNIT_EVADE:
+ case SMART_EVENT_DATA_SET:
return true;
default:
return false;
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 66d0deaa9..1d65711e3 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -978,6 +978,7 @@ struct SmartAction
{
uint32 delay;
uint32 forceRespawnTimer;
+ SAIBool removeObjectFromWorld;
} forceDespawn;
struct
@@ -1201,6 +1202,7 @@ struct SmartAction
SAIBool transport;
uint32 controlled;
uint32 ContactDistance;
+ uint32 combatReach;
} moveToPos;
struct
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 170782631..57836678c 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -33,6 +33,7 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
+#include
Player* ChatHandler::GetPlayer() const
{
@@ -888,3 +889,105 @@ int CliHandler::GetSessionDbLocaleIndex() const
{
return sObjectMgr->GetDBCLocaleIndex();
}
+
+bool AddonChannelCommandHandler::ParseCommands(std::string_view str)
+{
+ if (memcmp(str.data(), "AzerothCore\t", 12))
+ return false;
+ char opcode = str[12];
+ if (!opcode) // str[12] is opcode
+ return false;
+ if (!str[13] || !str[14] || !str[15] || !str[16]) // str[13] through str[16] is 4-character command counter
+ return false;
+ echo = str.substr(13);
+
+ switch (opcode)
+ {
+ case 'p': // p Ping
+ SendAck();
+ return true;
+ case 'h': // h Issue human-readable command
+ case 'i': // i Issue command
+ if (!str[17])
+ return false;
+ humanReadable = (opcode == 'h');
+ if (_ParseCommands(str.substr(17))) // actual command starts at str[17]
+ {
+ if (!hadAck)
+ SendAck();
+ if (HasSentErrorMessage())
+ SendFailed();
+ else
+ SendOK();
+ }
+ else
+ {
+ SendSysMessage(LANG_CMD_INVALID);
+ SendFailed();
+ }
+ return true;
+ default:
+ return false;
+ }
+}
+
+void AddonChannelCommandHandler::Send(std::string const& msg)
+{
+ WorldPacket data;
+ ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, LANG_ADDON, GetSession()->GetPlayer(), GetSession()->GetPlayer(), msg);
+ GetSession()->SendPacket(&data);
+}
+
+void AddonChannelCommandHandler::SendAck() // a Command acknowledged, no body
+{
+ ASSERT(echo.size());
+ std::string ack = "AzerothCore\ta";
+ ack.resize(18);
+ memcpy(&ack[13], echo.data(), 4);
+ ack[17] = '\0';
+ Send(ack);
+ hadAck = true;
+}
+
+void AddonChannelCommandHandler::SendOK() // o Command OK, no body
+{
+ ASSERT(echo.size());
+ std::string ok = "AzerothCore\to";
+ ok.resize(18);
+ memcpy(&ok[13], echo.data(), 4);
+ ok[17] = '\0';
+ Send(ok);
+}
+
+void AddonChannelCommandHandler::SendFailed() // f Command failed, no body
+{
+ ASSERT(echo.size());
+ std::string fail = "AzerothCore\tf";
+ fail.resize(18);
+ memcpy(&fail[13], echo.data(), 4);
+ fail[17] = '\0';
+ Send(fail);
+}
+
+// m Command message, message in body
+void AddonChannelCommandHandler::SendSysMessage(std::string_view str, bool escapeCharacters)
+{
+ ASSERT(echo.size());
+ if (!hadAck)
+ SendAck();
+
+ std::string msg = "AzerothCore\tm";
+ msg.append(echo.data(), 4);
+ std::string body(str);
+ if (escapeCharacters)
+ boost::replace_all(body, "|", "||");
+ size_t pos, lastpos;
+ for (lastpos = 0, pos = body.find('\n', lastpos); pos != std::string::npos; lastpos = pos + 1, pos = body.find('\n', lastpos))
+ {
+ std::string line(msg);
+ line.append(body, lastpos, pos - lastpos);
+ Send(line);
+ }
+ msg.append(body, lastpos, pos - lastpos);
+ Send(msg);
+}
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index d6f91bb86..c4873f2cc 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -168,4 +168,24 @@ private:
Print* m_print;
};
+class AC_GAME_API AddonChannelCommandHandler : public ChatHandler
+{
+ public:
+ using ChatHandler::ChatHandler;
+ bool ParseCommands(std::string_view str) override;
+ void SendSysMessage(std::string_view str, bool escapeCharacters) override;
+ using ChatHandler::SendSysMessage;
+ bool IsHumanReadable() const override { return humanReadable; }
+
+ private:
+ void Send(std::string const& msg);
+ void SendAck();
+ void SendOK();
+ void SendFailed();
+
+ std::string echo;
+ bool hadAck = false;
+ bool humanReadable = false;
+};
+
#endif
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 8b98e0b8b..805fcd06d 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -1054,10 +1054,10 @@ void ConditionMgr::LoadConditions(bool isReload)
LootTemplates_Spell.ResetConditions();
LootTemplates_Player.ResetConditions();
- LOG_INFO("server.loading", "Re-Loading `gossip_menu` Table for Conditions!");
+ LOG_INFO("server.loading", "Reloading `gossip_menu` Table for Conditions!");
sObjectMgr->LoadGossipMenu();
- LOG_INFO("server.loading", "Re-Loading `gossip_menu_option` Table for Conditions!");
+ LOG_INFO("server.loading", "Reloading `gossip_menu_option` Table for Conditions!");
sObjectMgr->LoadGossipMenuItems();
sSpellMgr->UnloadSpellInfoImplicitTargetConditionLists();
}
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 98389c5c2..113199ead 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -170,7 +170,7 @@ DBCStorage sSpellFocusObjectStore(SpellFocusObjectfmt);
DBCStorage sSpellRadiusStore(SpellRadiusfmt);
DBCStorage sSpellRangeStore(SpellRangefmt);
DBCStorage sSpellRuneCostStore(SpellRuneCostfmt);
-DBCStorage sSpellShapeshiftStore(SpellShapeshiftfmt);
+DBCStorage sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt);
DBCStorage sSpellVisualStore(SpellVisualfmt);
DBCStorage sStableSlotPricesStore(StableSlotPricesfmt);
DBCStorage sSummonPropertiesStore(SummonPropertiesfmt);
@@ -375,7 +375,7 @@ void LoadDBCStores(const std::string& dataPath)
LOAD_DBC(sSpellRadiusStore, "SpellRadius.dbc", "spellradius_dbc");
LOAD_DBC(sSpellRangeStore, "SpellRange.dbc", "spellrange_dbc");
LOAD_DBC(sSpellRuneCostStore, "SpellRuneCost.dbc", "spellrunecost_dbc");
- LOAD_DBC(sSpellShapeshiftStore, "SpellShapeshiftForm.dbc", "spellshapeshiftform_dbc");
+ LOAD_DBC(sSpellShapeshiftFormStore, "SpellShapeshiftForm.dbc", "spellshapeshiftform_dbc");
LOAD_DBC(sSpellVisualStore, "SpellVisual.dbc", "spellvisual_dbc");
LOAD_DBC(sStableSlotPricesStore, "StableSlotPrices.dbc", "stableslotprices_dbc");
LOAD_DBC(sSummonPropertiesStore, "SummonProperties.dbc", "summonproperties_dbc");
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index 20b9b0e29..5e93bce70 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -139,7 +139,7 @@ extern DBCStorage sItemLimitCategoryStore;
extern DBCStorage sItemRandomPropertiesStore;
extern DBCStorage sItemRandomSuffixStore;
extern DBCStorage sItemSetStore;
-extern DBCStorage sLFGDungeonStore;
+extern DBCStorage sLFGDungeonStore;
extern DBCStorage sLiquidTypeStore;
extern DBCStorage sLockStore;
extern DBCStorage sMailTemplateStore;
@@ -175,7 +175,7 @@ extern std::unordered_set sPetTalentSpells;
extern DBCStorage sSpellRadiusStore;
extern DBCStorage sSpellRangeStore;
extern DBCStorage sSpellRuneCostStore;
-extern DBCStorage sSpellShapeshiftStore;
+extern DBCStorage sSpellShapeshiftFormStore;
extern DBCStorage sSpellStore;
extern DBCStorage sSpellVisualStore;
extern DBCStorage sStableSlotPricesStore;
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 0db064434..44776dc46 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2173,15 +2173,6 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const
&& dz < (info->maxZ * scale) + radius && dz > (info->minZ * scale) - radius;
}
-void GameObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin, Player const* skipped_rcvr) const
-{
- dist += GetObjectSize();
- if (includeMargin)
- dist += VISIBILITY_COMPENSATION * 2.0f; // pussywizard: to ensure everyone receives all important packets
- Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr);
- Cell::VisitWorldObjects(this, notifier, dist);
-}
-
void GameObject::EventInform(uint32 eventId)
{
if (!eventId)
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index ed47aa084..678052b14 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -289,8 +289,6 @@ public:
void SendCustomAnim(uint32 anim);
[[nodiscard]] bool IsInRange(float x, float y, float z, float radius) const;
- void SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const override; // pussywizard!
-
void ModifyHealth(int32 change, Unit* attackerOrHealer = nullptr, uint32 spellId = 0);
void SetDestructibleBuildingModifyState(bool allow) { m_allowModifyDestructibleBuilding = allow; }
// sets GameObject type 33 destruction flags and optionally default health for that state
diff --git a/src/server/game/Entities/Item/enuminfo_Item.cpp b/src/server/game/Entities/Item/enuminfo_Item.cpp
index d43ff6470..a7b1ecc35 100644
--- a/src/server/game/Entities/Item/enuminfo_Item.cpp
+++ b/src/server/game/Entities/Item/enuminfo_Item.cpp
@@ -15,8 +15,8 @@
* with this program. If not, see .
*/
-#include "Define.h"
#include "Item.h"
+#include "Define.h"
#include "SmartEnum.h"
#include
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 5f505655d..e6b60ffca 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2077,15 +2077,24 @@ void Unit::BuildHeartBeatMsg(WorldPacket* data) const
BuildMovementPacket(data);
}
-void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin, Player const* skipped_rcvr) const
+void WorldObject::SendMessageToSet(WorldPacket const* data, bool self) const
{
- dist += GetObjectSize();
- if (includeMargin)
- dist += VISIBILITY_COMPENSATION; // pussywizard: to ensure everyone receives all important packets
- Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr);
+ if (IsInWorld())
+ SendMessageToSetInRange(data, GetVisibilityRange(), self);
+}
+
+void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/) const
+{
+ Acore::MessageDistDeliverer notifier(this, data, dist);
Cell::VisitWorldObjects(this, notifier, dist);
}
+void WorldObject::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const
+{
+ Acore::MessageDistDeliverer notifier(this, data, GetVisibilityRange(), false, skipped_rcvr);
+ Cell::VisitWorldObjects(this, notifier, GetVisibilityRange());
+}
+
void WorldObject::SendObjectDeSpawnAnim(ObjectGuid guid)
{
WorldPacket data(SMSG_GAMEOBJECT_DESPAWN_ANIM, 8);
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index f9a9ac69c..6dd7f0d7f 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -479,9 +479,9 @@ public:
virtual void CleanupsBeforeDelete(bool finalCleanup = true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
- virtual void SendMessageToSet(WorldPacket const* data, bool self) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), self, true); } // pussywizard!
- virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const; // pussywizard!
- virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), false, true, skipped_rcvr); } // pussywizard!
+ virtual void SendMessageToSet(WorldPacket const* data, bool self) const;
+ virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) const;
+ virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const;
virtual uint8 getLevelForTarget(WorldObject const* /*target*/) const { return 1; }
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index a998afa57..0f77f0c97 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -394,7 +394,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
// Send fake summon spell cast - this is needed for correct cooldown application for spells
// Example: 46584 - without this cooldown (which should be set always when pet is loaded) isn't set clientside
/// @todo pets should be summoned from real cast instead of just faking it?
- if (petInfo->CreatedBySpellId)
+ if (petInfo->CreatedBySpellId && spellInfo && (spellInfo->CategoryRecoveryTime > 0 || spellInfo->RecoveryTime > 0))
{
WorldPacket data(SMSG_SPELL_GO, (8 + 8 + 4 + 4 + 2));
data << owner->GetPackGUID();
@@ -2499,11 +2499,6 @@ float Pet::GetNativeObjectScale() const
{
uint8 ctFamily = GetCreatureTemplate()->family;
- // hackfix: Edge case where DBC scale values for DEVILSAUR pets make them too small.
- // Therefore we take data from spirit beast instead.
- if (ctFamily && ctFamily == CREATURE_FAMILY_DEVILSAUR)
- ctFamily = CREATURE_FAMILY_SPIRIT_BEAST;
-
CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(ctFamily);
if (creatureFamily && creatureFamily->minScale > 0.0f && getPetType() & HUNTER_PET)
{
@@ -2520,6 +2515,13 @@ float Pet::GetNativeObjectScale() const
float scale = (creatureFamily->maxScale - creatureFamily->minScale) * scaleMod + creatureFamily->minScale;
+ scale = std::min(scale, creatureFamily->maxScale);
+
+ if (CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId()))
+ {
+ if (scale < 1.f && displayInfo->scale > 1.f)
+ scale *= displayInfo->scale;
+ }
return scale;
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 24a8faa95..c127095fc 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -5612,25 +5612,40 @@ void Player::SaveRecallPosition()
m_recallO = GetOrientation();
}
-void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin, Player const* skipped_rcvr) const
+void Player::SendMessageToSet(WorldPacket const* data, bool self) const
+{
+ SendMessageToSetInRange(data, GetVisibilityRange(), self);
+}
+
+void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) const
{
if (self)
- GetSession()->SendPacket(data);
+ SendDirectMessage(data);
+
+ Acore::MessageDistDeliverer notifier(this, data, dist);
+ Cell::VisitWorldObjects(this, notifier, dist);
+}
+
+void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin, bool ownTeamOnly, bool required3dDist) const
+{
+ if (self)
+ SendDirectMessage(data);
dist += GetObjectSize();
if (includeMargin)
dist += VISIBILITY_COMPENSATION; // pussywizard: to ensure everyone receives all important packets
- Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr);
+
+ Acore::MessageDistDeliverer notifier(this, data, dist, ownTeamOnly, nullptr, required3dDist);
Cell::VisitWorldObjects(this, notifier, dist);
}
-void Player::SendMessageToSetInRange_OwnTeam(WorldPacket const* data, float dist, bool self) const
+void Player::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const
{
- if (self)
- GetSession()->SendPacket(data);
+ if (skipped_rcvr != this)
+ SendDirectMessage(data);
- Acore::MessageDistDeliverer notifier(this, data, dist, true);
- Cell::VisitWorldObjects(this, notifier, dist);
+ Acore::MessageDistDeliverer notifier(this, data, GetVisibilityRange(), false, skipped_rcvr);
+ Cell::VisitWorldObjects(this, notifier, GetVisibilityRange());
}
void Player::SendDirectMessage(WorldPacket const* data) const
@@ -9291,7 +9306,7 @@ void Player::Say(std::string_view text, Language language, WorldObject const* /*
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, language, this, this, _text);
- SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
+ SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true, false, false, true);
}
void Player::Say(uint32 textId, WorldObject const* target /*= nullptr*/)
@@ -9312,7 +9327,7 @@ void Player::Yell(std::string_view text, Language language, WorldObject const* /
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, language, this, this, _text);
- SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true);
+ SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true, false, false, true);
}
void Player::Yell(uint32 textId, WorldObject const* target /*= nullptr*/)
@@ -9334,14 +9349,7 @@ void Player::TextEmote(std::string_view text, WorldObject const* /*= nullptr*/,
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text);
- if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_EMOTE))
- {
- SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true);
- }
- else
- {
- SendMessageToSetInRange_OwnTeam(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true);
- }
+ SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, false, !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_EMOTE), true);
}
void Player::TextEmote(uint32 textId, WorldObject const* target /*= nullptr*/, bool /*isBossEmote = false*/)
@@ -10521,7 +10529,7 @@ void Player::InitDataForForm(bool reapplyMods)
{
ShapeshiftForm form = GetShapeshiftForm();
- SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(form);
+ SpellShapeshiftFormEntry const* ssEntry = sSpellShapeshiftFormStore.LookupEntry(form);
if (ssEntry && ssEntry->attackSpeed)
{
SetAttackTime(BASE_ATTACK, ssEntry->attackSpeed);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 3f3eb95c9..7c8fdf844 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2000,11 +2000,10 @@ public:
void ProcessTerrainStatusUpdate() override;
- void SendMessageToSet(WorldPacket const* data, bool self) const override { SendMessageToSetInRange(data, GetVisibilityRange(), self, true); } // pussywizard!
- void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const override; // pussywizard!
- void SendMessageToSetInRange_OwnTeam(WorldPacket const* data, float dist, bool self) const; // pussywizard! param includeMargin not needed here
- void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const override { SendMessageToSetInRange(data, GetVisibilityRange(), skipped_rcvr != this, true, skipped_rcvr); } // pussywizard!
-
+ void SendMessageToSet(WorldPacket const* data, bool self) const override;
+ void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) const override;
+ void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin, bool ownTeamOnly, bool required3dDist = false) const;
+ void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const override;
void SendTeleportAckPacket();
[[nodiscard]] Corpse* GetCorpse() const;
diff --git a/src/server/game/Entities/Player/PlayerQuest.cpp b/src/server/game/Entities/Player/PlayerQuest.cpp
index 329bb7ca9..2da11b7df 100644
--- a/src/server/game/Entities/Player/PlayerQuest.cpp
+++ b/src/server/game/Entities/Player/PlayerQuest.cpp
@@ -753,7 +753,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
else
{
sScriptMgr->OnGivePlayerXP(this, XP, nullptr, isLFGReward ? PlayerXPSource::XPSOURCE_QUEST_DF : PlayerXPSource::XPSOURCE_QUEST);
- GiveXP(XP, nullptr, isLFGReward);
+ GiveXP(XP, nullptr, 1.0f, isLFGReward);
}
// Give player extra money if GetRewOrReqMoney > 0 and get ReqMoney if negative
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index f4504bda5..3e3984c31 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3453,7 +3453,8 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spell, bool Ca
return SPELL_MISS_NONE;
// Return evade for units in evade mode
- if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks() && !spell->HasAura(SPELL_AURA_CONTROL_VEHICLE) && !spell->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE))
+ if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks() && !spell->HasAura(SPELL_AURA_CONTROL_VEHICLE)
+ && !spell->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) && !spell->HasAttribute(SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT))
return SPELL_MISS_EVADE;
// Try victim reflect spell
@@ -3528,7 +3529,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, Spell const* spell, bool CanRef
// Return evade for units in evade mode
if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks() && !spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) &&
- !spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE))
+ !spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) && !spellInfo->HasAttribute(SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT))
{
return SPELL_MISS_EVADE;
}
@@ -5384,7 +5385,8 @@ void Unit::RemoveEvadeAuras()
{
Aura const* aura = iter->second->GetBase();
SpellInfo const* spellInfo = aura->GetSpellInfo();
- if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) || spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) || spellInfo->HasAura(SPELL_AURA_CLONE_CASTER) || (aura->IsPassive() && GetOwnerGUID().IsPlayer()))
+ if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) || spellInfo->HasAttribute(SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT) || spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE)
+ || spellInfo->HasAura(SPELL_AURA_CLONE_CASTER) || (aura->IsPassive() && GetOwnerGUID().IsPlayer()))
++iter;
else
_UnapplyAura(iter, AURA_REMOVE_BY_DEFAULT);
@@ -5394,7 +5396,8 @@ void Unit::RemoveEvadeAuras()
{
Aura* aura = iter->second;
SpellInfo const* spellInfo = aura->GetSpellInfo();
- if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) || spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) || spellInfo->HasAura(SPELL_AURA_CLONE_CASTER) || (aura->IsPassive() && GetOwnerGUID().IsPlayer()))
+ if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) || spellInfo->HasAttribute(SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT) || spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE)
+ || spellInfo->HasAura(SPELL_AURA_CLONE_CASTER) || (aura->IsPassive() && GetOwnerGUID().IsPlayer()))
++iter;
else
RemoveOwnedAura(iter, AURA_REMOVE_BY_DEFAULT);
@@ -15190,7 +15193,7 @@ uint32 Unit::GetCreatureType() const
if (GetTypeId() == TYPEID_PLAYER)
{
ShapeshiftForm form = GetShapeshiftForm();
- SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(form);
+ SpellShapeshiftFormEntry const* ssEntry = sSpellShapeshiftFormStore.LookupEntry(form);
if (ssEntry && ssEntry->creatureType > 0)
return ssEntry->creatureType;
else
@@ -19677,7 +19680,7 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form, uint32 spellId) const
}
uint32 modelid = 0;
- SpellShapeshiftEntry const* formEntry = sSpellShapeshiftStore.LookupEntry(form);
+ SpellShapeshiftFormEntry const* formEntry = sSpellShapeshiftFormStore.LookupEntry(form);
if (formEntry && formEntry->modelID_A)
{
// Take the alliance modelid as default
@@ -21613,7 +21616,7 @@ bool Unit::IsInDisallowedMountForm() const
if (ShapeshiftForm form = GetShapeshiftForm())
{
- SpellShapeshiftEntry const* shapeshift = sSpellShapeshiftStore.LookupEntry(form);
+ SpellShapeshiftFormEntry const* shapeshift = sSpellShapeshiftFormStore.LookupEntry(form);
if (!shapeshift)
{
return true;
@@ -21656,6 +21659,20 @@ bool Unit::IsInDisallowedMountForm() const
return false;
}
+void Unit::SetUInt32Value(uint16 index, uint32 value)
+{
+ Object::SetUInt32Value(index, value);
+
+ switch (index)
+ {
+ // Invalidating the cache on health change should fix an issue where the client sees dead NPCs when they are not.
+ // We might also need to invalidate the cache for some other fields as well.
+ case UNIT_FIELD_HEALTH:
+ InvalidateValuesUpdateCache();
+ break;
+ }
+}
+
std::string Unit::GetDebugInfo() const
{
std::stringstream sstr;
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 4ac796c90..fb62a18d8 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1571,6 +1571,8 @@ public:
void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply);
void ApplyCastTimePercentMod(float val, bool apply);
+ void SetUInt32Value(uint16 index, uint32 value);
+
UnitFlags GetUnitFlags() const { return UnitFlags(GetUInt32Value(UNIT_FIELD_FLAGS)); }
bool HasUnitFlag(UnitFlags flags) const { return HasFlag(UNIT_FIELD_FLAGS, flags); }
void SetUnitFlag(UnitFlags flags) { SetFlag(UNIT_FIELD_FLAGS, flags); }
diff --git a/src/server/game/Entities/Unit/enuminfo_Unit.cpp b/src/server/game/Entities/Unit/enuminfo_Unit.cpp
index bd16ebd35..a3c4938c6 100644
--- a/src/server/game/Entities/Unit/enuminfo_Unit.cpp
+++ b/src/server/game/Entities/Unit/enuminfo_Unit.cpp
@@ -15,9 +15,9 @@
* with this program. If not, see .
*/
+#include "Unit.h"
#include "Define.h"
#include "SmartEnum.h"
-#include "Unit.h"
#include
namespace Acore::Impl::EnumUtilsImpl
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
index db2ad0a67..42661e934 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
@@ -217,8 +217,14 @@ void MessageDistDeliverer::Visit(PlayerMapType& m)
if (!target->InSamePhase(i_phaseMask))
continue;
- if (target->GetExactDist2dSq(i_source) > i_distSq)
- continue;
+ if (required3dDist)
+ {
+ if (target->GetExactDistSq(i_source) > i_distSq)
+ continue;
+ }
+ else
+ if (target->GetExactDist2dSq(i_source) > i_distSq)
+ continue;
// Send packet to all who are sharing the player's vision
if (target->HasSharedVision())
@@ -242,8 +248,14 @@ void MessageDistDeliverer::Visit(CreatureMapType& m)
if (!target->HasSharedVision() || !target->InSamePhase(i_phaseMask))
continue;
- if (target->GetExactDist2dSq(i_source) > i_distSq)
- continue;
+ if (required3dDist)
+ {
+ if (target->GetExactDistSq(i_source) > i_distSq)
+ continue;
+ }
+ else
+ if (target->GetExactDist2dSq(i_source) > i_distSq)
+ continue;
// Send packet to all who are sharing the creature's vision
SharedVisionList::const_iterator i = target->GetSharedVisionList().begin();
@@ -265,8 +277,14 @@ void MessageDistDeliverer::Visit(DynamicObjectMapType& m)
if (!target->IsViewpoint())
continue;
- if (target->GetExactDist2dSq(i_source) > i_distSq)
- continue;
+ if (required3dDist)
+ {
+ if (target->GetExactDistSq(i_source) > i_distSq)
+ continue;
+ }
+ else
+ if (target->GetExactDist2dSq(i_source) > i_distSq)
+ continue;
// Send packet back to the caster if the caster has vision of dynamic object
Player* caster = (Player*)target->GetCaster();
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index e06b9091f..97189e16c 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -102,10 +102,11 @@ namespace Acore
float i_distSq;
TeamId teamId;
Player const* skipped_receiver;
- MessageDistDeliverer(WorldObject const* src, WorldPacket const* msg, float dist, bool own_team_only = false, Player const* skipped = nullptr)
+ bool required3dDist;
+ MessageDistDeliverer(WorldObject const* src, WorldPacket const* msg, float dist, bool own_team_only = false, Player const* skipped = nullptr, bool req3dDist = false)
: i_source(src), i_message(msg), i_phaseMask(src->GetPhaseMask()), i_distSq(dist * dist)
, teamId((own_team_only && src->GetTypeId() == TYPEID_PLAYER) ? src->ToPlayer()->GetTeamId() : TEAM_NEUTRAL)
- , skipped_receiver(skipped)
+ , skipped_receiver(skipped), required3dDist(req3dDist)
{
}
void Visit(PlayerMapType& m);
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 8db5f3740..c9e8a5896 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -41,6 +41,8 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
+#include "ArenaTeam.h"
+#include "ArenaTeamMgr.h"
Roll::Roll(ObjectGuid _guid, LootItem const& li) : itemGUID(_guid), itemid(li.itemid),
itemRandomPropId(li.randomPropertyId), itemRandomSuffix(li.randomSuffix), itemCount(li.count),
@@ -896,7 +898,7 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p,
p->GetSession()->SendPacket(&data);
}
-void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll)
+void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll, bool autoPass)
{
WorldPacket data(SMSG_LOOT_ROLL, (8 + 4 + 8 + 4 + 4 + 4 + 1 + 1 + 1));
data << sourceGuid; // guid of the item rolled
@@ -907,7 +909,7 @@ void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rol
data << uint32(roll.itemRandomPropId); // Item random property ID
data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
- data << uint8(0); // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed
+ data << uint8(autoPass); // 1: "You automatically passed on: %s because you cannot loot that item."
for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
@@ -984,6 +986,23 @@ void Group::SendLooter(Creature* creature, Player* groupLooter)
BroadcastPacket(&data, false);
}
+bool CanRollOnItem(LootItem const& item, Player const* player, Loot* loot)
+{
+ // Players can't roll on unique items if they already reached the maximum quantity of that item
+ ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid);
+ if (!proto)
+ return false;
+
+ uint32 itemCount = player->GetItemCount(item.itemid);
+ if ((proto->MaxCount > 0 && static_cast(itemCount) >= proto->MaxCount) || (player->CanEquipUniqueItem(proto) != EQUIP_ERR_OK))
+ return false;
+
+ if (!item.AllowedForPlayer(player, loot->sourceWorldObjectGUID))
+ return false;
+
+ return true;
+}
+
void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
{
std::vector::iterator i;
@@ -1011,23 +1030,20 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* member = itr->GetSource();
- if (!member)
+ if (!member || !member->GetSession())
continue;
if (member->IsAtLootRewardDistance(pLootedObject))
{
- if (i->AllowedForPlayer(member, loot->sourceWorldObjectGUID))
- {
- r->totalPlayersRolling++;
+ r->totalPlayersRolling++;
- if (member->GetPassOnGroupLoot())
- {
- r->playerVote[member->GetGUID()] = PASS;
- r->totalPass++;
- // can't broadcast the pass now. need to wait until all rolling players are known.
- }
- else
- r->playerVote[member->GetGUID()] = NOT_EMITED_YET;
+ RollVote vote = member->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
+ if (!CanRollOnItem(*i, member, loot))
+ {
+ vote = PASS;
+ ++r->totalPass;
}
+
+ r->playerVote[member->GetGUID()] = vote;
}
}
@@ -1050,23 +1066,28 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
continue;
if (itr->second == PASS)
- SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
+ SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r, true);
}
}
- SendLootStartRoll(60000, pLootedObject->GetMapId(), *r);
-
- RollId.push_back(r);
-
- if (Creature* creature = pLootedObject->ToCreature())
+ if (r->totalPass == r->totalPlayersRolling)
+ delete r;
+ else
{
- creature->m_groupLootTimer = 60000;
- creature->lootingGroupLowGUID = GetGUID().GetCounter();
- }
- else if (GameObject* go = pLootedObject->ToGameObject())
- {
- go->m_groupLootTimer = 60000;
- go->lootingGroupLowGUID = GetGUID().GetCounter();
+ SendLootStartRoll(60000, pLootedObject->GetMapId(), *r);
+
+ RollId.push_back(r);
+
+ if (Creature* creature = pLootedObject->ToCreature())
+ {
+ creature->m_groupLootTimer = 60000;
+ creature->lootingGroupLowGUID = GetGUID().GetCounter();
+ }
+ else if (GameObject* go = pLootedObject->ToGameObject())
+ {
+ go->m_groupLootTimer = 60000;
+ go->lootingGroupLowGUID = GetGUID().GetCounter();
+ }
}
}
else
@@ -1094,16 +1115,18 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* member = itr->GetSource();
- if (!member)
+ if (!member || !member->GetSession())
continue;
if (member->IsAtLootRewardDistance(pLootedObject))
{
- if (i->AllowedForPlayer(member, loot->sourceWorldObjectGUID))
+ RollVote vote = NOT_EMITED_YET;
+ if (!CanRollOnItem(*i, member, loot))
{
- r->totalPlayersRolling++;
- r->playerVote[member->GetGUID()] = NOT_EMITED_YET;
+ vote = PASS;
+ ++r->totalPass;
}
+ r->playerVote[member->GetGUID()] = vote;
}
}
@@ -1154,20 +1177,21 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* playerToRoll = itr->GetSource();
- if (!playerToRoll)
+ if (!playerToRoll || !playerToRoll->GetSession())
continue;
- if (i->AllowedForPlayer(playerToRoll, loot->sourceWorldObjectGUID) && playerToRoll->IsAtLootRewardDistance(lootedObject))
+ if (playerToRoll->IsAtGroupRewardDistance(lootedObject))
{
r->totalPlayersRolling++;
- if (playerToRoll->GetPassOnGroupLoot())
+
+ RollVote vote = playerToRoll->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
+ if (!CanRollOnItem(*i, playerToRoll, loot))
{
- r->playerVote[playerToRoll->GetGUID()] = PASS;
- r->totalPass++;
- // can't broadcast the pass now. need to wait until all rolling players are known.
+ vote = PASS;
+ r->totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known
}
- else
- r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
+
+ r->playerVote[playerToRoll->GetGUID()] = vote;
}
}
@@ -1228,13 +1252,21 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* playerToRoll = itr->GetSource();
- if (!playerToRoll)
+ if (!playerToRoll || !playerToRoll->GetSession())
continue;
- if (i->AllowedForPlayer(playerToRoll, loot->sourceWorldObjectGUID) && playerToRoll->IsAtLootRewardDistance(lootedObject))
+ if (playerToRoll->IsAtGroupRewardDistance(lootedObject))
{
r->totalPlayersRolling++;
- r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
+
+ RollVote vote = playerToRoll->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
+ if (!CanRollOnItem(*i, playerToRoll, loot))
+ {
+ vote = PASS;
+ r->totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known
+ }
+
+ r->playerVote[playerToRoll->GetGUID()] = vote;
}
}
@@ -1996,6 +2028,35 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
if (bgTemplate->isArena() && memberscount != MinPlayerCount)
return ERR_ARENA_TEAM_PARTY_SIZE;
+ //check against other arena team members
+ if (isRated)
+ {
+ ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
+ for (auto const& itr : arenaTeam->GetMembers())
+ {
+ Player* teamMember = ObjectAccessor::FindConnectedPlayer(itr.Guid);
+ //are they online and not a member of this current group?
+ if (teamMember && !IsMember(teamMember->GetGUID()))
+ {
+ //are they already in queue for a rated arena?
+ if (teamMember->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId))
+ {
+ GroupQueueInfo ginfo;
+ BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
+ if (queue.GetPlayerGroupInfoData(teamMember->GetGUID(), &ginfo))
+ {
+ if (ginfo.IsRated)
+ return ERR_BATTLEGROUND_JOIN_FAILED;
+ }
+ }
+ //are they currently in an arena match?
+ Battleground* bg = teamMember->GetBattleground(false);
+ if (bg && bg->isRated() && bg->GetMinPlayersPerTeam() == MinPlayerCount)
+ return ERR_BATTLEGROUND_JOIN_FAILED;
+ }
+ }
+ }
+
return GroupJoinBattlegroundResult(bgTemplate->GetBgTypeID());
}
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index ffb7f2f2e..e07360342 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -288,7 +288,7 @@ public:
bool isRollLootActive() const;
void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll& r);
void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r);
- void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, const Roll& r);
+ void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, const Roll& r, bool autoPass = false);
void SendLootRollWon(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, const Roll& r);
void SendLootAllPassed(Roll const& roll);
void SendLooter(Creature* creature, Player* pLooter);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 53c476b90..4f8a3c782 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -889,6 +889,9 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder)
pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation());
else
pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation());
+
+ // Probably a hackfix, but currently the best workaround to prevent character names showing as Unknown after teleport out from instances at login.
+ pCurrChar->GetSession()->SendNameQueryOpcode(pCurrChar->GetGUID());
}
pCurrChar->SendInitialPacketsAfterAddToMap();
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index ffd54a76b..cd677556e 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -283,14 +283,22 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
if (msg.empty())
return;
- if (ChatHandler(this).ParseCommands(msg.c_str()))
- return;
-
- if (!_player->CanSpeak())
+ if (lang == LANG_ADDON)
{
- std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count());
- SendNotification(GetAcoreString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
- return;
+ if (AddonChannelCommandHandler(this).ParseCommands(msg.c_str()))
+ return;
+ }
+ else
+ {
+ if (ChatHandler(this).ParseCommands(msg.c_str()))
+ return;
+
+ if (!_player->CanSpeak())
+ {
+ std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count());
+ SendNotification(GetAcoreString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
+ return;
+ }
}
}
diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp
index 0150c83e4..6a92526de 100644
--- a/src/server/game/Handlers/CombatHandler.cpp
+++ b/src/server/game/Handlers/CombatHandler.cpp
@@ -84,9 +84,12 @@ void WorldSession::HandleSetSheathedOpcode(WorldPackets::Combat::SetSheathed& pa
void WorldSession::SendAttackStop(Unit const* enemy)
{
- WorldPacket data(SMSG_ATTACKSTOP, (8 + 8 + 4)); // we guess size
+ WorldPacket data(SMSG_ATTACKSTOP, (8 + 8 + 4)); // we guess size
data << GetPlayer()->GetPackGUID();
- data << (enemy ? enemy->GetPackGUID() : PackedGuid()); // must be packed guid
- data << uint32(0); // unk, can be 1 also
+ if (enemy)
+ {
+ data << enemy->GetPackGUID(); // must be packed guid
+ data << enemy->isDead();
+ }
SendPacket(&data);
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index d78da716b..b76bc49b9 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -3069,7 +3069,7 @@ void InstanceMap::CreateInstanceScript(bool load, std::string data, uint32 compl
bool isOtherAI = false;
- sScriptMgr->OnBeforeCreateInstanceScript(this, instance_data, load, data, completedEncounterMask);
+ sScriptMgr->OnBeforeCreateInstanceScript(this, &instance_data, load, data, completedEncounterMask);
if (instance_data)
isOtherAI = true;
diff --git a/src/server/game/Quests/enuminfo_QuestDef.cpp b/src/server/game/Quests/enuminfo_QuestDef.cpp
index cf4651adc..aec7b5de3 100644
--- a/src/server/game/Quests/enuminfo_QuestDef.cpp
+++ b/src/server/game/Quests/enuminfo_QuestDef.cpp
@@ -15,8 +15,8 @@
* with this program. If not, see .
*/
-#include "Define.h"
#include "QuestDef.h"
+#include "Define.h"
#include "SmartEnum.h"
#include
diff --git a/src/server/game/Scripting/ScriptDefines/AllMapScript.cpp b/src/server/game/Scripting/ScriptDefines/AllMapScript.cpp
index e35700a12..c778b8fff 100644
--- a/src/server/game/Scripting/ScriptDefines/AllMapScript.cpp
+++ b/src/server/game/Scripting/ScriptDefines/AllMapScript.cpp
@@ -279,7 +279,7 @@ void ScriptMgr::OnMapUpdate(Map* map, uint32 diff)
});
}
-void ScriptMgr::OnBeforeCreateInstanceScript(InstanceMap* instanceMap, InstanceScript* instanceData, bool load, std::string data, uint32 completedEncounterMask)
+void ScriptMgr::OnBeforeCreateInstanceScript(InstanceMap* instanceMap, InstanceScript** instanceData, bool load, std::string data, uint32 completedEncounterMask)
{
ExecuteScript([&](AllMapScript* script)
{
diff --git a/src/server/game/Scripting/ScriptDefines/AllMapScript.h b/src/server/game/Scripting/ScriptDefines/AllMapScript.h
index f97198866..77479fc1b 100644
--- a/src/server/game/Scripting/ScriptDefines/AllMapScript.h
+++ b/src/server/game/Scripting/ScriptDefines/AllMapScript.h
@@ -51,7 +51,7 @@ public:
* @param data Contains information about the instance save data
* @param completedEncounterMask Contains information about the completed encouter mask
*/
- virtual void OnBeforeCreateInstanceScript(InstanceMap* /*instanceMap*/, InstanceScript* /*instanceData*/, bool /*load*/, std::string /*data*/, uint32 /*completedEncounterMask*/) { }
+ virtual void OnBeforeCreateInstanceScript(InstanceMap* /*instanceMap*/, InstanceScript** /*instanceData*/, bool /*load*/, std::string /*data*/, uint32 /*completedEncounterMask*/) { }
/**
* @brief This hook called before destroy instance
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index bed6f0c35..79cad095f 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -605,7 +605,7 @@ public: /* AllGameobjectScript */
void OnGameObjectSaveToDB(GameObject* go);
public: /* AllMapScript */
- void OnBeforeCreateInstanceScript(InstanceMap* instanceMap, InstanceScript* instanceData, bool load, std::string data, uint32 completedEncounterMask);
+ void OnBeforeCreateInstanceScript(InstanceMap* instanceMap, InstanceScript** instanceData, bool load, std::string data, uint32 completedEncounterMask);
void OnDestroyInstance(MapInstanced* mapInstanced, Map* map);
public: /* BGScript */
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 3c7f16d7a..63af8f62b 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -2011,7 +2011,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
if (modelid > 0)
{
bool allow = true;
- if (target->getTransForm())
+ if (target->getTransForm() && !(target->GetMapId() == 560 /*The Escape From Durnholde*/))
if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(target->getTransForm()))
if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) || !transformSpellInfo->IsPositive())
allow = false;
@@ -2143,7 +2143,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
if (target->GetTypeId() == TYPEID_PLAYER)
{
- SpellShapeshiftEntry const* shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
+ SpellShapeshiftFormEntry const* shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form);
// Learn spells for shapeshift form - no need to send action bars or add spells to spellbook
for (uint8 i = 0; i < MAX_SHAPESHIFT_SPELLS; ++i)
{
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 06301226b..8cb33d758 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -5799,7 +5799,7 @@ SpellCastResult Spell::CheckCast(bool strict)
SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
if (effInfo->ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
{
- SpellShapeshiftEntry const* shapeShiftEntry = sSpellShapeshiftStore.LookupEntry(effInfo->MiscValue);
+ SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
break;
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index c90f3a9c4..42455c958 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -1435,10 +1435,10 @@ SpellCastResult SpellInfo::CheckShapeshift(uint32 form) const
return SPELL_CAST_OK;
bool actAsShifted = false;
- SpellShapeshiftEntry const* shapeInfo = nullptr;
+ SpellShapeshiftFormEntry const* shapeInfo = nullptr;
if (form > 0)
{
- shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
+ shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form);
if (!shapeInfo)
{
LOG_ERROR("spells", "GetErrorAtShapeshiftedCast: unknown shapeshift {}", form);
@@ -2437,7 +2437,7 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask, S
if (AttributesEx4 & SPELL_ATTR4_WEAPON_SPEED_COST_SCALING)
{
uint32 speed = 0;
- if (SpellShapeshiftEntry const* ss = sSpellShapeshiftStore.LookupEntry(caster->GetShapeshiftForm()))
+ if (SpellShapeshiftFormEntry const* ss = sSpellShapeshiftFormStore.LookupEntry(caster->GetShapeshiftForm()))
speed = ss->attackSpeed;
else
{
diff --git a/src/server/game/Time/UpdateTime.cpp b/src/server/game/Time/UpdateTime.cpp
index 8aa9592b7..3c4886376 100644
--- a/src/server/game/Time/UpdateTime.cpp
+++ b/src/server/game/Time/UpdateTime.cpp
@@ -165,10 +165,11 @@ void WorldUpdateTime::RecordUpdateTime(Milliseconds gameTimeMs, uint32 diff, uin
{
if (GetMSTimeDiff(_lastRecordTime, gameTimeMs) > _recordUpdateTimeInverval)
{
- LOG_INFO("time.update", "Last {} diffs summary with {} players online:", GetDatasetSize(), sessionCount);
- LOG_INFO("time.update", " - Mean: {};", GetAverageUpdateTime());
- LOG_INFO("time.update", " - Median: {};", GetPercentile(50));
- LOG_INFO("time.update", " - Percentiles (95, 99, max): {}, {}, {}.", GetPercentile(95), GetPercentile(99), GetPercentile(100));
+ LOG_INFO("time.update", "Update time diff: {}ms with {} players online", GetLastUpdateTime(), sessionCount);
+ LOG_INFO("time.update", "Last {} diffs summary:", GetDatasetSize());
+ LOG_INFO("time.update", "|- Mean: {}ms", GetAverageUpdateTime());
+ LOG_INFO("time.update", "|- Median: {}ms", GetPercentile(50));
+ LOG_INFO("time.update", "|- Percentiles (95, 99, max): {}ms, {}ms, {}ms", GetPercentile(95), GetPercentile(99), GetPercentile(100));
_lastRecordTime = gameTimeMs;
}
}
diff --git a/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp b/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp
index f4d906b69..f76872a82 100644
--- a/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp
+++ b/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp
@@ -15,9 +15,9 @@
* with this program. If not, see .
*/
+#include "WardenCheckMgr.h"
#include "Define.h"
#include "SmartEnum.h"
-#include "WardenCheckMgr.h"
#include
namespace Acore::Impl::EnumUtilsImpl
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index 1cd1e0a23..9ea10809b 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -223,7 +223,7 @@ public:
static bool HandleReloadBattlegroundTemplate(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Battleground Templates...");
+ LOG_INFO("server.loading", "Reloading Battleground Templates...");
sBattlegroundMgr->LoadBattlegroundTemplates();
handler->SendGlobalGMSysMessage("DB table `battleground_template` reloaded.");
return true;
@@ -247,7 +247,7 @@ public:
static bool HandleReloadAllLootCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables...");
+ LOG_INFO("server.loading", "Reloading Loot Tables...");
LoadLootTables();
handler->SendGlobalGMSysMessage("DB tables `*_loot_template` reloaded.");
sConditionMgr->LoadConditions(true);
@@ -271,7 +271,7 @@ public:
HandleReloadQuestTemplateCommand(handler);
HandleReloadLocalesQuestGreetingCommand(handler);
- LOG_INFO("server.loading", "Re-Loading Quests Relations...");
+ LOG_INFO("server.loading", "Reloading Quests Relations...");
sObjectMgr->LoadQuestStartersAndEnders();
handler->SendGlobalGMSysMessage("DB tables `*_queststarter` and `*_questender` reloaded.");
return true;
@@ -285,7 +285,7 @@ public:
return false;
}
- LOG_INFO("server.loading", "Re-Loading Scripts...");
+ LOG_INFO("server.loading", "Reloading Scripts...");
HandleReloadEventScriptsCommand(handler);
HandleReloadSpellScriptsCommand(handler);
handler->SendGlobalGMSysMessage("DB tables `*_scripts` reloaded.");
@@ -346,7 +346,7 @@ public:
static bool HandleReloadConfigCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading config settings...");
+ LOG_INFO("server.loading", "Reloading config settings...");
sWorld->LoadConfigSettings(true);
sMapMgr->InitializeVisibilityDistanceInfo();
handler->SendGlobalGMSysMessage("World config settings reloaded.");
@@ -355,7 +355,7 @@ public:
static bool HandleReloadDungeonAccessCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Dungeon Access Requirement definitions...");
+ LOG_INFO("server.loading", "Reloading Dungeon Access Requirement definitions...");
sObjectMgr->LoadAccessRequirements();
handler->SendGlobalGMSysMessage("DB tables `dungeon_access_template` AND `dungeon_access_requirements` reloaded.");
return true;
@@ -363,7 +363,7 @@ public:
static bool HandleReloadAchievementCriteriaDataCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Additional Achievement Criteria Data...");
+ LOG_INFO("server.loading", "Reloading Additional Achievement Criteria Data...");
sAchievementMgr->LoadAchievementCriteriaData();
handler->SendGlobalGMSysMessage("DB table `achievement_criteria_data` reloaded.");
return true;
@@ -371,7 +371,7 @@ public:
static bool HandleReloadAchievementRewardCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Achievement Reward Data...");
+ LOG_INFO("server.loading", "Reloading Achievement Reward Data...");
sAchievementMgr->LoadRewards();
handler->SendGlobalGMSysMessage("DB table `achievement_reward` reloaded.");
return true;
@@ -379,7 +379,7 @@ public:
static bool HandleReloadAreaTriggerTavernCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Tavern Area Triggers...");
+ LOG_INFO("server.loading", "Reloading Tavern Area Triggers...");
sObjectMgr->LoadTavernAreaTriggers();
handler->SendGlobalGMSysMessage("DB table `areatrigger_tavern` reloaded.");
return true;
@@ -387,7 +387,7 @@ public:
static bool HandleReloadAreaTriggerCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Area Trigger definitions...");
+ LOG_INFO("server.loading", "Reloading Area Trigger definitions...");
sObjectMgr->LoadAreaTriggers();
handler->SendGlobalGMSysMessage("DB table `areatrigger` reloaded.");
return true;
@@ -395,7 +395,7 @@ public:
static bool HandleReloadAreaTriggerTeleportCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Area Trigger teleport definitions...");
+ LOG_INFO("server.loading", "Reloading Area Trigger teleport definitions...");
sObjectMgr->LoadAreaTriggerTeleports();
handler->SendGlobalGMSysMessage("DB table `areatrigger_teleport` reloaded.");
return true;
@@ -403,7 +403,7 @@ public:
static bool HandleReloadAutobroadcastCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Autobroadcasts...");
+ LOG_INFO("server.loading", "Reloading Autobroadcasts...");
sAutobroadcastMgr->LoadAutobroadcasts();
handler->SendGlobalGMSysMessage("DB table `autobroadcast` reloaded.");
return true;
@@ -411,7 +411,7 @@ public:
static bool HandleReloadMotdCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Motd...");
+ LOG_INFO("server.loading", "Reloading Motd...");
sMotdMgr->LoadMotd();
handler->SendGlobalGMSysMessage("DB table `motd` reloaded.");
handler->SendGlobalSysMessage(sMotdMgr->GetMotd());
@@ -420,7 +420,7 @@ public:
static bool HandleReloadBroadcastTextCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Broadcast texts...");
+ LOG_INFO("server.loading", "Reloading Broadcast texts...");
sObjectMgr->LoadBroadcastTexts();
sObjectMgr->LoadBroadcastTextLocales();
handler->SendGlobalGMSysMessage("DB table `broadcast_text` reloaded.");
@@ -440,7 +440,7 @@ public:
static bool HandleReloadOnKillReputationCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading creature award reputation definitions...");
+ LOG_INFO("server.loading", "Reloading creature award reputation definitions...");
sObjectMgr->LoadReputationOnKill();
handler->SendGlobalGMSysMessage("DB table `creature_onkill_reputation` reloaded.");
return true;
@@ -510,7 +510,7 @@ public:
static bool HandleReloadGossipMenuCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading `gossip_menu` Table!");
+ LOG_INFO("server.loading", "Reloading `gossip_menu` Table!");
sObjectMgr->LoadGossipMenu();
handler->SendGlobalGMSysMessage("DB table `gossip_menu` reloaded.");
sConditionMgr->LoadConditions(true);
@@ -519,7 +519,7 @@ public:
static bool HandleReloadGossipMenuOptionCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading `gossip_menu_option` Table!");
+ LOG_INFO("server.loading", "Reloading `gossip_menu_option` Table!");
sObjectMgr->LoadGossipMenuItems();
handler->SendGlobalGMSysMessage("DB table `gossip_menu_option` reloaded.");
sConditionMgr->LoadConditions(true);
@@ -544,7 +544,7 @@ public:
static bool HandleReloadQuestAreaTriggersCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Quest Area Triggers...");
+ LOG_INFO("server.loading", "Reloading Quest Area Triggers...");
sObjectMgr->LoadQuestAreaTriggers();
handler->SendGlobalGMSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
return true;
@@ -552,7 +552,7 @@ public:
static bool HandleReloadQuestGreetingCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Quest Greeting ...");
+ LOG_INFO("server.loading", "Reloading Quest Greeting ...");
sObjectMgr->LoadQuestGreetings();
handler->SendGlobalGMSysMessage("DB table `quest_greeting` reloaded.");
return true;
@@ -560,7 +560,7 @@ public:
static bool HandleReloadLocalesQuestGreetingCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Quest Greeting locales...");
+ LOG_INFO("server.loading", "Reloading Quest Greeting locales...");
sObjectMgr->LoadQuestGreetingsLocales();
handler->SendGlobalGMSysMessage("DB table `quest_greeting_locale` reloaded.");
return true;
@@ -568,12 +568,12 @@ public:
static bool HandleReloadQuestTemplateCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Quest Templates...");
+ LOG_INFO("server.loading", "Reloading Quest Templates...");
sObjectMgr->LoadQuests();
handler->SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded.");
/// dependent also from `gameobject` but this table not reloaded anyway
- LOG_INFO("server.loading", "Re-Loading GameObjects for quests...");
+ LOG_INFO("server.loading", "Reloading GameObjects for quests...");
sObjectMgr->LoadGameObjectForQuests();
handler->SendGlobalGMSysMessage("Data GameObjects for quests reloaded.");
return true;
@@ -581,7 +581,7 @@ public:
static bool HandleReloadLootTemplatesCreatureCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`creature_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`creature_loot_template`)");
LoadLootTemplates_Creature();
LootTemplates_Creature.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `creature_loot_template` reloaded.");
@@ -591,7 +591,7 @@ public:
static bool HandleReloadCreatureMovementOverrideCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Creature movement overrides...");
+ LOG_INFO("server.loading", "Reloading Creature movement overrides...");
sObjectMgr->LoadCreatureMovementOverrides();
handler->SendGlobalGMSysMessage("DB table `creature_movement_override` reloaded.");
return true;
@@ -599,7 +599,7 @@ public:
static bool HandleReloadLootTemplatesDisenchantCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`disenchant_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`disenchant_loot_template`)");
LoadLootTemplates_Disenchant();
LootTemplates_Disenchant.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `disenchant_loot_template` reloaded.");
@@ -609,7 +609,7 @@ public:
static bool HandleReloadLootTemplatesFishingCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`fishing_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`fishing_loot_template`)");
LoadLootTemplates_Fishing();
LootTemplates_Fishing.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `fishing_loot_template` reloaded.");
@@ -619,7 +619,7 @@ public:
static bool HandleReloadLootTemplatesGameobjectCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`gameobject_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`gameobject_loot_template`)");
LoadLootTemplates_Gameobject();
LootTemplates_Gameobject.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `gameobject_loot_template` reloaded.");
@@ -629,7 +629,7 @@ public:
static bool HandleReloadLootTemplatesItemCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`item_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`item_loot_template`)");
LoadLootTemplates_Item();
LootTemplates_Item.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `item_loot_template` reloaded.");
@@ -639,7 +639,7 @@ public:
static bool HandleReloadLootTemplatesMillingCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`milling_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`milling_loot_template`)");
LoadLootTemplates_Milling();
LootTemplates_Milling.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `milling_loot_template` reloaded.");
@@ -649,7 +649,7 @@ public:
static bool HandleReloadLootTemplatesPickpocketingCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`pickpocketing_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`pickpocketing_loot_template`)");
LoadLootTemplates_Pickpocketing();
LootTemplates_Pickpocketing.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `pickpocketing_loot_template` reloaded.");
@@ -659,7 +659,7 @@ public:
static bool HandleReloadLootTemplatesProspectingCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`prospecting_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`prospecting_loot_template`)");
LoadLootTemplates_Prospecting();
LootTemplates_Prospecting.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `prospecting_loot_template` reloaded.");
@@ -669,7 +669,7 @@ public:
static bool HandleReloadLootTemplatesMailCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`mail_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`mail_loot_template`)");
LoadLootTemplates_Mail();
LootTemplates_Mail.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `mail_loot_template` reloaded.");
@@ -679,7 +679,7 @@ public:
static bool HandleReloadLootTemplatesReferenceCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`reference_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`reference_loot_template`)");
LoadLootTemplates_Reference();
handler->SendGlobalGMSysMessage("DB table `reference_loot_template` reloaded.");
sConditionMgr->LoadConditions(true);
@@ -688,7 +688,7 @@ public:
static bool HandleReloadLootTemplatesSkinningCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`skinning_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`skinning_loot_template`)");
LoadLootTemplates_Skinning();
LootTemplates_Skinning.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `skinning_loot_template` reloaded.");
@@ -698,7 +698,7 @@ public:
static bool HandleReloadLootTemplatesSpellCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`spell_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`spell_loot_template`)");
LoadLootTemplates_Spell();
LootTemplates_Spell.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `spell_loot_template` reloaded.");
@@ -708,7 +708,7 @@ public:
static bool HandleReloadLootTemplatesPlayerCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Loot Tables... (`player_loot_template`)");
+ LOG_INFO("server.loading", "Reloading Loot Tables... (`player_loot_template`)");
LoadLootTemplates_Player();
LootTemplates_Player.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `player_loot_template` reloaded.");
@@ -718,7 +718,7 @@ public:
static bool HandleReloadAcoreStringCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading acore_string Table!");
+ LOG_INFO("server.loading", "Reloading acore_string Table!");
sObjectMgr->LoadAcoreStrings();
handler->SendGlobalGMSysMessage("DB table `acore_string` reloaded.");
return true;
@@ -732,7 +732,7 @@ public:
return false;
}
- LOG_INFO("server.loading", "Re-Loading warden_action Table!");
+ LOG_INFO("server.loading", "Reloading warden_action Table!");
sWardenCheckMgr->LoadWardenOverrides();
handler->SendGlobalGMSysMessage("DB table `warden_action` reloaded.");
return true;
@@ -740,7 +740,7 @@ public:
static bool HandleReloadNpcTrainerCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading `npc_trainer` Table!");
+ LOG_INFO("server.loading", "Reloading `npc_trainer` Table!");
sObjectMgr->LoadTrainerSpell();
handler->SendGlobalGMSysMessage("DB table `npc_trainer` reloaded.");
return true;
@@ -748,7 +748,7 @@ public:
static bool HandleReloadNpcVendorCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading `npc_vendor` Table!");
+ LOG_INFO("server.loading", "Reloading `npc_vendor` Table!");
sObjectMgr->LoadVendors();
handler->SendGlobalGMSysMessage("DB table `npc_vendor` reloaded.");
return true;
@@ -756,7 +756,7 @@ public:
static bool HandleReloadPointsOfInterestCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading `points_of_interest` Table!");
+ LOG_INFO("server.loading", "Reloading `points_of_interest` Table!");
sObjectMgr->LoadPointsOfInterest();
handler->SendGlobalGMSysMessage("DB table `points_of_interest` reloaded.");
return true;
@@ -764,7 +764,7 @@ public:
static bool HandleReloadQuestPOICommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Quest POI ..." );
+ LOG_INFO("server.loading", "Reloading Quest POI ..." );
sObjectMgr->LoadQuestPOI();
handler->SendGlobalGMSysMessage("DB Table `quest_poi` and `quest_poi_points` reloaded.");
return true;
@@ -772,7 +772,7 @@ public:
static bool HandleReloadSpellClickSpellsCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading `npc_spellclick_spells` Table!");
+ LOG_INFO("server.loading", "Reloading `npc_spellclick_spells` Table!");
sObjectMgr->LoadNPCSpellClickSpells();
handler->SendGlobalGMSysMessage("DB table `npc_spellclick_spells` reloaded.");
return true;
@@ -780,7 +780,7 @@ public:
static bool HandleReloadReservedNameCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Reserved Names!");
+ LOG_INFO("server.loading", "Reloading Reserved Names!");
sObjectMgr->LoadReservedPlayerNamesDB();
sObjectMgr->LoadReservedPlayerNamesDBC(); // Needed because we clear the store in LoadReservedPlayerNamesDB()
handler->SendGlobalGMSysMessage("Reserved Names reloaded.");
@@ -789,7 +789,7 @@ public:
static bool HandleReloadProfanityNameCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Profanity Names!");
+ LOG_INFO("server.loading", "Reloading Profanity Names!");
sObjectMgr->LoadProfanityNamesFromDB();
sObjectMgr->LoadProfanityNamesFromDBC(); // Needed because we clear the store in LoadProfanityNamesFromDB()
handler->SendGlobalGMSysMessage("Profanity Names reloaded.");
@@ -798,7 +798,7 @@ public:
static bool HandleReloadReputationRewardRateCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading `reputation_reward_rate` Table!" );
+ LOG_INFO("server.loading", "Reloading `reputation_reward_rate` Table!" );
sObjectMgr->LoadReputationRewardRate();
handler->SendGlobalSysMessage("DB table `reputation_reward_rate` reloaded.");
return true;
@@ -806,7 +806,7 @@ public:
static bool HandleReloadReputationSpilloverTemplateCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading `reputation_spillover_template` Table!" );
+ LOG_INFO("server.loading", "Reloading `reputation_spillover_template` Table!" );
sObjectMgr->LoadReputationSpilloverTemplate();
handler->SendGlobalSysMessage("DB table `reputation_spillover_template` reloaded.");
return true;
@@ -814,7 +814,7 @@ public:
static bool HandleReloadSkillDiscoveryTemplateCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Skill Discovery Table...");
+ LOG_INFO("server.loading", "Reloading Skill Discovery Table...");
LoadSkillDiscoveryTable();
handler->SendGlobalGMSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
return true;
@@ -823,7 +823,7 @@ public:
static bool HandleReloadSkillPerfectItemTemplateCommand(ChatHandler* handler)
{
// latched onto HandleReloadSkillExtraItemTemplateCommand as it's part of that table group (and i don't want to chance all the command IDs)
- LOG_INFO("server.loading", "Re-Loading Skill Perfection Data Table...");
+ LOG_INFO("server.loading", "Reloading Skill Perfection Data Table...");
LoadSkillPerfectItemTable();
handler->SendGlobalGMSysMessage("DB table `skill_perfect_item_template` (perfect item procs when crafting) reloaded.");
return true;
@@ -831,7 +831,7 @@ public:
static bool HandleReloadSkillExtraItemTemplateCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Skill Extra Item Table...");
+ LOG_INFO("server.loading", "Reloading Skill Extra Item Table...");
LoadSkillExtraItemTable();
handler->SendGlobalGMSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
return HandleReloadSkillPerfectItemTemplateCommand(handler);
@@ -839,7 +839,7 @@ public:
static bool HandleReloadSkillFishingBaseLevelCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Skill Fishing base level requirements...");
+ LOG_INFO("server.loading", "Reloading Skill Fishing base level requirements...");
sObjectMgr->LoadFishingBaseSkillLevel();
handler->SendGlobalGMSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
return true;
@@ -847,7 +847,7 @@ public:
static bool HandleReloadSpellAreaCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading SpellArea Data...");
+ LOG_INFO("server.loading", "Reloading SpellArea Data...");
sSpellMgr->LoadSpellAreas();
handler->SendGlobalGMSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
return true;
@@ -855,7 +855,7 @@ public:
static bool HandleReloadSpellRequiredCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Spell Required Data... ");
+ LOG_INFO("server.loading", "Reloading Spell Required Data... ");
sSpellMgr->LoadSpellRequired();
handler->SendGlobalGMSysMessage("DB table `spell_required` reloaded.");
return true;
@@ -863,7 +863,7 @@ public:
static bool HandleReloadSpellGroupsCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Spell Groups...");
+ LOG_INFO("server.loading", "Reloading Spell Groups...");
sSpellMgr->LoadSpellGroups();
handler->SendGlobalGMSysMessage("DB table `spell_group` (spell groups) reloaded.");
return true;
@@ -871,7 +871,7 @@ public:
static bool HandleReloadSpellLinkedSpellCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Spell Linked Spells...");
+ LOG_INFO("server.loading", "Reloading Spell Linked Spells...");
sSpellMgr->LoadSpellLinked();
handler->SendGlobalGMSysMessage("DB table `spell_linked_spell` reloaded.");
return true;
@@ -879,7 +879,7 @@ public:
static bool HandleReloadSpellProcEventCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Spell Proc Event conditions...");
+ LOG_INFO("server.loading", "Reloading Spell Proc Event conditions...");
sSpellMgr->LoadSpellProcEvents();
handler->SendGlobalGMSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
return true;
@@ -887,7 +887,7 @@ public:
static bool HandleReloadSpellProcsCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Spell Proc conditions and data...");
+ LOG_INFO("server.loading", "Reloading Spell Proc conditions and data...");
sSpellMgr->LoadSpellProcs();
handler->SendGlobalGMSysMessage("DB table `spell_proc` (spell proc conditions and data) reloaded.");
return true;
@@ -895,7 +895,7 @@ public:
static bool HandleReloadSpellBonusesCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Spell Bonus Data...");
+ LOG_INFO("server.loading", "Reloading Spell Bonus Data...");
sSpellMgr->LoadSpellBonuses();
handler->SendGlobalGMSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
return true;
@@ -903,7 +903,7 @@ public:
static bool HandleReloadSpellTargetPositionCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Spell target coordinates...");
+ LOG_INFO("server.loading", "Reloading Spell target coordinates...");
sSpellMgr->LoadSpellTargetPositions();
handler->SendGlobalGMSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
return true;
@@ -911,7 +911,7 @@ public:
static bool HandleReloadSpellThreatsCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Aggro Spells Definitions...");
+ LOG_INFO("server.loading", "Reloading Aggro Spells Definitions...");
sSpellMgr->LoadSpellThreats();
handler->SendGlobalGMSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
return true;
@@ -919,7 +919,7 @@ public:
static bool HandleReloadSpellGroupStackRulesCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Spell Group Stack Rules...");
+ LOG_INFO("server.loading", "Reloading Spell Group Stack Rules...");
sSpellMgr->LoadSpellGroupStackRules();
handler->SendGlobalGMSysMessage("DB table `spell_group_stack_rules` (spell stacking definitions) reloaded.");
return true;
@@ -927,7 +927,7 @@ public:
static bool HandleReloadSpellPetAurasCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Spell pet auras...");
+ LOG_INFO("server.loading", "Reloading Spell pet auras...");
sSpellMgr->LoadSpellPetAuras();
handler->SendGlobalGMSysMessage("DB table `spell_pet_auras` reloaded.");
return true;
@@ -935,7 +935,7 @@ public:
static bool HandleReloadPageTextsCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Page Texts...");
+ LOG_INFO("server.loading", "Reloading Page Texts...");
sObjectMgr->LoadPageTexts();
handler->SendGlobalGMSysMessage("DB table `page_texts` reloaded.");
handler->SendGlobalGMSysMessage("You need to delete your client cache or change the cache number in config in order for your players see the changes.");
@@ -944,7 +944,7 @@ public:
static bool HandleReloadItemEnchantementsCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Item Random Enchantments Table...");
+ LOG_INFO("server.loading", "Reloading Item Random Enchantments Table...");
LoadRandomEnchantmentsTable();
handler->SendGlobalGMSysMessage("DB table `item_enchantment_template` reloaded.");
return true;
@@ -952,7 +952,7 @@ public:
static bool HandleReloadItemSetNamesCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Item set names...");
+ LOG_INFO("server.loading", "Reloading Item set names...");
sObjectMgr->LoadItemSetNames();
handler->SendGlobalGMSysMessage("DB table `item_set_names` reloaded.");
return true;
@@ -966,7 +966,7 @@ public:
return false;
}
- LOG_INFO("server.loading", "Re-Loading Scripts from `event_scripts`...");
+ LOG_INFO("server.loading", "Reloading Scripts from `event_scripts`...");
sObjectMgr->LoadEventScripts();
@@ -983,7 +983,7 @@ public:
return false;
}
- LOG_INFO("server.loading", "Re-Loading Scripts from `waypoint_scripts`...");
+ LOG_INFO("server.loading", "Reloading Scripts from `waypoint_scripts`...");
sObjectMgr->LoadWaypointScripts();
@@ -994,7 +994,7 @@ public:
static bool HandleReloadWpCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Waypoints data from 'waypoints_data'");
+ LOG_INFO("server.loading", "Reloading Waypoints data from 'waypoints_data'");
sWaypointMgr->Load();
handler->SendGlobalGMSysMessage("DB Table 'waypoint_data' reloaded.");
@@ -1009,7 +1009,7 @@ public:
return false;
}
- LOG_INFO("server.loading", "Re-Loading Scripts from `spell_scripts`...");
+ LOG_INFO("server.loading", "Reloading Scripts from `spell_scripts`...");
sObjectMgr->LoadSpellScripts();
@@ -1020,7 +1020,7 @@ public:
static bool HandleReloadGameGraveyardZoneCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Graveyard-zone links...");
+ LOG_INFO("server.loading", "Reloading Graveyard-zone links...");
sGraveyard->LoadGraveyardZones();
@@ -1031,7 +1031,7 @@ public:
static bool HandleReloadGameTeleCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Game Tele coordinates...");
+ LOG_INFO("server.loading", "Reloading Game Tele coordinates...");
sObjectMgr->LoadGameTele();
@@ -1042,7 +1042,7 @@ public:
static bool HandleReloadDisablesCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading disables table...");
+ LOG_INFO("server.loading", "Reloading disables table...");
DisableMgr::LoadDisables();
LOG_INFO("server.loading", "Checking quest disables...");
DisableMgr::CheckQuestDisables();
@@ -1052,7 +1052,7 @@ public:
static bool HandleReloadLocalesAchievementRewardCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Achievement Reward Data Locale...");
+ LOG_INFO("server.loading", "Reloading Achievement Reward Data Locale...");
sAchievementMgr->LoadRewardLocales();
handler->SendGlobalGMSysMessage("DB table `achievement_reward_locale` reloaded.");
return true;
@@ -1060,7 +1060,7 @@ public:
static bool HandleReloadLfgRewardsCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading lfg dungeon rewards...");
+ LOG_INFO("server.loading", "Reloading lfg dungeon rewards...");
sLFGMgr->LoadRewards();
handler->SendGlobalGMSysMessage("DB table `lfg_dungeon_rewards` reloaded.");
return true;
@@ -1068,7 +1068,7 @@ public:
static bool HandleReloadLocalesCreatureCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Creature Template Locale...");
+ LOG_INFO("server.loading", "Reloading Creature Template Locale...");
sObjectMgr->LoadCreatureLocales();
handler->SendGlobalGMSysMessage("DB table `creature_template_locale` reloaded.");
return true;
@@ -1076,7 +1076,7 @@ public:
static bool HandleReloadLocalesCreatureTextCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Creature Texts Locale...");
+ LOG_INFO("server.loading", "Reloading Creature Texts Locale...");
sCreatureTextMgr->LoadCreatureTextLocales();
handler->SendGlobalGMSysMessage("DB table `creature_text_locale` reloaded.");
return true;
@@ -1084,7 +1084,7 @@ public:
static bool HandleReloadLocalesGameobjectCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Gameobject Template Locale ... ");
+ LOG_INFO("server.loading", "Reloading Gameobject Template Locale ... ");
sObjectMgr->LoadGameObjectLocales();
handler->SendGlobalGMSysMessage("DB table `gameobject_template_locale` reloaded.");
return true;
@@ -1092,7 +1092,7 @@ public:
static bool HandleReloadLocalesGossipMenuOptionCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Gossip Menu Option Locale ... ");
+ LOG_INFO("server.loading", "Reloading Gossip Menu Option Locale ... ");
sObjectMgr->LoadGossipMenuItemsLocales();
handler->SendGlobalGMSysMessage("DB table `gossip_menu_option_locale` reloaded.");
return true;
@@ -1100,7 +1100,7 @@ public:
static bool HandleReloadLocalesItemCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Item Template Locale ... ");
+ LOG_INFO("server.loading", "Reloading Item Template Locale ... ");
sObjectMgr->LoadItemLocales();
handler->SendGlobalGMSysMessage("DB table `item_template_locale` reloaded.");
return true;
@@ -1108,7 +1108,7 @@ public:
static bool HandleReloadLocalesItemSetNameCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Item set name Locale... ");
+ LOG_INFO("server.loading", "Reloading Item set name Locale... ");
sObjectMgr->LoadItemSetNameLocales();
handler->SendGlobalGMSysMessage("DB table `item_set_name_locale` reloaded.");
return true;
@@ -1116,7 +1116,7 @@ public:
static bool HandleReloadLocalesNpcTextCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading NPC Text Locale ... ");
+ LOG_INFO("server.loading", "Reloading NPC Text Locale ... ");
sObjectMgr->LoadNpcTextLocales();
handler->SendGlobalGMSysMessage("DB table `npc_text_locale` reloaded.");
return true;
@@ -1124,7 +1124,7 @@ public:
static bool HandleReloadLocalesPageTextCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Page Text Locale ... ");
+ LOG_INFO("server.loading", "Reloading Page Text Locale ... ");
sObjectMgr->LoadPageTextLocales();
handler->SendGlobalGMSysMessage("DB table `page_text_locale` reloaded.");
handler->SendGlobalGMSysMessage("You need to delete your client cache or change the cache number in config in order for your players see the changes.");
@@ -1133,7 +1133,7 @@ public:
static bool HandleReloadLocalesPointsOfInterestCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Points Of Interest Locale ... ");
+ LOG_INFO("server.loading", "Reloading Points Of Interest Locale ... ");
sObjectMgr->LoadPointOfInterestLocales();
handler->SendGlobalGMSysMessage("DB table `points_of_interest_locale` reloaded.");
return true;
@@ -1141,7 +1141,7 @@ public:
static bool HandleReloadLocalesQuestCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Locales Quest ... ");
+ LOG_INFO("server.loading", "Reloading Locales Quest ... ");
sObjectMgr->LoadQuestLocales();
handler->SendGlobalGMSysMessage("DB table `quest_template_locale` reloaded.");
return true;
@@ -1149,7 +1149,7 @@ public:
static bool HandleReloadLocalesQuestOfferRewardCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Quest Offer Reward Locale... ");
+ LOG_INFO("server.loading", "Reloading Quest Offer Reward Locale... ");
sObjectMgr->LoadQuestOfferRewardLocale();
handler->SendGlobalGMSysMessage("DB table `quest_offer_reward_locale` reloaded.");
return true;
@@ -1157,7 +1157,7 @@ public:
static bool HandleReloadLocalesQuestRequestItemsCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Quest Request Item Locale... ");
+ LOG_INFO("server.loading", "Reloading Quest Request Item Locale... ");
sObjectMgr->LoadQuestRequestItemsLocale();
handler->SendGlobalGMSysMessage("DB table `quest_request_item_locale` reloaded.");
return true;
@@ -1165,7 +1165,7 @@ public:
static bool HandleReloadMailLevelRewardCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Player level dependent mail rewards...");
+ LOG_INFO("server.loading", "Reloading Player level dependent mail rewards...");
sObjectMgr->LoadMailLevelRewards();
handler->SendGlobalGMSysMessage("DB table `mail_level_reward` reloaded.");
return true;
@@ -1173,7 +1173,7 @@ public:
static bool HandleReloadMailServerTemplateCommand(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading `server_mail_template` table");
+ LOG_INFO("server.loading", "Reloading `server_mail_template` table");
sObjectMgr->LoadMailServerTemplates();
handler->SendGlobalGMSysMessage("DB table `server_mail_template` reloaded.");
return true;
@@ -1182,7 +1182,7 @@ public:
static bool HandleReloadAuctionsCommand(ChatHandler* handler)
{
///- Reload dynamic data tables from the database
- LOG_INFO("server.loading", "Re-Loading Auctions...");
+ LOG_INFO("server.loading", "Reloading Auctions...");
sAuctionMgr->LoadAuctionItems();
sAuctionMgr->LoadAuctions();
handler->SendGlobalGMSysMessage("Auctions reloaded.");
@@ -1191,7 +1191,7 @@ public:
static bool HandleReloadConditions(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Conditions...");
+ LOG_INFO("server.loading", "Reloading Conditions...");
sConditionMgr->LoadConditions(true);
handler->SendGlobalGMSysMessage("Conditions reloaded.");
return true;
@@ -1199,7 +1199,7 @@ public:
static bool HandleReloadCreatureText(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Creature Texts...");
+ LOG_INFO("server.loading", "Reloading Creature Texts...");
sCreatureTextMgr->LoadCreatureTexts();
handler->SendGlobalGMSysMessage("Creature Texts reloaded.");
return true;
@@ -1207,7 +1207,7 @@ public:
static bool HandleReloadSmartScripts(ChatHandler* handler)
{
- LOG_INFO("server.loading", "Re-Loading Smart Scripts...");
+ LOG_INFO("server.loading", "Reloading Smart Scripts...");
sSmartScriptMgr->LoadSmartAIFromDB();
handler->SendGlobalGMSysMessage("Smart Scripts reloaded.");
return true;
diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp
index 9df570105..0c1087436 100644
--- a/src/server/scripts/Commands/cs_server.cpp
+++ b/src/server/scripts/Commands/cs_server.cpp
@@ -244,23 +244,17 @@ public:
handler->PSendSysMessage("LoginDatabase queue size: %zu", LoginDatabase.QueueSize());
handler->PSendSysMessage("CharacterDatabase queue size: %zu", CharacterDatabase.QueueSize());
handler->PSendSysMessage("WorldDatabase queue size: %zu", WorldDatabase.QueueSize());
-
- if (Acore::Module::GetEnableModulesList().empty())
- handler->SendSysMessage("No modules enabled");
- else
- handler->SendSysMessage("> List enable modules:");
#ifdef MOD_PLAYERBOTS
handler->PSendSysMessage("PlayerbotsDatabase queue size: %zu", PlayerbotsDatabase.QueueSize());
#endif
if (Acore::Module::GetEnableModulesList().empty())
- handler->SendSysMessage("No modules enabled");
+ handler->SendSysMessage("No modules are enabled");
else
- handler->SendSysMessage("> List enable modules:");
-
+ handler->SendSysMessage("List of enabled modules:");
for (auto const& modName : Acore::Module::GetEnableModulesList())
{
- handler->SendSysMessage(Acore::StringFormatFmt("- {}", modName));
+ handler->SendSysMessage(Acore::StringFormatFmt("|- {}", modName));
}
return true;
@@ -283,9 +277,9 @@ public:
handler->PSendSysMessage("Connection peak: %u.", connPeak);
handler->PSendSysMessage(LANG_UPTIME, secsToTimeString(GameTime::GetUptime().count()).c_str());
handler->PSendSysMessage("Update time diff: %ums. Last %d diffs summary:", sWorldUpdateTime.GetLastUpdateTime(), sWorldUpdateTime.GetDatasetSize());
- handler->PSendSysMessage("- Mean: %ums", sWorldUpdateTime.GetAverageUpdateTime());
- handler->PSendSysMessage("- Median: %ums", sWorldUpdateTime.GetPercentile(50));
- handler->PSendSysMessage("- Percentiles (95, 99, max): %ums, %ums, %ums",
+ handler->PSendSysMessage("|- Mean: %ums", sWorldUpdateTime.GetAverageUpdateTime());
+ handler->PSendSysMessage("|- Median: %ums", sWorldUpdateTime.GetPercentile(50));
+ handler->PSendSysMessage("|- Percentiles (95, 99, max): %ums, %ums, %ums",
sWorldUpdateTime.GetPercentile(95),
sWorldUpdateTime.GetPercentile(99),
sWorldUpdateTime.GetPercentile(100));
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
index c63797afa..e586d9ecf 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
@@ -73,7 +73,11 @@ enum Spells
SPELL_SHADOW_PYRO = 29978,
- SPELL_ATIESH_VISUAL = 31796
+ SPELL_ATIESH_VISUAL = 31796,
+
+ SPELL_CURSE_OF_TONGUE_RANK1 = 1714,
+ SPELL_CURSE_OF_TONGUE_RANK2 = 11719,
+ SPELL_MIND_NUMBING_POISON = 5760
};
enum Creatures
@@ -100,6 +104,8 @@ enum Misc
Position const roomCenter = {-11158.f, -1920.f};
+std::vector immuneSpells = { SPELL_CURSE_OF_TONGUE_RANK1, SPELL_CURSE_OF_TONGUE_RANK2, SPELL_MIND_NUMBING_POISON };
+
struct boss_shade_of_aran : public BossAI
{
boss_shade_of_aran(Creature* creature) : BossAI(creature, DATA_ARAN), _atieshReaction(false) { }
@@ -118,6 +124,9 @@ struct boss_shade_of_aran : public BossAI
_drinking = false;
_hasDrunk = false;
+ for (int i = 0; i < immuneSpells.size(); i++)
+ me->ApplySpellImmune(0, IMMUNITY_ID, immuneSpells[i], true);
+
if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR)))
{
libraryDoor->SetGoState(GO_STATE_ACTIVE);
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
index 5631b5edc..af0e1e19d 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
@@ -46,19 +46,6 @@ enum Spells
SPELL_DEAFENINGROAR = 42398
};
-// Trash Waves
-float NalorakkWay[8][3] =
-{
- { 18.569f, 1414.512f, 11.42f}, // waypoint 1
- {-17.264f, 1419.551f, 12.62f},
- {-52.642f, 1419.357f, 27.31f}, // waypoint 2
- {-69.908f, 1419.721f, 27.31f},
- {-79.929f, 1395.958f, 27.31f},
- {-80.072f, 1374.555f, 40.87f}, // waypoint 3
- {-80.072f, 1314.398f, 40.87f},
- {-80.072f, 1295.775f, 48.60f} // waypoint 4
-};
-
enum Talks
{
SAY_WAVE1 = 0,
@@ -74,399 +61,300 @@ enum Talks
SAY_KILL_TWO,
SAY_DEATH,
SAY_NALORAKK_EVENT1, // Not implemented
- SAY_NALORAKK_EVENT2 // Not implemented
+ SAY_NALORAKK_EVENT2, // Not implemented
+ SAY_RUN_AWAY,
+ EMOTE_BEAR
};
-class boss_nalorakk : public CreatureScript
+enum Phases
{
-public:
- boss_nalorakk()
- : CreatureScript("boss_nalorakk")
+ PHASE_SEND_GUARDS_1 = 0,
+ PHASE_SEND_GUARDS_2 = 1,
+ PHASE_SEND_GUARDS_3 = 2,
+ PHASE_SEND_GUARDS_4 = 3,
+ PHASE_SEND_GUARDS_5 = 4,
+ PHASE_START_COMBAT = 5
+};
+
+enum NalorakkGroups
+{
+ GROUP_CHECK_DEAD = 1,
+ GROUP_MOVE = 2,
+ GROUP_BERSERK = 3,
+ GROUP_HUMAN = 4,
+ GROUP_BEAR = 5
+};
+
+struct boss_nalorakk : public BossAI
+{
+ boss_nalorakk(Creature* creature) : BossAI(creature, DATA_NALORAKKEVENT)
{
+ _ranIntro = false;
+ _active = true;
+ creature->SetReactState(REACT_PASSIVE);
+ me->SetImmuneToAll(true);
}
- struct boss_nalorakkAI : public ScriptedAI
+ void Reset() override
{
- boss_nalorakkAI(Creature* creature) : ScriptedAI(creature)
+ BossAI::Reset();
+ _waveList.clear();
+ _introScheduler.CancelAll();
+ if (_bearForm)
{
- MoveEvent = true;
- MovePhase = 0;
- instance = creature->GetInstanceScript();
+ me->RemoveAurasDueToSpell(SPELL_BEARFORM);
+ _bearForm = false;
}
-
- InstanceScript* instance;
-
- uint32 BrutalSwipe_Timer;
- uint32 Mangle_Timer;
- uint32 Surge_Timer;
-
- uint32 LaceratingSlash_Timer;
- uint32 RendFlesh_Timer;
- uint32 DeafeningRoar_Timer;
-
- uint32 ShapeShift_Timer;
- uint32 Berserk_Timer;
-
- bool inBearForm;
- bool MoveEvent;
- bool inMove;
- uint32 MovePhase;
- uint32 waitTimer;
-
- void Reset() override
+ if (_ranIntro)
{
- if (MoveEvent)
- {
- me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- inMove = false;
- waitTimer = 0;
- me->SetSpeed(MOVE_RUN, 2);
- me->SetWalk(false);
- ResetMobs();
- }
- else
- {
- (*me).GetMotionMaster()->MovePoint(0, NalorakkWay[7][0], NalorakkWay[7][1], NalorakkWay[7][2]);
- }
+ _phase = PHASE_START_COMBAT;
+ me->SetReactState(REACT_AGGRESSIVE);
+ _active = false;
- if (instance)
- {
- instance->SetData(DATA_NALORAKKEVENT, NOT_STARTED);
- }
-
- Surge_Timer = urand(15000, 20000);
- BrutalSwipe_Timer = urand(7000, 12000);
- Mangle_Timer = urand(10000, 15000);
- ShapeShift_Timer = urand(45000, 50000);
- Berserk_Timer = 600000;
-
- inBearForm = false;
- // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); /// @todo find the correct equipment id
}
+ }
- void ResetMobs()
+ void MoveInLineOfSight(Unit* who) override
+ {
+ if (who->IsPlayer() && _phase < PHASE_START_COMBAT && _active)
{
- std::list templist;
- float x, y, z;
- me->GetPosition(x, y, z);
-
+ _active = false;
+ switch (_phase)
{
- CellCoord pair(Acore::ComputeCellCoord(x, y));
- Cell cell(pair);
- cell.SetNoCreate();
-
- Acore::AllFriendlyCreaturesInGrid check(me);
- Acore::CreatureListSearcher searcher(me, templist, check);
-
- TypeContainerVisitor, GridTypeMapContainer> cSearcher(searcher);
-
- cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange());
- }
-
- if (templist.empty())
- return;
-
- for (std::list::const_iterator i = templist.begin(); i != templist.end(); ++i)
- if ((*i) && me->GetGUID() != (*i)->GetGUID() && me->IsWithinDistInMap((*i), 25))
- (*i)->AI()->Reset();
- }
-
- void SendAttacker(Unit* target)
- {
- std::list templist;
- float x, y, z;
- me->GetPosition(x, y, z);
-
- {
- CellCoord pair(Acore::ComputeCellCoord(x, y));
- Cell cell(pair);
- cell.SetNoCreate();
-
- Acore::AllFriendlyCreaturesInGrid check(me);
- Acore::CreatureListSearcher searcher(me, templist, check);
-
- TypeContainerVisitor, GridTypeMapContainer> cSearcher(searcher);
-
- cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange());
- }
-
- if (templist.empty())
- return;
-
- for (std::list::const_iterator i = templist.begin(); i != templist.end(); ++i)
- {
- if ((*i) && me->IsWithinDistInMap((*i), 25))
- {
- (*i)->SetNoCallAssistance(true);
- (*i)->AI()->AttackStart(target);
- }
- }
- }
-
- void AttackStart(Unit* who) override
- {
- if (!MoveEvent)
- ScriptedAI::AttackStart(who);
- }
-
- void MoveInLineOfSight(Unit* who) override
-
- {
- if (!MoveEvent)
- {
- ScriptedAI::MoveInLineOfSight(who);
- }
- else
- {
- if (me->IsHostileTo(who))
- {
- if (!inMove)
+ case PHASE_SEND_GUARDS_1:
+ me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_AXE_THROWER);
+ me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_TRIBESMAN);
+ GroupedAttack(_waveList);
+ Talk(SAY_WAVE1);
+ _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context)
{
- switch (MovePhase)
+ if (CheckFullyDeadGroup(_waveList))
{
- case 0:
- if (me->IsWithinDistInMap(who, 50))
+ if (_phase == PHASE_SEND_GUARDS_1)
+ {
+ _introScheduler.CancelGroup(GROUP_CHECK_DEAD);
+ _waveList.clear();
+ me->GetMotionMaster()->MovePath(me->GetEntry()*100+1, false);
+ Talk(SAY_RUN_AWAY);
+ _introScheduler.Schedule(5s, [this](TaskContext)
{
- Talk(SAY_WAVE1);
-
- (*me).GetMotionMaster()->MovePoint(1, NalorakkWay[1][0], NalorakkWay[1][1], NalorakkWay[1][2]);
- MovePhase ++;
- inMove = true;
-
- SendAttacker(who);
- }
- break;
- case 2:
- if (me->IsWithinDistInMap(who, 40))
- {
- Talk(SAY_WAVE2);
-
- (*me).GetMotionMaster()->MovePoint(3, NalorakkWay[3][0], NalorakkWay[3][1], NalorakkWay[3][2]);
- MovePhase ++;
- inMove = true;
-
- SendAttacker(who);
- }
- break;
- case 5:
- if (me->IsWithinDistInMap(who, 40))
- {
- Talk(SAY_WAVE3);
-
- (*me).GetMotionMaster()->MovePoint(6, NalorakkWay[6][0], NalorakkWay[6][1], NalorakkWay[6][2]);
- MovePhase ++;
- inMove = true;
-
- SendAttacker(who);
- }
- break;
- case 7:
- if (me->IsWithinDistInMap(who, 50))
- {
- SendAttacker(who);
-
- Talk(SAY_WAVE4);
-
- me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
-
- MoveEvent = false;
- }
- break;
+ me->SetFacingTo(6.25f);
+ _active = true;
+ });
+ _phase = PHASE_SEND_GUARDS_2;
+ }
}
- }
- }
- }
- }
-
- void JustEngagedWith(Unit* /*who*/) override
- {
- if (instance)
- instance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS);
-
- Talk(SAY_AGGRO);
- DoZoneInCombat();
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- ResetMobs();
-
- if (instance)
- instance->SetData(DATA_NALORAKKEVENT, DONE);
-
- Talk(SAY_DEATH);
- }
-
- void KilledUnit(Unit* /*victim*/) override
- {
- switch (urand(0, 1))
- {
- case 0:
- Talk(SAY_KILL_ONE);
+ context.Repeat(5s);
+ });
break;
- case 1:
- Talk(SAY_KILL_TWO);
- break;
- }
- }
-
- void MovementInform(uint32 type, uint32 id) override
- {
- if (MoveEvent)
- {
- if (type != POINT_MOTION_TYPE)
- return;
-
- if (!inMove)
- return;
-
- if (MovePhase != id)
- return;
-
- switch (MovePhase)
- {
- case 2:
- me->SetOrientation(3.1415f * 2);
- inMove = false;
- return;
- case 1:
- case 3:
- case 4:
- case 6:
- MovePhase ++;
- waitTimer = 1;
- inMove = true;
- return;
- case 5:
- me->SetOrientation(3.1415f * 0.5f);
- inMove = false;
- return;
- case 7:
- me->SetOrientation(3.1415f * 0.5f);
- inMove = false;
- return;
- }
- }
- }
-
- void UpdateAI(uint32 diff) override
- {
- if (waitTimer && inMove)
- {
- if (waitTimer <= diff)
- {
- (*me).GetMotionMaster()->MovementExpired();
- (*me).GetMotionMaster()->MovePoint(MovePhase, NalorakkWay[MovePhase][0], NalorakkWay[MovePhase][1], NalorakkWay[MovePhase][2]);
- waitTimer = 0;
- }
- else waitTimer -= diff;
- }
-
- if (!UpdateVictim())
- return;
-
- if (Berserk_Timer <= diff)
- {
- DoCast(me, SPELL_BERSERK, true);
- Talk(SAY_BERSERK);
- Berserk_Timer = 600000;
- }
- else Berserk_Timer -= diff;
-
- if (ShapeShift_Timer <= diff)
- {
- if (inBearForm)
- {
- // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);
- Talk(SAY_SHIFTEDTOTROLL);
- me->RemoveAurasDueToSpell(SPELL_BEARFORM);
- Surge_Timer = urand(15000, 20000);
- BrutalSwipe_Timer = urand(7000, 12000);
- Mangle_Timer = urand(10000, 15000);
- ShapeShift_Timer = urand(45000, 50000);
- inBearForm = false;
- }
- else
- {
- // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0);
- Talk(SAY_SHIFTEDTOBEAR);
- DoCast(me, SPELL_BEARFORM, true);
- LaceratingSlash_Timer = 2000; // dur 18s
- RendFlesh_Timer = 3000; // dur 5s
- DeafeningRoar_Timer = urand(5000, 10000); // dur 2s
- ShapeShift_Timer = urand(20000, 25000); // dur 30s
- inBearForm = true;
- }
- }
- else ShapeShift_Timer -= diff;
-
- if (!inBearForm)
- {
- if (BrutalSwipe_Timer <= diff)
- {
- DoCastVictim(SPELL_BRUTALSWIPE);
- BrutalSwipe_Timer = urand(7000, 12000);
- }
- else BrutalSwipe_Timer -= diff;
-
- if (Mangle_Timer <= diff)
- {
- if (me->GetVictim() && !me->GetVictim()->HasAura(SPELL_MANGLEEFFECT))
+ case PHASE_SEND_GUARDS_2:
+ me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_AXE_THROWER);
+ me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_TRIBESMAN);
+ me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_MEDICINE_MAN);
+ GroupedAttack(_waveList);
+ Talk(SAY_WAVE2);
+ _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context)
{
- DoCastVictim(SPELL_MANGLE);
- Mangle_Timer = 1000;
- }
- else Mangle_Timer = urand(10000, 15000);
- }
- else Mangle_Timer -= diff;
+ if (CheckFullyDeadGroup(_waveList))
+ {
+ if (_phase == PHASE_SEND_GUARDS_2)
+ {
+ _introScheduler.CancelGroup(GROUP_CHECK_DEAD);
+ _waveList.clear();
+ Talk(SAY_RUN_AWAY);
+ me->GetMotionMaster()->MovePath(me->GetEntry()*100+2, false);
+ _introScheduler.Schedule(6s, [this](TaskContext)
+ {
+ me->SetFacingTo(1.54f);
+ _active = true;
+ });
+ _phase = PHASE_SEND_GUARDS_3;
+ }
- if (Surge_Timer <= diff)
- {
- Talk(SAY_SURGE);
- Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 45, true);
- if (target)
- DoCast(target, SPELL_SURGE);
- Surge_Timer = urand(15000, 20000);
- }
- else Surge_Timer -= diff;
+ }
+ context.Repeat(5s);
+ });
+ break;
+ case PHASE_SEND_GUARDS_3:
+ me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_WARBRINGER);
+ GroupedAttack(_waveList);
+ Talk(SAY_WAVE3);
+ _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context)
+ {
+ if (CheckFullyDeadGroup(_waveList))
+ {
+ if (_phase == PHASE_SEND_GUARDS_3)
+ {
+ _introScheduler.CancelGroup(GROUP_CHECK_DEAD);
+ _waveList.clear();
+ Talk(SAY_RUN_AWAY);
+ me->GetMotionMaster()->MovePath(me->GetEntry()*100+3, false);
+ _introScheduler.Schedule(6s, [this](TaskContext)
+ {
+ me->SetFacingTo(1.54f);
+ _active = true;
+ });
+ _phase = PHASE_SEND_GUARDS_4;
+ }
+ }
+ context.Repeat(5s);
+ });
+ break;
+ case PHASE_SEND_GUARDS_4:
+ me->GetCreaturesWithEntryInRange(_waveList, 25.0f, NPC_AMANISHI_WARBRINGER);
+ me->GetCreaturesWithEntryInRange(_waveList, 25.0f, NPC_AMANISHI_MEDICINE_MAN);
+ GroupedAttack(_waveList);
+ Talk(SAY_WAVE4);
+ _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context)
+ {
+ if (CheckFullyDeadGroup(_waveList))
+ {
+ if (_phase == PHASE_SEND_GUARDS_4)
+ {
+ _introScheduler.CancelGroup(GROUP_CHECK_DEAD);
+ me->SetHomePosition(me->GetPosition());
+ me->SetImmuneToAll(false);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetInCombatWithZone();
+ _waveList.clear();
+ _phase = PHASE_START_COMBAT;
+ _ranIntro = true;
+ }
+ }
+ context.Repeat(5s);
+ });
+ break;
+ }
+ }
+ BossAI::MoveInLineOfSight(who);
+ }
+
+ void JustEngagedWith(Unit* who) override
+ {
+ BossAI::JustEngagedWith(who);
+ Talk(SAY_AGGRO);
+ scheduler.Schedule(15s, 20s, GROUP_HUMAN, [this](TaskContext context)
+ {
+ Talk(SAY_SURGE);
+ DoCastRandomTarget(SPELL_SURGE, 0, 45.0f, false, false, false);
+ context.Repeat();
+ }).Schedule(7s, 12s, GROUP_HUMAN, [this](TaskContext context)
+ {
+ DoCastVictim(SPELL_BRUTALSWIPE);
+ context.Repeat();
+ }).Schedule(10s, 15s, GROUP_HUMAN, [this](TaskContext context)
+ {
+ if (!me->GetVictim()->HasAura(SPELL_MANGLEEFFECT))
+ {
+ DoCastVictim(SPELL_MANGLE);
+ context.Repeat(1s);
}
else
{
- if (LaceratingSlash_Timer <= diff)
- {
- DoCastVictim(SPELL_LACERATINGSLASH);
- LaceratingSlash_Timer = urand(18000, 23000);
- }
- else LaceratingSlash_Timer -= diff;
-
- if (RendFlesh_Timer <= diff)
- {
- DoCastVictim(SPELL_RENDFLESH);
- RendFlesh_Timer = urand(5000, 10000);
- }
- else RendFlesh_Timer -= diff;
-
- if (DeafeningRoar_Timer <= diff)
- {
- DoCastVictim(SPELL_DEAFENINGROAR);
- DeafeningRoar_Timer = urand(15000, 20000);
- }
- else DeafeningRoar_Timer -= diff;
+ context.Repeat();
}
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetZulAmanAI(creature);
+ }).Schedule(10min, GROUP_BERSERK, [this](TaskContext)
+ {
+ Talk(SAY_BERSERK);
+ DoCastSelf(SPELL_BERSERK, true);
+ }).Schedule(45s, 50s, GROUP_HUMAN, [this](TaskContext)
+ {
+ ShapeShift(_bearForm);
+ });
}
+
+ void ShapeShift(bool currentlyInBearForm)
+ {
+ if (currentlyInBearForm)
+ {
+ Talk(SAY_SHIFTEDTOTROLL);
+ me->RemoveAurasDueToSpell(SPELL_BEARFORM);
+ scheduler.CancelGroup(GROUP_BEAR);
+ _bearForm = false;
+ scheduler.Schedule(15s, 20s, GROUP_HUMAN, [this](TaskContext context)
+ {
+ Talk(SAY_SURGE);
+ DoCastRandomTarget(SPELL_SURGE, 0, 45.0f, false, false, false);
+ context.Repeat();
+ }).Schedule(7s, 12s, GROUP_HUMAN, [this](TaskContext context)
+ {
+ DoCastVictim(SPELL_BRUTALSWIPE);
+ context.Repeat();
+ }).Schedule(10s, 15s, GROUP_HUMAN, [this](TaskContext context)
+ {
+ DoCastVictim(SPELL_MANGLE);
+ context.Repeat();
+ }).Schedule(10min, GROUP_BERSERK, [this](TaskContext)
+ {
+ Talk(SAY_BERSERK);
+ DoCastSelf(SPELL_BERSERK, true);
+ }).Schedule(45s, 50s, GROUP_HUMAN, [this](TaskContext)
+ {
+ ShapeShift(_bearForm);
+ });
+ }
+ else
+ {
+ Talk(SAY_SHIFTEDTOBEAR);
+ Talk(EMOTE_BEAR);
+ DoCastSelf(SPELL_BEARFORM, true);
+ scheduler.CancelGroup(GROUP_HUMAN);
+ _bearForm = true;
+ scheduler.Schedule(2s, GROUP_BEAR, [this](TaskContext context)
+ {
+ DoCastVictim(SPELL_LACERATINGSLASH);
+ context.Repeat(18s, 23s);
+ }).Schedule(3s, GROUP_BEAR, [this](TaskContext context)
+ {
+ DoCastVictim(SPELL_RENDFLESH);
+ context.Repeat(5s, 10s);
+ }).Schedule(5s, 10s, GROUP_BEAR, [this](TaskContext context)
+ {
+ DoCastSelf(SPELL_DEAFENINGROAR);
+ context.Repeat(15s, 20s);
+ }).Schedule(25s, 30s, GROUP_BEAR, [this](TaskContext context)
+ {
+ ShapeShift(_bearForm);
+ context.Repeat();
+ });
+ }
+ }
+
+ void GroupedAttack(std::list attackerList)
+ {
+ for (Creature* attacker : attackerList)
+ {
+ attacker->SetInCombatWithZone();
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _introScheduler.Update(diff);
+ BossAI::UpdateAI(diff);
+ }
+
+ bool CheckFullyDeadGroup(std::list groupToCheck)
+ {
+ for (Creature* member : groupToCheck)
+ {
+ if (member->IsAlive())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+private:
+ uint8 _phase;
+ bool _ranIntro;
+ bool _active;
+ bool _bearForm;
+ TaskScheduler _introScheduler;
+ std::list _waveList;
};
void AddSC_boss_nalorakk()
{
- new boss_nalorakk();
+ RegisterZulAmanCreatureAI(boss_nalorakk);
}
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
index baa83f557..ffb1b771b 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
@@ -57,8 +57,8 @@ Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f};
ObjectData const creatureData[] =
{
- { NPC_SPIRIT_LYNX, DATA_SPIRIT_LYNX },
- { 0, 0 }
+ { NPC_SPIRIT_LYNX, DATA_SPIRIT_LYNX },
+ { 0, 0 }
};
ObjectData const gameObjectData[] =
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
index 4ca81145b..caf94bfc2 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
+++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
@@ -46,7 +46,11 @@ enum CreatureIds
NPC_HEXLORD = 24239,
NPC_HALAZZI = 23577,
NPC_NALORAKK = 23576,
- NPC_SPIRIT_LYNX = 24143
+ NPC_SPIRIT_LYNX = 24143,
+ NPC_AMANISHI_WARBRINGER = 23580,
+ NPC_AMANISHI_TRIBESMAN = 23582,
+ NPC_AMANISHI_MEDICINE_MAN = 23581,
+ NPC_AMANISHI_AXE_THROWER = 23542
};
enum GameobjectIds
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
index cdf4fc11a..6b5fae927 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
@@ -18,6 +18,7 @@
#include "CreatureScript.h"
#include "Player.h"
#include "ScriptedCreature.h"
+#include "SpellAuraEffects.h"
#include "SpellAuras.h"
#include "SpellScript.h"
#include "SpellScriptLoader.h"
@@ -51,6 +52,7 @@ enum ArchiSpells
SPELL_DOOMFIRE_STRIKE = 31903, //summons two creatures
SPELL_DOOMFIRE_SPAWN = 32074,
SPELL_DOOMFIRE = 31945,
+ SPELL_DOOMFIRE_DOT = 31969,
SPELL_SOUL_CHARGE_YELLOW = 32045,
SPELL_SOUL_CHARGE_GREEN = 32051,
SPELL_SOUL_CHARGE_RED = 32052,
@@ -143,35 +145,37 @@ struct npc_doomfire_spirit : public ScriptedAI
{
npc_doomfire_spirit(Creature* creature) : ScriptedAI(creature){ }
+ float const turnConstant = 0.785402f;
+ float fAngle = urand(0, M_PI * 2);
+
void Reset() override
{
scheduler.CancelAll();
ScheduleTimedEvent(0s, [&] {
- me->GetMotionMaster()->MovePoint(NEAR_POINT, DoomfireMovement(me->GetPosition()));
- }, 1500ms);
+ float nextOrientation = Position::NormalizeOrientation(me->GetOrientation() + irand(-1, 1) * turnConstant);
+ Position pos = GetFirstRandomAngleCollisionPosition(8.f, nextOrientation); // both orientation and distance verified with sniffs
+ me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), nextOrientation);
+ }, 1600ms);
+
+ fAngle = urand(0, M_PI * 2);
}
- Position DoomfireMovement(Position mePos)
+ Position GetFirstRandomAngleCollisionPosition(float dist, float angle)
{
- float angle = mePos.GetOrientation();
- float distance = 100.0f;
- float newAngle = angle + ((rand() % 181) - 90) * M_PI / 180;
- float x = mePos.GetPositionX() + distance * cos(newAngle);
- float y = mePos.GetPositionY() + distance * sin(newAngle);
-
- Position targetPos = Position(x, y, me->GetPositionZ());
- return targetPos;
+ Position pos;
+ for (uint32 i = 0; i < 10; ++i)
+ {
+ pos = me->WorldObject::GetFirstCollisionPosition(dist, angle);
+ if (me->GetDistance(pos) > dist * 0.8f) // if at least 80% distance, good enough
+ break;
+ angle += (M_PI / 5); // else try slightly different angle
+ }
+ return pos;
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
-
- if (!UpdateVictim())
- return;
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
}
};
@@ -313,7 +317,7 @@ struct boss_archimonde : public BossAI
DoCastVictim(SPELL_RED_SKY_EFFECT);
DoCastVictim(SPELL_HAND_OF_DEATH);
}, 3s);
- scheduler.Schedule(25s, 35s, GROUP_FEAR, [this](TaskContext context)
+ scheduler.Schedule(40s, GROUP_FEAR, [this](TaskContext context)
{
DoCastAOE(SPELL_FEAR);
context.Repeat(42s);
@@ -381,11 +385,6 @@ struct boss_archimonde : public BossAI
summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN);
summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID());
}
- else if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT)
- {
- Position randomPosition = summoned->GetRandomNearPosition(40.0f);
- summoned->GetMotionMaster()->MovePoint(0, randomPosition);
- }
else
{
summoned->SetFaction(me->GetFaction()); //remove?
@@ -487,10 +486,38 @@ class spell_air_burst : public SpellScript
}
};
+class spell_doomfire : public AuraScript
+{
+ PrepareAuraScript(spell_doomfire);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_DOOMFIRE_DOT });
+ }
+
+ void PeriodicTick(AuraEffect const* aurEff)
+ {
+ Unit* target = GetTarget();
+ if (!target)
+ return;
+
+ int32 bp = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
+ float tickCoef = (static_cast(aurEff->GetTickNumber() - 1) / aurEff->GetTotalTicks()); // Tick moved back to ensure proper damage on each tick
+ int32 damage = bp - (bp*tickCoef);
+ SpellCastResult result = target->CastCustomSpell(target, SPELL_DOOMFIRE_DOT, &damage, &damage, &damage, true, nullptr, nullptr, target->GetGUID());
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_doomfire::PeriodicTick, EFFECT_ALL, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+};
+
void AddSC_boss_archimonde()
{
RegisterSpellScript(spell_red_sky_effect);
RegisterSpellScript(spell_air_burst);
+ RegisterSpellScript(spell_doomfire);
RegisterHyjalAI(boss_archimonde);
RegisterHyjalAI(npc_ancient_wisp);
RegisterHyjalAI(npc_doomfire_spirit);
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.h b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.h
index ceb3f0c91..3067078f6 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.h
+++ b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.h
@@ -7,36 +7,53 @@
namespace Razuvious {
-enum RazuviousSays
+enum Says
{
- RAZUVIOUS_SAY_AGGRO = 0,
- RAZUVIOUS_SAY_SLAY = 1,
- RAZUVIOUS_SAY_TAUNTED = 2,
- RAZUVIOUS_SAY_DEATH = 3
+ SAY_AGGRO = 0,
+ SAY_SLAY = 1,
+ SAY_TAUNTED = 2,
+ SAY_DEATH = 3,
+ SAY_PATHETIC = 4,
+ SAY_TARGET_DUMMY = 5,
+ SAY_DEATH_KNIGHT_UNDERSTUDY = 0,
};
-enum RazuviousSpells
+enum Spells
{
SPELL_UNBALANCING_STRIKE = 26613,
SPELL_DISRUPTING_SHOUT_10 = 55543,
SPELL_DISRUPTING_SHOUT_25 = 29107,
SPELL_JAGGED_KNIFE = 55550,
SPELL_HOPELESS = 29125,
-
- RAZUVIOUS_SPELL_TAUNT = 29060
+ SPELL_TAUNT = 29060
};
-enum RazuviousEvents
+enum Events
{
EVENT_UNBALANCING_STRIKE = 1,
EVENT_DISRUPTING_SHOUT = 2,
EVENT_JAGGED_KNIFE = 3
};
-enum RazuviousMisc
+enum NPCs
{
NPC_DEATH_KNIGHT_UNDERSTUDY = 16803,
- NPC_RAZUVIOUS = 16061
+ NPC_TARGET_DUMMY = 16211,
+};
+
+enum Actions
+{
+ ACTION_FACE_ME = 0,
+ ACTION_TALK = 1,
+ ACTION_EMOTE = 2,
+ ACTION_SALUTE = 3,
+ ACTION_BACK_TO_TRAINING = 4,
+};
+
+enum Misc
+{
+ GROUP_OOC_RP = 0,
+ POINT_DEATH_KNIGHT = 0,
};
class boss_razuvious : public CreatureScript
@@ -82,13 +99,106 @@ public:
summons.DespawnAll();
events.Reset();
SpawnHelpers();
+ ScheduleRP();
+ }
+
+ void ScheduleInteractWithDeathKnight()
+ {
+ if (_rpBuddyGUID)
+ if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
+ me->SetFacingToObject(understudy);
+
+ scheduler.Schedule(2s, GROUP_OOC_RP, [this](TaskContext /*context*/)
+ {
+ if (roll_chance_i(75))
+ {
+ bool longText = roll_chance_i(50);
+ Talk(longText ? SAY_TARGET_DUMMY : SAY_PATHETIC);
+ scheduler.Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/)
+ {
+ if (_rpBuddyGUID)
+ if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
+ understudy->AI()->DoAction(ACTION_TALK);
+ });
+ if (longText)
+ scheduler.DelayGroup(GROUP_OOC_RP, 5s);
+ }
+ else
+ {
+ me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
+ scheduler.Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/)
+ {
+ if (_rpBuddyGUID)
+ if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
+ {
+ if (roll_chance_i(25))
+ understudy->AI()->DoAction(ACTION_EMOTE);
+ else
+ understudy->AI()->DoAction(ACTION_TALK);
+ }
+ });
+ }
+ }).Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/)
+ {
+ if (_rpBuddyGUID)
+ if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
+ understudy->AI()->DoAction(ACTION_FACE_ME);
+ }).Schedule(10s, GROUP_OOC_RP, [this](TaskContext /*context*/)
+ {
+ if (_rpBuddyGUID)
+ if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
+ understudy->AI()->DoAction(ACTION_SALUTE);
+ }).Schedule(13s, GROUP_OOC_RP, [this](TaskContext /*context*/)
+ {
+ me->ResumeMovement();
+ }).Schedule(16s, GROUP_OOC_RP, [this](TaskContext /*context*/)
+ {
+ if (_rpBuddyGUID)
+ if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
+ understudy->AI()->DoAction(ACTION_BACK_TO_TRAINING);
+ ScheduleRP();
+ });
+ }
+
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type == POINT_MOTION_TYPE && id == POINT_DEATH_KNIGHT)
+ {
+ ScheduleInteractWithDeathKnight();
+ }
+ }
+
+ void ScheduleRP()
+ {
+ _rpBuddyGUID = Acore::Containers::SelectRandomContainerElement(summons);
+ scheduler.Schedule(60s, 80s, GROUP_OOC_RP, [this](TaskContext context)
+ {
+ if (_rpBuddyGUID)
+ {
+ if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
+ {
+ if (me->GetDistance2d(understudy) <= 6.0f)
+ {
+ me->PauseMovement();
+ scheduler.Schedule(500ms, GROUP_OOC_RP, [this](TaskContext /*context*/)
+ {
+ if (_rpBuddyGUID)
+ if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
+ me->GetMotionMaster()->MovePoint(POINT_DEATH_KNIGHT, understudy->GetNearPosition(3.2f, understudy->GetRelativeAngle(me)));
+ });
+ return;
+ }
+ }
+ }
+ context.Repeat(2s);
+ });
}
void KilledUnit(Unit* who) override
{
if (roll_chance_i(30))
{
- Talk(RAZUVIOUS_SAY_SLAY);
+ Talk(SAY_SLAY);
}
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
{
@@ -108,22 +218,23 @@ public:
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
- Talk(RAZUVIOUS_SAY_DEATH);
+ Talk(SAY_DEATH);
me->CastSpell(me, SPELL_HOPELESS, true);
}
void SpellHit(Unit* caster, SpellInfo const* spell) override
{
- if (spell->Id == RAZUVIOUS_SPELL_TAUNT)
+ if (spell->Id == SPELL_TAUNT)
{
- Talk(RAZUVIOUS_SAY_TAUNTED, caster);
+ Talk(SAY_TAUNTED, caster);
}
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
- Talk(RAZUVIOUS_SAY_AGGRO);
+ scheduler.CancelGroup(GROUP_OOC_RP);
+ Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, 20s);
events.ScheduleEvent(EVENT_DISRUPTING_SHOUT, 15s);
events.ScheduleEvent(EVENT_JAGGED_KNIFE, 10s);
@@ -132,6 +243,9 @@ public:
void UpdateAI(uint32 diff) override
{
+ if (!me->IsInCombat())
+ scheduler.Update(diff);
+
if (!UpdateVictim())
return;
@@ -159,6 +273,9 @@ public:
}
DoMeleeAttackIfReady();
}
+
+ private:
+ ObjectGuid _rpBuddyGUID;
};
};
@@ -167,20 +284,65 @@ class boss_razuvious_minion : public CreatureScript
public:
boss_razuvious_minion() : CreatureScript("boss_razuvious_minion") { }
- CreatureAI* GetAI(Creature* pCreature) const override
+ CreatureAI* GetAI(Creature* creature) const override
{
- return GetNaxxramasAI(pCreature);
+ return GetNaxxramasAI(creature);
}
struct boss_razuvious_minionAI : public ScriptedAI
{
- explicit boss_razuvious_minionAI(Creature* c) : ScriptedAI(c) { }
-
- EventMap events;
+ explicit boss_razuvious_minionAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
- events.Reset();
+ scheduler.CancelAll();
+ ScheduleAttackDummy();
+ }
+
+ void ScheduleAttackDummy()
+ {
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H);
+ if (Creature* targetDummy = me->FindNearestCreature(NPC_TARGET_DUMMY, 10.0f))
+ {
+ me->SetFacingToObject(targetDummy);
+ }
+ scheduler.Schedule(6s, 9s, GROUP_OOC_RP, [this](TaskContext context)
+ {
+ me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H);
+ context.Repeat(6s, 9s);
+ });
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_FACE_ME:
+ scheduler.CancelGroup(GROUP_OOC_RP);
+ me->SetSheath(SHEATH_STATE_UNARMED);
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
+ if (InstanceScript* instance = me->GetInstanceScript())
+ {
+ if (Creature* creature = instance->GetCreature(DATA_RAZUVIOUS))
+ {
+ me->SetFacingToObject(creature);
+ }
+ }
+ break;
+ case ACTION_TALK:
+ Talk(SAY_DEATH_KNIGHT_UNDERSTUDY);
+ break;
+ case ACTION_EMOTE:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
+ break;
+ case ACTION_SALUTE:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
+ break;
+ case ACTION_BACK_TO_TRAINING:
+ me->SetSheath(SHEATH_STATE_MELEE);
+ ScheduleAttackDummy();
+ break;
+ }
}
void KilledUnit(Unit* who) override
@@ -193,18 +355,23 @@ public:
void JustEngagedWith(Unit* who) override
{
- if (Creature* cr = me->FindNearestCreature(NPC_RAZUVIOUS, 100.0f))
+ scheduler.CancelGroup(GROUP_OOC_RP);
+ if (InstanceScript* instance = me->GetInstanceScript())
{
- cr->SetInCombatWithZone();
- cr->AI()->AttackStart(who);
+ if (Creature* creature = instance->GetCreature(DATA_RAZUVIOUS))
+ {
+ creature->SetInCombatWithZone();
+ creature->AI()->AttackStart(who);
+ }
}
}
void UpdateAI(uint32 diff) override
{
+ scheduler.Update(diff);
+
if (UpdateVictim())
{
- events.Update(diff);
if (!me->HasUnitState(UNIT_STATE_CASTING) || !me->IsCharmed())
{
DoMeleeAttackIfReady();
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index 2f45192b7..431e5ae55 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -52,6 +52,17 @@ inline uint8 GetEruptionSection(float x, float y)
return 3;
}
+ObjectData const creatureData[] =
+{
+ { NPC_RAZUVIOUS, DATA_RAZUVIOUS },
+ { 0, 0 }
+};
+
+ObjectData const gameObjectData[] =
+{
+ { 0, 0 }
+};
+
class instance_naxxramas : public InstanceMapScript
{
public:
@@ -68,6 +79,7 @@ public:
{
SetHeaders(DataHeader);
SetBossNumber(MAX_ENCOUNTERS);
+ LoadObjectData(creatureData, gameObjectData);
for (auto& i : HeiganEruption)
i.clear();
@@ -253,6 +265,8 @@ public:
_lichkingGUID = creature->GetGUID();
return;
}
+
+ InstanceScript::OnCreatureCreate(creature);
}
void OnGameObjectCreate(GameObject* pGo) override
@@ -498,6 +512,8 @@ public:
}
break;
}
+
+ InstanceScript::OnGameObjectCreate(pGo);
}
void OnGameObjectRemove(GameObject* pGo) override
diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
index 256ca8633..5c237d784 100644
--- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h
+++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
@@ -58,26 +58,27 @@ enum NXData
DATA_STALAGG_BOSS = 108,
DATA_FEUGEN_BOSS = 109,
DATA_THADDIUS_GATE = 110,
- DATA_GOTHIK_BOSS = 111,
- DATA_GOTHIK_ENTER_GATE = 112,
- DATA_GOTHIK_INNER_GATE = 113,
- DATA_GOTHIK_EXIT_GATE = 114,
- DATA_HORSEMEN_GATE = 115,
- DATA_LICH_KING_BOSS = 116,
- DATA_KELTHUZAD_FLOOR = 117,
- DATA_ABOMINATION_KILLED = 118,
- DATA_FRENZY_REMOVED = 119,
- DATA_CHARGES_CROSSED = 120,
- DATA_SPORE_KILLED = 121,
- DATA_HUNDRED_CLUB = 122,
- DATA_DANCE_FAIL = 123,
- DATA_IMMORTAL_FAIL = 124,
- DATA_KELTHUZAD_GATE = 125,
- DATA_HAD_THADDIUS_GREET = 126,
- DATA_KELTHUZAD_PORTAL_1 = 127,
- DATA_KELTHUZAD_PORTAL_2 = 128,
- DATA_KELTHUZAD_PORTAL_3 = 129,
- DATA_KELTHUZAD_PORTAL_4 = 130
+ DATA_RAZUVIOUS = 111,
+ DATA_GOTHIK_BOSS = 112,
+ DATA_GOTHIK_ENTER_GATE = 113,
+ DATA_GOTHIK_INNER_GATE = 114,
+ DATA_GOTHIK_EXIT_GATE = 115,
+ DATA_HORSEMEN_GATE = 116,
+ DATA_LICH_KING_BOSS = 117,
+ DATA_KELTHUZAD_FLOOR = 118,
+ DATA_ABOMINATION_KILLED = 119,
+ DATA_FRENZY_REMOVED = 120,
+ DATA_CHARGES_CROSSED = 121,
+ DATA_SPORE_KILLED = 122,
+ DATA_HUNDRED_CLUB = 123,
+ DATA_DANCE_FAIL = 124,
+ DATA_IMMORTAL_FAIL = 125,
+ DATA_KELTHUZAD_GATE = 126,
+ DATA_HAD_THADDIUS_GREET = 127,
+ DATA_KELTHUZAD_PORTAL_1 = 128,
+ DATA_KELTHUZAD_PORTAL_2 = 129,
+ DATA_KELTHUZAD_PORTAL_3 = 130,
+ DATA_KELTHUZAD_PORTAL_4 = 131
};
enum NXGOs
@@ -137,6 +138,9 @@ enum NXNPCs
NPC_STALAGG = 15929,
NPC_FEUGEN = 15930,
+ // Razuvious
+ NPC_RAZUVIOUS = 16061,
+
// Four horseman
NPC_BARON_RIVENDARE = 30549,
NPC_SIR_ZELIEK = 16063,
diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp
index 9085eeeb3..274748225 100644
--- a/src/server/scripts/Northrend/zone_dalaran.cpp
+++ b/src/server/scripts/Northrend/zone_dalaran.cpp
@@ -20,6 +20,7 @@
#include "Player.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
+#include "TaskScheduler.h"
#include "World.h"
// Ours
@@ -506,108 +507,113 @@ enum MinigobData
SPELL_IMPROVED_BLINK = 61995,
EVENT_SELECT_TARGET = 1,
- EVENT_BLINK = 2,
- EVENT_DESPAWN_VISUAL = 3,
- EVENT_DESPAWN = 4,
+ EVENT_POLYMORPH = 2,
+ EVENT_LAUGH = 3,
+ EVENT_MOVE = 4,
+ EVENT_DESPAWN_VISUAL = 5,
+ EVENT_DESPAWN = 6,
MAIL_MINIGOB_ENTRY = 264,
MAIL_DELIVER_DELAY_MIN = 5 * MINUTE,
MAIL_DELIVER_DELAY_MAX = 15 * MINUTE
};
-class npc_minigob_manabonk : public CreatureScript
+struct npc_minigob_manabonk : public ScriptedAI
{
-public:
- npc_minigob_manabonk() : CreatureScript("npc_minigob_manabonk") {}
-
- struct npc_minigob_manabonkAI : public ScriptedAI
+ npc_minigob_manabonk(Creature* creature) : ScriptedAI(creature)
{
- npc_minigob_manabonkAI(Creature* creature) : ScriptedAI(creature)
- {
- me->setActive(true);
- }
+ me->setActive(true);
+ }
- void Reset() override
- {
- me->SetVisible(false);
- events.ScheduleEvent(EVENT_SELECT_TARGET, IN_MILLISECONDS);
- }
+ void Reset() override
+ {
+ me->SetVisible(false);
+ events.ScheduleEvent(EVENT_SELECT_TARGET, 1s);
+ }
- Player* SelectTargetInDalaran()
- {
- std::list PlayerInDalaranList;
- PlayerInDalaranList.clear();
+ Player* SelectTargetInDalaran()
+ {
+ std::list playerInDalaranList;
+ playerInDalaranList.clear();
- Map::PlayerList const& players = me->GetMap()->GetPlayers();
- for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
- if (Player* player = itr->GetSource()->ToPlayer())
- if (player->GetZoneId() == ZONE_DALARAN && !player->IsFlying() && !player->IsMounted() && !player->IsGameMaster())
- PlayerInDalaranList.push_back(player);
-
- if (PlayerInDalaranList.empty())
- return nullptr;
- return Acore::Containers::SelectRandomContainerElement(PlayerInDalaranList);
- }
-
- void SendMailToPlayer(Player* player)
- {
- CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
- int16 deliverDelay = irand(MAIL_DELIVER_DELAY_MIN, MAIL_DELIVER_DELAY_MAX);
- MailDraft(MAIL_MINIGOB_ENTRY, true).SendMailTo(trans, MailReceiver(player), MailSender(MAIL_CREATURE, me->GetEntry()), MAIL_CHECK_MASK_NONE, deliverDelay);
- CharacterDatabase.CommitTransaction(trans);
- }
-
- void UpdateAI(uint32 diff) override
- {
- if (!sWorld->getBoolConfig(CONFIG_MINIGOB_MANABONK))
- return;
-
- events.Update(diff);
-
- while (uint32 eventId = events.ExecuteEvent())
+ me->GetMap()->DoForAllPlayers([&](Player* player)
{
- switch (eventId)
- {
- case EVENT_SELECT_TARGET:
- me->SetVisible(true);
- DoCast(me, SPELL_TELEPORT_VISUAL);
- if (Player* player = SelectTargetInDalaran())
- {
- me->NearTeleportTo(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0.0f);
- DoCast(player, SPELL_MANABONKED);
- SendMailToPlayer(player);
- }
- events.ScheduleEvent(EVENT_BLINK, 3ms);
- break;
- case EVENT_BLINK:
- {
- DoCast(me, SPELL_IMPROVED_BLINK);
- Position pos = me->GetRandomNearPosition((urand(15, 40)));
- me->GetMotionMaster()->MovePoint(0, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
- events.ScheduleEvent(EVENT_DESPAWN, 3ms);
- events.ScheduleEvent(EVENT_DESPAWN_VISUAL, 3ms);
- break;
- }
- case EVENT_DESPAWN_VISUAL:
- DoCast(me, SPELL_TELEPORT_VISUAL);
- break;
- case EVENT_DESPAWN:
+ if (player->GetZoneId() == ZONE_DALARAN && !player->IsFlying() && !player->IsMounted() && !player->IsGameMaster())
+ playerInDalaranList.push_back(player);
+ });
+
+ if (playerInDalaranList.empty())
+ return nullptr;
+ return Acore::Containers::SelectRandomContainerElement(playerInDalaranList);
+ }
+
+ void SendMailToPlayer(Player* player)
+ {
+ CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
+ int16 deliverDelay = irand(MAIL_DELIVER_DELAY_MIN, MAIL_DELIVER_DELAY_MAX);
+ MailDraft(MAIL_MINIGOB_ENTRY, true).SendMailTo(trans, MailReceiver(player), MailSender(MAIL_CREATURE, me->GetEntry()), MAIL_CHECK_MASK_NONE, deliverDelay);
+ CharacterDatabase.CommitTransaction(trans);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!sWorld->getBoolConfig(CONFIG_MINIGOB_MANABONK))
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SELECT_TARGET:
+ me->SetVisible(true);
+ DoCastSelf(SPELL_TELEPORT_VISUAL);
+ if (Player* player = SelectTargetInDalaran())
+ {
+ playerGUID = player->GetGUID();
+ Position pos = player->GetPosition();
+ me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
+ me->GetMotionMaster()->MoveRandom(10);
+ }
+ events.ScheduleEvent(EVENT_POLYMORPH, 30s);
+ break;
+ case EVENT_POLYMORPH:
+ if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
+ {
+ DoCast(player, SPELL_MANABONKED);
+ SendMailToPlayer(player);
+ }
+ else
me->DespawnOrUnsummon();
- break;
- default:
- break;
- }
+ events.ScheduleEvent(EVENT_LAUGH, 2s);
+ break;
+ case EVENT_LAUGH:
+ me->GetMotionMaster()->MoveIdle();
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH_NO_SHEATHE);
+ events.ScheduleEvent(EVENT_MOVE, 4s);
+ break;
+ case EVENT_MOVE:
+ {
+ Position pos = me->GetRandomNearPosition((urand(15, 40)));
+ me->GetMotionMaster()->MovePoint(0, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true);
+ }
+ events.ScheduleEvent(EVENT_DESPAWN_VISUAL, 3s);
+ events.ScheduleEvent(EVENT_DESPAWN, 4s);
+ break;
+ case EVENT_DESPAWN_VISUAL:
+ DoCastSelf(SPELL_IMPROVED_BLINK);
+ break;
+ case EVENT_DESPAWN:
+ me->DespawnOrUnsummon();
+ break;
+ default:
+ break;
}
}
-
- private:
- EventMap events;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_minigob_manabonkAI(creature);
}
+private:
+ ObjectGuid playerGUID;
};
class npc_dalaran_mage : public CreatureScript
@@ -861,8 +867,6 @@ void AddSC_dalaran()
new npc_dalaran_mage();
new npc_dalaran_warrior();
RegisterCreatureAI(npc_cosmetic_toy_plane);
-
- // theirs
new npc_mageguard_dalaran();
- new npc_minigob_manabonk();
+ RegisterCreatureAI(npc_minigob_manabonk);
}
diff --git a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp
index 00034a60f..8c0e5d9cb 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp
@@ -46,6 +46,7 @@ enum Spells
SPELL_POSSESS_SPIRIT_IMMUNE = 40282,
SPELL_SPIRITUAL_VENGEANCE = 40268,
SPELL_BRIEF_STUN = 41421,
+ SPELL_BERSERK = 45078,
SPELL_SPIRIT_LANCE = 40157,
SPELL_SPIRIT_CHAINS = 40175,
@@ -54,13 +55,7 @@ enum Spells
enum Misc
{
- SET_DATA_INTRO = 1,
-
- EVENT_SPELL_INCINERATE = 1,
- EVENT_SPELL_DOOM_BLOSSOM = 2,
- EVENT_SPELL_CRUSHING_SHADOWS = 3,
- EVENT_SPELL_SHADOW_OF_DEATH = 4,
- EVENT_TALK_KILL = 10
+ SET_DATA_INTRO = 1
};
struct ShadowOfDeathSelector
@@ -73,9 +68,11 @@ struct ShadowOfDeathSelector
struct boss_teron_gorefiend : public BossAI
{
- boss_teron_gorefiend(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND), intro(false) { }
-
- bool intro;
+ boss_teron_gorefiend(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND)
+ {
+ _recentlySpoken = false;
+ _intro = false;
+ }
void Reset() override
{
@@ -83,36 +80,72 @@ struct boss_teron_gorefiend : public BossAI
me->CastSpell(me, SPELL_SHADOW_OF_DEATH_REMOVE, true);
}
+ void JustEngagedWith(Unit* who) override
+ {
+ ScheduleTimedEvent(20s, 30s, [&]
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
+ {
+ if (roll_chance_i(50))
+ Talk(SAY_INCINERATE);
+ me->CastSpell(target, SPELL_INCINERATE, false);
+ }
+ }, 20s, 50s);
+
+ ScheduleTimedEvent(5s, 10s, [&]
+ {
+ if (roll_chance_i(50))
+ Talk(SAY_BLOSSOM);
+ me->CastSpell(me, SPELL_SUMMON_DOOM_BLOSSOM, false);
+ }, 35s);
+
+ ScheduleTimedEvent(17s, 22s, [&]
+ {
+ if (roll_chance_i(20))
+ Talk(SAY_CRUSHING);
+ me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me, false);
+ }, 10s, 26s);
+
+ ScheduleTimedEvent(10s, [&]
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, ShadowOfDeathSelector()))
+ me->CastSpell(target, SPELL_SHADOW_OF_DEATH, false);
+ }, 30s, 50s);
+
+ ScheduleTimedEvent(10min, [&]
+ {
+ DoCastSelf(SPELL_BERSERK);
+ }, 5min);
+
+ BossAI::JustEngagedWith(who);
+ }
+
+ void KilledUnit(Unit* victim) override
+ {
+ if (!_recentlySpoken && victim->IsPlayer())
+ {
+ Talk(SAY_SLAY);
+ _recentlySpoken = true;
+
+ ScheduleUniqueTimedEvent(6s, [&]
+ {
+ _recentlySpoken = false;
+ }, 1);
+ }
+ }
+
void SetData(uint32 type, uint32 id) override
{
if (type || !me->IsAlive())
return;
- if (id == SET_DATA_INTRO && !intro)
+ if (id == SET_DATA_INTRO && !_intro)
{
- intro = true;
+ _intro = true;
Talk(SAY_INTRO);
}
}
- void JustEngagedWith(Unit* who) override
- {
- BossAI::JustEngagedWith(who);
- events.ScheduleEvent(EVENT_SPELL_INCINERATE, 24000);
- events.ScheduleEvent(EVENT_SPELL_DOOM_BLOSSOM, 10000);
- events.ScheduleEvent(EVENT_SPELL_CRUSHING_SHADOWS, 17000);
- events.ScheduleEvent(EVENT_SPELL_SHADOW_OF_DEATH, 20000);
- }
-
- void KilledUnit(Unit* /*victim*/) override
- {
- if (events.GetNextEventTime(EVENT_TALK_KILL) == 0)
- {
- Talk(SAY_SLAY);
- events.ScheduleEvent(EVENT_TALK_KILL, 6000);
- }
- }
-
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
@@ -130,43 +163,13 @@ struct boss_teron_gorefiend : public BossAI
if (!UpdateVictim())
return;
- events.Update(diff);
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- switch (events.ExecuteEvent())
- {
- case EVENT_SPELL_INCINERATE:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- {
- if (roll_chance_i(50))
- Talk(SAY_INCINERATE);
- me->CastSpell(target, SPELL_INCINERATE, false);
- }
- events.ScheduleEvent(EVENT_SPELL_INCINERATE, 25000);
- break;
- case EVENT_SPELL_DOOM_BLOSSOM:
- if (roll_chance_i(50))
- Talk(SAY_BLOSSOM);
-
- me->CastSpell(me, SPELL_SUMMON_DOOM_BLOSSOM, false);
- events.ScheduleEvent(EVENT_SPELL_DOOM_BLOSSOM, 40000);
- break;
- case EVENT_SPELL_CRUSHING_SHADOWS:
- if (roll_chance_i(20))
- Talk(SAY_CRUSHING);
- me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me, false);
- events.ScheduleEvent(EVENT_SPELL_CRUSHING_SHADOWS, 15000);
- break;
- case EVENT_SPELL_SHADOW_OF_DEATH:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, ShadowOfDeathSelector()))
- me->CastSpell(target, SPELL_SHADOW_OF_DEATH, false);
- events.ScheduleEvent(EVENT_SPELL_SHADOW_OF_DEATH, 30000);
- break;
- }
-
+ scheduler.Update(diff);
DoMeleeAttackIfReady();
}
+
+ private:
+ bool _recentlySpoken;
+ bool _intro;
};
class spell_teron_gorefiend_shadow_of_death : public AuraScript
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
index b1f07c880..62818e025 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
@@ -392,34 +392,14 @@ struct boss_kaelthas : public BossAI
}
}
});
- scheduler.Schedule(2min, GROUP_PROGRESS_PHASE, [this](TaskContext)
+ scheduler.Schedule(90s, GROUP_PROGRESS_PHASE, [this](TaskContext)
{
PhaseAllAdvisorsExecute();
});
}, EVENT_PREFIGHT_PHASE52);
break;
case ACTION_PROGRESS_PHASE_CHECK:
- if (_phase == PHASE_WEAPONS)
- {
- bool aliveWeapon = false;
- summons.DoForAllSummons([&aliveWeapon](WorldObject* summon)
- {
- if (Creature* summonedCreature = summon->ToCreature())
- {
- if (summonedCreature->IsAlive())
- {
- if (summonedCreature->GetEntry() >= NPC_NETHERSTRAND_LONGBOW && summonedCreature->GetEntry() <= NPC_STAFF_OF_DISINTEGRATION)
- {
- aliveWeapon = true;
- return;
- }
- }
- }
- });
- if (!aliveWeapon)
- PhaseAllAdvisorsExecute();
- }
- else if (_phase == PHASE_ALL_ADVISORS)
+ if (_phase == PHASE_ALL_ADVISORS)
{
bool advisorAlive = false;
summons.DoForAllSummons([&advisorAlive](WorldObject* summon)
@@ -1163,9 +1143,19 @@ class spell_kaelthas_mind_control : public SpellScript
targets.remove_if(Acore::ObjectTypeIdCheck(TYPEID_PLAYER, false));
}
+ void HandleEffect(SpellEffIndex /*effIndex*/)
+ {
+ if (!GetCaster() || !GetHitPlayer())
+ return;
+
+ if (Player* player = GetHitPlayer())
+ GetCaster()->GetThreatMgr().ResetThreat(player);
+ }
+
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kaelthas_mind_control::SelectTarget, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_kaelthas_mind_control::HandleEffect, EFFECT_ALL, SPELL_AURA_ANY);
}
};
diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp
index 34ca2c9e0..bccd14d26 100644
--- a/src/server/scripts/Outland/zone_shattrath_city.cpp
+++ b/src/server/scripts/Outland/zone_shattrath_city.cpp
@@ -16,6 +16,7 @@
*/
#include "CreatureScript.h"
+#include "PassiveAI.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
@@ -253,9 +254,166 @@ public:
};
};
+enum ShattrathQuests
+{
+ // QuestID : Creature Template ID
+ // Heroic Daily Quests
+ QUEST_H_NAZZAN = 11354, // 24410
+ QUEST_H_KELIDAN = 11362, // 24413
+ QUEST_H_BLADEFIST = 11363, // 24414
+ QUEST_H_QUAG = 11368, // 24419
+ QUEST_H_BLACKSTALKER = 11369, // 24420
+ QUEST_H_WARLORD = 11370, // 24421
+ QUEST_H_IKISS = 11372, // 24422
+ QUEST_H_SHAFFAR = 11373, // 24423
+ QUEST_H_EXARCH = 11374, // 24424
+ QUEST_H_MURMUR = 11375, // 24425
+ QUEST_H_EPOCH = 11378, // 24427
+ QUEST_H_AEONUS = 11382, // 24428
+ QUEST_H_WARP = 11384, // 24431
+ QUEST_H_CALCULATOR = 11386, // 21504
+ QUEST_H_SKYRISS = 11388, // 24435
+ QUEST_H_KAEL = 11499, // 24855
+ // Normal Daily Quests
+ QUEST_N_CENTURIONS = 11364, // 24411
+ QUEST_N_MYRMIDONS = 11371, // 24415
+ QUEST_N_INSTRUCTORS = 11376, // 24426
+ QUEST_N_LORDS = 11383, // 24429
+ QUEST_N_CHANNELERS = 11385, // 24430
+ QUEST_N_DESTROYERS = 11387, // 24432
+ QUEST_N_SENTINELS = 11389, // 24434
+ QUEST_N_SISTERS = 11500, // 24854
+
+ ACTION_UPDATE_QUEST_STATUS = 1,
+
+ POOL_SHATTRATH_DAILY_H = 356,
+ POOL_SHATTRATH_DAILY_N = 357,
+
+ // Image NPCs
+ NPC_SHATTRATH_DAILY_H = 24854,
+ NPC_SHATTRATH_DAILY_N = 24410
+};
+
+struct npc_shattrath_daily_quest : public NullCreatureAI
+{
+ npc_shattrath_daily_quest(Creature* c) : NullCreatureAI(c) {}
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_UPDATE_QUEST_STATUS)
+ {
+ uint32 creature = me->GetEntry();
+ QueryResult result = CharacterDatabase.Query("SELECT `quest_id` FROM `pool_quest_save` WHERE `pool_id` = '{}'", creature == NPC_SHATTRATH_DAILY_H ? POOL_SHATTRATH_DAILY_H : POOL_SHATTRATH_DAILY_N);
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ int quest_id = fields[0].Get();
+ uint32 templateID;
+
+ if (creature == NPC_SHATTRATH_DAILY_H)
+ {
+ switch (quest_id)
+ {
+ case QUEST_H_NAZZAN:
+ templateID = 24410;
+ break;
+ case QUEST_H_KELIDAN:
+ templateID = 24413;
+ break;
+ case QUEST_H_BLADEFIST:
+ templateID = 24414;
+ break;
+ case QUEST_H_QUAG:
+ templateID = 24419;
+ break;
+ case QUEST_H_BLACKSTALKER:
+ templateID = 24420;
+ break;
+ case QUEST_H_WARLORD:
+ templateID = 24421;
+ break;
+ case QUEST_H_IKISS:
+ templateID = 24422;
+ break;
+ case QUEST_H_SHAFFAR:
+ templateID = 24423;
+ break;
+ case QUEST_H_EXARCH:
+ templateID = 24424;
+ break;
+ case QUEST_H_MURMUR:
+ templateID = 24425;
+ break;
+ case QUEST_H_EPOCH:
+ templateID = 24427;
+ break;
+ case QUEST_H_AEONUS:
+ templateID = 24428;
+ break;
+ case QUEST_H_WARP:
+ templateID = 24431;
+ break;
+ case QUEST_H_CALCULATOR:
+ templateID = 21504;
+ break;
+ case QUEST_H_SKYRISS:
+ templateID = 24435;
+ break;
+ case QUEST_H_KAEL:
+ templateID = 24855;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (creature == NPC_SHATTRATH_DAILY_N)
+ {
+ switch (quest_id)
+ {
+ case QUEST_N_CENTURIONS:
+ templateID = 24411;
+ break;
+ case QUEST_N_MYRMIDONS:
+ templateID = 24415;
+ break;
+ case QUEST_N_INSTRUCTORS:
+ templateID = 24426;
+ break;
+ case QUEST_N_LORDS:
+ templateID = 24429;
+ break;
+ case QUEST_N_CHANNELERS:
+ templateID = 24430;
+ break;
+ case QUEST_N_DESTROYERS:
+ templateID = 24432;
+ break;
+ case QUEST_N_SENTINELS:
+ templateID = 24434;
+ break;
+ case QUEST_N_SISTERS:
+ templateID = 24854;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(templateID))
+ {
+ CreatureModel const* model = ObjectMgr::ChooseDisplayId(ci);
+ me->SetDisplayId(model->CreatureDisplayID, model->DisplayScale);
+ }
+ }
+ }
+ }
+};
+
void AddSC_shattrath_city()
{
new npc_shattrathflaskvendors();
new npc_zephyr();
new npc_kservant();
+ RegisterCreatureAI(npc_shattrath_daily_quest);
}
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index 654d14a63..2a69287c2 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -3990,6 +3990,37 @@ class spell_item_eye_of_grillok_aura : public AuraScript
}
};
+enum FelManaPotion
+{
+ SPELL_ALCHEMIST_STONE = 17619,
+ SPELL_ALCHEMIST_STONE_ENERGIZE = 21400
+};
+
+class spell_item_fel_mana_potion : public AuraScript
+{
+ PrepareAuraScript(spell_item_fel_mana_potion)
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_ALCHEMIST_STONE, SPELL_ALCHEMIST_STONE_ENERGIZE });
+ }
+
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (caster->HasAura(SPELL_ALCHEMIST_STONE))
+ {
+ uint32 val = GetSpellInfo()->Effects[EFFECT_0].BasePoints * 0.4f;
+ caster->CastCustomSpell(SPELL_ALCHEMIST_STONE_ENERGIZE, SPELLVALUE_BASE_POINT0, val, caster, true);
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_item_fel_mana_potion::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_ENERGIZE);
+ }
+};
+
void AddSC_item_spell_scripts()
{
RegisterSpellScript(spell_item_massive_seaforium_charge);
@@ -4112,5 +4143,6 @@ void AddSC_item_spell_scripts()
RegisterSpellScript(spell_item_venomhide_feed);
RegisterSpellScript(spell_item_scroll_of_retribution);
RegisterSpellAndAuraScriptPair(spell_item_eye_of_grillok, spell_item_eye_of_grillok_aura);
+ RegisterSpellScript(spell_item_fel_mana_potion);
}
diff --git a/src/server/shared/DataStores/DBCStructure.h b/src/server/shared/DataStores/DBCStructure.h
index b3e634673..938411343 100644
--- a/src/server/shared/DataStores/DBCStructure.h
+++ b/src/server/shared/DataStores/DBCStructure.h
@@ -590,11 +590,11 @@ struct BarberShopStyleEntry
{
uint32 Id; // 0
uint32 type; // 1 value 0 -> hair, value 2 -> facialhair
- //char const* name[16]; // 2-17 name of hair style
- //uint32 name_flags; // 18
- //uint32 unk_name[16]; // 19-34, all empty
- //uint32 unk_flags; // 35
- //float CostMultiplier; // 36 values 1 and 0.75
+ //char const* displayNameLang[16]; // 2-17 name of hair style
+ //char const* displayNameLangMask; // 18
+ //char const* descriptionLang[16]; // 19-34, all empty
+ //char const* descriptionLangMask; // 35
+ //float costModifier; // 36 values 1 and 0.75
uint32 race; // 37 race
uint32 gender; // 38 0 -> male, 1 -> female
uint32 hair_id; // 39 real ID to hair/facial hair
@@ -618,11 +618,11 @@ struct BattlemasterListEntry
struct CharStartOutfitEntry
{
- //uint32 Id; // 0
+ //uint32 ID; // 0
uint8 Race; // 1
uint8 Class; // 2
uint8 Gender; // 3
- //uint8 Unused; // 4
+ //uint8 outfitID; // 4 unused
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
@@ -658,11 +658,11 @@ struct CharSectionsEntry
struct CharTitlesEntry
{
uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId()
- //uint32 unk1; // 1 flags?
+ //uint32 conditionID; // 1 Never used by the client. Should be used serverside?
char const* nameMale[16]; // 2-17
- // 18 string flag, unused
+ //uint32 nameLangMask // 18 string flag, unused
char const* nameFemale[16]; // 19-34
- // 35 string flag, unused
+ //uint32 nameLang1Mask // 35 string flag, unused
uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1< RankID; // 4-8
- // 9-12 not used, always 0, maybe not used high ranks
- uint32 DependsOn; // 13 index in Talent.dbc (TalentEntry)
- // 14-15 not used
- uint32 DependsOnRank; // 16
- // 17-18 not used
+ // uint32 spellRank [4] // 9-12 not used, always 0, maybe not used high ranks
+ uint32 DependsOn; // 13 preReqTalent1 index in Talent.dbc (TalentEntry)
+ // uint32 preReqTalent[2] // 14-15 not used
+ uint32 DependsOnRank; // 16 preReqRank1
+ // uint32 preReqRank[2] // 17-18 not used
uint32 addToSpellBook; // 19 also need disable higest ranks on reset talent tree
- //uint32 unk2; // 20, all 0
- //uint64 allowForPet; // 21-22 its a 64 bit mask for pet 1<.
*/
-#include "Define.h"
#include "SharedDefines.h"
+#include "Define.h"
#include "SmartEnum.h"
#include
@@ -311,7 +311,7 @@ AC_API_EXPORT EnumText EnumUtils::ToString(SpellAttr1 value)
case SPELL_ATTR1_FINISHING_MOVE_DURATION: return { "SPELL_ATTR1_FINISHING_MOVE_DURATION", "Requires combo points (type 2)", "" };
case SPELL_ATTR1_IGNORE_OWNERS_DEATH: return { "SPELL_ATTR1_IGNORE_OWNERS_DEATH", "Unknwon attribute 23@Attr1", "" };
case SPELL_ATTR1_SPECIAL_SKILLUP: return { "SPELL_ATTR1_SPECIAL_SKILLUP", "Fishing (client only)", "" };
- case SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT: return { "SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT", "Unknown attribute 25@Attr1", "" };
+ case SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT: return { "SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT", "Aura stays after combat", "Aura will not be removed when the unit leaves combat" };
case SPELL_ATTR1_REQUIRE_ALL_TARGETS: return { "SPELL_ATTR1_REQUIRE_ALL_TARGETS", "Unknown attribute 26@Attr1", "Related to [target=focus] and [target=mouseover] macros?" };
case SPELL_ATTR1_DISCOUNT_POWER_ON_MISS: return { "SPELL_ATTR1_DISCOUNT_POWER_ON_MISS", "Unknown attribute 27@Attr1", "Melee spell?" };
case SPELL_ATTR1_NO_AURA_ICON: return { "SPELL_ATTR1_NO_AURA_ICON", "Hide in aura bar (client only)", "" };