diff --git a/AUTHORS b/AUTHORS index 8cf220b41..8c5e802ab 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,7 +16,7 @@ Development of this project dates back to 2004, and was developed under various * SD2 project, 2008-2009, located at http://www.scriptdev2.com/ * TrinityCore, 2008-2012, located at https://www.trinitycore.org/ * SunwellCore 2012-2016, privately developed, more info at https://www.azerothcore.org/pages/sunwell.pl/ -* AzerothCore, 2016-2023, located at https://www.azerothcore.org/ +* AzerothCore, 2016-CURRENT, located at https://www.azerothcore.org/ ## Authorship of the code Authorship is assigned for each commit within the git history, which is stored in these git repositories: @@ -24,13 +24,13 @@ Authorship is assigned for each commit within the git history, which is stored i * github.com/TrinityCore/TrinityCore * github.com/azerothcore/azerothcore-wotlk -Unfortunately we have no detailed information of the history of the WoWD project; +Unfortunately, we have no detailed information on the history of the WoWD project; if somebody can provide information, please contact us, so that we can make this history available -SunwellCore developed privately and has no git history. +SunwellCore was developed privately and has unfortunately no git history. -## Exceptions with third party libraries -The third party libraries have their own way of addressing authorship, and the authorship of commits importing/ updating -a third party library reflects who did the importing instead of who wrote the code within the commit. +## Exceptions with third-party libraries +The third-party libraries have their own way of addressing authorship, and the authorship of commits importing/updating +a third-party library reflects who did the importing instead of who wrote the code within the commit. -The Authors of third party libraries are not explicitly mentioned, and usually are possible to obtain from the files belonging to the third party libraries. +The Authors of third-party libraries are not explicitly mentioned, and usually is possible to obtain from the files belonging to the third-party libraries. diff --git a/apps/ci/mac/ci-compile.sh b/apps/ci/mac/ci-compile.sh index 136c84b82..38e7db56a 100755 --- a/apps/ci/mac/ci-compile.sh +++ b/apps/ci/mac/ci-compile.sh @@ -10,12 +10,23 @@ ccache -s cd var/build/obj +mysql_include_path=$(brew --prefix mysql)/include/mysql +mysql_lib_path=$(brew --prefix mysql)/lib/libmysqlclient.dylib + +if [ ! -d "$mysql_include_path" ]; then + echo "Original mysql include directory doesn't exist. Lets try to use the first available folder in mysql dir." + base_dir=$(brew --cellar mysql)/$(basename $(ls -d $(brew --cellar mysql)/*/ | head -n 1)) + echo "Trying the next mysql base dir: $base_dir" + mysql_include_path=$base_dir/include/mysql + mysql_lib_path=$base_dir/lib/libmysqlclient.dylib +fi + time cmake ../../../ \ -DTOOLS_BUILD=all \ -DSCRIPTS=static \ -DCMAKE_BUILD_TYPE=Release \ --DMYSQL_ADD_INCLUDE_PATH=/usr/local/include \ --DMYSQL_LIBRARY=/usr/local/lib/libmysqlclient.dylib \ +-DMYSQL_ADD_INCLUDE_PATH=$mysql_include_path \ +-DMYSQL_LIBRARY=$mysql_lib_path \ -DREADLINE_INCLUDE_DIR=/usr/local/opt/readline/include \ -DREADLINE_LIBRARY=/usr/local/opt/readline/lib/libreadline.dylib \ -DOPENSSL_INCLUDE_DIR="$OPENSSL_ROOT_DIR/include" \ diff --git a/apps/docker/Dockerfile b/apps/docker/Dockerfile index 2050aad67..4a57db5b0 100644 --- a/apps/docker/Dockerfile +++ b/apps/docker/Dockerfile @@ -8,7 +8,6 @@ FROM ubuntu:$UBUNTU_VERSION AS skeleton ARG DOCKER=1 ARG DEBIAN_FRONTEND=noninteractive -ENV TZ=$TZ ENV AC_FORCE_CREATE_DB=1 RUN mkdir -pv \ @@ -29,11 +28,12 @@ RUN mkdir -pv \ /azerothcore/build # Configure Timezone -RUN apt-get update \ - && apt-get install -y tzdata ca-certificates \ - && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ - && echo $TZ > /etc/timezone \ - && dpkg-reconfigure --frontend noninteractive tzdata +RUN apt-get update \ + && apt-get install -y --no-install-recommends tzdata ca-certificates \ + && ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime \ + && echo "$TZ" > /etc/timezone \ + && dpkg-reconfigure --frontend noninteractive tzdata \ + && rm -rf /var/lib/apt/lists/* WORKDIR /azerothcore @@ -145,7 +145,7 @@ ENTRYPOINT ["/usr/bin/env", "bash", "/azerothcore/entrypoint.sh"] ############### FROM runtime AS authserver -LABEL description "AzerothCore Auth Server" +LABEL description="AzerothCore Auth Server" ENV ACORE_COMPONENT=authserver # Don't run database migrations. We can leave that up to the db-import container @@ -167,7 +167,7 @@ CMD ["authserver"] FROM runtime AS worldserver -LABEL description "AzerothCore World Server" +LABEL description="AzerothCore World Server" ENV ACORE_COMPONENT=worldserver # Don't run database migrations. We can leave that up to the db-import container @@ -190,7 +190,7 @@ CMD ["worldserver"] FROM runtime AS db-import -LABEL description "AzerothCore Database Import tool" +LABEL description="AzerothCore Database Import tool" USER $DOCKER_USER @@ -203,7 +203,7 @@ COPY --chown=$DOCKER_USER:$DOCKER_USER\ --from=build \ /azerothcore/env/dist/bin/dbimport /azerothcore/env/dist/bin/dbimport -CMD /azerothcore/env/dist/bin/dbimport +CMD [ "/azerothcore/env/dist/bin/dbimport" ] ############### # Client Data # @@ -225,7 +225,7 @@ VOLUME /azerothcore/env/dist/data USER $DOCKER_USER -CMD bash -c "source /azerothcore/apps/installer/includes/functions.sh && inst_download_client_data" +CMD ["bash", "-c", "source /azerothcore/apps/installer/includes/functions.sh && inst_download_client_data" ] ################## # Map Extractors # @@ -233,7 +233,7 @@ CMD bash -c "source /azerothcore/apps/installer/includes/functions.sh && inst_do FROM runtime AS tools -LABEL description "AzerothCore Tools" +LABEL description="AzerothCore Tools" WORKDIR /azerothcore/env/dist/ diff --git a/apps/installer/includes/functions.sh b/apps/installer/includes/functions.sh index b9bdd9550..7e95f78fc 100644 --- a/apps/installer/includes/functions.sh +++ b/apps/installer/includes/functions.sh @@ -39,7 +39,7 @@ function inst_configureOS() { # TODO: implement different configurations by distro source "$AC_PATH_INSTALLER/includes/os_configs/$DISTRO.sh" ;; - bsd*) echo "BSD is not supported yet" ;; + *bsd*) echo "BSD is not supported yet" ;; msys*) source "$AC_PATH_INSTALLER/includes/os_configs/windows.sh" ;; *) echo "This platform is not supported" ;; esac diff --git a/data/sql/updates/db_world/2024_08_13_00.sql b/data/sql/updates/db_world/2024_08_13_00.sql new file mode 100644 index 000000000..4505e1067 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_13_00.sql @@ -0,0 +1,311 @@ +-- DB update 2024_08_08_00 -> 2024_08_13_00 +SET +@ETCDMF = 32, -- Do not change this one +@BLIZZCON = 47, +@ETCGRIM = 81, +@ETCSHATT = 82, +@CGUID = 12556, +@DOMINOACTIONLIST = 15; + +DELETE FROM `game_event` WHERE `eventEntry` IN (@BLIZZCON, @ETCGRIM, @ETCSHATT); +INSERT INTO `game_event` (`eventEntry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `holidayStage`, `description`, `world_event`, `announce`) VALUES +(@BLIZZCON, '2008-07-31 12:00:00', '2008-08-05 12:00:00', 5184000, 7200, 0, 0, 'BlizzCon 2007', 0, 2), +(@ETCGRIM, '2008-01-02 08:00:00', '2030-12-31 06:00:00', 1440, 15, 0, 0, 'L70ETC Grim Guzzler Concert', 0, 2), +(@ETCSHATT, '2008-01-02 01:55:00', '2030-12-31 06:00:00', 240, 15, 0, 0, 'L70ETC World''s End Tavern Concert', 0, 2); + +DELETE FROM `creature` WHERE `guid` IN (6090, 7727, 9411, 26009, 34055, @CGUID+00, @CGUID+01, @CGUID+02, @CGUID+03, @CGUID+04, @CGUID+05, @CGUID+06, @CGUID+07, @CGUID+08, @CGUID+09, @CGUID+10, @CGUID+11, @CGUID+12, @CGUID+13, @CGUID+14, @CGUID+15, @CGUID+16, @CGUID+17, @CGUID+18, @CGUID+19, @CGUID+20, @CGUID+21, @CGUID+22) AND `id1` IN (23619, 23623, 23624, 23625, 23626, 23830, 23845, 23850, 23852, 23853, 23854, 23855, 28206, 28209, 28210); +INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`, `CreateObject`) VALUES +-- Grim Guzzler +(@CGUID+00, 23830, 230, 0, 0, 1, 1, 0, 846.56536865234375, -178.953567504882812, -49.6704864501953125, 2.076941728591918945, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 50664, 2), +(@CGUID+01, 23845, 230, 0, 0, 1, 1, 0, 851.30133056640625, -177.158447265625, -49.6711578369140625, 2.146754980087280273, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 50664, 2), +(@CGUID+02, 23850, 230, 0, 0, 1, 1, 0, 846.04388427734375, -177.730331420898437, -49.6703681945800781, 2.111848354339599609, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 50664, 2), +(@CGUID+03, 23852, 230, 0, 0, 1, 1, 0, 842.71783447265625, -181.561279296875, -49.6699752807617187, 1.93731546401977539, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 50664, 2), +(@CGUID+04, 23853, 230, 0, 0, 1, 1, 0, 847.64453125, -175.845840454101562, -49.6705551147460937, 2.076941728591918945, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 50664, 2), +(@CGUID+05, 23854, 230, 0, 0, 1, 1, 0, 843.40618896484375, -178.132888793945312, -49.6699714660644531, 2.042035102844238281, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 50664, 2), +(@CGUID+06, 23855, 230, 0, 0, 1, 1, 0, 847.55419921875, -180.630538940429687, -49.6706924438476562, 2.042035102844238281, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 50664, 2), +(@CGUID+07, 28206, 230, 0, 0, 1, 1, 0, 847.82305908203125, -181.144210815429687, -49.670745849609375, 1.850049018859863281, 7200, 0, 0, 42, 0, 0, 0, 0, 0, 50664, 2), +(@CGUID+08, 28209, 230, 0, 0, 1, 1, 0, 849.4901123046875, -179.31683349609375, -49.6709518432617187, 4.101523876190185546, 7200, 0, 0, 2215, 0, 0, 0, 0, 0, 50664, 2), +(@CGUID+09, 28210, 230, 0, 0, 1, 1, 0, 845.8807373046875, -182.202728271484375, -49.6704788208007812, 1.186823844909667968, 7200, 0, 0, 2215, 0, 0, 0, 0, 0, 50664, 2), +-- World's End Tavern +(@CGUID+10, 23830, 530, 0, 0, 1, 1, 0, -1750.517578125, 5136.13525390625, -36.1779632568359375, 2.076941728591918945, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 47966, 2), +(@CGUID+11, 23845, 530, 0, 0, 1, 1, 0, -1745.3955078125, 5136.41455078125, -36.1779708862304687, 2.0245819091796875, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 47966, 2), +(@CGUID+12, 23850, 530, 0, 0, 1, 1, 0, -1750.7196044921875, 5136.8251953125, -36.1779594421386718, 2.111848354339599609, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 47966, 2), +(@CGUID+13, 23852, 530, 0, 0, 1, 1, 0, -1754.9766845703125, 5133.36474609375, -36.1779670715332031, 1.93731546401977539, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 47966, 2), +(@CGUID+14, 23853, 530, 0, 0, 1, 1, 0, -1749.0806884765625, 5137.7958984375, -36.1779632568359375, 2.076941728591918945, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 47966, 2), +(@CGUID+15, 23854, 530, 0, 0, 1, 1, 0, -1752.90771484375, 5136.0673828125, -36.1779708862304687, 2.042035102844238281, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 47966, 2), +(@CGUID+16, 23855, 530, 0, 0, 1, 1, 0, -1749.9208984375, 5134.271484375, -36.1779632568359375, 2.042035102844238281, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 47966, 2), +-- BlizzCon spawns +(@CGUID+17, 23845, 530, 0, 0, 1, 1, 0, -2221.88, 5122.5, -16.52, 6.08419, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 0, 0), +(@CGUID+18, 23850, 530, 0, 0, 1, 1, 0, -2208.33, 5123.95, -20.1186, 2.94598, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 0, 0), -- Move this guy and also the FX controller +(@CGUID+19, 23852, 530, 0, 0, 1, 1, 0, -2220.98, 5130.86, -16.5221, 6.01916, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 0, 0), +(@CGUID+20, 23853, 530, 0, 0, 1, 1, 0, -2219.26, 5124.72, -16.5406, 6.08812, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 0, 0), +(@CGUID+21, 23854, 530, 0, 0, 1, 1, 0, -2220.87, 5128.07, -16.5431, 6.07022, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 0, 0), +(@CGUID+22, 23855, 530, 0, 0, 1, 1, 0, -2226.86, 5127.81, -12.9949, 5.91769, 7200, 0, 0, 4120, 0, 0, 0, 0, 0, 0, 0); + +DELETE FROM `gameobject` WHERE `id` = 186312; + +DELETE FROM `game_event_creature` WHERE `eventEntry` IN (@BLIZZCON, @ETCDMF) AND `guid` IN (6090, 7727, 9411, 26009, 34055, 38214, 39821, 39822, 39883, 39884, @CGUID+17, @CGUID+18, @CGUID+19, @CGUID+20, @CGUID+21, @CGUID+22); +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES +(@BLIZZCON, 38214), -- FX Controller +(@BLIZZCON, @CGUID+17), -- Bergrisst Controller +(@BLIZZCON, @CGUID+18), -- Concert Controller +(@BLIZZCON, @CGUID+19), -- Mai'kyl Controller +(@BLIZZCON, @CGUID+20), -- Samuro Controller +(@BLIZZCON, @CGUID+21), -- Sig Controller +(@BLIZZCON, @CGUID+22), -- Chief Thunder-Skins Controller +(@BLIZZCON, 39821), -- Concert Bruiser +(@BLIZZCON, 39822), -- Concert Bruiser +(@BLIZZCON, 39883), -- Concert Bruiser +(@BLIZZCON, 39884); -- Concert Bruiser + +DELETE FROM `game_event_gameobject` WHERE `eventEntry` IN (@BLIZZCON, @ETCDMF) AND `guid` IN (3110, 29801, 29806); +INSERT INTO `game_event_gameobject` (`eventEntry`, `guid`) VALUES +(@BLIZZCON, 3110), -- Stage +(@BLIZZCON, 29801), -- Bleachers +(@BLIZZCON, 29806); -- Bleachers + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` IN (23845, 23850, 23852, 23853, 23854, 23855, 25148, 25149, 25150, 25151, 25152, 28206, 28209, 28210); +UPDATE `gameobject_template` SET `ScriptName` = 'go_l70_etc_music' WHERE `entry` = 186312; + +DELETE FROM `creature_template_addon` WHERE `entry` = 28206; +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(28206, 0, 0, 0, 0, 0, 0, 28782); + +DELETE FROM `gossip_menu_option` WHERE `MenuID` IN (9666, 9667); +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES +(9666, 0, 0, 'But I drove my mole machine all the way down here...', 27600, 1, 1, 9667, 0, 0, 0, '', 0, 50664), +(9667, 0, 0, 'I\'m ready.', 27602, 1, 1, 0, 0, 0, 0, '', 0, 50664); + +DELETE FROM `creature_text` WHERE `CreatureID` = 28210; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(28210, 0, 0, 'Let\'s wrap it up, Miz. They\'ll be here in a second.', 12, 0, 100, 0, 0, 0, 27603, 0, 'Ognip Blastbolt'); + +/* +sai design doc +on event start concert controller calls domino action list (blizzcon/brd) +on blastbolt gossip select concert controller calls domino action list (brd) +on event start shattrath saul calls drumset spawn action list and walks around heralding etc concert (shattrath) + on certain point reached or timer, shattrath saul calls domino action list +domino action list calls action lists for each subcontroller, fx and members + also sets up a couple spawns/despawns +fx controller sets up casts +member controllers set up casts and summons + +some events need conditions, specifically drumset related ones as they vary by location + +members themselves get timed actionlists that repeat? must check timers + emotes are not consistently timed, deviation up to 10s indicates range, not strictly timed +members also need to cast pumped up spell on invoker for emote + +crew mates play emote 133 and stop at a range of (maybe) 5-15s repeatedly while at drumset +*/ + +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (23619, 23623, 23624, 23625, 23626)) AND (`source_type` = 0) AND (`id` IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)); +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 +(23619, 0, 0, 0, 1, 0, 100, 0, 10000, 25000, 10000, 25000, 0, 80, 2361900, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Out of Combat - Run Script'), +(23619, 0, 1, 0, 22, 0, 100, 0, 21, 0, 0, 0, 0, 11, 42741, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Received Emote 21 - Cast \'Pumped Up!\''), +(23623, 0, 0, 0, 1, 0, 100, 0, 10000, 25000, 10000, 25000, 0, 80, 2362300, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Out of Combat - Run Script'), +(23623, 0, 1, 0, 22, 0, 100, 0, 21, 0, 0, 0, 0, 11, 42741, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Received Emote 21 - Cast \'Pumped Up!\''), +(23624, 0, 0, 0, 1, 0, 100, 0, 10000, 25000, 10000, 25000, 0, 80, 2362400, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai''Kyl - Out of Combat - Run Script'), +(23624, 0, 1, 0, 22, 0, 100, 0, 21, 0, 0, 0, 0, 11, 42741, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai''Kyl - Received Emote 21 - Cast \'Pumped Up!\''), +(23625, 0, 0, 0, 1, 0, 100, 0, 10000, 25000, 10000, 25000, 0, 80, 2362500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Out of Combat - Run Script'), +(23625, 0, 1, 0, 22, 0, 100, 0, 21, 0, 0, 0, 0, 11, 42741, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Received Emote 21 - Cast \'Pumped Up!\''), +(23626, 0, 0, 0, 1, 0, 100, 0, 10000, 25000, 10000, 25000, 0, 80, 2362600, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Out of Combat - Run Script'), +(23626, 0, 1, 0, 22, 0, 100, 0, 21, 0, 0, 0, 0, 11, 42741, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Received Emote 21 - Cast \'Pumped Up!\''); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2361900) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3)); +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 +(2361900, 9, 0, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 402, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Actionlist - Play Emote 402'), +(2361900, 9, 1, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 403, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Actionlist - Play Emote 403'), +(2361900, 9, 2, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 404, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Actionlist - Play Emote 404'), +(2361900, 9, 3, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 405, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Actionlist - Play Emote 405'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2362300) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3)); +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 +(2362300, 9, 0, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 402, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Actionlist - Play Emote 402'), +(2362300, 9, 1, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 403, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Actionlist - Play Emote 403'), +(2362300, 9, 2, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 404, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Actionlist - Play Emote 404'), +(2362300, 9, 3, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 405, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Actionlist - Play Emote 405'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2362400) AND (`source_type` = 9) AND (`id` IN (0, 1, 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 +(2362400, 9, 0, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 402, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai''Kyl - Actionlist - Play Emote 402'), +(2362400, 9, 1, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 403, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai''Kyl - Actionlist - Play Emote 403'), +(2362400, 9, 2, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 404, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai''Kyl - Actionlist - Play Emote 404'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2362500) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3, 4, 5)); +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 +(2362500, 9, 0, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 402, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Actionlist - Play Emote 402'), +(2362500, 9, 1, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 403, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Actionlist - Play Emote 403'), +(2362500, 9, 2, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 404, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Actionlist - Play Emote 404'), +(2362500, 9, 3, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 405, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Actionlist - Play Emote 405'), +(2362500, 9, 4, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 406, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Actionlist - Play Emote 406'), +(2362500, 9, 5, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 407, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Actionlist - Play Emote 407'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2362600) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3)); +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 +(2362600, 9, 0, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 402, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Actionlist - Play Emote 402'), +(2362600, 9, 1, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 403, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Actionlist - Play Emote 403'), +(2362600, 9, 2, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 404, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Actionlist - Play Emote 404'), +(2362600, 9, 3, 0, 0, 0, 100, 0, 10000, 25000, 0, 0, 0, 5, 405, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Actionlist - Play Emote 405'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (23850, 2385000, 2385001)) AND (`source_type` IN (0, 9)) AND (`id` IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `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 +(23850, 0, 0, 0, 68, 0, 100, 0, @ETCDMF, 0, 0, 0, 0, 80, 2385000, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - On Game Event 32 Started - Run Script'), +(23850, 0, 1, 0, 68, 0, 100, 0, @ETCGRIM, 0, 0, 0, 0, 80, 2385000, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - On Game Event 81 Started - Run Script'), +(2385000, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 50, 186312, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - Actionlist - Summon Gameobject \'L70ETC Music Doodad\''), +(2385000, 9, 1, 0, 0, 0, 100, 0, 10, 10, 0, 0, 0, 80, 2383000, 0, 1, 0, 0, 0, 11, 23830, 21, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - Actionlist - Run Script'), +(2385000, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 80, 2385300, 0, 1, 0, 0, 0, 11, 23853, 21, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - Actionlist - Run Script'), +(2385000, 9, 3, 0, 0, 0, 100, 0, 3221, 3221, 0, 0, 0, 80, 2385200, 0, 1, 0, 0, 0, 11, 23852, 21, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - Actionlist - Run Script'), +(2385000, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 80, 2385400, 0, 1, 0, 0, 0, 11, 23854, 21, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - Actionlist - Run Script'), +(2385000, 9, 5, 0, 0, 0, 100, 0, 11343, 11343, 0, 0, 0, 80, 2385500, 0, 1, 0, 0, 0, 11, 23855, 21, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - Actionlist - Run Script'), +(2385000, 9, 6, 0, 0, 0, 100, 0, 3241, 3241, 0, 0, 0, 80, 2384500, 0, 1, 0, 0, 0, 11, 23845, 21, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - Actionlist - Run Script'), +(2385000, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 11, 28206, 10, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - Actionlist - Despawn Instant'), +(2385000, 9, 8, 0, 0, 0, 100, 0, 253803, 253803, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 10, 12563, 28206, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - Actionlist - Respawn Closest Creature \'[DND] L70ETC Drums\''), +(2385000, 9, 9, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 15, 186312, 10, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Concert Controller - Actionlist - Despawn Instant'), +(2385001, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 12, 28206, 7, 0, 0, 0, 0, 8, 0, 0, 0, 0, -1749.8168, 5134.219, -36.177956, 1.884955525398254394, '[DNT] L70ETC Concert Controller - Actionlist - Summon Creature'); -- Ran by Shattrath Saul + +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (23830, 2383000)) AND (`source_type` IN (0, 9)) AND (`id` IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)); +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 +(2383000, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 11, 42500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Lightning Cloud\''), -- to-do: condense these down into an actionlist of the three spells and five timed calls of said actionlist +(2383000, 9, 1, 0, 0, 0, 100, 0, 3221, 3221, 0, 0, 0, 11, 50934, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Earthquake SMALLER\''), +(2383000, 9, 2, 0, 0, 0, 100, 0, 3252, 3252, 0, 0, 0, 11, 42501, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Rain of Fire\''), +(2383000, 9, 3, 0, 0, 0, 100, 0, 66294, 66294, 0, 0, 0, 11, 42500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Lightning Cloud\''), +(2383000, 9, 4, 0, 0, 0, 100, 0, 3227, 3227, 0, 0, 0, 11, 50934, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Earthquake SMALLER\''), +(2383000, 9, 5, 0, 0, 0, 100, 0, 3228, 3228, 0, 0, 0, 11, 42501, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Rain of Fire\''), +(2383000, 9, 6, 0, 0, 0, 100, 0, 46860, 46860, 0, 0, 0, 11, 42500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Lightning Cloud\''), +(2383000, 9, 7, 0, 0, 0, 100, 0, 3222, 3222, 0, 0, 0, 11, 50934, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Earthquake SMALLER\''), +(2383000, 9, 8, 0, 0, 0, 100, 0, 3233, 3233, 0, 0, 0, 11, 42501, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Rain of Fire\''), +(2383000, 9, 9, 0, 0, 0, 100, 0, 97028, 97028, 0, 0, 0, 11, 42500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Lightning Cloud\''), +(2383000, 9, 10, 0, 0, 0, 100, 0, 3225, 3225, 0, 0, 0, 11, 50934, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Earthquake SMALLER\''), +(2383000, 9, 11, 0, 0, 0, 100, 0, 3240, 3240, 0, 0, 0, 11, 42501, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Rain of Fire\''), +(2383000, 9, 12, 0, 0, 0, 100, 0, 8081, 8081, 0, 0, 0, 11, 42500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Lightning Cloud\''), +(2383000, 9, 13, 0, 0, 0, 100, 0, 3231, 3240, 0, 0, 0, 11, 50934, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Earthquake SMALLER\''), +(2383000, 9, 14, 0, 0, 0, 100, 0, 3240, 3240, 0, 0, 0, 11, 42501, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC FX Controller - Actionlist - Cast \'L70ETC Rain of Fire\''); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2384500) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3, 4, 5)); +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 +(2384500, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 11, 42505, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Bergrisst Controller - Actionlist - Cast \'L70ETC Flare Effect\''), +(2384500, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 12, 23619, 1, 300000, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Bergrisst Controller - Actionlist - Summon Creature \'Bergrisst\''), +(2384500, 9, 2, 0, 0, 0, 100, 0, 124000, 124000, 0, 0, 0, 11, 25824, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Bergrisst Controller - Actionlist - Cast \'Spotlight\''), +(2384500, 9, 3, 0, 0, 0, 100, 0, 64000, 64000, 0, 0, 0, 28, 25824, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Bergrisst Controller - Actionlist - Remove Aura \'Spotlight\''), +(2384500, 9, 4, 0, 0, 0, 100, 0, 64000, 64000, 0, 0, 0, 11, 42505, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Bergrisst Controller - Actionlist - Cast \'L70ETC Flare Effect\''), +(2384500, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 11, 23619, 3, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Bergrisst Controller - Actionlist - Despawn Instant'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2385200) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3)); +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 +(2385200, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 11, 42505, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Mai\'Kyl Controller - Actionlist - Cast \'L70ETC Flare Effect\''), +(2385200, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 12, 23624, 1, 300000, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Mai\'Kyl Controller - Actionlist - Summon Creature \'Mai\'Kyl\''), +(2385200, 9, 2, 0, 0, 0, 100, 0, 268387, 268387, 0, 0, 0, 11, 42505, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Mai\'Kyl Controller - Actionlist - Cast \'L70ETC Flare Effect\''), +(2385200, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 11, 23624, 3, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Mai\'Kyl Controller - Actionlist - Despawn Instant'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2385300) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3, 4)); +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 +(2385300, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 11, 42505, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Samuro Controller - Actionlist - Cast \'L70ETC Flare Effect\''), +(2385300, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 12, 23625, 1, 300000, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Samuro Controller - Actionlist - Summon Creature \'Samuro\''), +(2385300, 9, 2, 0, 0, 0, 100, 0, 114783, 114783, 0, 0, 0, 11, 42510, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Samuro Controller - Actionlist - Cast \'L70ETC Call Lightning\''), +(2385300, 9, 3, 0, 0, 0, 100, 0, 156825, 156825, 0, 0, 0, 11, 42505, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Samuro Controller - Actionlist - Cast \'L70ETC Flare Effect\''), +(2385300, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 11, 23625, 3, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Samuro Controller - Actionlist - Despawn Instant'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2385400) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3)); +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 +(2385400, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 11, 42505, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Sig Controller - Actionlist - Cast \'L70ETC Flare Effect\''), +(2385400, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 12, 23626, 1, 300000, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Sig Controller - Actionlist - Summon Creature \'Sig Nicious\''), +(2385400, 9, 2, 0, 0, 0, 100, 0, 268387, 268387, 0, 0, 0, 11, 42505, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Sig Controller - Actionlist - Cast \'L70ETC Flare Effect\''), +(2385400, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 11, 23626, 3, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Sig Controller - Actionlist - Despawn Instant'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2385500) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3)); +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 +(2385500, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 11, 42505, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Chief Thunder-Skins Controller - Actionlist - Cast \'L70ETC Flare Effect\''), +(2385500, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 12, 23623, 1, 300000, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Chief Thunder-Skins Controller - Actionlist - Summon Creature \'Chief Thunder-Skins\''), +(2385500, 9, 2, 0, 0, 0, 100, 0, 257044, 257044, 0, 0, 0, 11, 42505, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Chief Thunder-Skins Controller - Actionlist - Cast \'L70ETC Flare Effect\''), +(2385500, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 11, 23623, 3, 0, 0, 0, 0, 0, 0, '[DNT] L70ETC Chief Thunder-Skins Controller - Actionlist - Despawn Instant'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28210) AND (`source_type` = 0) AND (`id` IN (0, 1, 2, 3, 4, 5)); +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 +(28210, 0, 0, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - On Reset - Set Emote State 133'), +(28210, 0, 1, 2, 62, 0, 100, 0, 9667, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - On Gossip Option 0 Selected - Close Gossip'), +(28210, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 0, 80, 2385000, 0, 0, 0, 0, 0, 11, 23850, 5, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - On Gossip Option 0 Selected - Run Script'), +(28210, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - On Gossip Option 0 Selected - Say Line 0'), +(28210, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 80, 2821000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - On Gossip Option 0 Selected - Run Script'), +(28210, 0, 5, 0, 68, 0, 100, 0, 81, 0, 0, 0, 0, 80, 2821000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - On Game Event 81 Started - Run Script'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2821000) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3, 4, 5, 6, 7, 8)); +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 +(2821000, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 80, 2820900, 0, 0, 0, 0, 0, 11, 28209, 5, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - Actionlist - Run Script'), +(2821000, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 846.874, -186.739, -49.754395, 0, 'Ognip Blastbolt - Actionlist - Move To Position'), +(2821000, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - Actionlist - Remove Npc Flags Gossip'), +(2821000, 9, 3, 0, 0, 0, 100, 0, 2500, 2500, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 2.077, 'Ognip Blastbolt - Actionlist - Set Orientation 2.077'), +(2821000, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 17, 423, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - Actionlist - Set Emote State 423'), +(2821000, 9, 5, 0, 0, 0, 100, 0, 270000, 270000, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 845.88074, -182.20273, -49.75489, 0, 'Ognip Blastbolt - Actionlist - Move To Position'), +(2821000, 9, 6, 0, 0, 0, 100, 0, 2500, 2500, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1.187, 'Ognip Blastbolt - Actionlist - Set Orientation 1.187'), +(2821000, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - Actionlist - Add Npc Flags Gossip'), +(2821000, 9, 8, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ognip Blastbolt - Actionlist - Set Emote State 133'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28209) AND (`source_type` = 0) AND (`id` = 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 +(28209, 0, 0, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mizli Crankwheel - On Reset - Set Emote State 133'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2820900) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3, 4, 5, 6, 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`, `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 +(2820900, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 853.608, -182.679, -49.755253, 0, 'Mizli Crankwheel - Actionlist - Move To Position'), +(2820900, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mizli Crankwheel - Actionlist - Remove Npc Flags Gossip'), +(2820900, 9, 2, 0, 0, 0, 100, 0, 2500, 2500, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 2.094, 'Mizli Crankwheel - Actionlist - Set Orientation 2.094'), +(2820900, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 17, 423, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mizli Crankwheel - Actionlist - Set Emote State 423'), +(2820900, 9, 4, 0, 0, 0, 100, 0, 270000, 270000, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 849.4901, -179.31683, -49.755436, 0, 'Mizli Crankwheel - Actionlist - Move To Position'), +(2820900, 9, 5, 0, 0, 0, 100, 0, 2500, 2500, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4.102, 'Mizli Crankwheel - Actionlist - Set Orientation 4.102'), +(2820900, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mizli Crankwheel - Actionlist - Add Npc Flags Gossip'), +(2820900, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 17, 133, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mizli Crankwheel - Actionlist - Set Emote State 133'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 15 AND `SourceGroup` = 9666 AND `SourceId` = 0; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(15, 9666, 0, 0, 0, 2, 0, 37863, 1, 0, 0, 0, 0, '', 'If player does not have \'Direbrew Remote\'s\' in inventory'); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` IN (1, 2)) AND (`SourceEntry` = 23850) AND (`SourceId` = 0) AND (`ElseGroup` IN (1, 2)) AND (`ConditionTypeOrReference` IN (23, 29)) AND (`ConditionTarget` = 1) AND (`ConditionValue1` IN (1584, 3519, 23625)) AND (`ConditionValue2` IN (0, 10)) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22, 1, 23850, 0, 1, 23, 1, 3519, 0, 0, 0, 0, 0, '', 'Object must be in \'Terokkar Forest\''), +(22, 2, 23850, 0, 2, 23, 1, 1584, 0, 0, 0, 0, 0, '', 'Object must be in \'Blackrock Depths\''), +(22, 2, 23850, 0, 2, 29, 1, 23625, 10, 0, 1, 0, 0, '', 'Object must not have creature \'Samuro\' within 10 yards'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (25148, 25149, 25150, 25151, 25152)) AND (`source_type` = 0) AND (`id` IN (0, 1, 2, 3, 4, 5, 6, 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`, `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 +(25148, 0, 0, 0, 22, 0, 100, 0, 21, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Received Emote 21 - Play Emote 14'), +(25148, 0, 1, 0, 22, 0, 100, 0, 34, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Received Emote 34 - Play Emote 14'), +(25148, 0, 2, 0, 22, 0, 100, 0, 58, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Received Emote 58 - Play Emote 14'), +(25148, 0, 3, 0, 22, 0, 100, 0, 77, 0, 0, 0, 0, 5, 11, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Received Emote 77 - Play Emote 11'), +(25148, 0, 4, 0, 22, 0, 100, 0, 78, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Received Emote 78 - Play Emote 14'), +(25148, 0, 5, 0, 22, 0, 100, 0, 101, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Received Emote 101 - Play Emote 14'), +(25148, 0, 6, 0, 22, 0, 100, 0, 104, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Received Emote 104 - Play Emote 14'), +(25148, 0, 7, 0, 22, 0, 100, 0, 328, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Bergrisst - Received Emote 328 - Play Emote 14'), +(25149, 0, 0, 0, 22, 0, 100, 0, 21, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Received Emote 21 - Play Emote 4'), +(25149, 0, 1, 0, 22, 0, 100, 0, 34, 0, 0, 0, 0, 5, 10, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Received Emote 34 - Play Emote 10'), +(25149, 0, 2, 0, 22, 0, 100, 0, 58, 0, 0, 0, 0, 5, 23, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Received Emote 58 - Play Emote 23'), +(25149, 0, 3, 0, 22, 0, 100, 0, 77, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Received Emote 77 - Play Emote 14'), +(25149, 0, 4, 0, 22, 0, 100, 0, 78, 0, 0, 0, 0, 5, 66, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Received Emote 78 - Play Emote 66'), +(25149, 0, 5, 0, 22, 0, 100, 0, 101, 0, 0, 0, 0, 5, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Received Emote 101 - Play Emote 3'), +(25149, 0, 6, 0, 22, 0, 100, 0, 104, 0, 0, 0, 0, 5, 23, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Received Emote 104 - Play Emote 23'), +(25149, 0, 7, 0, 22, 0, 100, 0, 328, 0, 0, 0, 0, 5, 11, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Chief Thunder-Skins - Received Emote 328 - Play Emote 11'), +(25150, 0, 0, 0, 22, 0, 100, 0, 21, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai\'Kyl - Received Emote 21 - Play Emote 4'), +(25150, 0, 1, 0, 22, 0, 100, 0, 34, 0, 0, 0, 0, 5, 10, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai\'Kyl - Received Emote 34 - Play Emote 10'), +(25150, 0, 2, 0, 22, 0, 100, 0, 58, 0, 0, 0, 0, 5, 23, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai\'Kyl - Received Emote 58 - Play Emote 23'), +(25150, 0, 3, 0, 22, 0, 100, 0, 77, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai\'Kyl - Received Emote 77 - Play Emote 14'), +(25150, 0, 4, 0, 22, 0, 100, 0, 78, 0, 0, 0, 0, 5, 66, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai\'Kyl - Received Emote 78 - Play Emote 66'), +(25150, 0, 5, 0, 22, 0, 100, 0, 101, 0, 0, 0, 0, 5, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai\'Kyl - Received Emote 101 - Play Emote 3'), +(25150, 0, 6, 0, 22, 0, 100, 0, 104, 0, 0, 0, 0, 5, 23, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai\'Kyl - Received Emote 104 - Play Emote 23'), +(25150, 0, 7, 0, 22, 0, 100, 0, 328, 0, 0, 0, 0, 5, 11, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Mai\'Kyl - Received Emote 328 - Play Emote 11'), +(25151, 0, 0, 0, 22, 0, 100, 0, 21, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Received Emote 21 - Play Emote 4'), +(25151, 0, 1, 0, 22, 0, 100, 0, 34, 0, 0, 0, 0, 5, 10, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Received Emote 34 - Play Emote 10'), +(25151, 0, 2, 0, 22, 0, 100, 0, 58, 0, 0, 0, 0, 5, 23, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Received Emote 58 - Play Emote 23'), +(25151, 0, 3, 0, 22, 0, 100, 0, 77, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Received Emote 77 - Play Emote 14'), +(25151, 0, 4, 0, 22, 0, 100, 0, 78, 0, 0, 0, 0, 5, 66, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Received Emote 78 - Play Emote 66'), +(25151, 0, 5, 0, 22, 0, 100, 0, 101, 0, 0, 0, 0, 5, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Received Emote 101 - Play Emote 3'), +(25151, 0, 6, 0, 22, 0, 100, 0, 104, 0, 0, 0, 0, 5, 23, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Received Emote 104 - Play Emote 23'), +(25151, 0, 7, 0, 22, 0, 100, 0, 328, 0, 0, 0, 0, 5, 11, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Samuro - Received Emote 328 - Play Emote 11'), +(25152, 0, 0, 0, 22, 0, 100, 0, 21, 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Received Emote 21 - Play Emote 4'), +(25152, 0, 1, 0, 22, 0, 100, 0, 34, 0, 0, 0, 0, 5, 10, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Received Emote 34 - Play Emote 10'), +(25152, 0, 2, 0, 22, 0, 100, 0, 58, 0, 0, 0, 0, 5, 23, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Received Emote 58 - Play Emote 23'), +(25152, 0, 3, 0, 22, 0, 100, 0, 77, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Received Emote 77 - Play Emote 14'), +(25152, 0, 4, 0, 22, 0, 100, 0, 78, 0, 0, 0, 0, 5, 66, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Received Emote 78 - Play Emote 66'), +(25152, 0, 5, 0, 22, 0, 100, 0, 101, 0, 0, 0, 0, 5, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Received Emote 101 - Play Emote 3'), +(25152, 0, 6, 0, 22, 0, 100, 0, 104, 0, 0, 0, 0, 5, 23, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Received Emote 104 - Play Emote 23'), +(25152, 0, 7, 0, 22, 0, 100, 0, 328, 0, 0, 0, 0, 5, 11, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sig Nicious - Received Emote 328 - Play Emote 11'); diff --git a/data/sql/updates/db_world/2024_08_13_01.sql b/data/sql/updates/db_world/2024_08_13_01.sql new file mode 100644 index 000000000..e54fce7d5 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_13_01.sql @@ -0,0 +1,356 @@ +-- DB update 2024_08_13_00 -> 2024_08_13_01 +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 19270) AND (`source_type` = 0) AND (`id` IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)); +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 +(19270, 0, 0, 2, 68, 0, 100, 0, 86, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Game Event 86 Started - Set Active On'), +(19270, 0, 1, 0, 69, 0, 100, 0, 86, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Game Event 86 Ended - Set Active Off'), +(19270, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 53, 0, 19270, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Game Event 86 Started - Start Waypoint'), +(19270, 0, 3, 4, 68, 0, 100, 0, 82, 0, 0, 0, 0, 0, 80, 2385001, 0, 0, 0, 0, 0, 11, 23850, 31, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Game Event 82 Started - Run Script'), +(19270, 0, 4, 6, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Game Event 82 Started - Set Active On'), +(19270, 0, 5, 0, 69, 0, 100, 0, 82, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Game Event 82 Ended - Set Active Off'), +(19270, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 53, 0, 19270, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Game Event 82 Started - Start Waypoint'), +(19270, 0, 7, 0, 40, 0, 100, 0, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 9 Reached - Say Line 0'), +(19270, 0, 8, 0, 40, 0, 100, 0, 46, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 46 Reached - Say Line 0'), +(19270, 0, 9, 0, 40, 0, 100, 0, 66, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 66 Reached - Say Line 0'), +(19270, 0, 10, 0, 40, 0, 100, 0, 130, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 130 Reached - Say Line 0'), +(19270, 0, 11, 0, 40, 0, 100, 0, 202, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 202 Reached - Say Line 0'), +(19270, 0, 12, 0, 40, 0, 100, 0, 232, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 232 Reached - Say Line 0'), +(19270, 0, 13, 0, 40, 0, 100, 0, 297, 0, 0, 0, 0, 0, 80, 1927000, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 297 Started - Run Script'), +(19270, 0, 14, 0, 40, 0, 100, 0, 9, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 9 Reached - Say Line 1'), +(19270, 0, 15, 0, 40, 0, 100, 0, 46, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 46 Reached - Say Line 1'), +(19270, 0, 16, 0, 40, 0, 100, 0, 66, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 66 Reached - Say Line 1'), +(19270, 0, 17, 0, 40, 0, 100, 0, 130, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 130 Reached - Say Line 1'), +(19270, 0, 18, 0, 40, 0, 100, 0, 202, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 202 Reached - Say Line 1'), +(19270, 0, 19, 0, 40, 0, 100, 0, 232, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 232 Reached - Say Line 1'), +(19270, 0, 20, 0, 40, 0, 100, 0, 297, 0, 0, 0, 0, 0, 80, 2385000, 0, 0, 0, 0, 0, 11, 23850, 31, 0, 0, 0, 0, 0, 0, 'Shattrath Saul - On Waypoint 297 Reached - Run Script'); + +DELETE FROM `smart_scripts` WHERE `entryorguid` = 1927000 AND `source_type` = 9 AND `id` IN (0, 1) AND `action_type` = 1; +UPDATE `smart_scripts` SET `id` = 0 WHERE `entryorguid` = 1927000 AND `source_type` = 9 AND `id` = 2 AND `action_type` = 12; +UPDATE `smart_scripts` SET `id` = 1, `event_param1` = 0, `event_param2` = 0 WHERE `entryorguid` = 1927000 AND `source_type` = 9 AND `id` = 3 AND `action_type` = 45; + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` IN (8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)) AND (`SourceEntry` = 19270) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 12) AND (`ConditionTarget` = 1) AND (`ConditionValue1` IN (82, 86)) AND (`ConditionValue2` = 0) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22, 8, 19270, 0, 0, 12, 1, 86, 0, 0, 0, 0, 0, '', 'Object must have event \'Perry Gatner\' active'), +(22, 9, 19270, 0, 0, 12, 1, 86, 0, 0, 0, 0, 0, '', 'Object must have event \'Perry Gatner\' active'), +(22, 10, 19270, 0, 0, 12, 1, 86, 0, 0, 0, 0, 0, '', 'Object must have event \'Perry Gatner\' active'), +(22, 11, 19270, 0, 0, 12, 1, 86, 0, 0, 0, 0, 0, '', 'Object must have event \'Perry Gatner\' active'), +(22, 12, 19270, 0, 0, 12, 1, 86, 0, 0, 0, 0, 0, '', 'Object must have event \'Perry Gatner\' active'), +(22, 13, 19270, 0, 0, 12, 1, 86, 0, 0, 0, 0, 0, '', 'Object must have event \'Perry Gatner\' active'), +(22, 14, 19270, 0, 0, 12, 1, 86, 0, 0, 0, 0, 0, '', 'Object must have event \'Perry Gatner\' active'), +(22, 15, 19270, 0, 0, 12, 1, 82, 0, 0, 0, 0, 0, '', 'Object must have event \'L70ETC World\'s End Tavern Concert\' active'), +(22, 16, 19270, 0, 0, 12, 1, 82, 0, 0, 0, 0, 0, '', 'Object must have event \'L70ETC World\'s End Tavern Concert\' active'), +(22, 17, 19270, 0, 0, 12, 1, 82, 0, 0, 0, 0, 0, '', 'Object must have event \'L70ETC World\'s End Tavern Concert\' active'), +(22, 18, 19270, 0, 0, 12, 1, 82, 0, 0, 0, 0, 0, '', 'Object must have event \'L70ETC World\'s End Tavern Concert\' active'), +(22, 19, 19270, 0, 0, 12, 1, 82, 0, 0, 0, 0, 0, '', 'Object must have event \'L70ETC World\'s End Tavern Concert\' active'), +(22, 20, 19270, 0, 0, 12, 1, 82, 0, 0, 0, 0, 0, '', 'Object must have event \'L70ETC World\'s End Tavern Concert\' active'), +(22, 21, 19270, 0, 0, 12, 1, 82, 0, 0, 0, 0, 0, '', 'Object must have event \'L70ETC World\'s End Tavern Concert\' active'); + +DELETE FROM `creature_text` WHERE `CreatureID` = 19270 AND `GroupID` IN (0, 1) AND `ID` IN (0, 1, 2, 3); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(19270, 0, 0, 'If you are ready to laugh, head over to the World\'s End Tavern!', 14, 0, 100, 0, 0, 0, 16380, 0, 'Shattrath Saul - Perry Gatner'), +(19270, 0, 1, 'Check out the comedy stylings of Perry Gatner in just a few minutes!', 14, 0, 100, 0, 0, 0, 16377, 0, 'Shattrath Saul - Perry Gatner'), +(19270, 1, 0, "TAUREN CHIEFTAINS! Playing LIVE, in the WORLD'S END TAVERN! Be there, at the top of the hour! Banished from Shattrath? SNEAK BACK IN!", 14, 0, 100, 0, 0, 0, 28504, 1, 'Shattrath Saul - L70ETC'), +(19270, 1, 1, "Are you ready to rock? Then head over to the World's End Tavern! The Tauren Chieftains start their show at the top of the hour.", 14, 0, 100, 0, 0, 0, 28496, 1, 'Shattrath Saul - L70ETC'), +(19270, 1, 2, "Who? The Tauren Chieftains! What? A live performance! Where? The World's End Tavern! When? The top of the hour! BE THERE!", 14, 0, 100, 0, 0, 0, 28502, 1, 'Shattrath Saul - L70ETC'), +(19270, 1, 3, "Now, in Shattrath City: The Tauren Chieftains! Playing in the World's End Tavern at the top of the hour!", 14, 0, 100, 0, 0, 0, 28481, 1, 'Shattrath Saul - L70ETC'); + +DELETE FROM `waypoints` WHERE `entry` = 19270; +INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`) VALUES +(19270, 1, -1752.2605, 5168.273, -37.204906, NULL, 0), +(19270, 2, -1753.1287, 5168.3877, -36.95703, NULL, 0), +(19270, 3, -1757.3787, 5166.8877, -36.95703, NULL, 0), +(19270, 4, -1757.6287, 5168.1377, -36.95703, NULL, 0), +(19270, 5, -1759.3787, 5173.6377, -38.20703, NULL, 0), +(19270, 6, -1758.8787, 5178.8877, -39.70703, NULL, 0), +(19270, 7, -1760.2949, 5180.1904, -40.20916, NULL, 0), +(19270, 8, -1762.3428, 5182.5586, -39.95916, NULL, 0), +(19270, 9, -1715.8907, 5182.9263, -40.209156, NULL, 0), +(19270, 10, -1709.1345, 5187.362, -40.209156, NULL, 0), +(19270, 11, -1705.3855, 5189.9243, -40.008324, NULL, 0), +(19270, 12, -1704.6355, 5190.6743, -40.008324, NULL, 0), +(19270, 13, -1701.1355, 5194.1743, -42.508324, NULL, 0), +(19270, 14, -1700.3855, 5194.9243, -43.258324, NULL, 0), +(19270, 15, -1695.1355, 5199.9243, -46.258324, NULL, 0), +(19270, 16, -1689.1355, 5201.6743, -48.008324, NULL, 0), +(19270, 17, -1688.3855, 5202.1743, -47.508324, NULL, 0), +(19270, 18, -1686.6355, 5203.4243, -47.008324, NULL, 0), +(19270, 19, -1685.1355, 5204.6743, -46.508324, NULL, 0), +(19270, 20, -1684.3855, 5205.1743, -46.258324, NULL, 0), +(19270, 21, -1682.6355, 5206.4243, -46.008324, NULL, 0), +(19270, 22, -1681.8855, 5206.9243, -45.508324, NULL, 0), +(19270, 23, -1678.5752, 5209.505, -46.132336, NULL, 0), +(19270, 24, -1676.8586, 5210.801, -45.722336, NULL, 0), +(19270, 25, -1674.3586, 5212.801, -45.972336, NULL, 0), +(19270, 26, -1672.6086, 5213.551, -45.472336, NULL, 0), +(19270, 27, -1667.8586, 5217.301, -45.222336, NULL, 0), +(19270, 28, -1667.1086, 5218.051, -44.972336, NULL, 0), +(19270, 29, -1666.3586, 5218.551, -44.722336, NULL, 0), +(19270, 30, -1664.8586, 5219.801, -44.472336, NULL, 0), +(19270, 31, -1660.3586, 5223.551, -44.972336, NULL, 0), +(19270, 32, -1658.8586, 5224.551, -45.222336, NULL, 0), +(19270, 33, -1658.6086, 5224.801, -45.222336, NULL, 0), +(19270, 34, -1651.6086, 5231.301, -42.472336, NULL, 0), +(19270, 35, -1645.2992, 5237.5195, -40.38224, NULL, 0), +(19270, 36, -1644.4756, 5238.287, -39.91925, NULL, 0), +(19270, 37, -1642.9756, 5239.787, -40.16925, NULL, 0), +(19270, 38, -1637.4756, 5245.787, -40.66925, NULL, 0), +(19270, 39, -1634.341, 5249.475, -40.88294, NULL, 0), +(19270, 40, -1632.1586, 5252.368, -40.735092, NULL, 0), +(19270, 41, -1631.1586, 5253.368, -40.735092, NULL, 0), +(19270, 42, -1634.1531, 5276.2627, -41.07452, NULL, 0), +(19270, 43, -1634.5375, 5279.121, -40.641838, NULL, 0), +(19270, 44, -1635.5375, 5283.121, -40.641838, NULL, 0), +(19270, 45, -1638.2875, 5295.621, -40.141838, NULL, 0), +(19270, 46, -1640.9219, 5304.98, -40.20916, NULL, 0), +(19270, 47, -1639.4663, 5308.7505, -40.20916, NULL, 0), +(19270, 48, -1637.9941, 5312.283, -39.95916, NULL, 0), +(19270, 49, -1622.8514, 5325.8657, -40.20916, NULL, 0), +(19270, 50, -1618.8865, 5329.6807, -39.95916, NULL, 0), +(19270, 51, -1617.3865, 5333.6807, -39.95916, NULL, 0), +(19270, 52, -1611.7811, 5351.376, -40.20916, NULL, 0), +(19270, 53, -1610.6606, 5354.3467, -39.95916, NULL, 0), +(19270, 54, -1609.7211, 5359.1987, -40.20916, NULL, 0), +(19270, 55, -1608.4541, 5364.588, -39.926785, NULL, 0), +(19270, 56, -1611.9541, 5367.838, -39.926785, NULL, 0), +(19270, 57, -1616.9541, 5372.338, -39.176785, NULL, 0), +(19270, 58, -1619.9541, 5375.338, -39.926785, NULL, 0), +(19270, 59, -1620.9541, 5376.088, -39.926785, NULL, 0), +(19270, 60, -1621.7041, 5376.588, -40.926785, NULL, 0), +(19270, 61, -1623.7041, 5378.588, -42.426785, NULL, 0), +(19270, 62, -1626.9541, 5381.838, -43.426785, NULL, 0), +(19270, 63, -1628.4541, 5381.838, -44.176785, NULL, 0), +(19270, 64, -1633.2041, 5386.838, -44.426785, NULL, 0), +(19270, 65, -1635.2041, 5389.088, -44.676785, NULL, 0), +(19270, 66, -1639.187, 5392.9766, -45.14441, NULL, 0), +(19270, 67, -1640.5592, 5391.6455, -45.136963, NULL, 0), +(19270, 68, -1642.1283, 5390.2734, -45.462597, NULL, 0), +(19270, 69, -1645.1692, 5387.582, -45.49398, NULL, 0), +(19270, 70, -1646.4192, 5386.332, -45.49398, NULL, 0), +(19270, 71, -1657.4192, 5367.582, -45.74398, NULL, 0), +(19270, 72, -1664.1788, 5356.7764, -45.99024, NULL, 0), +(19270, 73, -1666.3015, 5353.3613, -45.97572, NULL, 0), +(19270, 74, -1668.5515, 5343.6113, -45.97572, NULL, 0), +(19270, 75, -1669.5515, 5338.1113, -46.22572, NULL, 0), +(19270, 76, -1670.0515, 5336.1113, -46.47572, NULL, 0), +(19270, 77, -1670.5515, 5334.1113, -46.72572, NULL, 0), +(19270, 78, -1671.0515, 5332.1113, -46.97572, NULL, 0), +(19270, 79, -1671.5515, 5330.3613, -46.97572, NULL, 0), +(19270, 80, -1671.803, 5329.7666, -47.550205, NULL, 0), +(19270, 81, -1672.1868, 5328.0547, -47.59669, NULL, 0), +(19270, 82, -1672.9368, 5325.0547, -47.84669, NULL, 0), +(19270, 83, -1673.1868, 5322.0547, -48.09669, NULL, 0), +(19270, 84, -1673.1868, 5320.0547, -48.34669, NULL, 0), +(19270, 85, -1673.4368, 5318.0547, -48.84669, NULL, 0), +(19270, 86, -1673.4368, 5316.0547, -49.09669, NULL, 0), +(19270, 87, -1673.4368, 5312.0547, -49.09669, NULL, 0), +(19270, 88, -1673.6868, 5308.3047, -49.34669, NULL, 0), +(19270, 89, -1674.1868, 5304.3047, -49.59669, NULL, 0), +(19270, 90, -1674.1868, 5302.3047, -49.84669, NULL, 0), +(19270, 91, -1674.4368, 5298.3047, -50.09669, NULL, 0), +(19270, 92, -1674.7311, 5297.7847, -50.4066, NULL, 0), +(19270, 93, -1674.9521, 5293.9775, -50.48787, NULL, 0), +(19270, 94, -1674.9521, 5292.2275, -50.48787, NULL, 0), +(19270, 95, -1677.9521, 5284.9775, -50.73787, NULL, 0), +(19270, 96, -1679.2021, 5282.2275, -50.98787, NULL, 0), +(19270, 97, -1680.9521, 5277.7275, -50.98787, NULL, 0), +(19270, 98, -1685.047, 5267.4834, -51.55147, NULL, 0), +(19270, 99, -1687.0706, 5262.31, -51.1996, NULL, 0), +(19270, 100, -1690.8206, 5264.31, -50.9496, NULL, 0), +(19270, 101, -1692.5706, 5264.81, -50.4496, NULL, 0), +(19270, 102, -1694.5706, 5265.56, -49.9496, NULL, 0), +(19270, 103, -1695.8206, 5265.81, -49.6996, NULL, 0), +(19270, 104, -1698.0706, 5265.56, -49.4496, NULL, 0), +(19270, 105, -1703.0706, 5265.06, -47.4496, NULL, 0), +(19270, 106, -1705.3206, 5265.81, -45.4496, NULL, 0), +(19270, 107, -1706.0706, 5266.06, -45.4496, NULL, 0), +(19270, 108, -1706.8206, 5266.31, -44.9496, NULL, 0), +(19270, 109, -1709.5706, 5267.31, -44.1996, NULL, 0), +(19270, 110, -1710.8713, 5267.3696, -44.063465, NULL, 0), +(19270, 111, -1714.541, 5268.6797, -42.386314, NULL, 0), +(19270, 112, -1718.041, 5267.6797, -42.136314, NULL, 0), +(19270, 113, -1731.291, 5263.4297, -40.886314, NULL, 0), +(19270, 114, -1733.791, 5263.6797, -42.886314, NULL, 0), +(19270, 115, -1735.791, 5262.9297, -45.386314, NULL, 0), +(19270, 116, -1741.791, 5259.6797, -40.636314, NULL, 0), +(19270, 117, -1743.541, 5259.4297, -40.136314, NULL, 0), +(19270, 118, -1745.2354, 5258.7837, -40.22338, NULL, 0), +(19270, 119, -1748.6482, 5258.3574, -39.76657, NULL, 0), +(19270, 120, -1760.6482, 5257.3574, -39.76657, NULL, 0), +(19270, 121, -1760.6482, 5257.3574, -40.26657, NULL, 0), +(19270, 122, -1761.1482, 5257.6074, -39.76657, NULL, 0), +(19270, 123, -1761.8982, 5257.8574, -39.51657, NULL, 0), +(19270, 124, -1762.3982, 5258.3574, -39.01657, NULL, 0), +(19270, 125, -1762.6482, 5258.6074, -38.76657, NULL, 0), +(19270, 126, -1770.6727, 5262.7456, -38.816673, NULL, 0), +(19270, 127, -1771.8708, 5263.4224, -38.571022, NULL, 0), +(19270, 128, -1773.3708, 5264.4224, -38.571022, NULL, 0), +(19270, 129, -1772.6208, 5262.9224, -38.571022, NULL, 0), +(19270, 130, -1772.5688, 5262.099, -38.825367, NULL, 0), +(19270, 131, -1774.7759, 5254.046, -38.849823, NULL, 0), +(19270, 132, -1775.0278, 5253.452, -38.63588, NULL, 0), +(19270, 133, -1775.2778, 5252.452, -39.63588, NULL, 0), +(19270, 134, -1775.5278, 5251.702, -39.88588, NULL, 0), +(19270, 135, -1775.5278, 5251.202, -40.38588, NULL, 0), +(19270, 136, -1774.7778, 5249.952, -40.13588, NULL, 0), +(19270, 137, -1776.2778, 5248.452, -40.13588, NULL, 0), +(19270, 138, -1779.0278, 5241.952, -40.13588, NULL, 0), +(19270, 139, -1777.5278, 5236.952, -42.88588, NULL, 0), +(19270, 140, -1782.0278, 5229.452, -46.38588, NULL, 0), +(19270, 141, -1783.5278, 5226.952, -47.38588, NULL, 0), +(19270, 142, -1784.5278, 5223.702, -48.13588, NULL, 0), +(19270, 143, -1784.8121, 5223.6655, -48.529106, NULL, 0), +(19270, 144, -1785.3154, 5222.8843, -48.202736, NULL, 0), +(19270, 145, -1786.8154, 5221.3843, -48.452736, NULL, 0), +(19270, 146, -1787.5654, 5220.8843, -48.452736, NULL, 0), +(19270, 147, -1787.8154, 5219.8843, -48.452736, NULL, 0), +(19270, 148, -1791.5654, 5218.6343, -48.452736, NULL, 0), +(19270, 149, -1798.8154, 5216.1343, -48.702736, NULL, 0), +(19270, 150, -1801.5654, 5214.8843, -48.952736, NULL, 0), +(19270, 151, -1801.8154, 5214.8843, -48.952736, NULL, 0), +(19270, 152, -1804.8154, 5213.8843, -48.952736, NULL, 0), +(19270, 153, -1805.6951, 5213.3022, -48.983135, NULL, 0), +(19270, 154, -1809.7375, 5210.629, -46.825375, NULL, 0), +(19270, 155, -1811.9875, 5206.629, -46.325375, NULL, 0), +(19270, 156, -1812.7375, 5203.629, -49.075375, NULL, 0), +(19270, 157, -1812.9875, 5202.629, -50.075375, NULL, 0), +(19270, 158, -1813.2375, 5202.129, -50.325375, NULL, 0), +(19270, 159, -1816.7375, 5197.129, -50.325375, NULL, 0), +(19270, 160, -1817.9246, 5195.5425, -50.99481, NULL, 0), +(19270, 161, -1818.7246, 5194.3906, -51.111706, NULL, 0), +(19270, 162, -1819.2949, 5193.5693, -51.361706, NULL, 0), +(19270, 163, -1820.7802, 5191.4556, -51.667614, NULL, 0), +(19270, 164, -1820.7793, 5191.455, -51.486706, NULL, 0), +(19270, 165, -1821.3125, 5188.502, -51.736706, NULL, 0), +(19270, 166, -1821.875, 5185.416, -51.486706, NULL, 0), +(19270, 167, -1822.3594, 5183.4766, -51.236706, NULL, 0), +(19270, 168, -1822.3965, 5182.291, -51.236706, NULL, 0), +(19270, 169, -1822.916, 5181.25, -50.986706, NULL, 0), +(19270, 170, -1825, 5179.166, -50.736706, NULL, 0), +(19270, 171, -1828.5352, 5175.631, -50.236706, NULL, 0), +(19270, 172, -1829.166, 5175, -49.861706, NULL, 0), +(19270, 173, -1831.8496, 5173.658, -49.236706, NULL, 0), +(19270, 174, -1833.334, 5172.916, -48.861706, NULL, 0), +(19270, 175, -1835.8131, 5171.899, -48.52697, NULL, 0), +(19270, 176, -1838.8453, 5170.541, -47.88592, NULL, 0), +(19270, 177, -1840.5953, 5170.041, -47.63592, NULL, 0), +(19270, 178, -1840.5953, 5170.041, -47.88592, NULL, 0), +(19270, 179, -1841.5953, 5169.791, -47.38592, NULL, 0), +(19270, 180, -1844.3453, 5169.041, -47.13592, NULL, 0), +(19270, 181, -1846.3453, 5168.791, -46.88592, NULL, 0), +(19270, 182, -1851.3453, 5167.791, -47.13592, NULL, 0), +(19270, 183, -1852.3453, 5167.541, -47.38592, NULL, 0), +(19270, 184, -1854.0953, 5167.041, -47.63592, NULL, 0), +(19270, 185, -1856.0953, 5166.541, -47.88592, NULL, 0), +(19270, 186, -1857.8453, 5166.291, -48.13592, NULL, 0), +(19270, 187, -1859.8453, 5166.041, -48.13592, NULL, 0), +(19270, 188, -1863.8453, 5165.291, -48.38592, NULL, 0), +(19270, 189, -1866.5953, 5164.541, -48.13592, NULL, 0), +(19270, 190, -1870.5953, 5163.791, -48.13592, NULL, 0), +(19270, 191, -1872.5953, 5162.791, -48.13592, NULL, 0), +(19270, 192, -1874.3198, 5161.7744, -48.298702, NULL, 0), +(19270, 193, -1876.8809, 5160.3096, -47.25393, NULL, 0), +(19270, 194, -1879.6309, 5160.8096, -46.75393, NULL, 0), +(19270, 195, -1881.3809, 5161.0596, -46.25393, NULL, 0), +(19270, 196, -1885.1309, 5161.3096, -43.25393, NULL, 0), +(19270, 197, -1886.3809, 5161.5596, -42.75393, NULL, 0), +(19270, 198, -1889.3809, 5161.8096, -41.25393, NULL, 0), +(19270, 199, -1892.1309, 5162.3096, -40.00393, NULL, 0), +(19270, 200, -1895.8693, 5162.375, -40.20913, NULL, 0), +(19270, 201, -1899.768, 5163.162, -39.959145, NULL, 0), +(19270, 202, -1901.1666, 5165.9487, -40.20916, NULL, 0), +(19270, 203, -1907.0524, 5171.55, -40.20916, NULL, 0), +(19270, 204, -1911.2435, 5175.9854, -40.13343, NULL, 0), +(19270, 205, -1912.7435, 5182.9854, -40.13343, NULL, 0), +(19270, 206, -1914.4935, 5191.2354, -42.88343, NULL, 0), +(19270, 207, -1914.7435, 5192.4854, -43.13343, NULL, 0), +(19270, 208, -1915.0886, 5196.091, -46.718666, NULL, 0), +(19270, 209, -1915.1482, 5197.618, -47.56726, NULL, 0), +(19270, 210, -1915.6482, 5198.368, -47.31726, NULL, 0), +(19270, 211, -1916.3982, 5199.118, -47.06726, NULL, 0), +(19270, 212, -1917.3982, 5199.618, -47.06726, NULL, 0), +(19270, 213, -1924.1482, 5203.618, -47.06726, NULL, 0), +(19270, 214, -1930.9027, 5207.5723, -47.313946, NULL, 0), +(19270, 215, -1934.4938, 5209.9346, -46.939972, NULL, 0), +(19270, 216, -1935.2438, 5210.4346, -46.939972, NULL, 0), +(19270, 217, -1937.7438, 5211.9346, -47.189972, NULL, 0), +(19270, 218, -1942.9938, 5214.6846, -47.439972, NULL, 0), +(19270, 219, -1953.4938, 5220.1846, -47.189972, NULL, 0), +(19270, 220, -1954.2438, 5220.6846, -46.939972, NULL, 0), +(19270, 221, -1957.7438, 5222.6846, -46.939972, NULL, 0), +(19270, 222, -1960.4938, 5224.1846, -46.689972, NULL, 0), +(19270, 223, -1962.603, 5225.186, -46.7385, NULL, 0), +(19270, 224, -1964.0779, 5226.159, -46.377556, NULL, 0), +(19270, 225, -1964.5779, 5226.659, -46.377556, NULL, 0), +(19270, 226, -1967.0779, 5228.159, -46.127556, NULL, 0), +(19270, 227, -1970.3279, 5230.409, -45.877556, NULL, 0), +(19270, 228, -1982.5779, 5238.409, -46.127556, NULL, 0), +(19270, 229, -1982.9333, 5238.5513, -46.2599, NULL, 0), +(19270, 230, -1984.5637, 5239.8706, -45.78431, NULL, 0), +(19270, 231, -1998.8137, 5243.6206, -45.53431, NULL, 0), +(19270, 232, -2004.6942, 5245.19, -45.80872, NULL, 0), +(19270, 233, -1998.5764, 5243.411, -45.600166, NULL, 0), +(19270, 234, -1985.5764, 5239.661, -45.850166, NULL, 0), +(19270, 235, -1977.6184, 5236.9014, -45.91132, NULL, 0), +(19270, 236, -1976.6198, 5236.591, -45.613564, NULL, 0), +(19270, 237, -1973.1198, 5235.591, -45.613564, NULL, 0), +(19270, 238, -1967.8698, 5233.091, -46.113564, NULL, 0), +(19270, 239, -1966.1198, 5232.091, -46.113564, NULL, 0), +(19270, 240, -1964.1198, 5231.341, -46.363564, NULL, 0), +(19270, 241, -1957.8698, 5228.091, -46.613564, NULL, 0), +(19270, 242, -1953.6198, 5226.091, -46.863564, NULL, 0), +(19270, 243, -1951.1198, 5224.841, -47.113564, NULL, 0), +(19270, 244, -1940.3698, 5219.591, -46.863564, NULL, 0), +(19270, 245, -1937.4708, 5217.9136, -47.274998, NULL, 0), +(19270, 246, -1931.7573, 5215.2734, -47.047817, NULL, 0), +(19270, 247, -1927.0073, 5214.0234, -47.297817, NULL, 0), +(19270, 248, -1924.2573, 5213.2734, -47.547817, NULL, 0), +(19270, 249, -1911.7573, 5210.0234, -47.797817, NULL, 0), +(19270, 250, -1910.0073, 5209.5234, -48.047817, NULL, 0), +(19270, 251, -1908.0073, 5209.0234, -48.547817, NULL, 0), +(19270, 252, -1906.0073, 5208.5234, -48.547817, NULL, 0), +(19270, 253, -1904.0073, 5208.0234, -48.797817, NULL, 0), +(19270, 254, -1900.2573, 5207.0234, -49.047817, NULL, 0), +(19270, 255, -1898.9575, 5206.4375, -49.623775, NULL, 0), +(19270, 256, -1898.0679, 5206.1665, -49.437138, NULL, 0), +(19270, 257, -1893.8179, 5205.1665, -49.687138, NULL, 0), +(19270, 258, -1891.3179, 5202.1665, -49.687138, NULL, 0), +(19270, 259, -1882.8179, 5191.9165, -49.937138, NULL, 0), +(19270, 260, -1869.8179, 5176.1665, -49.687138, NULL, 0), +(19270, 261, -1868.9952, 5174.9146, -50.00228, NULL, 0), +(19270, 262, -1867.0022, 5172.68, -49.461166, NULL, 0), +(19270, 263, -1865.5022, 5171.18, -49.461166, NULL, 0), +(19270, 264, -1862.5022, 5171.18, -49.211166, NULL, 0), +(19270, 265, -1860.5022, 5171.18, -48.961166, NULL, 0), +(19270, 266, -1858.5022, 5171.18, -48.461166, NULL, 0), +(19270, 267, -1857.5022, 5170.93, -48.211166, NULL, 0), +(19270, 268, -1855.5022, 5170.93, -47.711166, NULL, 0), +(19270, 269, -1854.5022, 5170.93, -47.461166, NULL, 0), +(19270, 270, -1852.5022, 5170.93, -47.211166, NULL, 0), +(19270, 271, -1850.5022, 5170.93, -46.961166, NULL, 0), +(19270, 272, -1844.7522, 5170.93, -47.211166, NULL, 0), +(19270, 273, -1842.7522, 5170.93, -47.461166, NULL, 0), +(19270, 274, -1839.7522, 5170.93, -47.711166, NULL, 0), +(19270, 275, -1836.7522, 5170.68, -47.961166, NULL, 0), +(19270, 276, -1834.7522, 5170.68, -48.211166, NULL, 0), +(19270, 277, -1834.6604, 5170.502, -48.48815, NULL, 0), +(19270, 278, -1831.4863, 5170.4424, -48.31687, NULL, 0), +(19270, 279, -1830.2363, 5170.4424, -48.56687, NULL, 0), +(19270, 280, -1828.9863, 5170.9424, -48.56687, NULL, 0), +(19270, 281, -1827.2363, 5171.9424, -49.31687, NULL, 0), +(19270, 282, -1825.7363, 5173.1924, -49.81687, NULL, 0), +(19270, 283, -1824.7363, 5173.9424, -49.81687, NULL, 0), +(19270, 284, -1823.7363, 5173.9424, -50.06687, NULL, 0), +(19270, 285, -1821.9863, 5174.1924, -49.06687, NULL, 0), +(19270, 286, -1818.7363, 5173.6924, -46.31687, NULL, 0), +(19270, 287, -1809.4863, 5171.9424, -43.06687, NULL, 0), +(19270, 288, -1803.4863, 5170.9424, -41.81687, NULL, 0), +(19270, 289, -1802.1086, 5170.791, -41.44974, NULL, 0), +(19270, 290, -1800.2062, 5170.876, -40.57945, NULL, 0), +(19270, 291, -1796.4562, 5170.126, -40.57945, NULL, 0), +(19270, 292, -1794.4562, 5170.626, -40.32945, NULL, 0), +(19270, 293, -1789.9562, 5171.126, -40.07945, NULL, 0), +(19270, 294, -1786.8037, 5171.461, -40.209156, NULL, 0), +(19270, 295, -1773.7195, 5178.131, -39.70702, NULL, 0), +(19270, 296, -1764.2195, 5180.881, -39.70702, NULL, 0), +(19270, 297, -1758.1353, 5166.801, -37.204884, NULL, 0), +(19270, 298, -1753.0828, 5168.1416, -36.954895, NULL, 0), +(19270, 299, -1751.5304, 5168.483, -37.204906, NULL, 0); diff --git a/data/sql/updates/db_world/2024_08_13_02.sql b/data/sql/updates/db_world/2024_08_13_02.sql new file mode 100644 index 000000000..0aaf86858 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_13_02.sql @@ -0,0 +1,22 @@ +-- DB update 2024_08_13_01 -> 2024_08_13_02 +-- +DROP TABLE IF EXISTS `module_string`; +CREATE TABLE IF NOT EXISTS `module_string` ( + `module` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'module dir name, eg mod-cfbg', + `id` int unsigned NOT NULL, + `string` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`module`, `id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +DROP TABLE IF EXISTS `module_string_locale`; +CREATE TABLE IF NOT EXISTS `module_string_locale` ( + `module` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Corresponds to an existing entry in module_string', + `id` int unsigned NOT NULL COMMENT 'Corresponds to an existing entry in module_string', + `locale` ENUM('koKR', 'frFR', 'deDE', 'zhCN', 'zhTW', 'esES', 'esMX', 'ruRU') NOT NULL, + `string` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`module`, `id`, `locale`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +DELETE FROM `command` WHERE `name` = 'reload module_string'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('reload module_string', 3, 'Syntax: .reload module_string'); diff --git a/data/sql/updates/db_world/2024_08_13_03.sql b/data/sql/updates/db_world/2024_08_13_03.sql new file mode 100644 index 000000000..d84f8bc8a --- /dev/null +++ b/data/sql/updates/db_world/2024_08_13_03.sql @@ -0,0 +1,3 @@ +-- DB update 2024_08_13_02 -> 2024_08_13_03 +-- +DELETE FROM `command` WHERE `name` = 'reload quest_greeting_locale'; diff --git a/data/sql/updates/db_world/2024_08_17_00.sql b/data/sql/updates/db_world/2024_08_17_00.sql new file mode 100644 index 000000000..3ecba4eb8 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_17_00.sql @@ -0,0 +1,3 @@ +-- DB update 2024_08_13_03 -> 2024_08_17_00 +-- +UPDATE `creature_template` SET `flags_extra` = `flags_extra` |256, `mechanic_immune_mask` = `mechanic_immune_mask`|33554432 WHERE `entry` = 22950; diff --git a/data/sql/updates/db_world/2024_08_17_01.sql b/data/sql/updates/db_world/2024_08_17_01.sql new file mode 100644 index 000000000..4549e1bf8 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_17_01.sql @@ -0,0 +1,3 @@ +-- DB update 2024_08_17_00 -> 2024_08_17_01 +-- +UPDATE `creature_template` SET `flags_extra` = `flags_extra` |256 WHERE `entry` = 22949; diff --git a/data/sql/updates/db_world/2024_08_17_02.sql b/data/sql/updates/db_world/2024_08_17_02.sql new file mode 100644 index 000000000..aa01248aa --- /dev/null +++ b/data/sql/updates/db_world/2024_08_17_02.sql @@ -0,0 +1,3 @@ +-- DB update 2024_08_17_01 -> 2024_08_17_02 +-- +UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`&~2048 WHERE `entry` = 22952; diff --git a/src/common/Utilities/StartProcess.cpp b/src/common/Utilities/StartProcess.cpp index a8b35578b..7f745d6ff 100644 --- a/src/common/Utilities/StartProcess.cpp +++ b/src/common/Utilities/StartProcess.cpp @@ -22,13 +22,7 @@ #include "Util.h" #include #include -#include -#include -#include -#include -#include -#include -#include +#include "boost/process.hpp" #include using namespace boost::process; diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index a5a2f6792..507aeb113 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -3285,6 +3285,15 @@ LFG.KickPreventionTimer = 900 DungeonAccessRequirements.LFGLevelDBCOverride = 0 +# +# DungeonFinder.CastDeserter +# +# Description: Cast Deserter to player who leave a dungeon prematurely +# Default: 1 - (Enabled, Blizzlike) +# 0 - (Disabled) + +DungeonFinder.CastDeserter = 1 + # ################################################################################################### diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index 8e86d4658..96a340f9c 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -16,6 +16,7 @@ */ #include "PetAI.h" +#include "CharmInfo.h" #include "Creature.h" #include "Errors.h" #include "Group.h" diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 92fc23184..947a9293e 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -45,6 +45,11 @@ char const* ChatHandler::GetAcoreString(uint32 entry) const return m_session->GetAcoreString(entry); } +std::string const* ChatHandler::GetModuleString(std::string module, uint32 id) const +{ + return m_session->GetModuleString(module, id); +} + bool ChatHandler::IsAvailable(uint32 securityLevel) const { // check security level only for simple command (without child commands) diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 4c9b243eb..199e575b9 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -176,6 +176,21 @@ public: return Acore::StringFormatFmt(GetAcoreString(entry), std::forward(args)...); } + std::string const* GetModuleString(std::string module, uint32 id) const; + + template + void PSendModuleSysMessage(std::string module, uint32 id, Args&&... args) + { + if (HasSession()) + SendSysMessage(PGetParseModuleString(module, id, std::forward(args)...)); + } + + template + std::string PGetParseModuleString(std::string module, uint32 id, Args&&... args) const + { + return Acore::StringFormatFmt(GetModuleString(module, id)->c_str(), std::forward(args)...); + } + void SendErrorMessage(uint32 entry); void SendErrorMessage(std::string_view str, bool escapeCharacters); diff --git a/src/server/game/Combat/ThreatMgr.h b/src/server/game/Combat/ThreatMgr.h index bcc6d1614..6269d7326 100644 --- a/src/server/game/Combat/ThreatMgr.h +++ b/src/server/game/Combat/ThreatMgr.h @@ -290,6 +290,30 @@ private: //================================================= +struct RedirectThreatInfo +{ + RedirectThreatInfo() = default; + ObjectGuid _targetGUID; + uint32 _threatPct{ 0 }; + + [[nodiscard]] ObjectGuid GetTargetGUID() const { return _targetGUID; } + [[nodiscard]] uint32 GetThreatPct() const { return _threatPct; } + + void Set(ObjectGuid guid, uint32 pct) + { + _targetGUID = guid; + _threatPct = pct; + } + + void ModifyThreatPct(int32 amount) + { + amount += _threatPct; + _threatPct = uint32(std::max(0, amount)); + } +}; + +//================================================= + namespace Acore { // Binary predicate for sorting HostileReferences based on threat value diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 27081db22..53823525b 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -246,7 +246,8 @@ namespace lfg { // xinef: fixed dungeon deserter if (method != GROUP_REMOVEMETHOD_KICK_LFG && state != LFG_STATE_FINISHED_DUNGEON && - player->HasAura(LFG_SPELL_DUNGEON_COOLDOWN) && players >= LFG_GROUP_KICK_VOTES_NEEDED) + player->HasAura(LFG_SPELL_DUNGEON_COOLDOWN) && players >= LFG_GROUP_KICK_VOTES_NEEDED && + sWorld->getBoolConfig(CONFIG_LFG_CAST_DESERTER)) { player->AddAura(LFG_SPELL_DUNGEON_DESERTER, player); } diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 31ff02f56..877f8e2ec 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -19,6 +19,7 @@ #define AZEROTHCORE_CREATURE_H #include "Cell.h" +#include "CharmInfo.h" #include "Common.h" #include "CreatureData.h" #include "DatabaseEnv.h" diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index f0b1f75f7..0ec2ffa35 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -319,12 +319,16 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, std::string const if (QuestGreeting const* questGreeting = sObjectMgr->GetQuestGreeting(guid.GetTypeId(), guid.GetEntry())) { - std::string strGreeting = questGreeting->Text; - - LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); - if (localeConstant != LOCALE_enUS) - if (QuestGreetingLocale const* questGreetingLocale = sObjectMgr->GetQuestGreetingLocale(guid.GetTypeId(), guid.GetEntry())) - ObjectMgr::GetLocaleString(questGreetingLocale->Greeting, localeConstant, strGreeting); + std::string strGreeting; + // Check if greeting exists. Blizzlike that some creatures have empty greeting + if (!questGreeting->Greeting.empty()) + { + LocaleConstant locale = _session->GetSessionDbLocaleIndex(); + if (questGreeting->Greeting.size() > size_t(locale)) + strGreeting = questGreeting->Greeting[locale]; + else + strGreeting = questGreeting->Greeting[DEFAULT_LOCALE]; + } data << strGreeting; data << uint32(questGreeting->EmoteDelay); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index f293788b9..7008ce476 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -203,6 +203,10 @@ void GameObject::CheckRitualList() if (m_unique_users.empty()) return; + uint32 animSpell = GetGOInfo()->summoningRitual.animSpell; + if (!animSpell) + animSpell = GetSpellId(); + for (GuidSet::iterator itr = m_unique_users.begin(); itr != m_unique_users.end();) { if (*itr == GetOwnerGUID()) @@ -214,7 +218,7 @@ void GameObject::CheckRitualList() bool erase = true; if (Player* channeler = ObjectAccessor::GetPlayer(*this, *itr)) if (Spell* spell = channeler->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) - if (spell->m_spellInfo->Id == GetGOInfo()->summoningRitual.animSpell) + if (spell->m_spellInfo->Id == animSpell) erase = false; if (erase) @@ -226,10 +230,13 @@ void GameObject::CheckRitualList() void GameObject::ClearRitualList() { - uint32 animSpell = GetGOInfo()->summoningRitual.animSpell; - if (!animSpell || m_unique_users.empty()) + if (m_unique_users.empty()) return; + uint32 animSpell = GetGOInfo()->summoningRitual.animSpell; + if (!animSpell) + animSpell = GetSpellId(); + for (ObjectGuid const& guid : m_unique_users) { if (Player* channeler = ObjectAccessor::GetPlayer(*this, guid)) @@ -526,18 +533,15 @@ void GameObject::Update(uint32 diff) if (GameTime::GetGameTimeMS().count() < m_cooldownTime) return; GameObjectTemplate const* info = GetGOInfo(); - if (info->summoningRitual.animSpell) - { - // xinef: if ritual requires animation, ensure that all users performs channel - CheckRitualList(); - } + + CheckRitualList(); + if (GetUniqueUseCount() < info->summoningRitual.reqParticipants) { SetLootState(GO_READY); return; } - bool triggered = info->summoningRitual.animSpell; Unit* owner = GetOwner(); Unit* spellCaster = owner ? owner : ObjectAccessor::GetPlayer(*this, m_ritualOwnerGUID); if (!spellCaster) @@ -553,7 +557,6 @@ void GameObject::Update(uint32 diff) // spell have reagent and mana cost but it not expected use its // it triggered spell in fact casted at currently channeled GO spellId = 61993; - triggered = true; } // Cast casterTargetSpell at a random GO user @@ -583,7 +586,7 @@ void GameObject::Update(uint32 diff) SetLootState(GO_READY); ClearRitualList(); - spellCaster->CastSpell(spellCaster, spellId, triggered); + spellCaster->CastSpell(spellCaster, spellId, true); return; } case GAMEOBJECT_TYPE_CHEST: @@ -1848,17 +1851,18 @@ void GameObject::Use(Unit* user) return; } + CheckRitualList(); + + if (GetUniqueUseCount() == info->summoningRitual.reqParticipants) + return; + if (info->summoningRitual.animSpell) - { - // xinef: if ritual requires animation, ensure that all users performs channel - CheckRitualList(); - - // xinef: all participants found - if (GetUniqueUseCount() == info->summoningRitual.reqParticipants) - return; - player->CastSpell(player, info->summoningRitual.animSpell, true); - } + else + player->CastSpell(player, GetSpellId(), + TriggerCastFlags(TRIGGERED_IGNORE_EFFECTS + | TRIGGERED_IGNORE_POWER_AND_REAGENT_COST + | TRIGGERED_CAST_DIRECTLY)); AddUniqueUse(player); @@ -1866,11 +1870,9 @@ void GameObject::Use(Unit* user) if (GetUniqueUseCount() == info->summoningRitual.reqParticipants) { SetLootState(GO_NOT_READY); - // can be deleted now, if - if (!info->summoningRitual.animSpell) - m_cooldownTime = 0; - else // channel ready, maintain this - m_cooldownTime = GameTime::GetGameTimeMS().count() + 5 * IN_MILLISECONDS; + + // channel ready, maintain this + m_cooldownTime = GameTime::GetGameTimeMS().count() + 5 * IN_MILLISECONDS; } return; @@ -1891,7 +1893,6 @@ void GameObject::Use(Unit* user) user->RemoveAurasByType(SPELL_AURA_MOUNTED); spellId = info->spellcaster.spellId; - AddUse(); break; } case GAMEOBJECT_TYPE_MEETINGSTONE: //23 @@ -1905,8 +1906,8 @@ void GameObject::Use(Unit* user) Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetTarget()); - // accept only use by player from same raid as caster, except caster itself - if (!targetPlayer || targetPlayer == player || !targetPlayer->IsInSameRaidWith(player)) + // accept only use by player from same raid as caster + if (!targetPlayer || !targetPlayer->IsInSameRaidWith(player)) return; //required lvl checks! @@ -1917,10 +1918,7 @@ void GameObject::Use(Unit* user) if (level < info->meetingstone.minLevel) return; - if (info->entry == 194097) - spellId = 61994; // Ritual of Summoning - else - spellId = 23598; // Meeting Stone Summon + spellId = 23598; // Meeting Stone Summon break; } @@ -2067,7 +2065,10 @@ void GameObject::Use(Unit* user) sOutdoorPvPMgr->HandleCustomSpell(player, spellId, this); if (spellCaster) - spellCaster->CastSpell(user, spellInfo, triggered); + { + if ((spellCaster->CastSpell(user, spellInfo, triggered) == SPELL_CAST_OK) && GetGoType() == GAMEOBJECT_TYPE_SPELLCASTER) + AddUse(); + } else CastSpell(user, spellId); } diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index cf845c304..fe7d89bba 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -35,6 +35,12 @@ struct ItemSetEffect SpellInfo const* spells[8]; }; +enum InventorySlot +{ + NULL_BAG = 0, + NULL_SLOT = 255 +}; + // EnumUtils: DESCRIBE THIS enum InventoryResult : uint8 { diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 6968600b1..117b8f6a5 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -17,6 +17,7 @@ #include "Pet.h" #include "ArenaSpectator.h" +#include "CharmInfo.h" #include "Common.h" #include "DatabaseEnv.h" #include "GameTime.h" diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index a38baf814..9329a0b07 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -18,6 +18,7 @@ #ifndef AZEROTHCORE_PET_H #define AZEROTHCORE_PET_H +#include "CharmInfo.h" #include "PetDefines.h" #include "TemporarySummon.h" diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 62d6b85c3..c37f5f7e3 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -28,6 +28,7 @@ #include "BattlegroundAV.h" #include "BattlegroundMgr.h" #include "CellImpl.h" +#include "CharmInfo.h" #include "Channel.h" #include "CharacterCache.h" #include "CharacterDatabaseCleaner.h" diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 706e30d75..0d04f0800 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -20,6 +20,7 @@ #include "ArenaTeam.h" #include "Battleground.h" +#include "CharmInfo.h" #include "CharacterCache.h" #include "CinematicMgr.h" #include "DBCStores.h" diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 735fc3700..6709ede66 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -1017,7 +1017,7 @@ void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool def chance = chance < 1.0f ? 1.0f : chance; // minimum chance to increase skill is 1% - LOG_DEBUG("entities.player", "Player::UpdateCombatSkills(defence:{}, playerLevel:{}, moblevel:{}) -> ({}/{}) chance to increase skill is {}\%", defence, playerLevel, moblevel, currentSkillValue, currentSkillMax, chance); + LOG_DEBUG("entities.player", "Player::UpdateCombatSkills(defence:{}, playerLevel:{}, moblevel:{}) -> ({}/{}) chance to increase skill is {}%", defence, playerLevel, moblevel, currentSkillValue, currentSkillMax, chance); if (roll_chance_f(chance)) { diff --git a/src/server/game/Entities/Unit/CharmInfo.cpp b/src/server/game/Entities/Unit/CharmInfo.cpp new file mode 100644 index 000000000..4e0664304 --- /dev/null +++ b/src/server/game/Entities/Unit/CharmInfo.cpp @@ -0,0 +1,411 @@ +/* + * 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 . + */ + +#include "CharmInfo.h" +#include "Creature.h" +#include "GameTime.h" +#include "Map.h" +#include "SpellInfo.h" +#include "Player.h" +#include "SpellMgr.h" +#include "StringConvert.h" +#include "Tokenize.h" +#include "Unit.h" + +CharmInfo::CharmInfo(Unit* unit) + : _unit(unit), _CommandState(COMMAND_FOLLOW), _petnumber(0), _oldReactState(REACT_PASSIVE), + _isCommandAttack(false), _isCommandFollow(false), _isAtStay(false), _isFollowing(false), _isReturning(false), + _forcedSpellId(0), _stayX(0.0f), _stayY(0.0f), _stayZ(0.0f) +{ + for (uint8 i = 0; i < MAX_SPELL_CHARM; ++i) + _charmspells[i].SetActionAndType(0, ACT_DISABLED); + + if (_unit->GetTypeId() == TYPEID_UNIT) + { + _oldReactState = _unit->ToCreature()->GetReactState(); + _unit->ToCreature()->SetReactState(REACT_PASSIVE); + } +} + +CharmInfo::~CharmInfo() = default; + +void CharmInfo::RestoreState() +{ + if (Creature* creature = _unit->ToCreature()) + creature->SetReactState(_oldReactState); +} + +void CharmInfo::InitPetActionBar() +{ + // the first 3 SpellOrActions are attack, follow and stay + for (uint32 i = 0; i < ACTION_BAR_INDEX_PET_SPELL_START - ACTION_BAR_INDEX_START; ++i) + SetActionBar(ACTION_BAR_INDEX_START + i, COMMAND_ATTACK - i, ACT_COMMAND); + + // middle 4 SpellOrActions are spells/special attacks/abilities + for (uint32 i = 0; i < ACTION_BAR_INDEX_PET_SPELL_END - ACTION_BAR_INDEX_PET_SPELL_START; ++i) + SetActionBar(ACTION_BAR_INDEX_PET_SPELL_START + i, 0, ACT_PASSIVE); + + // last 3 SpellOrActions are reactions + for (uint32 i = 0; i < ACTION_BAR_INDEX_END - ACTION_BAR_INDEX_PET_SPELL_END; ++i) + SetActionBar(ACTION_BAR_INDEX_PET_SPELL_END + i, COMMAND_ATTACK - i, ACT_REACTION); +} + +void CharmInfo::InitEmptyActionBar(bool withAttack) +{ + if (withAttack) + SetActionBar(ACTION_BAR_INDEX_START, COMMAND_ATTACK, ACT_COMMAND); + else + SetActionBar(ACTION_BAR_INDEX_START, 0, ACT_PASSIVE); + for (uint32 x = ACTION_BAR_INDEX_START + 1; x < ACTION_BAR_INDEX_END; ++x) + SetActionBar(x, 0, ACT_PASSIVE); +} + +void CharmInfo::InitPossessCreateSpells() +{ + if (_unit->GetTypeId() == TYPEID_UNIT) + { + // Adding switch until better way is found. Malcrom + // Adding entrys to this switch will prevent COMMAND_ATTACK being added to pet bar. + switch (_unit->GetEntry()) + { + case 23575: // Mindless Abomination + case 24783: // Trained Rock Falcon + case 27664: // Crashin' Thrashin' Racer + case 40281: // Crashin' Thrashin' Racer + case 23109: // Vengeful Spirit + break; + default: + InitEmptyActionBar(); + break; + } + + for (uint32 i = 0; i < MAX_CREATURE_SPELLS; ++i) + { + uint32 spellId = _unit->ToCreature()->m_spells[i]; + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (spellInfo) + { + if (spellInfo->IsPassive()) + _unit->CastSpell(_unit, spellInfo, true); + else + AddSpellToActionBar(spellInfo, ACT_PASSIVE); + } + } + } + else + InitEmptyActionBar(); +} + +void CharmInfo::InitCharmCreateSpells() +{ + InitPetActionBar(); + + if (_unit->GetTypeId() == TYPEID_PLAYER) // charmed players don't have spells + return; + + for (uint32 i = 0; i < MAX_SPELL_CHARM; ++i) + { + uint32 spellId = _unit->ToCreature()->m_spells[i]; + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + + if (!spellInfo) + { + _charmspells[i].SetActionAndType(spellId, ACT_DISABLED); + continue; + } + + if (spellInfo->IsPassive()) + { + _unit->CastSpell(_unit, spellInfo, true); + _charmspells[i].SetActionAndType(spellId, ACT_PASSIVE); + } + else + { + _charmspells[i].SetActionAndType(spellId, ACT_DISABLED); + + ActiveStates newstate = ACT_PASSIVE; + + if (!spellInfo->IsAutocastable()) + newstate = ACT_PASSIVE; + else + { + if (spellInfo->NeedsExplicitUnitTarget()) + { + newstate = ACT_ENABLED; + ToggleCreatureAutocast(spellInfo, true); + } + else + newstate = ACT_DISABLED; + } + + AddSpellToActionBar(spellInfo, newstate); + } + } +} + +bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate) +{ + uint32 spell_id = spellInfo->Id; + uint32 first_id = spellInfo->GetFirstRankSpell()->Id; + + // new spell rank can be already listed + for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) + { + if (uint32 action = PetActionBar[i].GetAction()) + { + if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id) + { + PetActionBar[i].SetAction(spell_id); + return true; + } + } + } + + // or use empty slot in other case + for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) + { + if (!PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell()) + { + SetActionBar(i, spell_id, newstate == ACT_DECIDE ? spellInfo->IsAutocastable() ? ACT_DISABLED : ACT_PASSIVE : newstate); + + if (_unit->GetCharmer() && _unit->GetCharmer()->IsPlayer()) + { + if (Creature* creature = _unit->ToCreature()) + { + // Processing this packet needs to be delayed + _unit->m_Events.AddEventAtOffset([creature, spell_id]() + { + if (uint32 cooldown = creature->GetSpellCooldown(spell_id)) + { + WorldPacket data; + creature->BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, spell_id, cooldown); + if (creature->GetCharmer() && creature->GetCharmer()->IsPlayer()) + { + creature->GetCharmer()->ToPlayer()->SendDirectMessage(&data); + } + } + }, 500ms); + } + } + + return true; + } + } + return false; +} + +bool CharmInfo::RemoveSpellFromActionBar(uint32 spell_id) +{ + uint32 first_id = sSpellMgr->GetFirstSpellInChain(spell_id); + + for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) + { + if (uint32 action = PetActionBar[i].GetAction()) + { + if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id) + { + SetActionBar(i, 0, ACT_PASSIVE); + return true; + } + } + } + + return false; +} + +void CharmInfo::ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply) +{ + if (spellInfo->IsPassive()) + return; + + for (uint32 i = 0; i < MAX_SPELL_CHARM; ++i) + if (spellInfo->Id == _charmspells[i].GetAction()) + _charmspells[i].SetType(apply ? ACT_ENABLED : ACT_DISABLED); +} + +void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow) +{ + _petnumber = petnumber; + if (statwindow) + _unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, _petnumber); + else + _unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, 0); +} + +void CharmInfo::LoadPetActionBar(const std::string& data) +{ + std::vector tokens = Acore::Tokenize(data, ' ', false); + + if (tokens.size() != (ACTION_BAR_INDEX_END - ACTION_BAR_INDEX_START) * 2) + return; // non critical, will reset to default + + auto iter = tokens.begin(); + for (uint8 index = ACTION_BAR_INDEX_START; index < ACTION_BAR_INDEX_END; ++index) + { + Optional type = Acore::StringTo(*(iter++)); + Optional action = Acore::StringTo(*(iter++)); + + if (!type || !action) + { + continue; + } + + PetActionBar[index].SetActionAndType(*action, static_cast(*type)); + + // check correctness + if (PetActionBar[index].IsActionBarForSpell()) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(PetActionBar[index].GetAction()); + if (!spellInfo) + { + SetActionBar(index, 0, ACT_PASSIVE); + } + else if (!spellInfo->IsAutocastable()) + { + SetActionBar(index, PetActionBar[index].GetAction(), ACT_PASSIVE); + } + } + } +} + +void CharmInfo::BuildActionBar(WorldPacket* data) +{ + for (uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) + *data << uint32(PetActionBar[i].packedData); +} + +void CharmInfo::SetSpellAutocast(SpellInfo const* spellInfo, bool state) +{ + for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) + { + if (spellInfo->Id == PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell()) + { + PetActionBar[i].SetType(state ? ACT_ENABLED : ACT_DISABLED); + break; + } + } +} + +void CharmInfo::SetIsCommandAttack(bool val) +{ + _isCommandAttack = val; +} + +bool CharmInfo::IsCommandAttack() +{ + return _isCommandAttack; +} + +void CharmInfo::SetIsCommandFollow(bool val) +{ + _isCommandFollow = val; +} + +bool CharmInfo::IsCommandFollow() +{ + return _isCommandFollow; +} + +void CharmInfo::SaveStayPosition(bool atCurrentPos) +{ + //! At this point a new spline destination is enabled because of Unit::StopMoving() + G3D::Vector3 stayPos = G3D::Vector3(); + + if (atCurrentPos) + { + float z = INVALID_HEIGHT; + _unit->UpdateAllowedPositionZ(_unit->GetPositionX(), _unit->GetPositionY(), z); + stayPos = G3D::Vector3(_unit->GetPositionX(), _unit->GetPositionY(), z != INVALID_HEIGHT ? z : _unit->GetPositionZ()); + } + else + stayPos = _unit->movespline->FinalDestination(); + + if (_unit->movespline->onTransport) + if (TransportBase* transport = _unit->GetDirectTransport()) + transport->CalculatePassengerPosition(stayPos.x, stayPos.y, stayPos.z); + + _stayX = stayPos.x; + _stayY = stayPos.y; + _stayZ = stayPos.z; +} + +void CharmInfo::GetStayPosition(float& x, float& y, float& z) +{ + x = _stayX; + y = _stayY; + z = _stayZ; +} + +void CharmInfo::RemoveStayPosition() +{ + _stayX = 0.0f; + _stayY = 0.0f; + _stayZ = 0.0f; +} + +bool CharmInfo::HasStayPosition() +{ + return _stayX && _stayY && _stayZ; +} + +void CharmInfo::SetIsAtStay(bool val) +{ + _isAtStay = val; +} + +bool CharmInfo::IsAtStay() +{ + return _isAtStay; +} + +void CharmInfo::SetIsFollowing(bool val) +{ + _isFollowing = val; +} + +bool CharmInfo::IsFollowing() +{ + return _isFollowing; +} + +void CharmInfo::SetIsReturning(bool val) +{ + _isReturning = val; +} + +bool CharmInfo::IsReturning() +{ + return _isReturning; +} + +//////////////////////////////////////////////////////////// +// Methods of class GlobalCooldownMgr +bool GlobalCooldownMgr::HasGlobalCooldown(SpellInfo const* spellInfo) const +{ + GlobalCooldownList::const_iterator itr = m_GlobalCooldowns.find(spellInfo->StartRecoveryCategory); + return itr != m_GlobalCooldowns.end() && itr->second.duration && getMSTimeDiff(itr->second.cast_time, GameTime::GetGameTimeMS().count()) < itr->second.duration; +} + +void GlobalCooldownMgr::AddGlobalCooldown(SpellInfo const* spellInfo, uint32 gcd) +{ + m_GlobalCooldowns[spellInfo->StartRecoveryCategory] = GlobalCooldown(gcd, GameTime::GetGameTimeMS().count()); +} + +void GlobalCooldownMgr::CancelGlobalCooldown(SpellInfo const* spellInfo) +{ + m_GlobalCooldowns[spellInfo->StartRecoveryCategory].duration = 0; +} diff --git a/src/server/game/Entities/Unit/CharmInfo.h b/src/server/game/Entities/Unit/CharmInfo.h new file mode 100644 index 000000000..6a62c6ef8 --- /dev/null +++ b/src/server/game/Entities/Unit/CharmInfo.h @@ -0,0 +1,208 @@ +/* + * 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 . + */ + +#ifndef _CHARMINFO_H +#define _CHARMINFO_H + +#include "Object.h" + +#define MAX_SPELL_CHARM 4 +#define MAX_SPELL_VEHICLE 6 +#define MAX_SPELL_POSSESS 8 +#define MAX_SPELL_CONTROL_BAR 10 + +#define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START) + +#define UNIT_ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF) +#define UNIT_ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24) +#define MAKE_UNIT_ACTION_BUTTON(A, T) (uint32(A) | (uint32(T) << 24)) + +class GlobalCooldownMgr; +class SpellInfo; +class Unit; +class WorldPacket; + +enum CommandStates : uint8; +enum ReactStates : uint8; + +enum CharmType : uint8 +{ + CHARM_TYPE_CHARM, + CHARM_TYPE_POSSESS, + CHARM_TYPE_VEHICLE, + CHARM_TYPE_CONVERT, +}; + +enum ActionBarIndex +{ + ACTION_BAR_INDEX_START = 0, + ACTION_BAR_INDEX_PET_SPELL_START = 3, + ACTION_BAR_INDEX_PET_SPELL_END = 7, + ACTION_BAR_INDEX_END = 10, +}; + +enum ActiveStates : uint8 +{ + ACT_PASSIVE = 0x01, // 0x01 - passive + ACT_DISABLED = 0x81, // 0x80 - castable + ACT_ENABLED = 0xC1, // 0x40 | 0x80 - auto cast + castable + ACT_COMMAND = 0x07, // 0x01 | 0x02 | 0x04 + ACT_REACTION = 0x06, // 0x02 | 0x04 + ACT_DECIDE = 0x00 // custom +}; + +struct GlobalCooldown +{ + explicit GlobalCooldown(uint32 _dur = 0, uint32 _time = 0) : duration(_dur), cast_time(_time) {} + + uint32 duration; + uint32 cast_time; +}; + +typedef std::unordered_map GlobalCooldownList; + +class GlobalCooldownMgr // Shared by Player and CharmInfo +{ +public: + GlobalCooldownMgr() = default; + +public: + bool HasGlobalCooldown(SpellInfo const* spellInfo) const; + void AddGlobalCooldown(SpellInfo const* spellInfo, uint32 gcd); + void CancelGlobalCooldown(SpellInfo const* spellInfo); + +private: + GlobalCooldownList m_GlobalCooldowns; +}; + +struct UnitActionBarEntry +{ + UnitActionBarEntry() : packedData(uint32(ACT_DISABLED) << 24) {} + + uint32 packedData; + + // helper + [[nodiscard]] ActiveStates GetType() const { return ActiveStates(UNIT_ACTION_BUTTON_TYPE(packedData)); } + [[nodiscard]] uint32 GetAction() const { return UNIT_ACTION_BUTTON_ACTION(packedData); } + [[nodiscard]] bool IsActionBarForSpell() const + { + ActiveStates Type = GetType(); + return Type == ACT_DISABLED || Type == ACT_ENABLED || Type == ACT_PASSIVE; + } + + void SetActionAndType(uint32 action, ActiveStates type) + { + packedData = MAKE_UNIT_ACTION_BUTTON(action, type); + } + + void SetType(ActiveStates type) + { + packedData = MAKE_UNIT_ACTION_BUTTON(UNIT_ACTION_BUTTON_ACTION(packedData), type); + } + + void SetAction(uint32 action) + { + packedData = (packedData & 0xFF000000) | UNIT_ACTION_BUTTON_ACTION(action); + } +}; +typedef UnitActionBarEntry CharmSpellInfo; + +struct CharmInfo +{ +public: + explicit CharmInfo(Unit* unit); + ~CharmInfo(); + void RestoreState(); + [[nodiscard]] uint32 GetPetNumber() const { return _petnumber; } + void SetPetNumber(uint32 petnumber, bool statwindow); + + void SetCommandState(CommandStates st) { _CommandState = st; } + [[nodiscard]] CommandStates GetCommandState() const { return _CommandState; } + [[nodiscard]] bool HasCommandState(CommandStates state) const { return (_CommandState == state); } + + void InitPossessCreateSpells(); + void InitCharmCreateSpells(); + void InitPetActionBar(); + void InitEmptyActionBar(bool withAttack = true); + + //return true if successful + bool AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate = ACT_DECIDE); + bool RemoveSpellFromActionBar(uint32 spell_id); + void LoadPetActionBar(const std::string& data); + void BuildActionBar(WorldPacket* data); + void SetSpellAutocast(SpellInfo const* spellInfo, bool state); + void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type) + { + PetActionBar[index].SetActionAndType(spellOrAction, type); + } + [[nodiscard]] UnitActionBarEntry const* GetActionBarEntry(uint8 index) const { return &(PetActionBar[index]); } + + void ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply); + + CharmSpellInfo* GetCharmSpell(uint8 index) { return &(_charmspells[index]); } + + GlobalCooldownMgr& GetGlobalCooldownMgr() { return _GlobalCooldownMgr; } + + void SetIsCommandAttack(bool val); + bool IsCommandAttack(); + void SetIsCommandFollow(bool val); + bool IsCommandFollow(); + void SetIsAtStay(bool val); + bool IsAtStay(); + void SetIsFollowing(bool val); + bool IsFollowing(); + void SetIsReturning(bool val); + bool IsReturning(); + void SaveStayPosition(bool atCurrentPos); + void GetStayPosition(float& x, float& y, float& z); + void RemoveStayPosition(); + bool HasStayPosition(); + + void SetForcedSpell(uint32 id) { _forcedSpellId = id; } + int32 GetForcedSpell() { return _forcedSpellId; } + void SetForcedTargetGUID(ObjectGuid guid = ObjectGuid::Empty) { _forcedTargetGUID = guid; } + ObjectGuid GetForcedTarget() { return _forcedTargetGUID; } + + // Player react states + void SetPlayerReactState(ReactStates s) { _oldReactState = s; } + [[nodiscard]] ReactStates GetPlayerReactState() const { return _oldReactState; } + +private: + Unit* _unit; + UnitActionBarEntry PetActionBar[MAX_UNIT_ACTION_BAR_INDEX]; + CharmSpellInfo _charmspells[4]; + CommandStates _CommandState; + uint32 _petnumber; + + //for restoration after charmed + ReactStates _oldReactState; + + bool _isCommandAttack; + bool _isCommandFollow; + bool _isAtStay; + bool _isFollowing; + bool _isReturning; + int32 _forcedSpellId; + ObjectGuid _forcedTargetGUID; + float _stayX; + float _stayY; + float _stayZ; + + GlobalCooldownMgr _GlobalCooldownMgr; +}; + +#endif // _CHARMINFO_H diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index c917d04e0..6c87bf4cd 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -23,6 +23,7 @@ #include "Battleground.h" #include "CellImpl.h" #include "CharacterCache.h" +#include "CharmInfo.h" #include "Chat.h" #include "ChatPackets.h" #include "ChatTextBuilder.h" @@ -333,24 +334,6 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject), _lastExtraAttackSpell = 0; } -//////////////////////////////////////////////////////////// -// Methods of class GlobalCooldownMgr -bool GlobalCooldownMgr::HasGlobalCooldown(SpellInfo const* spellInfo) const -{ - GlobalCooldownList::const_iterator itr = m_GlobalCooldowns.find(spellInfo->StartRecoveryCategory); - return itr != m_GlobalCooldowns.end() && itr->second.duration && getMSTimeDiff(itr->second.cast_time, GameTime::GetGameTimeMS().count()) < itr->second.duration; -} - -void GlobalCooldownMgr::AddGlobalCooldown(SpellInfo const* spellInfo, uint32 gcd) -{ - m_GlobalCooldowns[spellInfo->StartRecoveryCategory] = GlobalCooldown(gcd, GameTime::GetGameTimeMS().count()); -} - -void GlobalCooldownMgr::CancelGlobalCooldown(SpellInfo const* spellInfo) -{ - m_GlobalCooldowns[spellInfo->StartRecoveryCategory].duration = 0; -} - //////////////////////////////////////////////////////////// // Methods of class Unit Unit::~Unit() @@ -15780,287 +15763,6 @@ void Unit::DeleteCharmInfo() m_charmInfo = nullptr; } -CharmInfo::CharmInfo(Unit* unit) - : _unit(unit), _CommandState(COMMAND_FOLLOW), _petnumber(0), _oldReactState(REACT_PASSIVE), - _isCommandAttack(false), _isCommandFollow(false), _isAtStay(false), _isFollowing(false), _isReturning(false), - _forcedSpellId(0), _stayX(0.0f), _stayY(0.0f), _stayZ(0.0f) -{ - for (uint8 i = 0; i < MAX_SPELL_CHARM; ++i) - _charmspells[i].SetActionAndType(0, ACT_DISABLED); - - if (_unit->GetTypeId() == TYPEID_UNIT) - { - _oldReactState = _unit->ToCreature()->GetReactState(); - _unit->ToCreature()->SetReactState(REACT_PASSIVE); - } -} - -CharmInfo::~CharmInfo() -{ -} - -void CharmInfo::RestoreState() -{ - if (Creature* creature = _unit->ToCreature()) - creature->SetReactState(_oldReactState); -} - -void CharmInfo::InitPetActionBar() -{ - // the first 3 SpellOrActions are attack, follow and stay - for (uint32 i = 0; i < ACTION_BAR_INDEX_PET_SPELL_START - ACTION_BAR_INDEX_START; ++i) - SetActionBar(ACTION_BAR_INDEX_START + i, COMMAND_ATTACK - i, ACT_COMMAND); - - // middle 4 SpellOrActions are spells/special attacks/abilities - for (uint32 i = 0; i < ACTION_BAR_INDEX_PET_SPELL_END - ACTION_BAR_INDEX_PET_SPELL_START; ++i) - SetActionBar(ACTION_BAR_INDEX_PET_SPELL_START + i, 0, ACT_PASSIVE); - - // last 3 SpellOrActions are reactions - for (uint32 i = 0; i < ACTION_BAR_INDEX_END - ACTION_BAR_INDEX_PET_SPELL_END; ++i) - SetActionBar(ACTION_BAR_INDEX_PET_SPELL_END + i, COMMAND_ATTACK - i, ACT_REACTION); -} - -void CharmInfo::InitEmptyActionBar(bool withAttack) -{ - if (withAttack) - SetActionBar(ACTION_BAR_INDEX_START, COMMAND_ATTACK, ACT_COMMAND); - else - SetActionBar(ACTION_BAR_INDEX_START, 0, ACT_PASSIVE); - for (uint32 x = ACTION_BAR_INDEX_START + 1; x < ACTION_BAR_INDEX_END; ++x) - SetActionBar(x, 0, ACT_PASSIVE); -} - -void CharmInfo::InitPossessCreateSpells() -{ - if (_unit->GetTypeId() == TYPEID_UNIT) - { - // Adding switch until better way is found. Malcrom - // Adding entrys to this switch will prevent COMMAND_ATTACK being added to pet bar. - switch (_unit->GetEntry()) - { - case 23575: // Mindless Abomination - case 24783: // Trained Rock Falcon - case 27664: // Crashin' Thrashin' Racer - case 40281: // Crashin' Thrashin' Racer - case 23109: // Vengeful Spirit - break; - default: - InitEmptyActionBar(); - break; - } - - for (uint32 i = 0; i < MAX_CREATURE_SPELLS; ++i) - { - uint32 spellId = _unit->ToCreature()->m_spells[i]; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (spellInfo) - { - if (spellInfo->IsPassive()) - _unit->CastSpell(_unit, spellInfo, true); - else - AddSpellToActionBar(spellInfo, ACT_PASSIVE); - } - } - } - else - InitEmptyActionBar(); -} - -void CharmInfo::InitCharmCreateSpells() -{ - InitPetActionBar(); - - if (_unit->GetTypeId() == TYPEID_PLAYER) // charmed players don't have spells - { - //InitEmptyActionBar(); - return; - } - - //InitPetActionBar(); - - for (uint32 x = 0; x < MAX_SPELL_CHARM; ++x) - { - uint32 spellId = _unit->ToCreature()->m_spells[x]; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - - if (!spellInfo) - { - _charmspells[x].SetActionAndType(spellId, ACT_DISABLED); - continue; - } - - if (spellInfo->IsPassive()) - { - _unit->CastSpell(_unit, spellInfo, true); - _charmspells[x].SetActionAndType(spellId, ACT_PASSIVE); - } - else - { - _charmspells[x].SetActionAndType(spellId, ACT_DISABLED); - - ActiveStates newstate = ACT_PASSIVE; - - if (!spellInfo->IsAutocastable()) - newstate = ACT_PASSIVE; - else - { - if (spellInfo->NeedsExplicitUnitTarget()) - { - newstate = ACT_ENABLED; - ToggleCreatureAutocast(spellInfo, true); - } - else - newstate = ACT_DISABLED; - } - - AddSpellToActionBar(spellInfo, newstate); - } - } -} - -bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate) -{ - uint32 spell_id = spellInfo->Id; - uint32 first_id = spellInfo->GetFirstRankSpell()->Id; - - // new spell rank can be already listed - for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) - { - if (uint32 action = PetActionBar[i].GetAction()) - { - if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id) - { - PetActionBar[i].SetAction(spell_id); - return true; - } - } - } - - // or use empty slot in other case - for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) - { - if (!PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell()) - { - SetActionBar(i, spell_id, newstate == ACT_DECIDE ? spellInfo->IsAutocastable() ? ACT_DISABLED : ACT_PASSIVE : newstate); - - if (_unit->GetCharmer() && _unit->GetCharmer()->IsPlayer()) - { - if (Creature* creature = _unit->ToCreature()) - { - // Processing this packet needs to be delayed - _unit->m_Events.AddEventAtOffset([creature, spell_id]() - { - if (uint32 cooldown = creature->GetSpellCooldown(spell_id)) - { - WorldPacket data; - creature->BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, spell_id, cooldown); - if (creature->GetCharmer() && creature->GetCharmer()->IsPlayer()) - { - creature->GetCharmer()->ToPlayer()->SendDirectMessage(&data); - } - } - }, 500ms); - } - } - - return true; - } - } - return false; -} - -bool CharmInfo::RemoveSpellFromActionBar(uint32 spell_id) -{ - uint32 first_id = sSpellMgr->GetFirstSpellInChain(spell_id); - - for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) - { - if (uint32 action = PetActionBar[i].GetAction()) - { - if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id) - { - SetActionBar(i, 0, ACT_PASSIVE); - return true; - } - } - } - - return false; -} - -void CharmInfo::ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply) -{ - if (spellInfo->IsPassive()) - return; - - for (uint32 x = 0; x < MAX_SPELL_CHARM; ++x) - if (spellInfo->Id == _charmspells[x].GetAction()) - _charmspells[x].SetType(apply ? ACT_ENABLED : ACT_DISABLED); -} - -void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow) -{ - _petnumber = petnumber; - if (statwindow) - _unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, _petnumber); - else - _unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, 0); -} - -void CharmInfo::LoadPetActionBar(const std::string& data) -{ - std::vector tokens = Acore::Tokenize(data, ' ', false); - - if (tokens.size() != (ACTION_BAR_INDEX_END - ACTION_BAR_INDEX_START) * 2) - return; // non critical, will reset to default - - auto iter = tokens.begin(); - for (uint8 index = ACTION_BAR_INDEX_START; index < ACTION_BAR_INDEX_END; ++index) - { - Optional type = Acore::StringTo(*(iter++)); - Optional action = Acore::StringTo(*(iter++)); - - if (!type || !action) - { - continue; - } - - PetActionBar[index].SetActionAndType(*action, static_cast(*type)); - - // check correctness - if (PetActionBar[index].IsActionBarForSpell()) - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(PetActionBar[index].GetAction()); - if (!spellInfo) - { - SetActionBar(index, 0, ACT_PASSIVE); - } - else if (!spellInfo->IsAutocastable()) - { - SetActionBar(index, PetActionBar[index].GetAction(), ACT_PASSIVE); - } - } - } -} - -void CharmInfo::BuildActionBar(WorldPacket* data) -{ - for (uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) - *data << uint32(PetActionBar[i].packedData); -} - -void CharmInfo::SetSpellAutocast(SpellInfo const* spellInfo, bool state) -{ - for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) - { - if (spellInfo->Id == PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell()) - { - PetActionBar[i].SetType(state ? ACT_ENABLED : ACT_DISABLED); - break; - } - } -} - bool Unit::isFrozen() const { return HasAuraState(AURA_STATE_FROZEN); @@ -20565,98 +20267,6 @@ uint32 Unit::GetResistance(SpellSchoolMask mask) const return uint32(resist); } -void CharmInfo::SetIsCommandAttack(bool val) -{ - _isCommandAttack = val; -} - -bool CharmInfo::IsCommandAttack() -{ - return _isCommandAttack; -} - -void CharmInfo::SetIsCommandFollow(bool val) -{ - _isCommandFollow = val; -} - -bool CharmInfo::IsCommandFollow() -{ - return _isCommandFollow; -} - -void CharmInfo::SaveStayPosition(bool atCurrentPos) -{ - //! At this point a new spline destination is enabled because of Unit::StopMoving() - G3D::Vector3 stayPos = G3D::Vector3(); - - if (atCurrentPos) - { - float z = INVALID_HEIGHT; - _unit->UpdateAllowedPositionZ(_unit->GetPositionX(), _unit->GetPositionY(), z); - stayPos = G3D::Vector3(_unit->GetPositionX(), _unit->GetPositionY(), z != INVALID_HEIGHT ? z : _unit->GetPositionZ()); - } - else - stayPos = _unit->movespline->FinalDestination(); - - if (_unit->movespline->onTransport) - if (TransportBase* transport = _unit->GetDirectTransport()) - transport->CalculatePassengerPosition(stayPos.x, stayPos.y, stayPos.z); - - _stayX = stayPos.x; - _stayY = stayPos.y; - _stayZ = stayPos.z; -} - -void CharmInfo::GetStayPosition(float& x, float& y, float& z) -{ - x = _stayX; - y = _stayY; - z = _stayZ; -} - -void CharmInfo::RemoveStayPosition() -{ - _stayX = 0.0f; - _stayY = 0.0f; - _stayZ = 0.0f; -} - -bool CharmInfo::HasStayPosition() -{ - return _stayX && _stayY && _stayZ; -} - -void CharmInfo::SetIsAtStay(bool val) -{ - _isAtStay = val; -} - -bool CharmInfo::IsAtStay() -{ - return _isAtStay; -} - -void CharmInfo::SetIsFollowing(bool val) -{ - _isFollowing = val; -} - -bool CharmInfo::IsFollowing() -{ - return _isFollowing; -} - -void CharmInfo::SetIsReturning(bool val) -{ - _isReturning = val; -} - -bool CharmInfo::IsReturning() -{ - return _isReturning; -} - void Unit::PetSpellFail(SpellInfo const* spellInfo, Unit* target, uint32 result) { CharmInfo* charmInfo = GetCharmInfo(); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index cff069123..e8c2fc5ef 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -29,6 +29,8 @@ #include "SpellAuraDefines.h" #include "SpellDefines.h" #include "ThreatMgr.h" +#include "UnitDefines.h" +#include "UnitUtils.h" #include #include @@ -38,127 +40,43 @@ #define BASE_MAXDAMAGE 2.0f #define BASE_ATTACK_TIME 2000 -enum UnitBytes1Offsets : uint8 -{ - UNIT_BYTES_1_OFFSET_STAND_STATE = 0, - UNIT_BYTES_1_OFFSET_PET_TALENTS = 1, - UNIT_BYTES_1_OFFSET_VIS_FLAG = 2, - UNIT_BYTES_1_OFFSET_ANIM_TIER = 3 -}; - -// byte value (UNIT_FIELD_BYTES_1, 0) -enum UnitStandStateType -{ - UNIT_STAND_STATE_STAND = 0, - UNIT_STAND_STATE_SIT = 1, - UNIT_STAND_STATE_SIT_CHAIR = 2, - UNIT_STAND_STATE_SLEEP = 3, - UNIT_STAND_STATE_SIT_LOW_CHAIR = 4, - UNIT_STAND_STATE_SIT_MEDIUM_CHAIR = 5, - UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6, - UNIT_STAND_STATE_DEAD = 7, - UNIT_STAND_STATE_KNEEL = 8, - UNIT_STAND_STATE_SUBMERGED = 9 -}; - -// byte flag value (UNIT_FIELD_BYTES_1, 2) -enum UnitStandFlags -{ - UNIT_STAND_FLAGS_UNK1 = 0x01, - UNIT_STAND_FLAGS_CREEP = 0x02, - UNIT_STAND_FLAGS_UNTRACKABLE = 0x04, - UNIT_STAND_FLAGS_UNK4 = 0x08, - UNIT_STAND_FLAGS_UNK5 = 0x10, - UNIT_STAND_FLAGS_ALL = 0xFF -}; - -// byte flags value (UNIT_FIELD_BYTES_1, 3) -enum UnitBytes1_Flags -{ - UNIT_BYTE1_FLAG_GROUND = 0x00, - UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01, - UNIT_BYTE1_FLAG_HOVER = 0x02, - UNIT_BYTE1_FLAG_FLY = 0x03, - UNIT_BYTE1_FLAG_SUBMERGED = 0x04, - UNIT_BYTE1_FLAG_ALL = 0xFF -}; - -// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2 -enum ShapeshiftForm -{ - FORM_NONE = 0x00, - FORM_CAT = 0x01, - FORM_TREE = 0x02, - FORM_TRAVEL = 0x03, - FORM_AQUA = 0x04, - FORM_BEAR = 0x05, - FORM_AMBIENT = 0x06, - FORM_GHOUL = 0x07, - FORM_DIREBEAR = 0x08, - FORM_STEVES_GHOUL = 0x09, - FORM_THARONJA_SKELETON = 0x0A, - FORM_TEST_OF_STRENGTH = 0x0B, - FORM_BLB_PLAYER = 0x0C, - FORM_SHADOW_DANCE = 0x0D, - FORM_CREATUREBEAR = 0x0E, - FORM_CREATURECAT = 0x0F, - FORM_GHOSTWOLF = 0x10, - FORM_BATTLESTANCE = 0x11, - FORM_DEFENSIVESTANCE = 0x12, - FORM_BERSERKERSTANCE = 0x13, - FORM_TEST = 0x14, - FORM_ZOMBIE = 0x15, - FORM_METAMORPHOSIS = 0x16, - FORM_UNDEAD = 0x19, - FORM_MASTER_ANGLER = 0x1A, - FORM_FLIGHT_EPIC = 0x1B, - FORM_SHADOW = 0x1C, - FORM_FLIGHT = 0x1D, - FORM_STEALTH = 0x1E, - FORM_MOONKIN = 0x1F, - FORM_SPIRITOFREDEMPTION = 0x20 -}; - -// low byte (0 from 0..3) of UNIT_FIELD_BYTES_2 -enum SheathState -{ - SHEATH_STATE_UNARMED = 0, // non prepared weapon - SHEATH_STATE_MELEE = 1, // prepared melee weapon - SHEATH_STATE_RANGED = 2 // prepared ranged weapon -}; - -#define MAX_SHEATH_STATE 3 - -// byte (1 from 0..3) of UNIT_FIELD_BYTES_2 -enum UnitPVPStateFlags -{ - UNIT_BYTE2_FLAG_PVP = 0x01, - UNIT_BYTE2_FLAG_UNK1 = 0x02, - UNIT_BYTE2_FLAG_FFA_PVP = 0x04, - UNIT_BYTE2_FLAG_SANCTUARY = 0x08, - UNIT_BYTE2_FLAG_UNK4 = 0x10, - UNIT_BYTE2_FLAG_UNK5 = 0x20, - UNIT_BYTE2_FLAG_UNK6 = 0x40, - UNIT_BYTE2_FLAG_UNK7 = 0x80 -}; - -// byte (2 from 0..3) of UNIT_FIELD_BYTES_2 -enum UnitRename -{ - UNIT_CAN_BE_RENAMED = 0x01, - UNIT_CAN_BE_ABANDONED = 0x02, -}; +#define MAX_AGGRO_RADIUS 45.0f // yards static constexpr uint32 MAX_CREATURE_SPELLS = 8; static constexpr uint32 infinityCooldownDelay = 0x9A7EC800; // used for set "infinity cooldowns" for spells and check, MONTH*IN_MILLISECONDS static constexpr uint32 infinityCooldownDelayCheck = 0x4D3F6400; // MONTH*IN_MILLISECONDS/2; -#define MAX_SPELL_CHARM 4 -#define MAX_SPELL_VEHICLE 6 -#define MAX_SPELL_POSSESS 8 -#define MAX_SPELL_CONTROL_BAR 10 +struct CharmInfo; +struct FactionTemplateEntry; +struct SpellValue; -#define MAX_AGGRO_RADIUS 45.0f // yards +class AuraApplication; +class Aura; +class UnitAura; +class AuraEffect; +class Creature; +class Spell; +class SpellInfo; +class DynamicObject; +class GameObject; +class Item; +class Pet; +class PetAura; +class Minion; +class Guardian; +class UnitAI; +class Totem; +class Transport; +class StaticTransport; +class MotionTransport; +class Vehicle; +class TransportBase; +class SpellCastTargets; + +typedef std::list UnitList; +typedef std::list< std::pair > DispelChargesList; + +enum CharmType : uint8; enum VictimState { @@ -203,42 +121,6 @@ enum HitInfo HITINFO_FAKE_DAMAGE = 0x01000000 // enables damage animation even if no damage done, set only if no damage }; -//i would like to remove this: (it is defined in item.h -enum InventorySlot -{ - NULL_BAG = 0, - NULL_SLOT = 255 -}; - -struct FactionTemplateEntry; -struct SpellValue; - -class AuraApplication; -class Aura; -class UnitAura; -class AuraEffect; -class Creature; -class Spell; -class SpellInfo; -class DynamicObject; -class GameObject; -class Item; -class Pet; -class PetAura; -class Minion; -class Guardian; -class UnitAI; -class Totem; -class Transport; -class StaticTransport; -class MotionTransport; -class Vehicle; -class TransportBase; -class SpellCastTargets; - -typedef std::list UnitList; -typedef std::list< std::pair > DispelChargesList; - enum UnitModifierType { BASE_VALUE = 0, @@ -319,74 +201,6 @@ enum class DeathState : uint8 JustRespawned = 4, }; -enum UnitState -{ - UNIT_STATE_DIED = 0x00000001, // player has fake death aura - UNIT_STATE_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone - //UNIT_STATE_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone - UNIT_STATE_STUNNED = 0x00000008, - UNIT_STATE_ROAMING = 0x00000010, - UNIT_STATE_CHASE = 0x00000020, - //UNIT_STATE_SEARCHING = 0x00000040, - UNIT_STATE_FLEEING = 0x00000080, - UNIT_STATE_IN_FLIGHT = 0x00000100, // player is in flight mode - UNIT_STATE_FOLLOW = 0x00000200, - UNIT_STATE_ROOT = 0x00000400, - UNIT_STATE_CONFUSED = 0x00000800, - UNIT_STATE_DISTRACTED = 0x00001000, - UNIT_STATE_ISOLATED = 0x00002000, // area auras do not affect other players - UNIT_STATE_ATTACK_PLAYER = 0x00004000, - UNIT_STATE_CASTING = 0x00008000, - UNIT_STATE_POSSESSED = 0x00010000, - UNIT_STATE_CHARGING = 0x00020000, - UNIT_STATE_JUMPING = 0x00040000, - UNIT_STATE_MOVE = 0x00100000, - UNIT_STATE_ROTATING = 0x00200000, - UNIT_STATE_EVADE = 0x00400000, - UNIT_STATE_ROAMING_MOVE = 0x00800000, - UNIT_STATE_CONFUSED_MOVE = 0x01000000, - UNIT_STATE_FLEEING_MOVE = 0x02000000, - UNIT_STATE_CHASE_MOVE = 0x04000000, - UNIT_STATE_FOLLOW_MOVE = 0x08000000, - UNIT_STATE_IGNORE_PATHFINDING = 0x10000000, // do not use pathfinding in any MovementGenerator - UNIT_STATE_NO_ENVIRONMENT_UPD = 0x20000000, // pussywizard - - UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE - | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED - | UNIT_STATE_DISTRACTED | UNIT_STATE_ISOLATED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING - | UNIT_STATE_POSSESSED | UNIT_STATE_CHARGING | UNIT_STATE_JUMPING | UNIT_STATE_MOVE | UNIT_STATE_ROTATING - | UNIT_STATE_EVADE | UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE - | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE | UNIT_STATE_IGNORE_PATHFINDING | UNIT_STATE_NO_ENVIRONMENT_UPD, - - UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT, - // for real move using movegen check and stop (except unstoppable flight) - UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE, - UNIT_STATE_CONTROLLED = (UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING), - UNIT_STATE_LOST_CONTROL = (UNIT_STATE_CONTROLLED | UNIT_STATE_JUMPING | UNIT_STATE_CHARGING), - UNIT_STATE_SIGHTLESS = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_EVADE), - UNIT_STATE_CANNOT_AUTOATTACK = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_CASTING), - UNIT_STATE_CANNOT_TURN = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_ROTATING | UNIT_STATE_ROOT), - // stay by different reasons - UNIT_STATE_NOT_MOVE = UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DIED | UNIT_STATE_DISTRACTED, - UNIT_STATE_IGNORE_ANTISPEEDHACK = UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED | UNIT_STATE_CHARGING | UNIT_STATE_DISTRACTED | UNIT_STATE_POSSESSED, - UNIT_STATE_ALL_STATE = 0xffffffff //(UNIT_STATE_STOPPED | UNIT_STATE_MOVING | UNIT_STATE_IN_COMBAT | UNIT_STATE_IN_FLIGHT) -}; - -enum UnitMoveType -{ - MOVE_WALK = 0, - MOVE_RUN = 1, - MOVE_RUN_BACK = 2, - MOVE_SWIM = 3, - MOVE_SWIM_BACK = 4, - MOVE_TURN_RATE = 5, - MOVE_FLIGHT = 6, - MOVE_FLIGHT_BACK = 7, - MOVE_PITCH_RATE = 8 -}; - -#define MAX_MOVE_TYPE 9 - extern float baseMoveSpeed[MAX_MOVE_TYPE]; extern float playerBaseMoveSpeed[MAX_MOVE_TYPE]; @@ -439,273 +253,6 @@ enum DamageEffectType : uint8 SELF_DAMAGE = 5 }; -// Used for IsClass hook -enum ClassContext : uint8 -{ - CLASS_CONTEXT_NONE = 0, // Default - CLASS_CONTEXT_INIT = 1, - CLASS_CONTEXT_TELEPORT = 2, - CLASS_CONTEXT_QUEST = 3, - CLASS_CONTEXT_STATS = 4, - CLASS_CONTEXT_TAXI = 5, - CLASS_CONTEXT_SKILL = 6, - CLASS_CONTEXT_TALENT_POINT_CALC = 7, - CLASS_CONTEXT_ABILITY = 8, - CLASS_CONTEXT_ABILITY_REACTIVE = 9, - CLASS_CONTEXT_PET = 10, - CLASS_CONTEXT_PET_CHARM = 11, - CLASS_CONTEXT_EQUIP_RELIC = 12, - CLASS_CONTEXT_EQUIP_SHIELDS = 13, - CLASS_CONTEXT_EQUIP_ARMOR_CLASS = 14, - CLASS_CONTEXT_WEAPON_SWAP = 15, - CLASS_CONTEXT_GRAVEYARD = 16, - CLASS_CONTEXT_CLASS_TRAINER = 17 -}; - -// Value masks for UNIT_FIELD_FLAGS -// EnumUtils: DESCRIBE THIS -enum UnitFlags : uint32 -{ - UNIT_FLAG_NONE = 0x00000000, - UNIT_FLAG_SERVER_CONTROLLED = 0x00000001, // set only when unit movement is controlled by server - by SPLINE/MONSTER_MOVE packets, together with UNIT_FLAG_STUNNED; only set to units controlled by client; client function CGUnit_C::IsClientControlled returns false when set for owner - UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable - UNIT_FLAG_DISABLE_MOVE = 0x00000004, - UNIT_FLAG_PLAYER_CONTROLLED = 0x00000008, // controlled by player, use _IMMUNE_TO_PC instead of _IMMUNE_TO_NPC - UNIT_FLAG_RENAME = 0x00000010, - UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR5_NO_REAGENT_COST_WITH_AURA - UNIT_FLAG_UNK_6 = 0x00000040, - UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PLAYER_CONTROLLED | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE - UNIT_FLAG_IMMUNE_TO_PC = 0x00000100, // disables combat/assistance with PlayerCharacters (PC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget - UNIT_FLAG_IMMUNE_TO_NPC = 0x00000200, // disables combat/assistance with NonPlayerCharacters (NPC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget - UNIT_FLAG_LOOTING = 0x00000400, // loot animation - UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8 - UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3 - UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1 - UNIT_FLAG_CANNOT_SWIM = 0x00004000, // 2.0.8 - UNIT_FLAG_SWIMMING = 0x00008000, // shows swim animation in water - UNIT_FLAG_NON_ATTACKABLE_2 = 0x00010000, // removes attackable icon, if on yourself, cannot assist self but can cast TARGET_SELF spells - added by SPELL_AURA_MOD_UNATTACKABLE - UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok - UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok - UNIT_FLAG_IN_COMBAT = 0x00080000, - UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag - UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. - UNIT_FLAG_CONFUSED = 0x00400000, - UNIT_FLAG_FLEEING = 0x00800000, - UNIT_FLAG_POSSESSED = 0x01000000, // under direct client control by a player (possess or vehicle) - UNIT_FLAG_NOT_SELECTABLE = 0x02000000, - UNIT_FLAG_SKINNABLE = 0x04000000, - UNIT_FLAG_MOUNT = 0x08000000, - UNIT_FLAG_UNK_28 = 0x10000000, - UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT = 0x20000000, // Prevent automatically playing emotes from parsing chat text, for example "lol" in /say, ending message with ? or !, or using /yell - UNIT_FLAG_SHEATHE = 0x40000000, - UNIT_FLAG_IMMUNE = 0x80000000, // Immune to damage -}; - -DEFINE_ENUM_FLAG(UnitFlags); - -// Value masks for UNIT_FIELD_FLAGS_2 -enum UnitFlags2 : uint32 -{ - UNIT_FLAG2_NONE = 0x00000000, - UNIT_FLAG2_FEIGN_DEATH = 0x00000001, - UNIT_FLAG2_HIDE_BODY = 0x00000002, // Hide unit model (show only player equip) - UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004, - UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, - UNIT_FLAG2_MIRROR_IMAGE = 0x00000010, - UNIT_FLAG2_DO_NOT_FADE_IN = 0x00000020, // Unit model instantly appears when summoned (does not fade in) - UNIT_FLAG2_FORCE_MOVEMENT = 0x00000040, - UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, - UNIT_FLAG2_DISABLE_PRED_STATS = 0x00000100, // Player has disabled predicted stats (Used by raid frames) - UNIT_FLAG2_DISARM_RANGED = 0x00000400, // this does not disable ranged weapon display (maybe additional flag needed?) - UNIT_FLAG2_REGENERATE_POWER = 0x00000800, - UNIT_FLAG2_RESTRICT_PARTY_INTERACTION = 0x00001000, // Restrict interaction to party or raid - UNIT_FLAG2_PREVENT_SPELL_CLICK = 0x00002000, // Prevent spellclick - UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000, - UNIT_FLAG2_CANNOT_TURN = 0x00008000, - UNIT_FLAG2_UNK2 = 0x00010000, - UNIT_FLAG2_PLAY_DEATH_ANIM = 0x00020000, // Plays special death animation upon death - UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000, // Allows casting spells with AttributesEx7 & SPELL_ATTR7_DEBUG_SPELL - UNIT_FLAG2_UNUSED_6 = 0x01000000, -}; - -DEFINE_ENUM_FLAG(UnitFlags2); - -/// Non Player Character flags -// EnumUtils: DESCRIBE THIS -enum NPCFlags : uint32 -{ - UNIT_NPC_FLAG_NONE = 0x00000000, // SKIP - UNIT_NPC_FLAG_GOSSIP = 0x00000001, // TITLE has gossip menu DESCRIPTION 100% - UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // TITLE is quest giver DESCRIPTION guessed, probably ok - UNIT_NPC_FLAG_UNK1 = 0x00000004, - UNIT_NPC_FLAG_UNK2 = 0x00000008, - UNIT_NPC_FLAG_TRAINER = 0x00000010, // TITLE is trainer DESCRIPTION 100% - UNIT_NPC_FLAG_TRAINER_CLASS = 0x00000020, // TITLE is class trainer DESCRIPTION 100% - UNIT_NPC_FLAG_TRAINER_PROFESSION = 0x00000040, // TITLE is profession trainer DESCRIPTION 100% - UNIT_NPC_FLAG_VENDOR = 0x00000080, // TITLE is vendor (generic) DESCRIPTION 100% - UNIT_NPC_FLAG_VENDOR_AMMO = 0x00000100, // TITLE is vendor (ammo) DESCRIPTION 100%, general goods vendor - UNIT_NPC_FLAG_VENDOR_FOOD = 0x00000200, // TITLE is vendor (food) DESCRIPTION 100% - UNIT_NPC_FLAG_VENDOR_POISON = 0x00000400, // TITLE is vendor (poison) DESCRIPTION guessed - UNIT_NPC_FLAG_VENDOR_REAGENT = 0x00000800, // TITLE is vendor (reagents) DESCRIPTION 100% - UNIT_NPC_FLAG_REPAIR = 0x00001000, // TITLE can repair DESCRIPTION 100% - UNIT_NPC_FLAG_FLIGHTMASTER = 0x00002000, // TITLE is flight master DESCRIPTION 100% - UNIT_NPC_FLAG_SPIRITHEALER = 0x00004000, // TITLE is spirit healer DESCRIPTION guessed - UNIT_NPC_FLAG_SPIRITGUIDE = 0x00008000, // TITLE is spirit guide DESCRIPTION guessed - UNIT_NPC_FLAG_INNKEEPER = 0x00010000, // TITLE is innkeeper - UNIT_NPC_FLAG_BANKER = 0x00020000, // TITLE is banker DESCRIPTION 100% - UNIT_NPC_FLAG_PETITIONER = 0x00040000, // TITLE handles guild/arena petitions DESCRIPTION 100% 0xC0000 = guild petitions, 0x40000 = arena team petitions - UNIT_NPC_FLAG_TABARDDESIGNER = 0x00080000, // TITLE is guild tabard designer DESCRIPTION 100% - UNIT_NPC_FLAG_BATTLEMASTER = 0x00100000, // TITLE is battlemaster DESCRIPTION 100% - UNIT_NPC_FLAG_AUCTIONEER = 0x00200000, // TITLE is auctioneer DESCRIPTION 100% - UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // TITLE is stable master DESCRIPTION 100% - UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // TITLE is guild banker DESCRIPTION cause client to send 997 opcode - UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // TITLE has spell click enabled DESCRIPTION cause client to send 1015 opcode (spell click) - UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // TITLE is player vehicle DESCRIPTION players with mounts that have vehicle data should have it set - UNIT_NPC_FLAG_MAILBOX = 0x04000000, // TITLE is mailbox - - UNIT_NPC_FLAG_VENDOR_MASK = UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_VENDOR_AMMO | UNIT_NPC_FLAG_VENDOR_POISON | UNIT_NPC_FLAG_VENDOR_REAGENT -}; - -DEFINE_ENUM_FLAG(NPCFlags); - -enum MovementFlags -{ - MOVEMENTFLAG_NONE = 0x00000000, - MOVEMENTFLAG_FORWARD = 0x00000001, - MOVEMENTFLAG_BACKWARD = 0x00000002, - MOVEMENTFLAG_STRAFE_LEFT = 0x00000004, - MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008, - MOVEMENTFLAG_LEFT = 0x00000010, - MOVEMENTFLAG_RIGHT = 0x00000020, - MOVEMENTFLAG_PITCH_UP = 0x00000040, - MOVEMENTFLAG_PITCH_DOWN = 0x00000080, - MOVEMENTFLAG_WALKING = 0x00000100, // Walking - MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures - MOVEMENTFLAG_DISABLE_GRAVITY = 0x00000400, // Former MOVEMENTFLAG_LEVITATING. This is used when walking is not possible. - MOVEMENTFLAG_ROOT = 0x00000800, // Must not be set along with MOVEMENTFLAG_MASK_MOVING - MOVEMENTFLAG_FALLING = 0x00001000, // damage dealt on that type of falling - MOVEMENTFLAG_FALLING_FAR = 0x00002000, - MOVEMENTFLAG_PENDING_STOP = 0x00004000, - MOVEMENTFLAG_PENDING_STRAFE_STOP = 0x00008000, - MOVEMENTFLAG_PENDING_FORWARD = 0x00010000, - MOVEMENTFLAG_PENDING_BACKWARD = 0x00020000, - MOVEMENTFLAG_PENDING_STRAFE_LEFT = 0x00040000, - MOVEMENTFLAG_PENDING_STRAFE_RIGHT = 0x00080000, - MOVEMENTFLAG_PENDING_ROOT = 0x00100000, - MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also - MOVEMENTFLAG_ASCENDING = 0x00400000, // press "space" when flying - MOVEMENTFLAG_DESCENDING = 0x00800000, - MOVEMENTFLAG_CAN_FLY = 0x01000000, // Appears when unit can fly AND also walk - MOVEMENTFLAG_FLYING = 0x02000000, // unit is actually flying. pretty sure this is only used for players. creatures use disable_gravity - MOVEMENTFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths - MOVEMENTFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths - MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water - MOVEMENTFLAG_FALLING_SLOW = 0x20000000, // active rogue safe fall spell (passive) - MOVEMENTFLAG_HOVER = 0x40000000, // hover, cannot jump - - /// @todo: Check if PITCH_UP and PITCH_DOWN really belong here.. - MOVEMENTFLAG_MASK_MOVING = - MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT | - MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN | MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING | - MOVEMENTFLAG_SPLINE_ELEVATION, - - MOVEMENTFLAG_MASK_TURNING = - MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT, - - MOVEMENTFLAG_MASK_MOVING_FLY = - MOVEMENTFLAG_FLYING | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING, - - /// @todo if needed: add more flags to this masks that are exclusive to players - MOVEMENTFLAG_MASK_PLAYER_ONLY = - MOVEMENTFLAG_FLYING, - - /// Movement flags that have change status opcodes associated for players - MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE = MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT | - MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER -}; - -enum MovementFlags2 -{ - MOVEMENTFLAG2_NONE = 0x00000000, - MOVEMENTFLAG2_NO_STRAFE = 0x00000001, - MOVEMENTFLAG2_NO_JUMPING = 0x00000002, - MOVEMENTFLAG2_UNK3 = 0x00000004, // Overrides various clientside checks - MOVEMENTFLAG2_FULL_SPEED_TURNING = 0x00000008, - MOVEMENTFLAG2_FULL_SPEED_PITCHING = 0x00000010, - MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING = 0x00000020, - MOVEMENTFLAG2_UNK7 = 0x00000040, - MOVEMENTFLAG2_UNK8 = 0x00000080, - MOVEMENTFLAG2_UNK9 = 0x00000100, - MOVEMENTFLAG2_UNK10 = 0x00000200, - MOVEMENTFLAG2_INTERPOLATED_MOVEMENT = 0x00000400, - MOVEMENTFLAG2_INTERPOLATED_TURNING = 0x00000800, - MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00001000, - MOVEMENTFLAG2_UNK14 = 0x00002000, - MOVEMENTFLAG2_UNK15 = 0x00004000, - MOVEMENTFLAG2_UNK16 = 0x00008000, -}; - -enum SplineFlags -{ - SPLINEFLAG_NONE = 0x00000000, - SPLINEFLAG_FORWARD = 0x00000001, - SPLINEFLAG_BACKWARD = 0x00000002, - SPLINEFLAG_STRAFE_LEFT = 0x00000004, - SPLINEFLAG_STRAFE_RIGHT = 0x00000008, - SPLINEFLAG_TURN_LEFT = 0x00000010, - SPLINEFLAG_TURN_RIGHT = 0x00000020, - SPLINEFLAG_PITCH_UP = 0x00000040, - SPLINEFLAG_PITCH_DOWN = 0x00000080, - SPLINEFLAG_DONE = 0x00000100, - SPLINEFLAG_FALLING = 0x00000200, - SPLINEFLAG_NO_SPLINE = 0x00000400, - SPLINEFLAG_TRAJECTORY = 0x00000800, - SPLINEFLAG_WALK_MODE = 0x00001000, - SPLINEFLAG_FLYING = 0x00002000, - SPLINEFLAG_KNOCKBACK = 0x00004000, - SPLINEFLAG_FINAL_POINT = 0x00008000, - SPLINEFLAG_FINAL_TARGET = 0x00010000, - SPLINEFLAG_FINAL_FACING = 0x00020000, - SPLINEFLAG_CATMULL_ROM = 0x00040000, - SPLINEFLAG_CYCLIC = 0x00080000, - SPLINEFLAG_ENTER_CYCLE = 0x00100000, - SPLINEFLAG_ANIMATION_TIER = 0x00200000, - SPLINEFLAG_FROZEN = 0x00400000, - SPLINEFLAG_TRANSPORT = 0x00800000, - SPLINEFLAG_TRANSPORT_EXIT = 0x01000000, - SPLINEFLAG_UNKNOWN7 = 0x02000000, - SPLINEFLAG_UNKNOWN8 = 0x04000000, - SPLINEFLAG_ORIENTATION_INVERTED = 0x08000000, - SPLINEFLAG_USE_PATH_SMOOTHING = 0x10000000, - SPLINEFLAG_ANIMATION = 0x20000000, - SPLINEFLAG_UNCOMPRESSED_PATH = 0x40000000, - SPLINEFLAG_UNKNOWN10 = 0x80000000, -}; - -enum SplineType -{ - SPLINETYPE_NORMAL = 0, - SPLINETYPE_STOP = 1, - SPLINETYPE_FACING_SPOT = 2, - SPLINETYPE_FACING_TARGET = 3, - SPLINETYPE_FACING_ANGLE = 4, -}; - -enum UnitTypeMask -{ - UNIT_MASK_NONE = 0x00000000, - UNIT_MASK_SUMMON = 0x00000001, - UNIT_MASK_MINION = 0x00000002, - UNIT_MASK_GUARDIAN = 0x00000004, - UNIT_MASK_TOTEM = 0x00000008, - UNIT_MASK_PET = 0x00000010, - UNIT_MASK_VEHICLE = 0x00000020, - UNIT_MASK_PUPPET = 0x00000040, - UNIT_MASK_HUNTER_PET = 0x00000080, - UNIT_MASK_CONTROLABLE_GUARDIAN = 0x00000100, - UNIT_MASK_ACCESSORY = 0x00000200, -}; - namespace Movement { class MoveSpline; @@ -978,28 +525,6 @@ struct SpellPeriodicAuraLogInfo void createProcFlags(SpellInfo const* spellInfo, WeaponAttackType attackType, bool positive, uint32& procAttacker, uint32& procVictim); uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition); -struct RedirectThreatInfo -{ - RedirectThreatInfo() = default; - ObjectGuid _targetGUID; - uint32 _threatPct{0}; - - [[nodiscard]] ObjectGuid GetTargetGUID() const { return _targetGUID; } - [[nodiscard]] uint32 GetThreatPct() const { return _threatPct; } - - void Set(ObjectGuid guid, uint32 pct) - { - _targetGUID = guid; - _threatPct = pct; - } - - void ModifyThreatPct(int32 amount) - { - amount += _threatPct; - _threatPct = uint32(std::max(0, amount)); - } -}; - #define MAX_DECLINED_NAME_CASES 5 struct DeclinedName @@ -1018,40 +543,6 @@ enum CurrentSpellTypes #define CURRENT_FIRST_NON_MELEE_SPELL 1 #define CURRENT_MAX_SPELL 4 -struct GlobalCooldown -{ - explicit GlobalCooldown(uint32 _dur = 0, uint32 _time = 0) : duration(_dur), cast_time(_time) {} - - uint32 duration; - uint32 cast_time; -}; - -typedef std::unordered_map GlobalCooldownList; - -class GlobalCooldownMgr // Shared by Player and CharmInfo -{ -public: - GlobalCooldownMgr() = default; - -public: - bool HasGlobalCooldown(SpellInfo const* spellInfo) const; - void AddGlobalCooldown(SpellInfo const* spellInfo, uint32 gcd); - void CancelGlobalCooldown(SpellInfo const* spellInfo); - -private: - GlobalCooldownList m_GlobalCooldowns; -}; - -enum ActiveStates : uint8 -{ - ACT_PASSIVE = 0x01, // 0x01 - passive - ACT_DISABLED = 0x81, // 0x80 - castable - ACT_ENABLED = 0xC1, // 0x40 | 0x80 - auto cast + castable - ACT_COMMAND = 0x07, // 0x01 | 0x02 | 0x04 - ACT_REACTION = 0x06, // 0x02 | 0x04 - ACT_DECIDE = 0x00 // custom -}; - enum ReactStates : uint8 { REACT_PASSIVE = 0, @@ -1059,7 +550,7 @@ enum ReactStates : uint8 REACT_AGGRESSIVE = 2 }; -enum CommandStates +enum CommandStates : uint8 { COMMAND_STAY = 0, COMMAND_FOLLOW = 1, @@ -1067,147 +558,8 @@ enum CommandStates COMMAND_ABANDON = 3 }; -#define UNIT_ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF) -#define UNIT_ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24) -#define MAKE_UNIT_ACTION_BUTTON(A, T) (uint32(A) | (uint32(T) << 24)) - -struct UnitActionBarEntry -{ - UnitActionBarEntry() : packedData(uint32(ACT_DISABLED) << 24) {} - - uint32 packedData; - - // helper - [[nodiscard]] ActiveStates GetType() const { return ActiveStates(UNIT_ACTION_BUTTON_TYPE(packedData)); } - [[nodiscard]] uint32 GetAction() const { return UNIT_ACTION_BUTTON_ACTION(packedData); } - [[nodiscard]] bool IsActionBarForSpell() const - { - ActiveStates Type = GetType(); - return Type == ACT_DISABLED || Type == ACT_ENABLED || Type == ACT_PASSIVE; - } - - void SetActionAndType(uint32 action, ActiveStates type) - { - packedData = MAKE_UNIT_ACTION_BUTTON(action, type); - } - - void SetType(ActiveStates type) - { - packedData = MAKE_UNIT_ACTION_BUTTON(UNIT_ACTION_BUTTON_ACTION(packedData), type); - } - - void SetAction(uint32 action) - { - packedData = (packedData & 0xFF000000) | UNIT_ACTION_BUTTON_ACTION(action); - } -}; - typedef std::list SharedVisionList; -enum CharmType -{ - CHARM_TYPE_CHARM, - CHARM_TYPE_POSSESS, - CHARM_TYPE_VEHICLE, - CHARM_TYPE_CONVERT, -}; - -typedef UnitActionBarEntry CharmSpellInfo; - -enum ActionBarIndex -{ - ACTION_BAR_INDEX_START = 0, - ACTION_BAR_INDEX_PET_SPELL_START = 3, - ACTION_BAR_INDEX_PET_SPELL_END = 7, - ACTION_BAR_INDEX_END = 10, -}; - -#define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START) - -struct CharmInfo -{ -public: - explicit CharmInfo(Unit* unit); - ~CharmInfo(); - void RestoreState(); - [[nodiscard]] uint32 GetPetNumber() const { return _petnumber; } - void SetPetNumber(uint32 petnumber, bool statwindow); - - void SetCommandState(CommandStates st) { _CommandState = st; } - [[nodiscard]] CommandStates GetCommandState() const { return _CommandState; } - [[nodiscard]] bool HasCommandState(CommandStates state) const { return (_CommandState == state); } - - void InitPossessCreateSpells(); - void InitCharmCreateSpells(); - void InitPetActionBar(); - void InitEmptyActionBar(bool withAttack = true); - - //return true if successful - bool AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate = ACT_DECIDE); - bool RemoveSpellFromActionBar(uint32 spell_id); - void LoadPetActionBar(const std::string& data); - void BuildActionBar(WorldPacket* data); - void SetSpellAutocast(SpellInfo const* spellInfo, bool state); - void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type) - { - PetActionBar[index].SetActionAndType(spellOrAction, type); - } - [[nodiscard]] UnitActionBarEntry const* GetActionBarEntry(uint8 index) const { return &(PetActionBar[index]); } - - void ToggleCreatureAutocast(SpellInfo const* spellInfo, bool apply); - - CharmSpellInfo* GetCharmSpell(uint8 index) { return &(_charmspells[index]); } - - GlobalCooldownMgr& GetGlobalCooldownMgr() { return _GlobalCooldownMgr; } - - void SetIsCommandAttack(bool val); - bool IsCommandAttack(); - void SetIsCommandFollow(bool val); - bool IsCommandFollow(); - void SetIsAtStay(bool val); - bool IsAtStay(); - void SetIsFollowing(bool val); - bool IsFollowing(); - void SetIsReturning(bool val); - bool IsReturning(); - void SaveStayPosition(bool atCurrentPos); - void GetStayPosition(float& x, float& y, float& z); - void RemoveStayPosition(); - bool HasStayPosition(); - - void SetForcedSpell(uint32 id) { _forcedSpellId = id; } - int32 GetForcedSpell() { return _forcedSpellId; } - void SetForcedTargetGUID(ObjectGuid guid = ObjectGuid::Empty) { _forcedTargetGUID = guid; } - ObjectGuid GetForcedTarget() { return _forcedTargetGUID; } - - // Player react states - void SetPlayerReactState(ReactStates s) { _oldReactState = s; } - [[nodiscard]] ReactStates GetPlayerReactState() const { return _oldReactState; } - -private: - Unit* _unit; - UnitActionBarEntry PetActionBar[MAX_UNIT_ACTION_BAR_INDEX]; - CharmSpellInfo _charmspells[4]; - CommandStates _CommandState; - uint32 _petnumber; - - //for restoration after charmed - ReactStates _oldReactState; - - bool _isCommandAttack; - bool _isCommandFollow; - bool _isAtStay; - bool _isFollowing; - bool _isReturning; - int32 _forcedSpellId; - ObjectGuid _forcedTargetGUID; - float _stayX; - float _stayY; - float _stayZ; - - GlobalCooldownMgr _GlobalCooldownMgr; -}; - struct AttackPosition { AttackPosition(Position pos) : _pos(std::move(pos)), _taken(false) {} bool operator==(const int val) @@ -1274,108 +626,6 @@ typedef std::unordered_map PacketCooldowns; struct SpellProcEventEntry; // used only privately -// pussywizard: -class MMapTargetData -{ -public: - MMapTargetData() = default; - MMapTargetData(uint32 endTime, const Position* o, const Position* t) - { - _endTime = endTime; - _posOwner.Relocate(o); - _posTarget.Relocate(t); - } - MMapTargetData(const MMapTargetData& c) - { - _endTime = c._endTime; - _posOwner.Relocate(c._posOwner); - _posTarget.Relocate(c._posTarget); - } - MMapTargetData(MMapTargetData&&) = default; - MMapTargetData& operator=(const MMapTargetData&) = default; - MMapTargetData& operator=(MMapTargetData&&) = default; - [[nodiscard]] bool PosChanged(const Position& o, const Position& t) const - { - return _posOwner.GetExactDistSq(&o) > 0.5f * 0.5f || _posTarget.GetExactDistSq(&t) > 0.5f * 0.5f; - } - uint32 _endTime; - Position _posOwner; - Position _posTarget; -}; - -class SafeUnitPointer -{ -public: - explicit SafeUnitPointer(Unit* defVal) : ptr(defVal), defaultValue(defVal) {} - SafeUnitPointer(const SafeUnitPointer& /*p*/) { ABORT(); } - void Initialize(Unit* defVal) { defaultValue = defVal; ptr = defVal; } - ~SafeUnitPointer(); - void SetPointedTo(Unit* u); - void UnitDeleted(); - Unit* operator->() const { return ptr; } - void operator=(Unit* u) { SetPointedTo(u); } - operator Unit* () const { return ptr; } -private: - Unit* ptr; - Unit* defaultValue; -}; - -// BuildValuesCachePosPointers is marks of the position of some data inside of BuildValue cache. -struct BuildValuesCachePosPointers -{ - BuildValuesCachePosPointers() : - UnitNPCFlagsPos(-1), UnitFieldAuraStatePos(-1), UnitFieldFlagsPos(-1), UnitFieldDisplayPos(-1), - UnitDynamicFlagsPos(-1), UnitFieldBytes2Pos(-1), UnitFieldFactionTemplatePos(-1) {} - - void ApplyOffset(uint32 offset) - { - if (UnitNPCFlagsPos >= 0) - UnitNPCFlagsPos += offset; - - if (UnitFieldAuraStatePos >= 0) - UnitFieldAuraStatePos += offset; - - if (UnitFieldFlagsPos >= 0) - UnitFieldFlagsPos += offset; - - if (UnitFieldDisplayPos >= 0) - UnitFieldDisplayPos += offset; - - if (UnitDynamicFlagsPos >= 0) - UnitDynamicFlagsPos += offset; - - if (UnitFieldBytes2Pos >= 0) - UnitFieldBytes2Pos += offset; - - if (UnitFieldFactionTemplatePos >= 0) - UnitFieldFactionTemplatePos += offset; - - for (auto it = other.begin(); it != other.end(); ++it) - it->second += offset; - } - - int32 UnitNPCFlagsPos; - int32 UnitFieldAuraStatePos; - int32 UnitFieldFlagsPos; - int32 UnitFieldDisplayPos; - int32 UnitDynamicFlagsPos; - int32 UnitFieldBytes2Pos; - int32 UnitFieldFactionTemplatePos; - - std::unordered_map other; -}; - -// BuildValuesCachedBuffer cache for calculated BuildValue. -struct BuildValuesCachedBuffer -{ - BuildValuesCachedBuffer(uint32 bufferSize) : - buffer(bufferSize), posPointers() {} - - ByteBuffer buffer; - - BuildValuesCachePosPointers posPointers; -}; - class Unit : public WorldObject { public: @@ -1883,7 +1133,6 @@ public: virtual bool SetFeatherFall(bool enable, bool packetOnly = false); virtual bool SetHover(bool enable, bool packetOnly = false, bool updateAnimationTier = true); - // pussywizard: void SendMovementWaterWalking(Player* sendTo); void SendMovementFeatherFall(Player* sendTo); void SendMovementHover(Player* sendTo); @@ -2772,15 +2021,4 @@ protected: AuraEffect* _auraEffect; }; -class VehicleDespawnEvent : public BasicEvent -{ -public: - VehicleDespawnEvent(Unit& self, uint32 duration) : _self(self), _duration(duration) { } - bool Execute(uint64 e_time, uint32 p_time) override; - -protected: - Unit& _self; - uint32 _duration; -}; - #endif diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h new file mode 100644 index 000000000..b694bbcd9 --- /dev/null +++ b/src/server/game/Entities/Unit/UnitDefines.h @@ -0,0 +1,462 @@ +/* + * 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 . + */ + +#include "Define.h" +#include "EnumFlag.h" + +enum UnitBytes1Offsets : uint8 +{ + UNIT_BYTES_1_OFFSET_STAND_STATE = 0, + UNIT_BYTES_1_OFFSET_PET_TALENTS = 1, + UNIT_BYTES_1_OFFSET_VIS_FLAG = 2, + UNIT_BYTES_1_OFFSET_ANIM_TIER = 3 +}; + +// byte value (UNIT_FIELD_BYTES_1, 0) +enum UnitStandStateType +{ + UNIT_STAND_STATE_STAND = 0, + UNIT_STAND_STATE_SIT = 1, + UNIT_STAND_STATE_SIT_CHAIR = 2, + UNIT_STAND_STATE_SLEEP = 3, + UNIT_STAND_STATE_SIT_LOW_CHAIR = 4, + UNIT_STAND_STATE_SIT_MEDIUM_CHAIR = 5, + UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6, + UNIT_STAND_STATE_DEAD = 7, + UNIT_STAND_STATE_KNEEL = 8, + UNIT_STAND_STATE_SUBMERGED = 9 +}; + +// byte flag value (UNIT_FIELD_BYTES_1, 2) +enum UnitStandFlags +{ + UNIT_STAND_FLAGS_UNK1 = 0x01, + UNIT_STAND_FLAGS_CREEP = 0x02, + UNIT_STAND_FLAGS_UNTRACKABLE = 0x04, + UNIT_STAND_FLAGS_UNK4 = 0x08, + UNIT_STAND_FLAGS_UNK5 = 0x10, + UNIT_STAND_FLAGS_ALL = 0xFF +}; + +// byte flags value (UNIT_FIELD_BYTES_1, 3) +enum UnitBytes1_Flags +{ + UNIT_BYTE1_FLAG_GROUND = 0x00, + UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01, + UNIT_BYTE1_FLAG_HOVER = 0x02, + UNIT_BYTE1_FLAG_FLY = 0x03, + UNIT_BYTE1_FLAG_SUBMERGED = 0x04, + UNIT_BYTE1_FLAG_ALL = 0xFF +}; + +// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2 +enum ShapeshiftForm +{ + FORM_NONE = 0x00, + FORM_CAT = 0x01, + FORM_TREE = 0x02, + FORM_TRAVEL = 0x03, + FORM_AQUA = 0x04, + FORM_BEAR = 0x05, + FORM_AMBIENT = 0x06, + FORM_GHOUL = 0x07, + FORM_DIREBEAR = 0x08, + FORM_STEVES_GHOUL = 0x09, + FORM_THARONJA_SKELETON = 0x0A, + FORM_TEST_OF_STRENGTH = 0x0B, + FORM_BLB_PLAYER = 0x0C, + FORM_SHADOW_DANCE = 0x0D, + FORM_CREATUREBEAR = 0x0E, + FORM_CREATURECAT = 0x0F, + FORM_GHOSTWOLF = 0x10, + FORM_BATTLESTANCE = 0x11, + FORM_DEFENSIVESTANCE = 0x12, + FORM_BERSERKERSTANCE = 0x13, + FORM_TEST = 0x14, + FORM_ZOMBIE = 0x15, + FORM_METAMORPHOSIS = 0x16, + FORM_UNDEAD = 0x19, + FORM_MASTER_ANGLER = 0x1A, + FORM_FLIGHT_EPIC = 0x1B, + FORM_SHADOW = 0x1C, + FORM_FLIGHT = 0x1D, + FORM_STEALTH = 0x1E, + FORM_MOONKIN = 0x1F, + FORM_SPIRITOFREDEMPTION = 0x20 +}; + +// low byte (0 from 0..3) of UNIT_FIELD_BYTES_2 +enum SheathState +{ + SHEATH_STATE_UNARMED = 0, // non prepared weapon + SHEATH_STATE_MELEE = 1, // prepared melee weapon + SHEATH_STATE_RANGED = 2 // prepared ranged weapon +}; + +#define MAX_SHEATH_STATE 3 + +// byte (1 from 0..3) of UNIT_FIELD_BYTES_2 +enum UnitPVPStateFlags +{ + UNIT_BYTE2_FLAG_PVP = 0x01, + UNIT_BYTE2_FLAG_UNK1 = 0x02, + UNIT_BYTE2_FLAG_FFA_PVP = 0x04, + UNIT_BYTE2_FLAG_SANCTUARY = 0x08, + UNIT_BYTE2_FLAG_UNK4 = 0x10, + UNIT_BYTE2_FLAG_UNK5 = 0x20, + UNIT_BYTE2_FLAG_UNK6 = 0x40, + UNIT_BYTE2_FLAG_UNK7 = 0x80 +}; + +// byte (2 from 0..3) of UNIT_FIELD_BYTES_2 +enum UnitRename +{ + UNIT_CAN_BE_RENAMED = 0x01, + UNIT_CAN_BE_ABANDONED = 0x02 +}; + +enum UnitTypeMask +{ + UNIT_MASK_NONE = 0x00000000, + UNIT_MASK_SUMMON = 0x00000001, + UNIT_MASK_MINION = 0x00000002, + UNIT_MASK_GUARDIAN = 0x00000004, + UNIT_MASK_TOTEM = 0x00000008, + UNIT_MASK_PET = 0x00000010, + UNIT_MASK_VEHICLE = 0x00000020, + UNIT_MASK_PUPPET = 0x00000040, + UNIT_MASK_HUNTER_PET = 0x00000080, + UNIT_MASK_CONTROLABLE_GUARDIAN = 0x00000100, + UNIT_MASK_ACCESSORY = 0x00000200 +}; + +enum UnitState +{ + UNIT_STATE_DIED = 0x00000001, // player has fake death aura + UNIT_STATE_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone + //UNIT_STATE_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone + UNIT_STATE_STUNNED = 0x00000008, + UNIT_STATE_ROAMING = 0x00000010, + UNIT_STATE_CHASE = 0x00000020, + //UNIT_STATE_SEARCHING = 0x00000040, + UNIT_STATE_FLEEING = 0x00000080, + UNIT_STATE_IN_FLIGHT = 0x00000100, // player is in flight mode + UNIT_STATE_FOLLOW = 0x00000200, + UNIT_STATE_ROOT = 0x00000400, + UNIT_STATE_CONFUSED = 0x00000800, + UNIT_STATE_DISTRACTED = 0x00001000, + UNIT_STATE_ISOLATED = 0x00002000, // area auras do not affect other players + UNIT_STATE_ATTACK_PLAYER = 0x00004000, + UNIT_STATE_CASTING = 0x00008000, + UNIT_STATE_POSSESSED = 0x00010000, + UNIT_STATE_CHARGING = 0x00020000, + UNIT_STATE_JUMPING = 0x00040000, + UNIT_STATE_MOVE = 0x00100000, + UNIT_STATE_ROTATING = 0x00200000, + UNIT_STATE_EVADE = 0x00400000, + UNIT_STATE_ROAMING_MOVE = 0x00800000, + UNIT_STATE_CONFUSED_MOVE = 0x01000000, + UNIT_STATE_FLEEING_MOVE = 0x02000000, + UNIT_STATE_CHASE_MOVE = 0x04000000, + UNIT_STATE_FOLLOW_MOVE = 0x08000000, + UNIT_STATE_IGNORE_PATHFINDING = 0x10000000, // do not use pathfinding in any MovementGenerator + UNIT_STATE_NO_ENVIRONMENT_UPD = 0x20000000, + + UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE + | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED + | UNIT_STATE_DISTRACTED | UNIT_STATE_ISOLATED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING + | UNIT_STATE_POSSESSED | UNIT_STATE_CHARGING | UNIT_STATE_JUMPING | UNIT_STATE_MOVE | UNIT_STATE_ROTATING + | UNIT_STATE_EVADE | UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE + | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE | UNIT_STATE_IGNORE_PATHFINDING | UNIT_STATE_NO_ENVIRONMENT_UPD, + + UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT, + + // for real move using movegen check and stop (except unstoppable flight) + UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE, + UNIT_STATE_CONTROLLED = (UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING), + UNIT_STATE_LOST_CONTROL = (UNIT_STATE_CONTROLLED | UNIT_STATE_JUMPING | UNIT_STATE_CHARGING), + UNIT_STATE_SIGHTLESS = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_EVADE), + UNIT_STATE_CANNOT_AUTOATTACK = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_CASTING), + UNIT_STATE_CANNOT_TURN = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_ROTATING | UNIT_STATE_ROOT), + + // stay by different reasons + UNIT_STATE_NOT_MOVE = UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DIED | UNIT_STATE_DISTRACTED, + UNIT_STATE_IGNORE_ANTISPEEDHACK = UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED | UNIT_STATE_CHARGING | UNIT_STATE_DISTRACTED | UNIT_STATE_POSSESSED, + UNIT_STATE_ALL_STATE = 0xffffffff //(UNIT_STATE_STOPPED | UNIT_STATE_MOVING | UNIT_STATE_IN_COMBAT | UNIT_STATE_IN_FLIGHT) +}; + +// Used for IsClass hook +enum ClassContext : uint8 +{ + CLASS_CONTEXT_NONE = 0, // Default + CLASS_CONTEXT_INIT = 1, + CLASS_CONTEXT_TELEPORT = 2, + CLASS_CONTEXT_QUEST = 3, + CLASS_CONTEXT_STATS = 4, + CLASS_CONTEXT_TAXI = 5, + CLASS_CONTEXT_SKILL = 6, + CLASS_CONTEXT_TALENT_POINT_CALC = 7, + CLASS_CONTEXT_ABILITY = 8, + CLASS_CONTEXT_ABILITY_REACTIVE = 9, + CLASS_CONTEXT_PET = 10, + CLASS_CONTEXT_PET_CHARM = 11, + CLASS_CONTEXT_EQUIP_RELIC = 12, + CLASS_CONTEXT_EQUIP_SHIELDS = 13, + CLASS_CONTEXT_EQUIP_ARMOR_CLASS = 14, + CLASS_CONTEXT_WEAPON_SWAP = 15, + CLASS_CONTEXT_GRAVEYARD = 16, + CLASS_CONTEXT_CLASS_TRAINER = 17 +}; + +// Value masks for UNIT_FIELD_FLAGS +enum UnitFlags : uint32 +{ + UNIT_FLAG_NONE = 0x00000000, + UNIT_FLAG_SERVER_CONTROLLED = 0x00000001, // set only when unit movement is controlled by server - by SPLINE/MONSTER_MOVE packets, together with UNIT_FLAG_STUNNED; only set to units controlled by client; client function CGUnit_C::IsClientControlled returns false when set for owner + UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable + UNIT_FLAG_DISABLE_MOVE = 0x00000004, + UNIT_FLAG_PLAYER_CONTROLLED = 0x00000008, // controlled by player, use _IMMUNE_TO_PC instead of _IMMUNE_TO_NPC + UNIT_FLAG_RENAME = 0x00000010, + UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR5_NO_REAGENT_COST_WITH_AURA + UNIT_FLAG_UNK_6 = 0x00000040, + UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PLAYER_CONTROLLED | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE + UNIT_FLAG_IMMUNE_TO_PC = 0x00000100, // disables combat/assistance with PlayerCharacters (PC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget + UNIT_FLAG_IMMUNE_TO_NPC = 0x00000200, // disables combat/assistance with NonPlayerCharacters (NPC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget + UNIT_FLAG_LOOTING = 0x00000400, // loot animation + UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8 + UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3 + UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1 + UNIT_FLAG_CANNOT_SWIM = 0x00004000, // 2.0.8 + UNIT_FLAG_SWIMMING = 0x00008000, // shows swim animation in water + UNIT_FLAG_NON_ATTACKABLE_2 = 0x00010000, // removes attackable icon, if on yourself, cannot assist self but can cast TARGET_SELF spells - added by SPELL_AURA_MOD_UNATTACKABLE + UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok + UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok + UNIT_FLAG_IN_COMBAT = 0x00080000, + UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag + UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. + UNIT_FLAG_CONFUSED = 0x00400000, + UNIT_FLAG_FLEEING = 0x00800000, + UNIT_FLAG_POSSESSED = 0x01000000, // under direct client control by a player (possess or vehicle) + UNIT_FLAG_NOT_SELECTABLE = 0x02000000, + UNIT_FLAG_SKINNABLE = 0x04000000, + UNIT_FLAG_MOUNT = 0x08000000, + UNIT_FLAG_UNK_28 = 0x10000000, + UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT = 0x20000000, // Prevent automatically playing emotes from parsing chat text, for example "lol" in /say, ending message with ? or !, or using /yell + UNIT_FLAG_SHEATHE = 0x40000000, + UNIT_FLAG_IMMUNE = 0x80000000 // Immune to damage +}; +DEFINE_ENUM_FLAG(UnitFlags); + +// Value masks for UNIT_FIELD_FLAGS_2 +enum UnitFlags2 : uint32 +{ + UNIT_FLAG2_NONE = 0x00000000, + UNIT_FLAG2_FEIGN_DEATH = 0x00000001, + UNIT_FLAG2_HIDE_BODY = 0x00000002, // Hide unit model (show only player equip) + UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004, + UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, + UNIT_FLAG2_MIRROR_IMAGE = 0x00000010, + UNIT_FLAG2_DO_NOT_FADE_IN = 0x00000020, // Unit model instantly appears when summoned (does not fade in) + UNIT_FLAG2_FORCE_MOVEMENT = 0x00000040, + UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, + UNIT_FLAG2_DISABLE_PRED_STATS = 0x00000100, // Player has disabled predicted stats (Used by raid frames) + UNIT_FLAG2_DISARM_RANGED = 0x00000400, // this does not disable ranged weapon display (maybe additional flag needed?) + UNIT_FLAG2_REGENERATE_POWER = 0x00000800, + UNIT_FLAG2_RESTRICT_PARTY_INTERACTION = 0x00001000, // Restrict interaction to party or raid + UNIT_FLAG2_PREVENT_SPELL_CLICK = 0x00002000, // Prevent spellclick + UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000, + UNIT_FLAG2_CANNOT_TURN = 0x00008000, + UNIT_FLAG2_UNK2 = 0x00010000, + UNIT_FLAG2_PLAY_DEATH_ANIM = 0x00020000, // Plays special death animation upon death + UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000, // Allows casting spells with AttributesEx7 & SPELL_ATTR7_DEBUG_SPELL + UNIT_FLAG2_UNUSED_6 = 0x01000000 +}; +DEFINE_ENUM_FLAG(UnitFlags2); + +/// Non Player Character flags +enum NPCFlags : uint32 +{ + UNIT_NPC_FLAG_NONE = 0x00000000, // SKIP + UNIT_NPC_FLAG_GOSSIP = 0x00000001, // TITLE has gossip menu DESCRIPTION 100% + UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // TITLE is quest giver DESCRIPTION guessed, probably ok + UNIT_NPC_FLAG_UNK1 = 0x00000004, + UNIT_NPC_FLAG_UNK2 = 0x00000008, + UNIT_NPC_FLAG_TRAINER = 0x00000010, // TITLE is trainer DESCRIPTION 100% + UNIT_NPC_FLAG_TRAINER_CLASS = 0x00000020, // TITLE is class trainer DESCRIPTION 100% + UNIT_NPC_FLAG_TRAINER_PROFESSION = 0x00000040, // TITLE is profession trainer DESCRIPTION 100% + UNIT_NPC_FLAG_VENDOR = 0x00000080, // TITLE is vendor (generic) DESCRIPTION 100% + UNIT_NPC_FLAG_VENDOR_AMMO = 0x00000100, // TITLE is vendor (ammo) DESCRIPTION 100%, general goods vendor + UNIT_NPC_FLAG_VENDOR_FOOD = 0x00000200, // TITLE is vendor (food) DESCRIPTION 100% + UNIT_NPC_FLAG_VENDOR_POISON = 0x00000400, // TITLE is vendor (poison) DESCRIPTION guessed + UNIT_NPC_FLAG_VENDOR_REAGENT = 0x00000800, // TITLE is vendor (reagents) DESCRIPTION 100% + UNIT_NPC_FLAG_REPAIR = 0x00001000, // TITLE can repair DESCRIPTION 100% + UNIT_NPC_FLAG_FLIGHTMASTER = 0x00002000, // TITLE is flight master DESCRIPTION 100% + UNIT_NPC_FLAG_SPIRITHEALER = 0x00004000, // TITLE is spirit healer DESCRIPTION guessed + UNIT_NPC_FLAG_SPIRITGUIDE = 0x00008000, // TITLE is spirit guide DESCRIPTION guessed + UNIT_NPC_FLAG_INNKEEPER = 0x00010000, // TITLE is innkeeper + UNIT_NPC_FLAG_BANKER = 0x00020000, // TITLE is banker DESCRIPTION 100% + UNIT_NPC_FLAG_PETITIONER = 0x00040000, // TITLE handles guild/arena petitions DESCRIPTION 100% 0xC0000 = guild petitions, 0x40000 = arena team petitions + UNIT_NPC_FLAG_TABARDDESIGNER = 0x00080000, // TITLE is guild tabard designer DESCRIPTION 100% + UNIT_NPC_FLAG_BATTLEMASTER = 0x00100000, // TITLE is battlemaster DESCRIPTION 100% + UNIT_NPC_FLAG_AUCTIONEER = 0x00200000, // TITLE is auctioneer DESCRIPTION 100% + UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // TITLE is stable master DESCRIPTION 100% + UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // TITLE is guild banker DESCRIPTION cause client to send 997 opcode + UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // TITLE has spell click enabled DESCRIPTION cause client to send 1015 opcode (spell click) + UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // TITLE is player vehicle DESCRIPTION players with mounts that have vehicle data should have it set + UNIT_NPC_FLAG_MAILBOX = 0x04000000, // TITLE is mailbox + + UNIT_NPC_FLAG_VENDOR_MASK = UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_VENDOR_AMMO | UNIT_NPC_FLAG_VENDOR_POISON | UNIT_NPC_FLAG_VENDOR_REAGENT +}; +DEFINE_ENUM_FLAG(NPCFlags); + +enum UnitMoveType +{ + MOVE_WALK = 0, + MOVE_RUN = 1, + MOVE_RUN_BACK = 2, + MOVE_SWIM = 3, + MOVE_SWIM_BACK = 4, + MOVE_TURN_RATE = 5, + MOVE_FLIGHT = 6, + MOVE_FLIGHT_BACK = 7, + MOVE_PITCH_RATE = 8 +}; + +#define MAX_MOVE_TYPE 9 + +enum MovementFlags +{ + MOVEMENTFLAG_NONE = 0x00000000, + MOVEMENTFLAG_FORWARD = 0x00000001, + MOVEMENTFLAG_BACKWARD = 0x00000002, + MOVEMENTFLAG_STRAFE_LEFT = 0x00000004, + MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008, + MOVEMENTFLAG_LEFT = 0x00000010, + MOVEMENTFLAG_RIGHT = 0x00000020, + MOVEMENTFLAG_PITCH_UP = 0x00000040, + MOVEMENTFLAG_PITCH_DOWN = 0x00000080, + MOVEMENTFLAG_WALKING = 0x00000100, // Walking + MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures + MOVEMENTFLAG_DISABLE_GRAVITY = 0x00000400, // Former MOVEMENTFLAG_LEVITATING. This is used when walking is not possible. + MOVEMENTFLAG_ROOT = 0x00000800, // Must not be set along with MOVEMENTFLAG_MASK_MOVING + MOVEMENTFLAG_FALLING = 0x00001000, // damage dealt on that type of falling + MOVEMENTFLAG_FALLING_FAR = 0x00002000, + MOVEMENTFLAG_PENDING_STOP = 0x00004000, + MOVEMENTFLAG_PENDING_STRAFE_STOP = 0x00008000, + MOVEMENTFLAG_PENDING_FORWARD = 0x00010000, + MOVEMENTFLAG_PENDING_BACKWARD = 0x00020000, + MOVEMENTFLAG_PENDING_STRAFE_LEFT = 0x00040000, + MOVEMENTFLAG_PENDING_STRAFE_RIGHT = 0x00080000, + MOVEMENTFLAG_PENDING_ROOT = 0x00100000, + MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also + MOVEMENTFLAG_ASCENDING = 0x00400000, // press "space" when flying + MOVEMENTFLAG_DESCENDING = 0x00800000, + MOVEMENTFLAG_CAN_FLY = 0x01000000, // Appears when unit can fly AND also walk + MOVEMENTFLAG_FLYING = 0x02000000, // unit is actually flying. pretty sure this is only used for players. creatures use disable_gravity + MOVEMENTFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths + MOVEMENTFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths + MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water + MOVEMENTFLAG_FALLING_SLOW = 0x20000000, // active rogue safe fall spell (passive) + MOVEMENTFLAG_HOVER = 0x40000000, // hover, cannot jump + + /// @todo: Check if PITCH_UP and PITCH_DOWN really belong here.. + MOVEMENTFLAG_MASK_MOVING = + MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT | + MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN | MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING | + MOVEMENTFLAG_SPLINE_ELEVATION, + + MOVEMENTFLAG_MASK_TURNING = + MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT, + + MOVEMENTFLAG_MASK_MOVING_FLY = + MOVEMENTFLAG_FLYING | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING, + + /// @todo if needed: add more flags to this masks that are exclusive to players + MOVEMENTFLAG_MASK_PLAYER_ONLY = + MOVEMENTFLAG_FLYING, + + /// Movement flags that have change status opcodes associated for players + MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE = MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT | + MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER +}; + +enum MovementFlags2 +{ + MOVEMENTFLAG2_NONE = 0x00000000, + MOVEMENTFLAG2_NO_STRAFE = 0x00000001, + MOVEMENTFLAG2_NO_JUMPING = 0x00000002, + MOVEMENTFLAG2_UNK3 = 0x00000004, // Overrides various clientside checks + MOVEMENTFLAG2_FULL_SPEED_TURNING = 0x00000008, + MOVEMENTFLAG2_FULL_SPEED_PITCHING = 0x00000010, + MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING = 0x00000020, + MOVEMENTFLAG2_UNK7 = 0x00000040, + MOVEMENTFLAG2_UNK8 = 0x00000080, + MOVEMENTFLAG2_UNK9 = 0x00000100, + MOVEMENTFLAG2_UNK10 = 0x00000200, + MOVEMENTFLAG2_INTERPOLATED_MOVEMENT = 0x00000400, + MOVEMENTFLAG2_INTERPOLATED_TURNING = 0x00000800, + MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00001000, + MOVEMENTFLAG2_UNK14 = 0x00002000, + MOVEMENTFLAG2_UNK15 = 0x00004000, + MOVEMENTFLAG2_UNK16 = 0x00008000 +}; + +enum SplineFlags +{ + SPLINEFLAG_NONE = 0x00000000, + SPLINEFLAG_FORWARD = 0x00000001, + SPLINEFLAG_BACKWARD = 0x00000002, + SPLINEFLAG_STRAFE_LEFT = 0x00000004, + SPLINEFLAG_STRAFE_RIGHT = 0x00000008, + SPLINEFLAG_TURN_LEFT = 0x00000010, + SPLINEFLAG_TURN_RIGHT = 0x00000020, + SPLINEFLAG_PITCH_UP = 0x00000040, + SPLINEFLAG_PITCH_DOWN = 0x00000080, + SPLINEFLAG_DONE = 0x00000100, + SPLINEFLAG_FALLING = 0x00000200, + SPLINEFLAG_NO_SPLINE = 0x00000400, + SPLINEFLAG_TRAJECTORY = 0x00000800, + SPLINEFLAG_WALK_MODE = 0x00001000, + SPLINEFLAG_FLYING = 0x00002000, + SPLINEFLAG_KNOCKBACK = 0x00004000, + SPLINEFLAG_FINAL_POINT = 0x00008000, + SPLINEFLAG_FINAL_TARGET = 0x00010000, + SPLINEFLAG_FINAL_FACING = 0x00020000, + SPLINEFLAG_CATMULL_ROM = 0x00040000, + SPLINEFLAG_CYCLIC = 0x00080000, + SPLINEFLAG_ENTER_CYCLE = 0x00100000, + SPLINEFLAG_ANIMATION_TIER = 0x00200000, + SPLINEFLAG_FROZEN = 0x00400000, + SPLINEFLAG_TRANSPORT = 0x00800000, + SPLINEFLAG_TRANSPORT_EXIT = 0x01000000, + SPLINEFLAG_UNKNOWN7 = 0x02000000, + SPLINEFLAG_UNKNOWN8 = 0x04000000, + SPLINEFLAG_ORIENTATION_INVERTED = 0x08000000, + SPLINEFLAG_USE_PATH_SMOOTHING = 0x10000000, + SPLINEFLAG_ANIMATION = 0x20000000, + SPLINEFLAG_UNCOMPRESSED_PATH = 0x40000000, + SPLINEFLAG_UNKNOWN10 = 0x80000000 +}; + +enum SplineType +{ + SPLINETYPE_NORMAL = 0, + SPLINETYPE_STOP = 1, + SPLINETYPE_FACING_SPOT = 2, + SPLINETYPE_FACING_TARGET = 3, + SPLINETYPE_FACING_ANGLE = 4 +}; diff --git a/src/server/game/Entities/Unit/UnitUtils.h b/src/server/game/Entities/Unit/UnitUtils.h new file mode 100644 index 000000000..42f0ba1a0 --- /dev/null +++ b/src/server/game/Entities/Unit/UnitUtils.h @@ -0,0 +1,117 @@ +/* + * 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 . + */ + +class MMapTargetData +{ +public: + MMapTargetData() = default; + MMapTargetData(uint32 endTime, const Position* o, const Position* t) + { + _endTime = endTime; + _posOwner.Relocate(o); + _posTarget.Relocate(t); + } + MMapTargetData(const MMapTargetData& c) + { + _endTime = c._endTime; + _posOwner.Relocate(c._posOwner); + _posTarget.Relocate(c._posTarget); + } + MMapTargetData(MMapTargetData&&) = default; + MMapTargetData& operator=(const MMapTargetData&) = default; + MMapTargetData& operator=(MMapTargetData&&) = default; + [[nodiscard]] bool PosChanged(const Position& o, const Position& t) const + { + return _posOwner.GetExactDistSq(&o) > 0.5f * 0.5f || _posTarget.GetExactDistSq(&t) > 0.5f * 0.5f; + } + uint32 _endTime; + Position _posOwner; + Position _posTarget; +}; + +class SafeUnitPointer +{ +public: + explicit SafeUnitPointer(Unit* defVal) : ptr(defVal), defaultValue(defVal) {} + SafeUnitPointer(const SafeUnitPointer& /*p*/) { ABORT(); } + void Initialize(Unit* defVal) { defaultValue = defVal; ptr = defVal; } + ~SafeUnitPointer(); + void SetPointedTo(Unit* u); + void UnitDeleted(); + Unit* operator->() const { return ptr; } + void operator=(Unit* u) { SetPointedTo(u); } + operator Unit* () const { return ptr; } +private: + Unit* ptr; + Unit* defaultValue; +}; + +// BuildValuesCachePosPointers is marks of the position of some data inside of BuildValue cache. +struct BuildValuesCachePosPointers +{ + BuildValuesCachePosPointers() : + UnitNPCFlagsPos(-1), UnitFieldAuraStatePos(-1), UnitFieldFlagsPos(-1), UnitFieldDisplayPos(-1), + UnitDynamicFlagsPos(-1), UnitFieldBytes2Pos(-1), UnitFieldFactionTemplatePos(-1) {} + + void ApplyOffset(uint32 offset) + { + if (UnitNPCFlagsPos >= 0) + UnitNPCFlagsPos += offset; + + if (UnitFieldAuraStatePos >= 0) + UnitFieldAuraStatePos += offset; + + if (UnitFieldFlagsPos >= 0) + UnitFieldFlagsPos += offset; + + if (UnitFieldDisplayPos >= 0) + UnitFieldDisplayPos += offset; + + if (UnitDynamicFlagsPos >= 0) + UnitDynamicFlagsPos += offset; + + if (UnitFieldBytes2Pos >= 0) + UnitFieldBytes2Pos += offset; + + if (UnitFieldFactionTemplatePos >= 0) + UnitFieldFactionTemplatePos += offset; + + for (auto it = other.begin(); it != other.end(); ++it) + it->second += offset; + } + + int32 UnitNPCFlagsPos; + int32 UnitFieldAuraStatePos; + int32 UnitFieldFlagsPos; + int32 UnitFieldDisplayPos; + int32 UnitDynamicFlagsPos; + int32 UnitFieldBytes2Pos; + int32 UnitFieldFactionTemplatePos; + + std::unordered_map other; +}; + +// BuildValuesCachedBuffer cache for calculated BuildValue. +struct BuildValuesCachedBuffer +{ + BuildValuesCachedBuffer(uint32 bufferSize) : + buffer(bufferSize), posPointers() {} + + ByteBuffer buffer; + + BuildValuesCachePosPointers posPointers; +}; diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 694efb9fd..b7bb2bf1d 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -96,4 +96,15 @@ private: Status _status; }; +class VehicleDespawnEvent : public BasicEvent +{ +public: + VehicleDespawnEvent(Unit& self, uint32 duration) : _self(self), _duration(duration) { } + bool Execute(uint64 e_time, uint32 p_time) override; + +protected: + Unit& _self; + uint32 _duration; +}; + #endif diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 2b07f99ba..aff933782 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6213,7 +6213,7 @@ void ObjectMgr::LoadQuestAreaTriggers() QuestGreeting const* ObjectMgr::GetQuestGreeting(TypeID type, uint32 id) const { - uint32 typeIndex; + uint8 typeIndex; if (type == TYPEID_UNIT) typeIndex = 0; else if (type == TYPEID_GAMEOBJECT) @@ -6221,15 +6221,19 @@ QuestGreeting const* ObjectMgr::GetQuestGreeting(TypeID type, uint32 id) const else return nullptr; - return Acore::Containers::MapGetValuePtr(_questGreetingStore[typeIndex], id); + std::pair pairKey = std::make_pair(id, typeIndex); + QuestGreetingContainer::const_iterator itr = _questGreetingStore.find(pairKey); + if (itr == _questGreetingStore.end()) + return nullptr; + + return &itr->second; } void ObjectMgr::LoadQuestGreetings() { uint32 oldMSTime = getMSTime(); - for (std::size_t i = 0; i < _questGreetingStore.size(); ++i) - _questGreetingStore[i].clear(); + _questGreetingStore.clear(); // For reload case // 0 1 2 3 4 QueryResult result = WorldDatabase.Query("SELECT ID, Type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting"); @@ -6239,8 +6243,6 @@ void ObjectMgr::LoadQuestGreetings() return; } - uint32 count = 0; - do { Field* fields = result->Fetch(); @@ -6249,35 +6251,35 @@ void ObjectMgr::LoadQuestGreetings() uint8 type = fields[1].Get(); switch (type) { - case 0: // Creature - if (!sObjectMgr->GetCreatureTemplate(id)) - { - LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry {} does not exist.", id); + case 0: // Creature + if (!sObjectMgr->GetCreatureTemplate(id)) + { + LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry {} does not exist.", id); + continue; + } + break; + case 1: // GameObject + if (!sObjectMgr->GetGameObjectTemplate(id)) + { + LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry {} does not exist.", id); + continue; + } + break; + default: + LOG_ERROR("sql.sql", "Table `quest_greeting` has unknown type {} for id {}, skipped.", type, id); continue; - } - break; - case 1: // GameObject - if (!sObjectMgr->GetGameObjectTemplate(id)) - { - LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry {} does not exist.", id); - continue; - } - break; - default: - continue; } - uint16 greetEmoteType = fields[2].Get(); - uint32 greetEmoteDelay = fields[3].Get(); - std::string greeting = fields[4].Get(); + std::pair pairKey = std::make_pair(id, type); + QuestGreeting& data = _questGreetingStore[pairKey]; - _questGreetingStore[type].emplace(std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(greetEmoteType, greetEmoteDelay, std::move(greeting))); - - ++count; + data.EmoteType = fields[2].Get(); + data.EmoteDelay = fields[3].Get(); + AddLocaleString(fields[4].Get(), LOCALE_enUS, data.Greeting); } while (result->NextRow()); - LOG_INFO("server.loading", ">> Loaded {} quest_greeting in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", ">> Loaded {} quest_greeting in {} ms", _questGreetingStore.size(), GetMSTimeDiffToNow(oldMSTime)); LOG_INFO("server.loading", " "); } @@ -6285,8 +6287,6 @@ void ObjectMgr::LoadQuestGreetingsLocales() { uint32 oldMSTime = getMSTime(); - _questGreetingLocaleStore.clear(); - // 0 1 2 3 QueryResult result = WorldDatabase.Query("SELECT ID, Type, Locale, Greeting FROM quest_greeting_locale"); if (!result) @@ -6295,6 +6295,7 @@ void ObjectMgr::LoadQuestGreetingsLocales() return; } + uint32 localeCount = 0; do { Field* fields = result->Fetch(); @@ -6321,17 +6322,25 @@ void ObjectMgr::LoadQuestGreetingsLocales() continue; } - std::string localeName = fields[2].Get(); + std::pair pairKey = std::make_pair(id, type); + QuestGreeting& data = _questGreetingStore[pairKey]; - LocaleConstant locale = GetLocaleByName(localeName); + QuestGreetingContainer::iterator qgc = _questGreetingStore.find(pairKey); + if (qgc == _questGreetingStore.end()) + { + LOG_ERROR("sql.sql", "QuestGreeting (Id: {} Type: {}) found in table `quest_greeting_locale` but does not exist in `quest_greeting`. Skipped!", id, type); + continue; + } + + LocaleConstant locale = GetLocaleByName(fields[2].Get()); if (locale == LOCALE_enUS) continue; - QuestGreetingLocale& data = _questGreetingLocaleStore[MAKE_PAIR32(type, id)]; AddLocaleString(fields[3].Get(), locale, data.Greeting); + localeCount++; } while (result->NextRow()); - LOG_INFO("server.loading", ">> Loaded {} quest greeting Locale Strings in {} ms", (uint32)_questGreetingLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", ">> Loaded {} quest greeting Locale Strings in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime)); LOG_INFO("server.loading", " "); } @@ -8544,6 +8553,98 @@ void ObjectMgr::LoadGameObjectForQuests() LOG_INFO("server.loading", " "); } +bool ObjectMgr::LoadModuleStrings() +{ + uint32 oldMSTime = getMSTime(); + + _moduleStringStore.clear(); // for reload case + QueryResult result = WorldDatabase.Query("SELECT module, id, string FROM module_string"); + if (!result) + { + LOG_WARN("server.loading", ">> Loaded 0 module strings. DB table `module_string` is empty."); + LOG_INFO("server.loading", " "); + return false; + } + + do + { + Field* fields = result->Fetch(); + + std::string module = fields[0].Get(); + uint32 id = fields[1].Get(); + + std::pair pairKey = std::make_pair(module, id); + ModuleString& data = _moduleStringStore[pairKey]; + + AddLocaleString(fields[2].Get(), LOCALE_enUS, data.Content); + } while (result->NextRow()); + + LOG_INFO("server.loading", ">> Loaded {} Module Strings in {} ms", _moduleStringStore.size(), GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", " "); + + return true; +} + +bool ObjectMgr::LoadModuleStringsLocale() +{ + uint32 oldMSTime = getMSTime(); + + QueryResult result = WorldDatabase.Query("SELECT module, id, locale, string FROM module_string_locale"); + if (!result) + { + LOG_WARN("server.loading", ">> Loaded 0 module strings locale. DB table `module_string_locale` is empty."); + LOG_INFO("server.loading", " "); + return false; + } + + uint32 localeCount = 0; + do + { + Field* fields = result->Fetch(); + + std::string module = fields[0].Get(); + uint32 id = fields[1].Get(); + + std::pair pairKey = std::make_pair(module, id); + ModuleString& data = _moduleStringStore[pairKey]; + + ModuleStringContainer::iterator ms = _moduleStringStore.find(pairKey); + if (ms == _moduleStringStore.end()) + { + LOG_ERROR("sql.sql", "ModuleString (Module: {} Id: {}) found in table `module_string_locale` but does not exist in `module_string`. Skipped!", module, id); + continue; + } + + LocaleConstant locale = GetLocaleByName(fields[2].Get()); + if (locale == LOCALE_enUS) + continue; + + AddLocaleString(fields[3].Get(), locale, data.Content); + localeCount++; + } while (result->NextRow()); + + LOG_INFO("server.loading", ">> Loaded {} Module Strings Locales in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", " "); + + return true; +} + +std::string const* ObjectMgr::GetModuleString(std::string module, uint32 id, LocaleConstant locale) const +{ + ModuleString const* ms = GetModuleString(module, id); + if (ms->Content.size()) + { + if (ms->Content.size() > size_t(locale) && !ms->Content[locale].empty()) + return &ms->Content[locale]; + + return &ms->Content[DEFAULT_LOCALE]; + } + + LOG_ERROR("sql.sql", "Module string module {} id {} not found in DB.", module, id); + + return (std::string*)"error"; +} + bool ObjectMgr::LoadAcoreStrings() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 16aa58f93..836f93f55 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -493,6 +493,11 @@ typedef std::unordered_map Content; +}; + struct AcoreString { std::vector Content; @@ -511,6 +516,7 @@ typedef std::unordered_map QuestOfferRewardLocal typedef std::unordered_map QuestRequestItemsLocaleContainer; typedef std::unordered_map NpcTextLocaleContainer; typedef std::unordered_map PageTextLocaleContainer; +typedef std::map, ModuleString> ModuleStringContainer; typedef std::unordered_map AcoreStringContainer; typedef std::unordered_map GossipMenuItemsLocaleContainer; typedef std::unordered_map PointOfInterestLocaleContainer; @@ -593,20 +599,9 @@ struct QuestGreeting { uint16 EmoteType; uint32 EmoteDelay; - std::string Text; - - QuestGreeting() : EmoteType(0), EmoteDelay(0) { } - QuestGreeting(uint16 emoteType, uint32 emoteDelay, std::string text) - : EmoteType(emoteType), EmoteDelay(emoteDelay), Text(std::move(text)) { } -}; - -struct QuestGreetingLocale -{ std::vector Greeting; }; -typedef std::unordered_map QuestGreetingLocaleContainer; - struct GossipMenuItems { uint32 MenuID; @@ -666,7 +661,7 @@ struct QuestPOI typedef std::vector QuestPOIVector; typedef std::unordered_map QuestPOIContainer; -typedef std::array, 2> QuestGreetingContainer; +typedef std::map, QuestGreeting> QuestGreetingContainer; typedef std::unordered_map CacheVendorItemContainer; typedef std::unordered_map CacheTrainerSpellContainer; @@ -1013,6 +1008,8 @@ public: void ValidateSpellScripts(); void InitializeSpellInfoPrecomputedData(); + bool LoadModuleStrings(); + bool LoadModuleStringsLocale(); bool LoadAcoreStrings(); void LoadBroadcastTexts(); void LoadBroadcastTextLocales(); @@ -1268,26 +1265,6 @@ public: if (itr == _pointOfInterestLocaleStore.end()) return nullptr; return &itr->second; } - [[nodiscard]] QuestGreetingLocale const* GetQuestGreetingLocale(TypeID type, uint32 id) const - { - uint32 typeIndex; - if (type == TYPEID_UNIT) - { - typeIndex = 0; - } - else if (type == TYPEID_GAMEOBJECT) - { - typeIndex = 1; - } - else - { - return nullptr; - } - - QuestGreetingLocaleContainer::const_iterator itr = _questGreetingLocaleStore.find(MAKE_PAIR32(typeIndex, id)); - if (itr == _questGreetingLocaleStore.end()) return nullptr; - return &itr->second; - } [[nodiscard]] QuestOfferRewardLocale const* GetQuestOfferRewardLocale(uint32 entry) const { auto itr = _questOfferRewardLocaleStore.find(entry); @@ -1306,11 +1283,22 @@ public: if (itr == _npcTextLocaleStore.end()) return nullptr; return &itr->second; } - QuestGreeting const* GetQuestGreeting(TypeID type, uint32 id) const; + [[nodiscard]] QuestGreeting const* GetQuestGreeting(TypeID type, uint32 id) const; GameObjectData& NewGOData(ObjectGuid::LowType guid) { return _gameObjectDataStore[guid]; } void DeleteGOData(ObjectGuid::LowType guid); + [[nodiscard]] ModuleString const* GetModuleString(std::string module, uint32 id) const + { + std::pair pairKey = std::make_pair(module, id); + ModuleStringContainer::const_iterator itr = _moduleStringStore.find(pairKey); + if (itr == _moduleStringStore.end()) + return nullptr; + + return &itr->second; + } + [[nodiscard]] std::string const* GetModuleString(std::string module, uint32 id, LocaleConstant locale) const; + [[nodiscard]] AcoreString const* GetAcoreString(uint32 entry) const { AcoreStringContainer::const_iterator itr = _acoreStringStore.find(entry); @@ -1599,10 +1587,10 @@ private: QuestRequestItemsLocaleContainer _questRequestItemsLocaleStore; NpcTextLocaleContainer _npcTextLocaleStore; PageTextLocaleContainer _pageTextLocaleStore; + ModuleStringContainer _moduleStringStore; AcoreStringContainer _acoreStringStore; GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore; PointOfInterestLocaleContainer _pointOfInterestLocaleStore; - QuestGreetingLocaleContainer _questGreetingLocaleStore; CacheVendorItemContainer _cacheVendorItemStore; CacheTrainerSpellContainer _cacheTrainerSpellStore; diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 9c0b4d4a6..2f313c701 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -16,6 +16,7 @@ */ #include "Common.h" +#include "CharmInfo.h" #include "CreatureAI.h" #include "DisableMgr.h" #include "GameTime.h" diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index b69dd0ffb..371c6ad45 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -820,6 +820,11 @@ char const* WorldSession::GetAcoreString(uint32 entry) const return sObjectMgr->GetAcoreString(entry, GetSessionDbLocaleIndex()); } +std::string const* WorldSession::GetModuleString(std::string module, uint32 id) const +{ + return sObjectMgr->GetModuleString(module, id, GetSessionDbLocaleIndex()); +} + void WorldSession::Handle_NULL(WorldPacket& null) { LOG_ERROR("network.opcode", "Received unhandled opcode {} from {}", diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 7a968a0f8..aacc59b6b 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -517,6 +517,7 @@ public: LocaleConstant GetSessionDbcLocale() const { return /*_isBot? LOCALE_enUS : */m_sessionDbcLocale; } LocaleConstant GetSessionDbLocaleIndex() const { return /*_isBot? LOCALE_enUS : */m_sessionDbLocaleIndex; } char const* GetAcoreString(uint32 entry) const; + std::string const* GetModuleString(std::string module, uint32 id) const; uint32 GetLatency() const { return m_latency; } void SetLatency(uint32 latency) { m_latency = latency; } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 2bc4495ba..ac239941e 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -19,6 +19,7 @@ #include "BattlefieldMgr.h" #include "Battleground.h" #include "CellImpl.h" +#include "CharmInfo.h" #include "Common.h" #include "GameTime.h" #include "GridNotifiers.h" diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index c2f40e4d2..759d6db19 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -20,6 +20,7 @@ #include "BattlefieldMgr.h" #include "Battleground.h" #include "BattlegroundIC.h" +#include "CharmInfo.h" #include "CellImpl.h" #include "Common.h" #include "ConditionMgr.h" @@ -3738,6 +3739,10 @@ void Spell::cancel(bool bySelf) if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID)) unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL); + if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (m_spellInfo->HasAttribute(SPELL_ATTR0_COOLDOWN_ON_EVENT)) + m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true); + SendChannelUpdate(0); SendInterrupted(SPELL_FAILED_INTERRUPTED); } @@ -4104,6 +4109,9 @@ void Spell::handle_immediate() if (m_spellInfo->IsChanneled()) { int32 duration = m_spellInfo->GetDuration(); + if (HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS)) + duration = -1; + if (duration > 0) { // First mod_duration then haste - see Missile Barrage @@ -4370,8 +4378,12 @@ void Spell::SendSpellCooldown() return; } - // have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation) - if (m_spellInfo->IsCooldownStartedOnEvent() || m_spellInfo->IsPassive() || (HasTriggeredCastFlag(TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD) && !m_CastItem)) + // have infinity cooldown but set at aura apply + // do not set cooldown for triggered spells (needed by reincarnation) + if (m_spellInfo->IsCooldownStartedOnEvent() + || m_spellInfo->IsPassive() + || (HasTriggeredCastFlag(TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD) && !m_CastItem) + || HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS)) return; _player->AddSpellAndCategoryCooldowns(m_spellInfo, m_CastItem ? m_CastItem->GetEntry() : 0, this); @@ -5600,6 +5612,9 @@ void Spell::HandleThreatSpells() void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode) { + if (HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS)) + return; + effectHandleMode = mode; unitTarget = pUnitTarget; itemTarget = pItemTarget; @@ -6016,6 +6031,11 @@ SpellCastResult Spell::CheckCast(bool strict) return castResult; } + if (HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS)) + { + return SPELL_CAST_OK; + } + // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection) if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_CASTER_AURAS) || (m_spellInfo->PreventionType > SPELL_PREVENTION_TYPE_NONE && m_triggeredByAuraSpell && m_triggeredByAuraSpell.spellInfo->IsPositive())) { @@ -6453,7 +6473,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_BAD_TARGETS; Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetTarget()); - if (!target || m_caster->ToPlayer() == target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell + if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell return SPELL_FAILED_BAD_TARGETS; // Xinef: Implement summon pending error @@ -8056,6 +8076,9 @@ bool Spell::IsAutoActionResetSpell() const bool Spell::IsNeedSendToClient(bool go) const { + if (HasTriggeredCastFlag(TRIGGERED_IGNORE_EFFECTS)) + return false; + return m_spellInfo->SpellVisual[0] || m_spellInfo->SpellVisual[1] || m_spellInfo->IsChanneled() || m_spellInfo->Speed > 0.0f || (!m_triggeredByAuraSpell && !IsTriggered()) || (go && m_triggeredByAuraSpell && m_triggeredByAuraSpell.spellInfo->IsChanneled()); diff --git a/src/server/game/Spells/SpellDefines.h b/src/server/game/Spells/SpellDefines.h index f3e08fc34..08a76cba6 100644 --- a/src/server/game/Spells/SpellDefines.h +++ b/src/server/game/Spells/SpellDefines.h @@ -148,6 +148,7 @@ enum TriggerCastFlags TRIGGERED_FULL_MASK = 0x0007FFFF, //! Used when doing CastSpell with triggered == true TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements TRIGGERED_NO_PERIODIC_RESET = 0x00100000, //! Periodic aura tick wont be reset on override + TRIGGERED_IGNORE_EFFECTS = 0x00200000, //! Ignore spell effects - used for ritual portals TRIGGERED_FULL_DEBUG_MASK = 0xFFFFFFFF }; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 90724ec7d..9e1d22a08 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5380,9 +5380,6 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) } Map* cMap = m_caster->GetMap(); - // if gameobject is summoning object, it should be spawned right on caster's position - if (goinfo->type == GAMEOBJECT_TYPE_SUMMONING_RITUAL) - m_caster->GetPosition(fx, fy, fz); GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject(); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 42455c958..5c30b040d 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -500,6 +500,9 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const break; } + if ((sSpellMgr->GetSpellInfo(_spellInfo->Effects[_effIndex].TriggerSpell) && sSpellMgr->GetSpellInfo(_spellInfo->Effects[_effIndex].TriggerSpell)->HasAttribute(SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL)) && _spellInfo->HasAttribute(SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL)) + canEffectScale = false; + if (canEffectScale) { CreatureTemplate const* cInfo = caster->ToCreature()->GetCreatureTemplate(); diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index 3e5064c7f..cc2f04c5a 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -139,6 +139,7 @@ enum WorldBoolConfigs CONFIG_AUTOBROADCAST, CONFIG_ALLOW_TICKETS, CONFIG_DELETE_CHARACTER_TICKET_TRACE, + CONFIG_LFG_CAST_DESERTER, CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES, CONFIG_PRESERVE_CUSTOM_CHANNELS, CONFIG_PDUMP_NO_PATHS, diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index d81729d5f..c4e89ee68 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1363,7 +1363,9 @@ void World::LoadConfigSettings(bool reload) _int_configs[CONFIG_WARDEN_CLIENT_RESPONSE_DELAY] = sConfigMgr->GetOption("Warden.ClientResponseDelay", 600); // Dungeon finder - _int_configs[CONFIG_LFG_OPTIONSMASK] = sConfigMgr->GetOption("DungeonFinder.OptionsMask", 5); + _int_configs[CONFIG_LFG_OPTIONSMASK] = sConfigMgr->GetOption("DungeonFinder.OptionsMask", 5); + + _bool_configs[CONFIG_LFG_CAST_DESERTER] = sConfigMgr->GetOption("DungeonFinder.CastDeserter", true); // DBC_ItemAttributes _bool_configs[CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES] = sConfigMgr->GetOption("DBC.EnforceItemAttributes", true); @@ -1543,6 +1545,11 @@ void World::SetInitialWorldSettings() if (!sObjectMgr->LoadAcoreStrings()) exit(1); // Error message displayed in function already + LOG_INFO("server.loading", "Loading Module Strings..."); + sObjectMgr->LoadModuleStrings(); + LOG_INFO("server.loading", "Loading Module Strings Locale..."); + sObjectMgr->LoadModuleStringsLocale(); + ///- Update the realm entry in the database with the realm type from the config file //No SQL injection as values are treated as integers @@ -1789,7 +1796,7 @@ void World::SetInitialWorldSettings() LOG_INFO("server.loading", "Loading Quest Greetings..."); sObjectMgr->LoadQuestGreetings(); // must be loaded after creature_template, gameobject_template tables LOG_INFO("server.loading", "Loading Quest Greeting Locales..."); - sObjectMgr->LoadQuestGreetingsLocales(); // must be loaded after creature_template, gameobject_template tables + sObjectMgr->LoadQuestGreetingsLocales(); // must be loaded after creature_template, gameobject_template tables, quest_greeting LOG_INFO("server.loading", "Loading Quest Money Rewards..."); sObjectMgr->LoadQuestMoneyRewards(); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 81f3e2639..87737ac4e 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -139,7 +139,6 @@ public: { "points_of_interest", HandleReloadPointsOfInterestCommand, SEC_ADMINISTRATOR, Console::Yes }, { "prospecting_loot_template", HandleReloadLootTemplatesProspectingCommand, SEC_ADMINISTRATOR, Console::Yes }, { "quest_greeting", HandleReloadQuestGreetingCommand, SEC_ADMINISTRATOR, Console::Yes }, - { "quest_greeting_locale", HandleReloadLocalesQuestGreetingCommand, SEC_ADMINISTRATOR, Console::Yes }, { "quest_poi", HandleReloadQuestPOICommand, SEC_ADMINISTRATOR, Console::Yes }, { "quest_template", HandleReloadQuestTemplateCommand, SEC_ADMINISTRATOR, Console::Yes }, { "reference_loot_template", HandleReloadLootTemplatesReferenceCommand, SEC_ADMINISTRATOR, Console::Yes }, @@ -166,6 +165,7 @@ public: { "spell_threats", HandleReloadSpellThreatsCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_group_stack_rules", HandleReloadSpellGroupStackRulesCommand, SEC_ADMINISTRATOR, Console::Yes }, { "player_loot_template", HandleReloadLootTemplatesPlayerCommand, SEC_ADMINISTRATOR, Console::Yes }, + { "module_string", HandleReloadModuleStringCommand, SEC_ADMINISTRATOR, Console::Yes }, { "acore_string", HandleReloadAcoreStringCommand, SEC_ADMINISTRATOR, Console::Yes }, { "warden_action", HandleReloadWardenactionCommand, SEC_ADMINISTRATOR, Console::Yes }, { "waypoint_scripts", HandleReloadWpScriptsCommand, SEC_ADMINISTRATOR, Console::Yes }, @@ -269,7 +269,6 @@ public: HandleReloadQuestAreaTriggersCommand(handler); HandleReloadQuestPOICommand(handler); HandleReloadQuestTemplateCommand(handler); - HandleReloadLocalesQuestGreetingCommand(handler); LOG_INFO("server.loading", "Reloading Quests Relations..."); sObjectMgr->LoadQuestStartersAndEnders(); @@ -555,13 +554,8 @@ public: LOG_INFO("server.loading", "Reloading Quest Greeting ..."); sObjectMgr->LoadQuestGreetings(); handler->SendGlobalGMSysMessage("DB table `quest_greeting` reloaded."); - return true; - } - - static bool HandleReloadLocalesQuestGreetingCommand(ChatHandler* handler) - { LOG_INFO("server.loading", "Reloading Quest Greeting locales..."); - sObjectMgr->LoadQuestGreetingsLocales(); + sObjectMgr->LoadQuestGreetingsLocales(); // Must be after LoadQuestGreetings() handler->SendGlobalGMSysMessage("DB table `quest_greeting_locale` reloaded."); return true; } @@ -716,6 +710,17 @@ public: return true; } + static bool HandleReloadModuleStringCommand(ChatHandler* handler) + { + LOG_INFO("server.loading", "Reloading module_string Table!"); + sObjectMgr->LoadModuleStrings(); + handler->SendGlobalGMSysMessage("DB table `module_string` reloaded."); + LOG_INFO("server.loading", "Reloading module_string_locale Table!"); + sObjectMgr->LoadModuleStringsLocale(); + handler->SendGlobalGMSysMessage("DB table `module_string_locale` reloaded."); + return true; + } + static bool HandleReloadAcoreStringCommand(ChatHandler* handler) { LOG_INFO("server.loading", "Reloading acore_string Table!"); diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp index 93e559147..eeff38ecc 100644 --- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp @@ -659,13 +659,14 @@ class spell_illidari_council_judgement : public SpellScript void HandleScriptEffect(SpellEffIndex /*effIndex*/) { - Unit::AuraEffectList const& auras = GetCaster()->GetAuraEffectsByType(SPELL_AURA_DUMMY); - for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) + auto const& auras = GetCaster()->GetAuraEffectsByType(SPELL_AURA_DUMMY); + for (auto i = auras.begin(); i != auras.end(); ++i) { if ((*i)->GetSpellInfo()->GetSpellSpecific() == SPELL_SPECIFIC_SEAL && (*i)->GetEffIndex() == EFFECT_2) if (sSpellMgr->GetSpellInfo((*i)->GetAmount())) { GetCaster()->CastSpell(GetHitUnit(), (*i)->GetAmount(), true); + GetCaster()->RemoveAurasDueToSpell((*i)->GetSpellInfo()->Id); break; } } diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index 76db9de22..9067db635 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -468,6 +468,57 @@ public: } }; +/*#### +## go_l70_etc_music +####*/ +enum L70ETCMusic +{ + MUSIC_L70_ETC_MUSIC = 11803 +}; + +enum L70ETCMusicEvents +{ + EVENT_ETC_START_MUSIC = 1 +}; + +class go_l70_etc_music : public GameObjectScript +{ +public: + go_l70_etc_music() : GameObjectScript("go_l70_etc_music") { } + + struct go_l70_etc_musicAI : public GameObjectAI + { + go_l70_etc_musicAI(GameObject* go) : GameObjectAI(go) + { + _events.ScheduleEvent(EVENT_ETC_START_MUSIC, 1600); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ETC_START_MUSIC: + me->PlayDirectMusic(MUSIC_L70_ETC_MUSIC); + _events.ScheduleEvent(EVENT_ETC_START_MUSIC, 1600); // Every 1.6 seconds SMSG_PLAY_MUSIC packet (PlayDirectMusic) is pushed to the client (sniffed value) + break; + default: + break; + } + } + } + private: + EventMap _events; + }; + + GameObjectAI* GetAI(GameObject* go) const override + { + return new go_l70_etc_musicAI(go); + } +}; + // Theirs /*#### ## go_brewfest_music @@ -1911,6 +1962,7 @@ void AddSC_go_scripts() new go_heat(); new go_bear_trap(); new go_duskwither_spire_power_source(); + new go_l70_etc_music(); // Theirs new go_brewfest_music(); diff --git a/src/server/shared/Network/Socket.h b/src/server/shared/Network/Socket.h index 0a431eb4d..45b9633b1 100644 --- a/src/server/shared/Network/Socket.h +++ b/src/server/shared/Network/Socket.h @@ -176,7 +176,7 @@ protected: virtual void OnClose() { } virtual void ReadHandler() = 0; - [[nodiscard]] bool AsyncProcessQueue() + bool AsyncProcessQueue() { if (_isWritingAsync) return false;