Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2023-08-07 23:58:57 +08:00
40 changed files with 515 additions and 232 deletions
+1
View File
@@ -20,6 +20,7 @@ Versions of MySQL:
| MySQL Version | Supported |
| ------------- | ------------------ |
| 8.1 | :white_check_mark: |
| 8.0 | :white_check_mark: |
| 5.7 | :white_check_mark: |
| 5.6 and lower | :red_circle: |
+12 -13
View File
@@ -4,17 +4,16 @@ set -e
echo "Pending SQL check script:"
echo
for i in `find data/sql/updates/pending* -name "*.sql" -type f`; do
if $(cat "$i"|sed "s/'.*'\(.*\)/\1/g"|grep -q -i -E "(PROCEDURE|FUNCTION)"); then
echo "> PROCEDURE check - Failed"
exit 1
else
echo "> PROCEDURE check - OK"
fi
done
for i in `find data/sql/updates/pending* -name "*.sql" -type f`; do
if [[ $(cat "$i"|sed 's/ --[^--]*$//'|tr -d '\n'|tr -d " "|tail -c 1) != ";" ]]; then
# We want to ensure the end of file has a semicolon and doesn't have extra
# newlines
find data/sql/updates/pending* -name "*.sql" -type f | while read -r file; do
# The first sed script collapses all strings into an empty string. The
# contents of strings aren't necessary for this check and its still valid
# sql.
#
# The second rule removes sql comments.
ERR_AT_EOF="$(sed -e "s/'.*'/''/g" -e 's/ --([^-])*$//' "$file" | tr -d '\n ' | tail -c 1)"
if [[ "$ERR_AT_EOF" != ";" ]]; then
echo "Missing Semicolon (;) or multiple newlines at the end of the file."
exit 1
else
@@ -22,8 +21,8 @@ for i in `find data/sql/updates/pending* -name "*.sql" -type f`; do
fi
done
for i in `find data/sql/updates/pending* -name "*sql" -type f`; do
if $(cat "$i"|sed "s/'.*'\(.*\)/\1/g"|grep -q -i -E "broadcast_text"); then
find data/sql/updates/pending* -name "*.sql" -type f | while read -r file; do
if sed "s/'.*'\(.*\)/\1/g" "$file" | grep -q -i -E "broadcast_text"; then
echo "> broadcast_text check - Failed"
echo " - DON'T EDIT broadcast_text TABLE UNLESS YOU KNOW WHAT YOU ARE DOING!"
echo " - This error can safely be ignored if the changes are approved to be sniffed."
+3 -3
View File
@@ -3,11 +3,11 @@ CREATE USER 'acore'@'localhost' IDENTIFIED BY 'acore' WITH MAX_QUERIES_PER_HOUR
GRANT ALL PRIVILEGES ON * . * TO 'acore'@'localhost' WITH GRANT OPTION;
CREATE DATABASE `acore_world` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_general_ci;
CREATE DATABASE `acore_world` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE `acore_characters` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_general_ci;
CREATE DATABASE `acore_characters` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE `acore_auth` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_general_ci;
CREATE DATABASE `acore_auth` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON `acore_world` . * TO 'acore'@'localhost' WITH GRANT OPTION;
@@ -0,0 +1,3 @@
-- DB update 2023_08_04_00 -> 2023_08_06_00
--
UPDATE `creature_template` SET `pickpocketloot` = 18331 WHERE (`entry` = 20256);
@@ -0,0 +1,3 @@
-- DB update 2023_08_06_00 -> 2023_08_06_01
-- https://www.wowhead.com/wotlk/quest=9433/
UPDATE `creature_template` SET `ScriptName`='npc_controller' WHERE `entry` IN (17178, 19405);
@@ -0,0 +1,10 @@
-- DB update 2023_08_06_01 -> 2023_08_06_02
--
UPDATE `creature_template` SET `ScriptName` = 'npc_magister_aledis' WHERE `entry` = 20159;
-- Gossip to start combat vs event completion and quest reward
UPDATE `conditions` SET `ConditionTypeOrReference`=28, `Comment`='Show gossip option 0 if player has quest Arelion\'s Secret completed OR' WHERE `SourceGroup`=8081 AND `ElseGroup`=0;
DELETE FROM `conditions` WHERE `SourceGroup`=8081 AND `ElseGroup`=1;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(15, 8081, 0, 0, 1, 8, 0, 10286, 0, 0, 0, 0, 0, '', 'Show gossip option 0 if player has quest Arelion\'s Secret rewarded');
@@ -0,0 +1,8 @@
-- DB update 2023_08_06_02 -> 2023_08_06_03
--
UPDATE `creature_template` SET `gossip_menu_id` = 7092, `npcflag` = `npcflag`|1 WHERE `entry`=16123;
DELETE FROM `gossip_menu` WHERE `MenuID` = 7092;
INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES (7092, 8345);
DELETE FROM `npc_text` WHERE `ID` = 8345;
INSERT INTO `npc_text` (`ID`, `Probability0`, `BroadcastTextID0`) VALUES (8345, 1, 11932);
@@ -0,0 +1,6 @@
-- DB update 2023_08_06_03 -> 2023_08_06_04
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 17350;
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 17350);
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
(17350, 0, 0, 0, 0, 0, 100, 0, 1500, 1500, 10500, 10500, 11, 36332, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Royal Blue Flutterer - In Combat - Cast \'36332\'');
@@ -0,0 +1,3 @@
-- DB update 2023_08_06_04 -> 2023_08_06_05
--
UPDATE `item_template` SET `spellppmRate_1` = 1 WHERE (`entry` = 31193);
@@ -0,0 +1,27 @@
-- DB update 2023_08_06_05 -> 2023_08_06_06
-- Verog the Dervish
DELETE FROM `smart_scripts` WHERE `entryorguid` = 3395 AND `source_type` = 0;
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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, 53, 0, 3395, 0, 0, 300000, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Verog the Dervish - Out of Combat - Start Waypoint Movement (No Repeat)'),
(3395, 0, 1, 0, 40, 0, 100, 1, 3, 3395, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 'Verog the Dervish - On WP reached - Set Orientation (No Repeat)'),
(3395, 0, 2, 0, 11, 0, 100, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Verog the Dervish - On Respawn - Say Line 0 (No Repeat)');
-- wp data (sniffed only final orientation is wrong)
DELETE FROM `waypoints` WHERE `entry` = 3395;
INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `point_comment`) VALUES
(3395, 1, -1209.9082, -2731.1567, 105.875336, NULL, 0, 'Verog the Dervish'),
(3395, 2, -1209.5896, -2736.3755, 103.212364, NULL, 0, 'Verog the Dervish'),
(3395, 3, -1209.0471, -2739.1501, 102.66668, NULL, 0, 'Verog the Dervish');
-- summons (sniffed position)
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (3274, 3275, 3397) AND `source_type` = 0;
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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
(3274, 0, 0, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 11, 9128, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Kolkar Pack Runner - On Aggro - Cast \'Battle Shout\' (No Repeat)'),
(3274, 0, 1, 2, 6, 0, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Kolkar Pack Runner - On Just Died - Say Line 0'),
(3274, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 12, 3395, 4, 300000, 0, 0, 0, 8, 0, 0, 0, 0, -1210.5857, -2725.839, 106.782524, 4.956735134124755859, 'Kolkar Pack Runner - On Just Died - Summon Creature \'Verog the Dervish\''),(3275, 0, 0, 0, 0, 0, 80, 0, 12000, 12000, 7000, 7000, 0, 11, 11976, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Kolkar Marauder - In Combat - Cast \'Strike\''),
(3275, 0, 1, 2, 6, 0, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Kolkar Marauder - On Just Died - Say Line 0'),
(3275, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 12, 3395, 4, 300000, 0, 0, 0, 8, 0, 0, 0, 0, -1210.5857, -2725.839, 106.782524, 4.956735134124755859, 'Kolkar Marauder - On Just Died - Summon Creature \'Verog the Dervish\''),
(3397, 0, 0, 0, 0, 0, 100, 0, 35000, 35000, 10000, 10000, 0, 11, 6742, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Kolkar Bloodcharger - In Combat - Cast \'Bloodlust\' (No Repeat)'),
(3397, 0, 1, 0, 0, 0, 100, 0, 20000, 20000, 5000, 5000, 0, 11, 172, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Kolkar Bloodcharger - In Combat - Cast \'Corruption\' (No Repeat)'),
(3397, 0, 2, 3, 6, 0, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Kolkar Bloodcharger - On Just Died - Say Line 0'),
(3397, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 12, 3395, 4, 300000, 0, 0, 0, 8, 0, 0, 0, 0, -1210.5857, -2725.839, 106.782524, 4.956735134124755859, 'Kolkar Bloodcharger - On Just Died - Summon Creature \'Verog the Dervish\'');
@@ -0,0 +1,3 @@
-- DB update 2023_08_06_06 -> 2023_08_06_07
--
UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask`|256|4096 WHERE `entry` = 17256;
@@ -0,0 +1,3 @@
-- DB update 2023_08_06_07 -> 2023_08_06_08
--
UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask`|33554432 WHERE `entry` IN (15689, 17225);
@@ -0,0 +1,3 @@
-- DB update 2023_08_06_08 -> 2023_08_06_09
--
UPDATE `creature_template` SET `spell_school_immune_mask` = 0 WHERE (`entry` = 16488);
@@ -0,0 +1,55 @@
-- DB update 2023_08_06_09 -> 2023_08_06_10
-- Master Woodsman Anderhol smart ai
SET @ENTRY := 27277;
DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY;
UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @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, 1, 20, 0, 100, 0, 12227, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On player rewarded quest Doing Your Duty (12227) - Self: Talk Alright Ben. We\'ve retrieved the amberseeds again. You know ... (0) to invoker'),
(@ENTRY, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 10, 113907, 27071, 0, 0, 0, 0, 0, 'On player rewarded quest Doing Your Duty (12227) - Creature Benjamin Jacobs (27071) with guid 113907 (fetching): Set creature data #0 to 0');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 27277 AND `SourceId` = 0;
DELETE FROM `creature_text` WHERE `CreatureID` = 27277;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(27277, 0, 0, 'Alright Ben. We\'ve retrieved the amberseeds again. You know the drill.', 12, 0, 100, 0, 0, 0, 26350, 0, 'Master Woodsman Anderhol // Master Woodsman Anderhol');
DELETE FROM `creature_text` WHERE `CreatureID` = 27071;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(27071, 0, 0, 'I know, I know. Back in the bucket....', 12, 0, 100, 0, 0, 0, 26351, 0, 'Benjamin Jacobs // Benjamin Jacobs');
DELETE FROM `waypoints` WHERE (`entry` = 27071) AND (`pointid` IN (1, 2));
DELETE FROM `waypoints` WHERE (`entry` = 2707100) AND (`pointid` BETWEEN 1 AND 13);
INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `point_comment`) VALUES
(27071, 1, 3405.55, -2792.33, 201.809, NULL, 0, NULL),
(27071, 2, 3414.19, -2795.07, 201.514, NULL, 0, NULL),
(2707100, 1, 3416.03, -2792.59, 201.818, NULL, 0, NULL),
(2707100, 2, 3416.28, -2791.84, 201.818, NULL, 0, NULL),
(2707100, 3, 3420.28, -2786.09, 201.818, NULL, 0, NULL),
(2707100, 4, 3421, -2785.11, 201.657, NULL, 0, NULL),
(2707100, 5, 3421.46, -2784.44, 201.777, NULL, 0, NULL),
(2707100, 6, 3422.37, -2783.12, 202.621, NULL, 0, NULL),
(2707100, 7, 3422.38, -2783.11, 202.614, NULL, 0, NULL),
(2707100, 8, 3423.12, -2782.5, 202.625, NULL, 0, NULL),
(2707100, 9, 3424.93, -2780.98, 202.628, NULL, 0, NULL),
(2707100, 10, 3426.54, -2779.83, 202.889, NULL, 0, NULL),
(2707100, 11, 3427.29, -2779.33, 202.889, NULL, 0, NULL),
(2707100, 12, 3428.04, -2779.33, 202.889, NULL, 0, NULL),
(2707100, 13, 3431.14, -2779.69, 202.65, NULL, 0, NULL);
-- Benjamin Jacobs smart ai
SET @ENTRY := 27071;
DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY;
UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @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, 1, 38, 0, 100, 0, 0, 0, 0, 0, 53, 0, 27071, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On data[0] set to 0 - Self: Start path #27071, walk, do not repeat, Passive'),
(@ENTRY, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 67, 1, 6000, 6000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'On data[0] set to 0 - Trigger timed event timedEvent[1] in 6000 - 6000 ms // -meta_wait'),
(@ENTRY, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 67, 2, 14000, 14000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'On data[0] set to 0 - Trigger timed event timedEvent[2] in 14000 - 14000 ms // -meta_wait'),
(@ENTRY, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 67, 3, 24000, 24000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'On data[0] set to 0 - Trigger timed event timedEvent[3] in 24000 - 24000 ms // -meta_wait'),
(@ENTRY, 0, 4, 0, 59, 0, 100, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On timed event timedEvent[1] triggered - Self: Talk I know, I know. Back in the bucket.... (0) to invoker'),
(@ENTRY, 0, 5, 0, 59, 0, 100, 0, 2, 0, 0, 0, 53, 0, 2707100, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On timed event timedEvent[2] triggered - Self: Start path #2707100, walk, do not repeat, Passive'),
(@ENTRY, 0, 6, 7, 59, 0, 100, 0, 3, 0, 0, 0, 90, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On timed event timedEvent[3] triggered - Self: Set stand state to KNEEL'),
(@ENTRY, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 41, 6000, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On timed event timedEvent[3] triggered - Self: Despawn in 6 s respawn in 1 seconds'),
(@ENTRY, 0, 8, 0, 11, 0, 100, 0, 0, 0, 0, 0, 91, 8, 0, 0, 0, 0, 0, 10, 113907, 27071, 0, 0, 0, 0, 0, 'On respawn - Creature Benjamin Jacobs (27071) with guid 113907 (fetching): Remove stand state KNEEL');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 27071 AND `SourceId` = 0;
@@ -0,0 +1,14 @@
-- DB update 2023_08_06_10 -> 2023_08_06_11
UPDATE `creature_template` SET `scriptname` = '' WHERE `entry` = 27326;
DELETE FROM `spell_target_position` WHERE `ID` = 48324 AND `EffectIndex` = 0;
INSERT INTO `spell_target_position` (`ID`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `VerifiedBuild`) VALUES
(48324, 0, 571, 3454.11, -2802.37, 202.14, 0, 34149345);
DELETE FROM `spell_script_names` WHERE `spell_id` IN (48382, 47533);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(48382, 'spell_q12227_outhouse_groans'),
(47533, 'spell_q12227_camera_shake');
UPDATE `creature_template` SET `flags_extra`=`flags_extra`|128 WHERE `entry` =27326;
@@ -0,0 +1,5 @@
-- DB update 2023_08_06_11 -> 2023_08_07_00
--
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 18829) AND (`source_type` = 0) AND (`id` IN (2));
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`, `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
(18829, 0, 2, 0, 0, 0, 100, 0, 8200, 8800, 12150, 19450, 0, 11, 34435, 32, 0, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Hellfire Warder - In Combat - Cast \'Rain of Fire\'');
@@ -22,7 +22,7 @@
#include "Duration.h"
#include "Log.h"
#include "SRP6.h"
#include "ServerMotd.h"
#include "MotdMgr.h"
#include "Util.h"
#include "World.h"
#include <boost/asio/buffer.hpp>
@@ -75,7 +75,7 @@ void RASession::Start()
LOG_INFO("commands.ra", "User {} (IP: {}) authenticated correctly to RA", username, GetRemoteIpAddress());
// Authentication successful, send the motd
Send(std::string(std::string(Motd::GetMotd()) + "\r\n").c_str());
Send(std::string(std::string(sMotdMgr->GetMotd()) + "\r\n").c_str());
// Read commands
for (;;)
@@ -606,6 +606,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
me->InterruptNonMeleeSpells(false);
}
if (e.action.cast.castFlags & SMARTCAST_THREATLIST_NOT_SINGLE)
if (me->GetThreatMgr().GetThreatListSize() <= 1)
break;
TriggerCastFlags triggerFlags = TRIGGERED_NONE;
if (e.action.cast.castFlags & SMARTCAST_TRIGGERED)
{
@@ -1876,7 +1876,8 @@ enum SmartCastFlags
//CAST_NO_MELEE_IF_OOM = 0x08, //Prevents creature from entering melee if out of mana or out of range
//CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself
SMARTCAST_AURA_NOT_PRESENT = 0x20, //Only casts the spell if the target does not have an aura from the spell
SMARTCAST_COMBAT_MOVE = 0x40 //Prevents combat movement if cast successful. Allows movement on range, OOM, LOS
SMARTCAST_COMBAT_MOVE = 0x40, //Prevents combat movement if cast successful. Allows movement on range, OOM, LOS
SMARTCAST_THREATLIST_NOT_SINGLE = 0x80 //Only cast if the source's threatlist is higher than one. This includes pets (see Skeram's True Fulfillment)
};
// one line in DB is one event
+11 -2
View File
@@ -2492,13 +2492,22 @@ float Pet::GetNativeObjectScale() const
scale = creatureFamily->minScale + float(GetLevel() - creatureFamily->minScaleLevel) / creatureFamily->maxScaleLevel * (creatureFamily->maxScale - creatureFamily->minScale);
if (CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId()))
{
if (displayInfo->scale > 1.f && GetCreatureTemplate()->IsExotic())
{
// Exotic pets have a scale of 1
scale = 1.0f;
}
else
{
scale *= displayInfo->scale;
}
}
return scale;
}
return Guardian::GetNativeObjectScale();
// Fallback value if the conditions are not met
return 1.0f;
}
std::string Pet::GenerateActionBarData() const
+3
View File
@@ -14660,6 +14660,8 @@ void Unit::TauntApply(Unit* taunter)
return;
SetInFront(taunter);
SetGuidValue(UNIT_FIELD_TARGET, taunter->GetGUID());
if (creature->IsAIEnabled)
creature->AI()->AttackStart(taunter);
@@ -14698,6 +14700,7 @@ void Unit::TauntFadeOut(Unit* taunter)
if (target && target != taunter)
{
SetGuidValue(UNIT_FIELD_TARGET, target->GetGUID());
SetInFront(target);
if (creature->IsAIEnabled)
creature->AI()->AttackStart(target);
@@ -45,7 +45,7 @@
#include "Realm.h"
#include "ReputationMgr.h"
#include "ScriptMgr.h"
#include "ServerMotd.h"
#include "MotdMgr.h"
#include "SharedDefines.h"
#include "SocialMgr.h"
#include "SpellAuraEffects.h"
@@ -819,7 +819,7 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder)
// Send MOTD
{
SendPacket(Motd::GetMotdPacket());
SendPacket(sMotdMgr->GetMotdPacket());
// send server info
if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
@@ -1134,7 +1134,7 @@ void WorldSession::HandlePlayerLoginToCharInWorld(Player* pCurrChar)
// Send MOTD
{
SendPacket(Motd::GetMotdPacket());
SendPacket(sMotdMgr->GetMotdPacket());
// send server info
if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
+104
View File
@@ -0,0 +1,104 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "MotdMgr.h"
#include "Config.h"
#include "Opcodes.h"
#include "ScriptMgr.h"
#include "Util.h"
#include "WorldPacket.h"
#include "Tokenize.h"
#include <iterator>
namespace
{
WorldPacket MotdPacket;
std::string FormattedMotd;
}
MotdMgr* MotdMgr::instance()
{
static MotdMgr instance;
return &instance;
}
void MotdMgr::SetMotd(std::string motd)
{
// scripts may change motd
sScriptMgr->OnMotdChange(motd);
WorldPacket data(SMSG_MOTD); // new in 2.0.1
std::vector<std::string_view> motdTokens = Acore::Tokenize(motd, '@', true);
data << uint32(motdTokens.size()); // line count
for (std::string_view token : motdTokens)
data << token;
MotdPacket = data;
if (!motdTokens.size())
return;
std::ostringstream oss;
std::copy(motdTokens.begin(), motdTokens.end() - 1, std::ostream_iterator<std::string_view>(oss, "\n"));
oss << *(motdTokens.end() - 1); // copy back element
FormattedMotd = oss.str();
}
void MotdMgr::LoadMotd()
{
uint32 oldMSTime = getMSTime();
uint32 realmId = sConfigMgr->GetOption<int32>("RealmID", 0);
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_MOTD);
stmt->SetData(0, realmId);
PreparedQueryResult result = LoginDatabase.Query(stmt);
std::string motd;
if (result)
{
Field* fields = result->Fetch();
motd = fields[0].Get<std::string>();
}
else
{
LOG_WARN("server.loading", ">> Loaded 0 motd definitions. DB table `motd` is empty for this realm!");
LOG_INFO("server.loading", " ");
}
motd = /* fctlsup << //0x338// "63"+"cx""d2"+"1e""dd"+"cx""ds"+"ce""dd"+"ce""7D"+ << */ motd
/*"d3"+"ce"*/ + "@|" + "cf" +/*"as"+"k4"*/"fF" + "F4" +/*"d5"+"f3"*/"A2" + "DT"/*"F4"+"Az"*/ + "hi" + "s "
/*"fd"+"hy"*/ + "se" + "rv" +/*"nh"+"k3"*/"er" + " r" +/*"x1"+"A2"*/"un" + "s "/*"F2"+"Ay"*/ + "on" + " Az"
/*"xs"+"5n"*/ + "er" + "ot" +/*"xs"+"A2"*/"hC" + "or" +/*"a4"+"f3"*/"e|" + "r "/*"f2"+"A2"*/ + "|c" + "ff"
/*"5g"+"A2"*/ + "3C" + "E7" +/*"k5"+"AX"*/"FF" + "ww" +/*"sx"+"Gj"*/"w." + "az"/*"a1"+"vf"*/ + "er" + "ot"
/*"ds"+"sx"*/ + "hc" + "or" +/*"F4"+"k5"*/"e." + "or" +/*"po"+"xs"*/"g|r"/*"F4"+"p2"+"o4"+"A2"+"i2"*/;;
MotdMgr::SetMotd(motd);
LOG_INFO("server.loading", ">> Loaded Motd Definitions in {} ms", GetMSTimeDiffToNow(oldMSTime));
LOG_INFO("server.loading", " ");
}
char const* MotdMgr::GetMotd()
{
return FormattedMotd.c_str();
}
WorldPacket const* MotdMgr::GetMotdPacket()
{
return &MotdPacket;
}
@@ -15,25 +15,32 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ServerMotd_h__
#define ServerMotd_h__
#ifndef _MOTDMGR_H_
#define _MOTDMGR_H_
#include "Define.h"
#include <string>
class WorldPacket;
namespace Motd
class AC_GAME_API MotdMgr
{
public:
static MotdMgr* instance();
/// Set a new Message of the Day
void SetMotd(std::string motd);
/// Load Message of the Day
void LoadMotd();
/// Get the current Message of the Day
char const* GetMotd();
/// Get the motd packet to send at login
WorldPacket const* GetMotdPacket();
}
};
#endif //ServerMotd_h_
// _
#define sMotdMgr MotdMgr::instance()
#endif // _MOTDMGR_H_
-64
View File
@@ -1,64 +0,0 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ServerMotd.h"
#include "Opcodes.h"
#include "ScriptMgr.h"
#include "Util.h"
#include "WorldPacket.h"
#include "Tokenize.h"
#include <iterator>
namespace
{
WorldPacket MotdPacket;
std::string FormattedMotd;
}
void Motd::SetMotd(std::string motd)
{
// scripts may change motd
sScriptMgr->OnMotdChange(motd);
WorldPacket data(SMSG_MOTD); // new in 2.0.1
std::vector<std::string_view> motdTokens = Acore::Tokenize(motd, '@', true);
data << uint32(motdTokens.size()); // line count
for (std::string_view token : motdTokens)
data << token;
MotdPacket = data;
if (!motdTokens.size())
return;
std::ostringstream oss;
std::copy(motdTokens.begin(), motdTokens.end() - 1, std::ostream_iterator<std::string_view>(oss, "\n"));
oss << *(motdTokens.end() - 1); // copy back element
FormattedMotd = oss.str();
}
char const* Motd::GetMotd()
{
return FormattedMotd.c_str();
}
WorldPacket const* Motd::GetMotdPacket()
{
return &MotdPacket;
}
@@ -303,29 +303,15 @@ static Optional<float> GetVelocity(Unit* owner, Unit* target, G3D::Vector3 const
}
UnitMoveType moveType = Movement::SelectSpeedType(moveFlags);
speed = std::max(target->GetSpeed(moveType), owner->GetSpeed(moveType));
speed = target->GetSpeed(moveType);
if (playerPet)
{
float distance = owner->GetDistance2d(dest.x, dest.y) - (*speed / 2.f);
float distance = owner->GetDistance2d(dest.x, dest.y) - target->GetObjectSize() - (*speed / 2.f);
if (distance > 0.f)
{
float multiplier = 1.f + (distance / 10.f);
*speed *= multiplier;
}
else
{
switch (moveType)
{
case MOVE_RUN_BACK:
case MOVE_SWIM_BACK:
case MOVE_FLIGHT_BACK:
break;
default:
*speed *= 0.9f;
break;
}
}
}
}
@@ -1101,6 +1101,20 @@ void AuraEffect::PeriodicTick(AuraApplication* aurApp, Unit* caster) const
Unit* target = aurApp->GetTarget();
// Update serverside orientation of tracking channeled auras on periodic update ticks
// exclude players because can turn during channeling and shouldn't desync orientation client/server
if (caster && !caster->IsPlayer() && m_spellInfo->IsChanneled() && m_spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL))
{
ObjectGuid const channelGuid = caster->GetGuidValue(UNIT_FIELD_CHANNEL_OBJECT);
if (!channelGuid.IsEmpty() && channelGuid != caster->GetGUID())
{
if (WorldObject const* objectTarget = ObjectAccessor::GetWorldObject(*caster, channelGuid))
{
caster->SetInFront(objectTarget);
}
}
}
switch (GetAuraType())
{
case SPELL_AURA_PERIODIC_DUMMY:
@@ -6122,14 +6136,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
GetBase()->GetUnitOwner()->CastSpell(target, triggeredSpellInfo, true, 0, this, GetBase()->GetUnitOwner()->GetGUID());
return;
}
// Slime Spray - temporary here until preventing default effect works again
// added on 9.10.2010
case 69508:
{
if (caster)
caster->CastSpell(target, triggerSpellId, true, nullptr, nullptr, caster->GetGUID());
return;
}
// Trial of the Crusader, Jaraxxus, Spinning Pain Spike
case 66283:
{
-3
View File
@@ -3317,9 +3317,6 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/)
if (HostileReference* forcedVictim = unitTarget->GetThreatMgr().GetOnlineContainer().getReferenceByTarget(m_caster))
unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
}
if (unitTarget->ToCreature()->IsAIEnabled && !unitTarget->ToCreature()->HasReactState(REACT_PASSIVE))
unitTarget->ToCreature()->AI()->AttackStart(m_caster);
}
void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
@@ -662,7 +662,8 @@ void SpellMgr::LoadSpellInfoCorrections()
});
// Kill Command
ApplySpellFix({ 34027 }, [](SpellInfo* spellInfo)
// Kill Command, Overpower
ApplySpellFix({ 34027, 37529 }, [](SpellInfo* spellInfo)
{
spellInfo->ProcCharges = 0;
});
@@ -4516,6 +4517,12 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
});
// Silence
ApplySpellFix({ 18278 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx4 |= SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND;
});
// Absorb Life
ApplySpellFix({ 34239 }, [](SpellInfo* spellInfo)
{
-1
View File
@@ -601,7 +601,6 @@ public:
#ifdef MOD_PLAYERBOTS
[[nodiscard]] virtual char const* GetPlayerbotsDBRevision() const = 0;
#endif
virtual void LoadMotd() = 0;
virtual void UpdateAreaDependentAuras() = 0;
[[nodiscard]] virtual uint32 GetCleaningFlags() const = 0;
virtual void SetCleaningFlags(uint32 flags) = 0;
+3 -36
View File
@@ -74,7 +74,7 @@
#include "PoolMgr.h"
#include "Realm.h"
#include "ScriptMgr.h"
#include "ServerMotd.h"
#include "MotdMgr.h"
#include "SkillDiscovery.h"
#include "SkillExtraItems.h"
#include "SmartAI.h"
@@ -2006,8 +2006,8 @@ void World::SetInitialWorldSettings()
sAutobroadcastMgr->LoadAutobroadcasts();
///- Load Motd
LOG_INFO("server.loading", "Loading MotD...");
LoadMotd();
LOG_INFO("server.loading", "Loading Motd...");
sMotdMgr->LoadMotd();
///- Load and initialize scripts
sObjectMgr->LoadSpellScripts(); // must be after load Creature/Gameobject(Template/Data)
@@ -2237,39 +2237,6 @@ void World::DetectDBCLang()
LOG_INFO("server.loading", " ");
}
void World::LoadMotd()
{
uint32 oldMSTime = getMSTime();
uint32 realmId = sConfigMgr->GetOption<int32>("RealmID", 0);
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_MOTD);
stmt->SetData(0, realmId);
PreparedQueryResult result = LoginDatabase.Query(stmt);
std::string motd;
if (result)
{
Field* fields = result->Fetch();
motd = fields[0].Get<std::string>();
}
else
{
LOG_WARN("server.loading", ">> Loaded 0 motd definitions. DB table `motd` is empty for this realm!");
LOG_INFO("server.loading", " ");
}
motd = /* fctlsup << //0x338// "63"+"cx""d2"+"1e""dd"+"cx""ds"+"ce""dd"+"ce""7D"+ << */ motd
/*"d3"+"ce"*/ + "@|" + "cf" +/*"as"+"k4"*/"fF" + "F4" +/*"d5"+"f3"*/"A2" + "DT"/*"F4"+"Az"*/ + "hi" + "s "
/*"fd"+"hy"*/ + "se" + "rv" +/*"nh"+"k3"*/"er" + " r" +/*"x1"+"A2"*/"un" + "s "/*"F2"+"Ay"*/ + "on" + " Az"
/*"xs"+"5n"*/ + "er" + "ot" +/*"xs"+"A2"*/"hC" + "or" +/*"a4"+"f3"*/"e|" + "r "/*"f2"+"A2"*/ + "|c" + "ff"
/*"5g"+"A2"*/ + "3C" + "E7" +/*"k5"+"AX"*/"FF" + "ww" +/*"sx"+"Gj"*/"w." + "az"/*"a1"+"vf"*/ + "er" + "ot"
/*"ds"+"sx"*/ + "hc" + "or" +/*"F4"+"k5"*/"e." + "or" +/*"po"+"xs"*/"g|r"/*"F4"+"p2"+"o4"+"A2"+"i2"*/;;
Motd::SetMotd(motd);
LOG_INFO("server.loading", ">> Loaded Motd Definitions in {} ms", GetMSTimeDiffToNow(oldMSTime));
LOG_INFO("server.loading", " ");
}
/// Update the World !
void World::Update(uint32 diff)
{
-1
View File
@@ -340,7 +340,6 @@ public:
#ifdef MOD_PLAYERBOTS
[[nodiscard]] char const* GetPlayerbotsDBRevision() const override { return m_PlayerbotsDBRevision.c_str(); }
#endif
void LoadMotd() override;
void UpdateAreaDependentAuras() override;
+3 -3
View File
@@ -33,7 +33,7 @@ EndScriptData */
#include "LFGMgr.h"
#include "Language.h"
#include "MapMgr.h"
#include "ServerMotd.h"
#include "MotdMgr.h"
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "SkillDiscovery.h"
@@ -412,9 +412,9 @@ public:
static bool HandleReloadMotdCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Motd...");
sWorld->LoadMotd();
sMotdMgr->LoadMotd();
handler->SendGlobalGMSysMessage("DB table `motd` reloaded.");
handler->SendGlobalSysMessage(Motd::GetMotd());
handler->SendGlobalSysMessage(sMotdMgr->GetMotd());
return true;
}
+3 -3
View File
@@ -32,7 +32,7 @@
#include "Player.h"
#include "Realm.h"
#include "ScriptMgr.h"
#include "ServerMotd.h"
#include "MotdMgr.h"
#include "StringConvert.h"
#include "UpdateTime.h"
#include "VMapFactory.h"
@@ -295,7 +295,7 @@ public:
// Display the 'Message of the day' for the realm
static bool HandleServerMotdCommand(ChatHandler* handler)
{
handler->PSendSysMessage(LANG_MOTD_CURRENT, Motd::GetMotd());
handler->PSendSysMessage(LANG_MOTD_CURRENT, sMotdMgr->GetMotd());
return true;
}
@@ -567,7 +567,7 @@ public:
trans->Append(stmt);
LoginDatabase.CommitTransaction(trans);
sWorld->LoadMotd();
sMotdMgr->LoadMotd();
handler->PSendSysMessage(LANG_MOTD_NEW, Acore::StringTo<int32>(realmId).value(), strMotd);
return true;
}
@@ -277,13 +277,9 @@ public:
{
if (Creature* c = me->SummonCreature(NPC_OOZE_SPRAY_STALKER, *target, TEMPSUMMON_TIMED_DESPAWN, 8000))
{
me->SetOrientation(me->GetAngle(c));
me->SetControlled(true, UNIT_STATE_ROOT);
me->DisableRotate(true);
me->SetFacingTo(me->GetAngle(c));
me->SendMovementFlagUpdate();
me->SetFacingToObject(c);
Talk(EMOTE_SLIME_SPRAY);
me->CastSpell(c, SPELL_SLIME_SPRAY, false);
DoCastSelf(SPELL_SLIME_SPRAY);
}
}
events.DelayEvents(1);
@@ -328,65 +328,69 @@ enum Outhouse
SOUND_FEMALE = 12671,
SOUND_MALE = 12670,
// Spell
SPELL_OUTHOUSE_GROANS = 48382,
SPELL_CAMERA_SHAKE = 47533,
SPELL_DUST_FIELD = 48329
SPELL_DUST_FIELD = 48329,
// Item
ITEM_ANDERHOLS_SLIDER_CIDER = 37247,
// NPC
NPC_OUTHOUSE_BUNNY_GRIZZLY = 27326,
};
class npc_outhouse_bunny : public CreatureScript
class spell_q12227_outhouse_groans : public SpellScript
{
public:
npc_outhouse_bunny() : CreatureScript("npc_outhouse_bunny") { }
PrepareSpellScript(spell_q12227_outhouse_groans);
struct npc_outhouse_bunnyAI : public ScriptedAI
bool Validate(SpellInfo const* /*spellInfo*/) override
{
npc_outhouse_bunnyAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
_counter = 0;
_gender = 0;
return ValidateSpellInfo({ SPELL_CAMERA_SHAKE, SPELL_DUST_FIELD });
}
void SetData(uint32 Type, uint32 Data) override
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (Type == 1)
_gender = Data;
}
if (Player* player = GetCaster()->ToPlayer())
{
player->CastSpell(player, SPELL_CAMERA_SHAKE, true);
void SpellHit(Unit* Caster, SpellInfo const* Spell) override
{
if (Spell->Id == SPELL_OUTHOUSE_GROANS)
{
++_counter;
if (_counter < 5)
DoCast(Caster, SPELL_CAMERA_SHAKE, true);
else
_counter = 0;
DoCast(me, SPELL_DUST_FIELD, true);
switch (_gender)
switch (GetCaster()->getGender())
{
case GENDER_FEMALE:
DoPlaySoundToSet(me, SOUND_FEMALE);
player->PlayDirectSound(SOUND_FEMALE);
break;
case GENDER_MALE:
DoPlaySoundToSet(me, SOUND_MALE);
player->PlayDirectSound(SOUND_MALE);
break;
default:
break;
}
}
}
private:
uint8 _counter;
uint8 _gender;
};
CreatureAI* GetAI(Creature* creature) const override
void Register() override
{
return new npc_outhouse_bunnyAI(creature);
OnEffectHitTarget += SpellEffectFn(spell_q12227_outhouse_groans::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_q12227_camera_shake : public SpellScript
{
PrepareSpellScript(spell_q12227_camera_shake);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_DUST_FIELD });
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (Player* player = GetCaster()->ToPlayer())
if (Creature* target = GetClosestCreatureWithEntry(player, NPC_OUTHOUSE_BUNNY_GRIZZLY, 3.0f)) // hackfix: Outhouse bunny doesnt show in any script. But the visual of Dust Field do not show if cast by the player
target->CastSpell(target, SPELL_DUST_FIELD, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_q12227_camera_shake::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// Tallhorn Stage
enum TallhornStage
@@ -1300,7 +1304,6 @@ void AddSC_grizzly_hills()
new npc_emily();
new npc_mrfloppy();
new npc_ravenous_worg();
new npc_outhouse_bunny();
new npc_tallhorn_stag();
new npc_amberpine_woodsman();
RegisterCreatureAI(npc_wounded_skirmisher);
@@ -1314,4 +1317,6 @@ void AddSC_grizzly_hills()
new spell_warhead_detonate();
new spell_vehicle_warhead_fuse();
new spell_warhead_fuse();
RegisterSpellScript(spell_q12227_outhouse_groans);
RegisterSpellScript(spell_q12227_camera_shake);
}
@@ -397,6 +397,113 @@ public:
}
};
enum Aledis
{
SAY_CHALLENGE = 0,
SAY_DEFEATED = 1,
EVENT_TALK = 1,
EVENT_ATTACK = 2,
EVENT_EVADE = 3,
EVENT_FIREBALL = 4,
EVENT_FROSTNOVA = 5,
SPELL_FIREBALL = 20823,
SPELL_FROSTNOVA = 11831,
};
struct npc_magister_aledis : public ScriptedAI
{
npc_magister_aledis(Creature* creature) : ScriptedAI(creature) { }
void StartFight(Player* player)
{
me->Dismount();
me->SetFacingToObject(player);
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
_playerGUID = player->GetGUID();
_events.ScheduleEvent(EVENT_TALK, 2s);
}
void Reset() override
{
me->RestoreFaction();
me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
me->SetImmuneToPC(true);
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*spellInfo = nullptr*/) override
{
if (damage > me->GetHealth() || me->HealthBelowPctDamaged(20, damage))
{
damage = 0;
_events.Reset();
me->RestoreFaction();
me->RemoveAllAuras();
me->GetThreatMgr().ClearAllThreat();
me->CombatStop(true);
me->SetNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
me->SetImmuneToPC(true);
Talk(SAY_DEFEATED);
_events.ScheduleEvent(EVENT_EVADE, 1min);
}
}
void UpdateAI(uint32 diff) override
{
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_TALK:
Talk(SAY_CHALLENGE);
_events.ScheduleEvent(EVENT_ATTACK, 2s);
break;
case EVENT_ATTACK:
me->SetImmuneToPC(false);
me->SetFaction(FACTION_MONSTER);
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID))
{
AttackStart(player);
}
_events.ScheduleEvent(EVENT_FIREBALL, 1ms);
_events.ScheduleEvent(EVENT_FROSTNOVA, 5s);
break;
case EVENT_FIREBALL:
DoCast(SPELL_FIREBALL);
_events.ScheduleEvent(EVENT_FIREBALL, 10s);
break;
case EVENT_FROSTNOVA:
DoCastAOE(SPELL_FROSTNOVA);
_events.ScheduleEvent(EVENT_FROSTNOVA, 20s);
break;
case EVENT_EVADE:
EnterEvadeMode();
break;
}
}
if (UpdateVictim())
{
DoMeleeAttackIfReady();
}
}
void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/) override
{
CloseGossipMenuFor(player);
me->StopMoving();
StartFight(player);
}
private:
EventMap _events;
ObjectGuid _playerGUID;
};
enum Beacon
{
NPC_STONESCHYE_WHELP = 16927,
@@ -464,4 +571,6 @@ void AddSC_hellfire_peninsula()
new npc_wounded_blood_elf();
new npc_fel_guard_hound();
new go_beacon();
RegisterCreatureAI(npc_magister_aledis);
}
+8 -16
View File
@@ -1612,19 +1612,17 @@ public:
## go_amberpine_outhouse
######*/
#define GOSSIP_USE_OUTHOUSE "Use the outhouse."
#define GO_ANDERHOLS_SLIDER_CIDER_NOT_FOUND "Quest item Anderhol's Slider Cider not found."
enum AmberpineOuthouse
{
ITEM_ANDERHOLS_SLIDER_CIDER = 37247,
NPC_OUTHOUSE_BUNNY = 27326,
QUEST_DOING_YOUR_DUTY = 12227,
SPELL_INDISPOSED = 53017,
SPELL_INDISPOSED_II = 48324,
SPELL_INDISPOSED_III = 48341,
SPELL_CREATE_AMBERSEEDS = 48330,
GOSSIP_OUTHOUSE_INUSE = 12775,
GOSSIP_OUTHOUSE_VACANT = 12779
GOSSIP_OUTHOUSE_VACANT = 12779,
GOSSIP_USE_OUTHOUSE = 9492,
};
class go_amberpine_outhouse : public GameObjectScript
@@ -1637,7 +1635,7 @@ public:
QuestStatus status = player->GetQuestStatus(QUEST_DOING_YOUR_DUTY);
if (status == QUEST_STATUS_INCOMPLETE || status == QUEST_STATUS_COMPLETE || status == QUEST_STATUS_REWARDED)
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_USE_OUTHOUSE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
AddGossipItemFor(player, GOSSIP_USE_OUTHOUSE, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, GOSSIP_OUTHOUSE_VACANT, go->GetGUID());
}
else
@@ -1646,21 +1644,15 @@ public:
return true;
}
bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 action) override
bool OnGossipSelect(Player* player, GameObject* /*go*/, uint32 /*sender*/, uint32 action) override
{
ClearGossipMenuFor(player);
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
CloseGossipMenuFor(player);
Creature* target = GetClosestCreatureWithEntry(player, NPC_OUTHOUSE_BUNNY, 3.0f);
if (target)
{
target->AI()->SetData(1, player->getGender());
go->CastSpell(target, SPELL_INDISPOSED_III);
}
go->CastSpell(player, SPELL_INDISPOSED);
if (player->HasItemCount(ITEM_ANDERHOLS_SLIDER_CIDER))
player->CastSpell(player, SPELL_CREATE_AMBERSEEDS, true);
player->CastSpell(player, SPELL_INDISPOSED);
player->CastSpell(player, SPELL_INDISPOSED_II);
player->CastSpell(player, SPELL_INDISPOSED_III);
return true;
}
else
+14
View File
@@ -2668,6 +2668,19 @@ private:
TaskScheduler _scheduler;
};
struct npc_controller : public PossessedAI
{
npc_controller(Creature* creature) : PossessedAI(creature) { }
void OnCharmed(bool apply) override
{
if (!apply)
{
me->GetCharmerOrOwner()->InterruptNonMeleeSpells(false);
}
}
};
void AddSC_npcs_special()
{
// Ours
@@ -2696,4 +2709,5 @@ void AddSC_npcs_special()
new npc_stable_master();
RegisterCreatureAI(npc_arcanite_dragonling);
RegisterCreatureAI(npc_crashin_thrashin_robot);
RegisterCreatureAI(npc_controller);
}
-1
View File
@@ -111,7 +111,6 @@ public:
MOCK_METHOD(LocaleConstant, GetAvailableDbcLocale, (LocaleConstant locale), (const));
MOCK_METHOD(void, LoadDBVersion, ());
MOCK_METHOD(char const *, GetDBVersion, (), (const));
MOCK_METHOD(void, LoadMotd, ());
MOCK_METHOD(void, UpdateAreaDependentAuras, ());
MOCK_METHOD(uint32, GetCleaningFlags, (), (const));
MOCK_METHOD(void, SetCleaningFlags, (uint32 flags), ());