From 651f159fc5927b8e6a57c012fc1bdf00dd547217 Mon Sep 17 00:00:00 2001 From: daobashun <49193927+fangshun2004@users.noreply.github.com> Date: Mon, 26 Aug 2024 23:10:53 +0800 Subject: [PATCH 01/46] fix(DB/Creature): Added dialogue for the mob "Pilot Bellowfiz" (1378) when idle (#19732) * Add conversations when you're idle * fix error * fix * Update rev_1724552482874297000.sql The modification range has been increased from 10 yards to 15 yards * Update rev_1724552482874297000.sql --------- Co-authored-by: sudlud --- .../rev_1724552482874297000.sql | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1724552482874297000.sql diff --git a/data/sql/updates/pending_db_world/rev_1724552482874297000.sql b/data/sql/updates/pending_db_world/rev_1724552482874297000.sql new file mode 100644 index 000000000..ff5e231e3 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1724552482874297000.sql @@ -0,0 +1,46 @@ +-- Pilot Bellowfiz Smart Ai + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 1378; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 1378); +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 +(1378, 0, 0, 0, 1, 0, 100, 0, 240000, 240000, 240000, 240000, 0, 0, 63, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pilot Bellowfiz - Out of Combat - Add 1 to Counter Id 1'), +(1378, 0, 1, 0, 77, 0, 100, 0, 1, 1, 0, 0, 0, 0, 80, 137800, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pilot Bellowfiz - On Counter 1 Set To 1 - Run Script'), +(1378, 0, 2, 0, 77, 0, 100, 0, 1, 2, 0, 0, 0, 0, 80, 137801, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pilot Bellowfiz - On Counter 1 Set To 2 - Run Script'), +(1378, 0, 3, 0, 77, 0, 100, 0, 1, 3, 0, 0, 0, 0, 80, 137802, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pilot Bellowfiz - On Counter 1 Set To 3 - Run Script'), +(1378, 0, 4, 0, 77, 0, 100, 0, 1, 4, 0, 0, 0, 0, 80, 137803, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pilot Bellowfiz - On Counter 1 Set To 4 - Run Script'), +(1378, 0, 5, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 0, 63, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'On reset - Self: Set script counter_1 to 0'); + + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 137800); +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 +(137800, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Talk 0 to invoker'), +(137800, 9, 1, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 19, 1377, 15, 0, 0, 0, 0, 0, 0, ' Closest alive creature Pilot Stonegear (1377) in 15 yards: Talk 0 to invoker'), +(137800, 9, 2, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Talk 1 to invoker'), +(137800, 9, 3, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 19, 1377, 15, 0, 0, 0, 0, 0, 0, 'Closest alive creature Pilot Stonegear (1377) in 15 yards: Talk 1 to invoker'), +(137800, 9, 4, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Talk 2 to invoker'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 137801); +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 +(137801, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 19, 1377, 15, 0, 0, 0, 0, 0, 0, 'Closest alive creature Pilot Stonegear (1377) in 10 yards: Talk 2 to invoker'), +(137801, 9, 1, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Talk 3 to invoker'), +(137801, 9, 2, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 19, 1377, 15, 0, 0, 0, 0, 0, 0, 'Closest alive creature Pilot Stonegear (1377) in 15 yards: Talk 3 to invoker'), +(137801, 9, 3, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Talk 4 to invoker'), +(137801, 9, 4, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 19, 1377, 15, 0, 0, 0, 0, 0, 0, 'Closest alive creature Pilot Stonegear (1377) in 15 yards: Talk 4 to invoker'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 137802); +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 +(137802, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Talk 5 to invoker'), +(137802, 9, 1, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 19, 1377, 15, 0, 0, 0, 0, 0, 0, 'Closest alive creature Pilot Stonegear (1377) in 15 yards: Talk 5 to invoker'), +(137802, 9, 2, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Talk 6 to invoker'), +(137802, 9, 3, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 19, 1377, 15, 0, 0, 0, 0, 0, 0, 'Closest alive creature Pilot Stonegear (1377) in 15 yards: Talk 6 to invoker'), +(137802, 9, 4, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 0, 0, 1, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Talk 7 to invoker'), +(137802, 9, 5, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 7, 0, 0, 0, 0, 0, 19, 1377, 15, 0, 0, 0, 0, 0, 0, 'Closest alive creature Pilot Stonegear (1377) in 15 yards: Talk 7 to invoker'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 137803); +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 +(137803, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Talk 8 to invoker'), +(137803, 9, 1, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 0, 0, 1, 8, 0, 0, 0, 0, 0, 19, 1377, 15, 0, 0, 0, 0, 0, 0, 'Closest alive creature Pilot Stonegear (1377) in 15 yards: Talk 8 to invoker'), +(137803, 9, 2, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 0, 0, 1, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Talk 9 to invoker'), +(137803, 9, 3, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 1, 9, 0, 0, 0, 0, 0, 19, 1377, 15, 0, 0, 0, 0, 0, 0, 'Closest alive creature Pilot Stonegear (1377) in 15 yards: Talk 9 to invoker'), +(137803, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 63, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Self: Set script counter_1 to 0'); From 6bd29e7f936874ae104d70970339a6234f2a3eb8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 26 Aug 2024 15:11:48 +0000 Subject: [PATCH 02/46] chore(DB): import pending files Referenced commit(s): 651f159fc5927b8e6a57c012fc1bdf00dd547217 --- .../rev_1724552482874297000.sql => db_world/2024_08_26_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1724552482874297000.sql => db_world/2024_08_26_02.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1724552482874297000.sql b/data/sql/updates/db_world/2024_08_26_02.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1724552482874297000.sql rename to data/sql/updates/db_world/2024_08_26_02.sql index ff5e231e3..6fd9a8e14 100644 --- a/data/sql/updates/pending_db_world/rev_1724552482874297000.sql +++ b/data/sql/updates/db_world/2024_08_26_02.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_26_01 -> 2024_08_26_02 -- Pilot Bellowfiz Smart Ai UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 1378; From 4ed1815de64e97a373bacf075073b7e2cde46dc5 Mon Sep 17 00:00:00 2001 From: sudlud Date: Mon, 26 Aug 2024 17:29:12 +0200 Subject: [PATCH 03/46] fix(apps/installer): update for Ubuntu 22.04/24.04 with mysql 8.4 LTS (#19737) --- apps/installer/includes/os_configs/ubuntu.sh | 41 +++++++++++++------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/apps/installer/includes/os_configs/ubuntu.sh b/apps/installer/includes/os_configs/ubuntu.sh index ad20d620c..662458895 100644 --- a/apps/installer/includes/os_configs/ubuntu.sh +++ b/apps/installer/includes/os_configs/ubuntu.sh @@ -4,26 +4,41 @@ fi UBUNTU_VERSION=$(lsb_release -sr); +case $UBUNTU_VERSION in + "22.04") + ;; + "24.04") + ;; + *) + echo "########## ########## ##########" + echo "" + echo " using unsupported Ubuntu version " $UBUNTU_VERSION + echo " please update to Ubuntu 22.04 or later" + echo "" + echo "########## ########## ##########" + ;; +esac + sudo apt update # shared deps -sudo apt-get -y install ccache clang cmake curl google-perftools libmysqlclient-dev make unzip +sudo DEBIAN_FRONTEND="noninteractive" \ +apt-get -y install ccache clang cmake curl google-perftools libmysqlclient-dev make unzip if [[ $CONTINUOUS_INTEGRATION || $DOCKER ]]; then + # TODO: update CI / Docker section for Ubuntu 22.04+ sudo add-apt-repository -y ppa:mhier/libboost-latest && sudo apt update && sudo apt-get -y install build-essential cmake-data \ libboost1.74-dev libbz2-dev libncurses5-dev libmysql++-dev libgoogle-perftools-dev libreadline6-dev libssl-dev libtool \ openssl zlib1g-dev else - case $UBUNTU_VERSION in - "20.04") - sudo apt-get install -y g++ gdb gdbserver gcc git \ - libboost-all-dev libbz2-dev libncurses-dev libreadline-dev \ - libssl-dev mysql-server - ;; - *) - sudo add-apt-repository -y ppa:mhier/libboost-latest && sudo apt update && sudo apt-get install -y g++ gdb gdbserver gcc git \ - libboost-all-dev libbz2-dev libncurses-dev libreadline-dev \ - libssl-dev mysql-server - ;; - esac + sudo DEBIAN_FRONTEND="noninteractive" \ + apt-get install -y g++ gdb gdbserver gcc git \ + libboost-all-dev libbz2-dev libncurses-dev libreadline-dev \ + libssl-dev + + # run noninteractive install for MYSQL 8.4 LTS + wget https://dev.mysql.com/get/mysql-apt-config_0.8.32-1_all.deb + sudo DEBIAN_FRONTEND="noninteractive" dpkg -i ./mysql-apt-config_0.8.32-1_all.deb + sudo apt-get update + sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y mysql-server fi From 83f8871c31fd2b9f374587f921c11b2e00cbf733 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:44:05 -0300 Subject: [PATCH 04/46] refactor(Core/BossAI): Improve the ScheduleHealthCheck() code (#19743) * refactor(Core/BossAI): Improve the ScheduleHealthCheck() code * Update ScriptedCreature.cpp --------- Co-authored-by: sudlud --- .../game/AI/ScriptedAI/ScriptedCreature.cpp | 22 +++++++++---------- .../game/AI/ScriptedAI/ScriptedCreature.h | 4 ++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 39eeed124..63d63c925 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -720,9 +720,18 @@ void BossAI::DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /* { if (!_healthCheckEvents.empty()) { + for (auto& check : _healthCheckEvents) + { + if (check._valid && me->HealthBelowPctDamaged(check._healthPct, damage)) + { + check._exec(); + check._valid = false; + } + } + _healthCheckEvents.remove_if([&](HealthCheckEventData data) -> bool { - return _ProccessHealthCheckEvent(data._healthPct, damage, data._exec); + return !data._valid; }); } } @@ -746,17 +755,6 @@ void BossAI::ScheduleHealthCheckEvent(std::initializer_list healthPct, st } } -bool BossAI::_ProccessHealthCheckEvent(uint8 healthPct, uint32 damage, std::function exec) const -{ - if (me->HealthBelowPctDamaged(healthPct, damage)) - { - exec(); - return true; - } - - return false; -} - // WorldBossAI - for non-instanced bosses WorldBossAI::WorldBossAI(Creature* creature) : diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index cc9c116f4..709d6698b 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -449,10 +449,11 @@ private: struct HealthCheckEventData { - HealthCheckEventData(uint8 healthPct, std::function exec) : _healthPct(healthPct), _exec(exec) { }; + HealthCheckEventData(uint8 healthPct, std::function exec, bool valid = true) : _healthPct(healthPct), _exec(exec), _valid(valid) { }; uint8 _healthPct; std::function _exec; + bool _valid; }; class BossAI : public ScriptedAI @@ -497,7 +498,6 @@ protected: void _JustDied(); void _JustReachedHome() { me->setActive(false); } void _EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER); - [[nodiscard]] bool _ProccessHealthCheckEvent(uint8 healthPct, uint32 damage, std::function exec) const; void TeleportCheaters(); From 126f3a31ee3748a3e2a8ac82e48dcef0e48d2d80 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:28:48 -0300 Subject: [PATCH 05/46] refactor(Scripts/BlackTemple): Update the Illidari Council script to the new registration method (#19744) refactor(Scripts/BlackTemple): Update Illidari council to new model --- .../BlackTemple/boss_illidari_council.cpp | 660 ++++++++++++++++ .../Outland/BlackTemple/illidari_council.cpp | 714 ------------------ 2 files changed, 660 insertions(+), 714 deletions(-) create mode 100644 src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp delete mode 100644 src/server/scripts/Outland/BlackTemple/illidari_council.cpp diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp new file mode 100644 index 000000000..73aed25b6 --- /dev/null +++ b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp @@ -0,0 +1,660 @@ +/* + * 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 "CreatureScript.h" +#include "ScriptedCreature.h" +#include "SpellScriptLoader.h" +#include "black_temple.h" +#include "Player.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" + +enum Says +{ + SAY_COUNCIL_AGGRO = 0, + SAY_COUNCIL_ENRAGE = 1, + SAY_COUNCIL_SPECIAL = 2, + SAY_COUNCIL_SLAY = 3, + SAY_COUNCIL_DEATH = 4 +}; + +enum Spells +{ + SPELL_EMPYREAL_BALANCE = 41499, + SPELL_BERSERK = 41924, + + // Gathios the Shatterer + SPELL_BLESSING_OF_PROTECTION = 41450, + SPELL_BLESSING_OF_SPELL_WARDING = 41451, + SPELL_CONSECRATION = 41541, + SPELL_HAMMER_OF_JUSTICE = 41468, + SPELL_SEAL_OF_COMMAND = 41469, + SPELL_SEAL_OF_BLOOD = 41459, + SPELL_CHROMATIC_RESISTANCE_AURA = 41453, + SPELL_DEVOTION_AURA = 41452, + SPELL_JUDGEMENT = 41467, + + // High Nethermancer Zerevor + SPELL_FLAMESTRIKE = 41481, + SPELL_BLIZZARD = 41482, + SPELL_ARCANE_BOLT = 41483, + SPELL_ARCANE_EXPLOSION = 41524, + SPELL_DAMPEN_MAGIC = 41478, + + // Lady Malande + SPELL_EMPOWERED_SMITE = 41471, + SPELL_CIRCLE_OF_HEALING = 41455, + SPELL_REFLECTIVE_SHIELD = 41475, + SPELL_REFLECTIVE_SHIELD_T = 33619, + SPELL_DIVINE_WRATH = 41472, + SPELL_HEAL_VISUAL = 24171, + + // Veras Darkshadow + SPELL_DEADLY_STRIKE = 41480, + SPELL_DEADLY_POISON = 41485, + SPELL_ENVENOM = 41487, + SPELL_VANISH = 41476, + SPELL_VANISH_OUT = 41479, + SPELL_VANISH_VISUAL = 24222 +}; + +enum Misc +{ + ACTION_START_ENCOUNTER = 1, + ACTION_END_ENCOUNTER = 2, + ACTION_ENRAGE = 3, + + EVENT_SPELL_BLESSING = 1, + EVENT_SPELL_AURA = 2, + EVENT_SPELL_SEAL = 3, + EVENT_SPELL_HAMMER_OF_JUSTICE = 4, + EVENT_SPELL_JUDGEMENT = 5, + EVENT_SPELL_CONSECRATION = 6, + + EVENT_SPELL_FLAMESTRIKE = 10, + EVENT_SPELL_BLIZZARD = 11, + EVENT_SPELL_ARCANE_BOLT = 12, + EVENT_SPELL_DAMPEN_MAGIC = 13, + EVENT_SPELL_ARCANE_EXPLOSION = 14, + + EVENT_SPELL_REFLECTIVE_SHIELD = 20, + EVENT_SPELL_CIRCLE_OF_HEALING = 21, + EVENT_SPELL_DIVINE_WRATH = 22, + EVENT_SPELL_EMPOWERED_SMITE = 23, + + EVENT_SPELL_VANISH = 30, + EVENT_SPELL_VANISH_OUT = 31, + EVENT_SPELL_ENRAGE = 32, + + EVENT_KILL_TALK = 100 +}; + +class VerasEnvenom : public BasicEvent +{ +public: + VerasEnvenom(Unit& owner, ObjectGuid targetGUID) : _owner(owner), _targetGUID(targetGUID) { } + + bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override + { + if (Player* target = ObjectAccessor::GetPlayer(_owner, _targetGUID)) + { + target->m_clientGUIDs.insert(_owner.GetGUID()); + _owner.CastSpell(target, SPELL_ENVENOM, true); + target->RemoveAurasDueToSpell(SPELL_DEADLY_POISON); + target->m_clientGUIDs.erase(_owner.GetGUID()); + } + return true; + } + +private: + Unit& _owner; + ObjectGuid _targetGUID; +}; + +struct boss_illidari_council : public BossAI +{ + boss_illidari_council(Creature* creature) : BossAI(creature, DATA_ILLIDARI_COUNCIL) { } + + void EnterEvadeMode(EvadeReason why) override + { + for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) + if (Creature* member = instance->GetCreature(i)) + member->AI()->EnterEvadeMode(); + + BossAI::EnterEvadeMode(why); + } + + void AttackStart(Unit*) override { } + void MoveInLineOfSight(Unit*) override { } + + void DoAction(int32 param) override + { + if (!me->isActiveObject() && param == ACTION_START_ENCOUNTER) + { + me->setActive(true); + + bool spoken = false; + for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) + { + if (Creature* member = instance->GetCreature(i)) + { + if (!spoken && (roll_chance_i(33) || i == 3)) + { + spoken = true; + member->AI()->Talk(SAY_COUNCIL_AGGRO); + } + member->SetOwnerGUID(me->GetGUID()); + member->SetInCombatWithZone(); + } + } + } + else if (param == ACTION_ENRAGE) + { + for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) + if (Creature* member = instance->GetCreature(i)) + member->AI()->DoAction(ACTION_ENRAGE); + } + else if (param == ACTION_END_ENCOUNTER) + { + me->setActive(false); + for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) + if (Creature* member = instance->GetCreature(i)) + if (member->IsAlive()) + Unit::Kill(me, member); + me->KillSelf(); + } + } + + void UpdateAI(uint32 /*diff*/) override + { + if (!me->isActiveObject()) + return; + + if (!SelectTargetFromPlayerList(115.0f)) + { + EnterEvadeMode(EVADE_REASON_NO_HOSTILES); + return; + } + + me->CastSpell(me, SPELL_EMPYREAL_BALANCE, true); + } +}; + +struct boss_illidari_council_memberAI : public ScriptedAI +{ + boss_illidari_council_memberAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + SetBoundary(instance->GetBossBoundary(DATA_ILLIDARI_COUNCIL)); + } + + InstanceScript* instance; + EventMap events; + + void Reset() override + { + events.Reset(); + } + + void EnterEvadeMode(EvadeReason why) override + { + me->SetOwnerGUID(ObjectGuid::Empty); + ScriptedAI::EnterEvadeMode(why); + } + + void DoAction(int32 param) override + { + if (param == ACTION_ENRAGE) + { + me->CastSpell(me, SPELL_BERSERK, true); + Talk(SAY_COUNCIL_ENRAGE); + } + } + + void KilledUnit(Unit*) override + { + if (events.GetNextEventTime(EVENT_KILL_TALK) == 0) + { + Talk(SAY_COUNCIL_SLAY); + events.ScheduleEvent(EVENT_KILL_TALK, 6000); + } + } + + void JustDied(Unit*) override + { + Talk(SAY_COUNCIL_DEATH); + if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) + council->GetAI()->DoAction(ACTION_END_ENCOUNTER); + } + + void JustEngagedWith(Unit* /*who*/) override + { + if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) + council->GetAI()->DoAction(ACTION_START_ENCOUNTER); + } +}; + +struct boss_gathios_the_shatterer : public boss_illidari_council_memberAI +{ + boss_gathios_the_shatterer(Creature* creature) : boss_illidari_council_memberAI(creature) + { + _toggleBlessing = RAND(true, false); + _toggleAura = RAND(true, false); + _toggleSeal = RAND(true, false); + } + + Creature* SelectCouncilMember() + { + if (roll_chance_i(50)) + return instance->GetCreature(DATA_LADY_MALANDE); + + if (roll_chance_i(20)) + if (Creature* veras = instance->GetCreature(DATA_VERAS_DARKSHADOW)) + if (!veras->HasAura(SPELL_VANISH)) + return veras; + + return instance->GetCreature(RAND(DATA_GATHIOS_THE_SHATTERER, DATA_HIGH_NETHERMANCER_ZEREVOR)); + } + + void JustEngagedWith(Unit* who) override + { + boss_illidari_council_memberAI::JustEngagedWith(who); + events.ScheduleEvent(EVENT_SPELL_BLESSING, 10000); + events.ScheduleEvent(EVENT_SPELL_AURA, 0); + events.ScheduleEvent(EVENT_SPELL_SEAL, 2000); + events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, 6000); + events.ScheduleEvent(EVENT_SPELL_JUDGEMENT, 8000); + events.ScheduleEvent(EVENT_SPELL_CONSECRATION, 4000); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_SPELL_BLESSING: + if (Unit* member = SelectCouncilMember()) + { + me->CastSpell(member, _toggleBlessing ? SPELL_BLESSING_OF_PROTECTION : SPELL_BLESSING_OF_SPELL_WARDING); + _toggleBlessing = !_toggleBlessing; + } + events.ScheduleEvent(EVENT_SPELL_BLESSING, 15000); + break; + case EVENT_SPELL_AURA: + me->CastSpell(me, _toggleAura ? SPELL_DEVOTION_AURA : SPELL_CHROMATIC_RESISTANCE_AURA); + _toggleAura = !_toggleAura; + events.ScheduleEvent(EVENT_SPELL_AURA, 60000); + break; + case EVENT_SPELL_CONSECRATION: + if (roll_chance_i(50)) + Talk(SAY_COUNCIL_SPECIAL); + me->CastSpell(me, SPELL_CONSECRATION, false); + events.ScheduleEvent(EVENT_SPELL_AURA, 30000); + break; + case EVENT_SPELL_HAMMER_OF_JUSTICE: + if (Unit* target = me->GetVictim()) + if (target->IsPlayer() && me->IsInRange(target, 10.0f, 40.0f, true)) + { + me->CastSpell(target, SPELL_HAMMER_OF_JUSTICE); + events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, 20s); + break; + } + events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, 0); + break; + case EVENT_SPELL_SEAL: + me->CastSpell(me, _toggleSeal ? SPELL_SEAL_OF_COMMAND : SPELL_SEAL_OF_BLOOD); + _toggleSeal = !_toggleSeal; + events.ScheduleEvent(EVENT_SPELL_SEAL, 20000); + break; + case EVENT_SPELL_JUDGEMENT: + me->CastSpell(me->GetVictim(), SPELL_JUDGEMENT, false); + events.ScheduleEvent(EVENT_SPELL_JUDGEMENT, 20000); + break; + } + + DoMeleeAttackIfReady(); + } +private: + bool _toggleBlessing; + bool _toggleAura; + bool _toggleSeal; +}; + +struct boss_high_nethermancer_zerevor : public boss_illidari_council_memberAI +{ + boss_high_nethermancer_zerevor(Creature* creature) : boss_illidari_council_memberAI(creature) { } + + void AttackStart(Unit* who) override + { + if (who && me->Attack(who, true)) + me->GetMotionMaster()->MoveChase(who, 20.0f); + } + + void JustEngagedWith(Unit* who) override + { + boss_illidari_council_memberAI::JustEngagedWith(who); + events.ScheduleEvent(EVENT_SPELL_FLAMESTRIKE, 25000); + events.ScheduleEvent(EVENT_SPELL_BLIZZARD, 5000); + events.ScheduleEvent(EVENT_SPELL_ARCANE_BOLT, 15000); + events.ScheduleEvent(EVENT_SPELL_DAMPEN_MAGIC, 0); + events.ScheduleEvent(EVENT_SPELL_ARCANE_EXPLOSION, 10000); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_SPELL_DAMPEN_MAGIC: + me->CastSpell(me, SPELL_DAMPEN_MAGIC, false); + events.ScheduleEvent(EVENT_SPELL_DAMPEN_MAGIC, 120000); + break; + case EVENT_SPELL_ARCANE_BOLT: + me->CastSpell(me->GetVictim(), SPELL_ARCANE_BOLT, false); + events.ScheduleEvent(EVENT_SPELL_ARCANE_BOLT, 3000); + break; + case EVENT_SPELL_FLAMESTRIKE: + if (roll_chance_i(50)) + Talk(SAY_COUNCIL_SPECIAL); + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f)) + me->CastSpell(target, SPELL_FLAMESTRIKE, false); + events.ScheduleEvent(EVENT_SPELL_FLAMESTRIKE, 40000); + break; + case EVENT_SPELL_BLIZZARD: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f)) + me->CastSpell(target, SPELL_BLIZZARD, false); + events.ScheduleEvent(EVENT_SPELL_BLIZZARD, 40000); + break; + case EVENT_SPELL_ARCANE_EXPLOSION: + if (SelectTarget(SelectTargetMethod::Random, 0, 10.0f)) + me->CastSpell(me, SPELL_ARCANE_EXPLOSION, false); + events.ScheduleEvent(EVENT_SPELL_ARCANE_EXPLOSION, 10000); + break; + } + + DoMeleeAttackIfReady(); + } +}; + +struct boss_lady_malande : public boss_illidari_council_memberAI +{ + boss_lady_malande(Creature* creature) : boss_illidari_council_memberAI(creature) { } + + void AttackStart(Unit* who) override + { + if (who && me->Attack(who, true)) + me->GetMotionMaster()->MoveChase(who, 20.0f); + } + + void JustEngagedWith(Unit* who) override + { + boss_illidari_council_memberAI::JustEngagedWith(who); + events.ScheduleEvent(EVENT_SPELL_REFLECTIVE_SHIELD, 10000); + events.ScheduleEvent(EVENT_SPELL_CIRCLE_OF_HEALING, 20000); + events.ScheduleEvent(EVENT_SPELL_DIVINE_WRATH, 5000); + events.ScheduleEvent(EVENT_SPELL_EMPOWERED_SMITE, 15000); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_SPELL_CIRCLE_OF_HEALING: + me->CastSpell(me, SPELL_CIRCLE_OF_HEALING, false); + events.ScheduleEvent(EVENT_SPELL_CIRCLE_OF_HEALING, 20000); + break; + case EVENT_SPELL_REFLECTIVE_SHIELD: + if (roll_chance_i(50)) + Talk(SAY_COUNCIL_SPECIAL); + me->CastSpell(me, SPELL_REFLECTIVE_SHIELD, false); + events.ScheduleEvent(EVENT_SPELL_REFLECTIVE_SHIELD, 40000); + break; + case EVENT_SPELL_DIVINE_WRATH: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f)) + me->CastSpell(target, SPELL_DIVINE_WRATH, false); + events.ScheduleEvent(EVENT_SPELL_DIVINE_WRATH, 20000); + break; + case EVENT_SPELL_EMPOWERED_SMITE: + me->CastSpell(me->GetVictim(), SPELL_EMPOWERED_SMITE, false); + events.ScheduleEvent(EVENT_SPELL_EMPOWERED_SMITE, 3000); + break; + } + } +}; + +struct boss_veras_darkshadow : public boss_illidari_council_memberAI +{ + boss_veras_darkshadow(Creature* creature) : boss_illidari_council_memberAI(creature) { } + + void JustEngagedWith(Unit* who) override + { + me->SetCanDualWield(true); + boss_illidari_council_memberAI::JustEngagedWith(who); + events.ScheduleEvent(EVENT_SPELL_VANISH, 10000); + events.ScheduleEvent(EVENT_SPELL_ENRAGE, 900000); + } + + void JustSummoned(Creature* summon) override + { + summon->CastSpell(summon, SPELL_VANISH_VISUAL, true); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_SPELL_VANISH: + if (roll_chance_i(50)) + Talk(SAY_COUNCIL_SPECIAL); + me->CastSpell(me, SPELL_DEADLY_STRIKE, false); + me->CastSpell(me, SPELL_VANISH, false); + events.ScheduleEvent(EVENT_SPELL_VANISH, 60000); + events.ScheduleEvent(EVENT_SPELL_VANISH_OUT, 29000); + break; + case EVENT_SPELL_VANISH_OUT: + me->CastSpell(me, SPELL_VANISH_OUT, false); + break; + case EVENT_SPELL_ENRAGE: + DoResetThreatList(); + if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) + council->GetAI()->DoAction(ACTION_ENRAGE); + break; + } + + if (events.GetNextEventTime(EVENT_SPELL_VANISH_OUT) == 0) + DoMeleeAttackIfReady(); + } +}; + +class spell_illidari_council_balance_of_power_aura : public AuraScript +{ + PrepareAuraScript(spell_illidari_council_balance_of_power_aura); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + // Set absorbtion amount to unlimited (no absorb) + amount = -1; + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_illidari_council_balance_of_power_aura::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + } +}; + +class spell_illidari_council_empyreal_balance : public SpellScript +{ + PrepareSpellScript(spell_illidari_council_empyreal_balance); + + bool Load() override + { + _sharedHealth = 0; + _sharedHealthMax = 0; + _targetCount = 0; + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Unit* target = GetHitUnit()) + { + _targetCount++; + _sharedHealth += target->GetHealth(); + _sharedHealthMax += target->GetMaxHealth(); + } + } + + void HandleAfterCast() + { + if (_targetCount != 4) + { + GetCaster()->ToCreature()->AI()->EnterEvadeMode(); + return; + } + + float pct = (_sharedHealth / _sharedHealthMax) * 100.0f; + std::list const* targetsInfo = GetSpell()->GetUniqueTargetInfo(); + for (std::list::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit) + if (Creature* target = ObjectAccessor::GetCreature(*GetCaster(), ihit->targetGUID)) + { + target->LowerPlayerDamageReq(target->GetMaxHealth()); + target->SetHealth(CalculatePct(target->GetMaxHealth(), pct)); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_balance::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + AfterCast += SpellCastFn(spell_illidari_council_empyreal_balance::HandleAfterCast); + } + +private: + float _sharedHealth; + float _sharedHealthMax; + uint8 _targetCount; +}; + +class spell_illidari_council_reflective_shield_aura : public AuraScript +{ + PrepareAuraScript(spell_illidari_council_reflective_shield_aura); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_REFLECTIVE_SHIELD_T }); + } + + void ReflectDamage(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) + { + Unit* target = GetTarget(); + if (dmgInfo.GetAttacker() == target) + return; + + int32 bp = absorbAmount / 2; + target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_REFLECTIVE_SHIELD_T, &bp, nullptr, nullptr, true, nullptr, aurEff); + } + + void Register() override + { + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_reflective_shield_aura::ReflectDamage, EFFECT_0); + } +}; + +class spell_illidari_council_judgement : public SpellScript +{ + PrepareSpellScript(spell_illidari_council_judgement); + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + 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; + } + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidari_council_judgement::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +class spell_illidari_council_deadly_strike_aura : public AuraScript +{ + PrepareAuraScript(spell_illidari_council_deadly_strike_aura); + + void Update(AuraEffect const* effect) + { + PreventDefaultAction(); + if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true)) + { + GetUnitOwner()->CastSpell(target, GetSpellInfo()->Effects[effect->GetEffIndex()].TriggerSpell, true); + GetUnitOwner()->m_Events.AddEvent(new VerasEnvenom(*GetUnitOwner(), target->GetGUID()), GetUnitOwner()->m_Events.CalculateTime(urand(1500, 3500))); + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_council_deadly_strike_aura::Update, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; + +void AddSC_boss_illidari_council() +{ + RegisterBlackTempleCreatureAI(boss_illidari_council); + RegisterBlackTempleCreatureAI(boss_gathios_the_shatterer); + RegisterBlackTempleCreatureAI(boss_lady_malande); + RegisterBlackTempleCreatureAI(boss_veras_darkshadow); + RegisterBlackTempleCreatureAI(boss_high_nethermancer_zerevor); + RegisterSpellScript(spell_illidari_council_balance_of_power_aura); + RegisterSpellScript(spell_illidari_council_empyreal_balance); + RegisterSpellScript(spell_illidari_council_reflective_shield_aura); + RegisterSpellScript(spell_illidari_council_judgement); + RegisterSpellScript(spell_illidari_council_deadly_strike_aura); +} diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp deleted file mode 100644 index 39417fd2c..000000000 --- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp +++ /dev/null @@ -1,714 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "CreatureScript.h" -#include "ScriptedCreature.h" -#include "SpellScriptLoader.h" -#include "black_temple.h" -#include "Player.h" -#include "SpellAuraEffects.h" -#include "SpellScript.h" - -enum Says -{ - SAY_COUNCIL_AGGRO = 0, - SAY_COUNCIL_ENRAGE = 1, - SAY_COUNCIL_SPECIAL = 2, - SAY_COUNCIL_SLAY = 3, - SAY_COUNCIL_DEATH = 4 -}; - -enum Spells -{ - SPELL_EMPYREAL_BALANCE = 41499, - SPELL_BERSERK = 41924, - - // Gathios the Shatterer - SPELL_BLESSING_OF_PROTECTION = 41450, - SPELL_BLESSING_OF_SPELL_WARDING = 41451, - SPELL_CONSECRATION = 41541, - SPELL_HAMMER_OF_JUSTICE = 41468, - SPELL_SEAL_OF_COMMAND = 41469, - SPELL_SEAL_OF_BLOOD = 41459, - SPELL_CHROMATIC_RESISTANCE_AURA = 41453, - SPELL_DEVOTION_AURA = 41452, - SPELL_JUDGEMENT = 41467, - - // High Nethermancer Zerevor - SPELL_FLAMESTRIKE = 41481, - SPELL_BLIZZARD = 41482, - SPELL_ARCANE_BOLT = 41483, - SPELL_ARCANE_EXPLOSION = 41524, - SPELL_DAMPEN_MAGIC = 41478, - - // Lady Malande - SPELL_EMPOWERED_SMITE = 41471, - SPELL_CIRCLE_OF_HEALING = 41455, - SPELL_REFLECTIVE_SHIELD = 41475, - SPELL_REFLECTIVE_SHIELD_T = 33619, - SPELL_DIVINE_WRATH = 41472, - SPELL_HEAL_VISUAL = 24171, - - // Veras Darkshadow - SPELL_DEADLY_STRIKE = 41480, - SPELL_DEADLY_POISON = 41485, - SPELL_ENVENOM = 41487, - SPELL_VANISH = 41476, - SPELL_VANISH_OUT = 41479, - SPELL_VANISH_VISUAL = 24222 -}; - -enum Misc -{ - ACTION_START_ENCOUNTER = 1, - ACTION_END_ENCOUNTER = 2, - ACTION_ENRAGE = 3, - - EVENT_SPELL_BLESSING = 1, - EVENT_SPELL_AURA = 2, - EVENT_SPELL_SEAL = 3, - EVENT_SPELL_HAMMER_OF_JUSTICE = 4, - EVENT_SPELL_JUDGEMENT = 5, - EVENT_SPELL_CONSECRATION = 6, - - EVENT_SPELL_FLAMESTRIKE = 10, - EVENT_SPELL_BLIZZARD = 11, - EVENT_SPELL_ARCANE_BOLT = 12, - EVENT_SPELL_DAMPEN_MAGIC = 13, - EVENT_SPELL_ARCANE_EXPLOSION = 14, - - EVENT_SPELL_REFLECTIVE_SHIELD = 20, - EVENT_SPELL_CIRCLE_OF_HEALING = 21, - EVENT_SPELL_DIVINE_WRATH = 22, - EVENT_SPELL_EMPOWERED_SMITE = 23, - - EVENT_SPELL_VANISH = 30, - EVENT_SPELL_VANISH_OUT = 31, - EVENT_SPELL_ENRAGE = 32, - - EVENT_KILL_TALK = 100 -}; - -class VerasEnvenom : public BasicEvent -{ -public: - VerasEnvenom(Unit& owner, ObjectGuid targetGUID) : _owner(owner), _targetGUID(targetGUID) { } - - bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override - { - if (Player* target = ObjectAccessor::GetPlayer(_owner, _targetGUID)) - { - target->m_clientGUIDs.insert(_owner.GetGUID()); - _owner.CastSpell(target, SPELL_ENVENOM, true); - target->RemoveAurasDueToSpell(SPELL_DEADLY_POISON); - target->m_clientGUIDs.erase(_owner.GetGUID()); - } - return true; - } - -private: - Unit& _owner; - ObjectGuid _targetGUID; -}; - -class boss_illidari_council : public CreatureScript -{ -public: - boss_illidari_council() : CreatureScript("boss_illidari_council") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI(creature); - } - - struct boss_illidari_councilAI : public BossAI - { - boss_illidari_councilAI(Creature* creature) : BossAI(creature, DATA_ILLIDARI_COUNCIL) { } - - void EnterEvadeMode(EvadeReason why) override - { - for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) - if (Creature* member = instance->GetCreature(i)) - member->AI()->EnterEvadeMode(); - - BossAI::EnterEvadeMode(why); - } - - void AttackStart(Unit*) override { } - void MoveInLineOfSight(Unit*) override { } - - void DoAction(int32 param) override - { - if (!me->isActiveObject() && param == ACTION_START_ENCOUNTER) - { - me->setActive(true); - - bool spoken = false; - for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) - { - if (Creature* member = instance->GetCreature(i)) - { - if (!spoken && (roll_chance_i(33) || i == 3)) - { - spoken = true; - member->AI()->Talk(SAY_COUNCIL_AGGRO); - } - member->SetOwnerGUID(me->GetGUID()); - member->SetInCombatWithZone(); - } - } - } - else if (param == ACTION_ENRAGE) - { - for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) - if (Creature* member = instance->GetCreature(i)) - member->AI()->DoAction(ACTION_ENRAGE); - } - else if (param == ACTION_END_ENCOUNTER) - { - me->setActive(false); - for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) - if (Creature* member = instance->GetCreature(i)) - if (member->IsAlive()) - Unit::Kill(me, member); - me->KillSelf(); - } - } - - void UpdateAI(uint32 /*diff*/) override - { - if (!me->isActiveObject()) - return; - - if (!SelectTargetFromPlayerList(115.0f)) - { - EnterEvadeMode(EVADE_REASON_NO_HOSTILES); - return; - } - - me->CastSpell(me, SPELL_EMPYREAL_BALANCE, true); - } - }; -}; -struct boss_illidari_council_memberAI : public ScriptedAI -{ - boss_illidari_council_memberAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - SetBoundary(instance->GetBossBoundary(DATA_ILLIDARI_COUNCIL)); - } - - InstanceScript* instance; - EventMap events; - - void Reset() override - { - events.Reset(); - } - - void EnterEvadeMode(EvadeReason why) override - { - me->SetOwnerGUID(ObjectGuid::Empty); - ScriptedAI::EnterEvadeMode(why); - } - - void DoAction(int32 param) override - { - if (param == ACTION_ENRAGE) - { - me->CastSpell(me, SPELL_BERSERK, true); - Talk(SAY_COUNCIL_ENRAGE); - } - } - - void KilledUnit(Unit*) override - { - if (events.GetNextEventTime(EVENT_KILL_TALK) == 0) - { - Talk(SAY_COUNCIL_SLAY); - events.ScheduleEvent(EVENT_KILL_TALK, 6000); - } - } - - void JustDied(Unit*) override - { - Talk(SAY_COUNCIL_DEATH); - if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) - council->GetAI()->DoAction(ACTION_END_ENCOUNTER); - } - - void JustEngagedWith(Unit* /*who*/) override - { - if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) - council->GetAI()->DoAction(ACTION_START_ENCOUNTER); - } -}; - -class boss_gathios_the_shatterer : public CreatureScript -{ -public: - boss_gathios_the_shatterer() : CreatureScript("boss_gathios_the_shatterer") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI(creature); - } - - struct boss_gathios_the_shattererAI : public boss_illidari_council_memberAI - { - boss_gathios_the_shattererAI(Creature* creature) : boss_illidari_council_memberAI(creature) - { - _toggleBlessing = RAND(true, false); - _toggleAura = RAND(true, false); - _toggleSeal = RAND(true, false); - } - - Creature* SelectCouncilMember() - { - if (roll_chance_i(50)) - return instance->GetCreature(DATA_LADY_MALANDE); - - if (roll_chance_i(20)) - if (Creature* veras = instance->GetCreature(DATA_VERAS_DARKSHADOW)) - if (!veras->HasAura(SPELL_VANISH)) - return veras; - - return instance->GetCreature(RAND(DATA_GATHIOS_THE_SHATTERER, DATA_HIGH_NETHERMANCER_ZEREVOR)); - } - - void JustEngagedWith(Unit* who) override - { - boss_illidari_council_memberAI::JustEngagedWith(who); - events.ScheduleEvent(EVENT_SPELL_BLESSING, 10000); - events.ScheduleEvent(EVENT_SPELL_AURA, 0); - events.ScheduleEvent(EVENT_SPELL_SEAL, 2000); - events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, 6000); - events.ScheduleEvent(EVENT_SPELL_JUDGEMENT, 8000); - events.ScheduleEvent(EVENT_SPELL_CONSECRATION, 4000); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_BLESSING: - if (Unit* member = SelectCouncilMember()) - { - me->CastSpell(member, _toggleBlessing ? SPELL_BLESSING_OF_PROTECTION : SPELL_BLESSING_OF_SPELL_WARDING); - _toggleBlessing = !_toggleBlessing; - } - events.ScheduleEvent(EVENT_SPELL_BLESSING, 15000); - break; - case EVENT_SPELL_AURA: - me->CastSpell(me, _toggleAura ? SPELL_DEVOTION_AURA : SPELL_CHROMATIC_RESISTANCE_AURA); - _toggleAura = !_toggleAura; - events.ScheduleEvent(EVENT_SPELL_AURA, 60000); - break; - case EVENT_SPELL_CONSECRATION: - if (roll_chance_i(50)) - Talk(SAY_COUNCIL_SPECIAL); - me->CastSpell(me, SPELL_CONSECRATION, false); - events.ScheduleEvent(EVENT_SPELL_AURA, 30000); - break; - case EVENT_SPELL_HAMMER_OF_JUSTICE: - if (Unit* target = me->GetVictim()) - if (target->IsPlayer() && me->IsInRange(target, 10.0f, 40.0f, true)) - { - me->CastSpell(target, SPELL_HAMMER_OF_JUSTICE); - events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, 20s); - break; - } - events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, 0); - break; - case EVENT_SPELL_SEAL: - me->CastSpell(me, _toggleSeal ? SPELL_SEAL_OF_COMMAND : SPELL_SEAL_OF_BLOOD); - _toggleSeal = !_toggleSeal; - events.ScheduleEvent(EVENT_SPELL_SEAL, 20000); - break; - case EVENT_SPELL_JUDGEMENT: - me->CastSpell(me->GetVictim(), SPELL_JUDGEMENT, false); - events.ScheduleEvent(EVENT_SPELL_JUDGEMENT, 20000); - break; - } - - DoMeleeAttackIfReady(); - } - private: - bool _toggleBlessing; - bool _toggleAura; - bool _toggleSeal; - }; -}; - -class boss_high_nethermancer_zerevor : public CreatureScript -{ -public: - boss_high_nethermancer_zerevor() : CreatureScript("boss_high_nethermancer_zerevor") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI(creature); - } - - struct boss_high_nethermancer_zerevorAI : public boss_illidari_council_memberAI - { - boss_high_nethermancer_zerevorAI(Creature* creature) : boss_illidari_council_memberAI(creature) { } - - void AttackStart(Unit* who) override - { - if (who && me->Attack(who, true)) - me->GetMotionMaster()->MoveChase(who, 20.0f); - } - - void JustEngagedWith(Unit* who) override - { - boss_illidari_council_memberAI::JustEngagedWith(who); - events.ScheduleEvent(EVENT_SPELL_FLAMESTRIKE, 25000); - events.ScheduleEvent(EVENT_SPELL_BLIZZARD, 5000); - events.ScheduleEvent(EVENT_SPELL_ARCANE_BOLT, 15000); - events.ScheduleEvent(EVENT_SPELL_DAMPEN_MAGIC, 0); - events.ScheduleEvent(EVENT_SPELL_ARCANE_EXPLOSION, 10000); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_DAMPEN_MAGIC: - me->CastSpell(me, SPELL_DAMPEN_MAGIC, false); - events.ScheduleEvent(EVENT_SPELL_DAMPEN_MAGIC, 120000); - break; - case EVENT_SPELL_ARCANE_BOLT: - me->CastSpell(me->GetVictim(), SPELL_ARCANE_BOLT, false); - events.ScheduleEvent(EVENT_SPELL_ARCANE_BOLT, 3000); - break; - case EVENT_SPELL_FLAMESTRIKE: - if (roll_chance_i(50)) - Talk(SAY_COUNCIL_SPECIAL); - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f)) - me->CastSpell(target, SPELL_FLAMESTRIKE, false); - events.ScheduleEvent(EVENT_SPELL_FLAMESTRIKE, 40000); - break; - case EVENT_SPELL_BLIZZARD: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f)) - me->CastSpell(target, SPELL_BLIZZARD, false); - events.ScheduleEvent(EVENT_SPELL_BLIZZARD, 40000); - break; - case EVENT_SPELL_ARCANE_EXPLOSION: - if (SelectTarget(SelectTargetMethod::Random, 0, 10.0f)) - me->CastSpell(me, SPELL_ARCANE_EXPLOSION, false); - events.ScheduleEvent(EVENT_SPELL_ARCANE_EXPLOSION, 10000); - break; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -class boss_lady_malande : public CreatureScript -{ -public: - boss_lady_malande() : CreatureScript("boss_lady_malande") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI(creature); - } - - struct boss_lady_malandeAI : public boss_illidari_council_memberAI - { - boss_lady_malandeAI(Creature* creature) : boss_illidari_council_memberAI(creature) { } - - void AttackStart(Unit* who) override - { - if (who && me->Attack(who, true)) - me->GetMotionMaster()->MoveChase(who, 20.0f); - } - - void JustEngagedWith(Unit* who) override - { - boss_illidari_council_memberAI::JustEngagedWith(who); - events.ScheduleEvent(EVENT_SPELL_REFLECTIVE_SHIELD, 10000); - events.ScheduleEvent(EVENT_SPELL_CIRCLE_OF_HEALING, 20000); - events.ScheduleEvent(EVENT_SPELL_DIVINE_WRATH, 5000); - events.ScheduleEvent(EVENT_SPELL_EMPOWERED_SMITE, 15000); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_CIRCLE_OF_HEALING: - me->CastSpell(me, SPELL_CIRCLE_OF_HEALING, false); - events.ScheduleEvent(EVENT_SPELL_CIRCLE_OF_HEALING, 20000); - break; - case EVENT_SPELL_REFLECTIVE_SHIELD: - if (roll_chance_i(50)) - Talk(SAY_COUNCIL_SPECIAL); - me->CastSpell(me, SPELL_REFLECTIVE_SHIELD, false); - events.ScheduleEvent(EVENT_SPELL_REFLECTIVE_SHIELD, 40000); - break; - case EVENT_SPELL_DIVINE_WRATH: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f)) - me->CastSpell(target, SPELL_DIVINE_WRATH, false); - events.ScheduleEvent(EVENT_SPELL_DIVINE_WRATH, 20000); - break; - case EVENT_SPELL_EMPOWERED_SMITE: - me->CastSpell(me->GetVictim(), SPELL_EMPOWERED_SMITE, false); - events.ScheduleEvent(EVENT_SPELL_EMPOWERED_SMITE, 3000); - break; - } - } - }; -}; - -class boss_veras_darkshadow : public CreatureScript -{ -public: - boss_veras_darkshadow() : CreatureScript("boss_veras_darkshadow") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI(creature); - } - - struct boss_veras_darkshadowAI : public boss_illidari_council_memberAI - { - boss_veras_darkshadowAI(Creature* creature) : boss_illidari_council_memberAI(creature) { } - - void JustEngagedWith(Unit* who) override - { - me->SetCanDualWield(true); - boss_illidari_council_memberAI::JustEngagedWith(who); - events.ScheduleEvent(EVENT_SPELL_VANISH, 10000); - events.ScheduleEvent(EVENT_SPELL_ENRAGE, 900000); - } - - void JustSummoned(Creature* summon) override - { - summon->CastSpell(summon, SPELL_VANISH_VISUAL, true); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_VANISH: - if (roll_chance_i(50)) - Talk(SAY_COUNCIL_SPECIAL); - me->CastSpell(me, SPELL_DEADLY_STRIKE, false); - me->CastSpell(me, SPELL_VANISH, false); - events.ScheduleEvent(EVENT_SPELL_VANISH, 60000); - events.ScheduleEvent(EVENT_SPELL_VANISH_OUT, 29000); - break; - case EVENT_SPELL_VANISH_OUT: - me->CastSpell(me, SPELL_VANISH_OUT, false); - break; - case EVENT_SPELL_ENRAGE: - DoResetThreatList(); - if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) - council->GetAI()->DoAction(ACTION_ENRAGE); - break; - } - - if (events.GetNextEventTime(EVENT_SPELL_VANISH_OUT) == 0) - DoMeleeAttackIfReady(); - } - }; -}; - -class spell_illidari_council_balance_of_power_aura : public AuraScript -{ - PrepareAuraScript(spell_illidari_council_balance_of_power_aura); - - void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) - { - // Set absorbtion amount to unlimited (no absorb) - amount = -1; - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_illidari_council_balance_of_power_aura::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - } -}; - -class spell_illidari_council_empyreal_balance : public SpellScript -{ - PrepareSpellScript(spell_illidari_council_empyreal_balance); - - bool Load() override - { - _sharedHealth = 0; - _sharedHealthMax = 0; - _targetCount = 0; - return GetCaster()->GetTypeId() == TYPEID_UNIT; - } - - void HandleDummy(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - if (Unit* target = GetHitUnit()) - { - _targetCount++; - _sharedHealth += target->GetHealth(); - _sharedHealthMax += target->GetMaxHealth(); - } - } - - void HandleAfterCast() - { - if (_targetCount != 4) - { - GetCaster()->ToCreature()->AI()->EnterEvadeMode(); - return; - } - - float pct = (_sharedHealth / _sharedHealthMax) * 100.0f; - std::list const* targetsInfo = GetSpell()->GetUniqueTargetInfo(); - for (std::list::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit) - if (Creature* target = ObjectAccessor::GetCreature(*GetCaster(), ihit->targetGUID)) - { - target->LowerPlayerDamageReq(target->GetMaxHealth()); - target->SetHealth(CalculatePct(target->GetMaxHealth(), pct)); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_balance::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - AfterCast += SpellCastFn(spell_illidari_council_empyreal_balance::HandleAfterCast); - } - -private: - float _sharedHealth; - float _sharedHealthMax; - uint8 _targetCount; -}; - -class spell_illidari_council_reflective_shield_aura : public AuraScript -{ - PrepareAuraScript(spell_illidari_council_reflective_shield_aura); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_REFLECTIVE_SHIELD_T }); - } - - void ReflectDamage(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) - { - Unit* target = GetTarget(); - if (dmgInfo.GetAttacker() == target) - return; - - int32 bp = absorbAmount / 2; - target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_REFLECTIVE_SHIELD_T, &bp, nullptr, nullptr, true, nullptr, aurEff); - } - - void Register() override - { - AfterEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_reflective_shield_aura::ReflectDamage, EFFECT_0); - } -}; - -class spell_illidari_council_judgement : public SpellScript -{ - PrepareSpellScript(spell_illidari_council_judgement); - - void HandleScriptEffect(SpellEffIndex /*effIndex*/) - { - 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; - } - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidari_council_judgement::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } -}; - -class spell_illidari_council_deadly_strike_aura : public AuraScript -{ - PrepareAuraScript(spell_illidari_council_deadly_strike_aura); - - void Update(AuraEffect const* effect) - { - PreventDefaultAction(); - if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true)) - { - GetUnitOwner()->CastSpell(target, GetSpellInfo()->Effects[effect->GetEffIndex()].TriggerSpell, true); - GetUnitOwner()->m_Events.AddEvent(new VerasEnvenom(*GetUnitOwner(), target->GetGUID()), GetUnitOwner()->m_Events.CalculateTime(urand(1500, 3500))); - } - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_council_deadly_strike_aura::Update, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } -}; - -void AddSC_boss_illidari_council() -{ - new boss_illidari_council(); - new boss_gathios_the_shatterer(); - new boss_lady_malande(); - new boss_veras_darkshadow(); - new boss_high_nethermancer_zerevor(); - RegisterSpellScript(spell_illidari_council_balance_of_power_aura); - RegisterSpellScript(spell_illidari_council_empyreal_balance); - RegisterSpellScript(spell_illidari_council_reflective_shield_aura); - RegisterSpellScript(spell_illidari_council_judgement); - RegisterSpellScript(spell_illidari_council_deadly_strike_aura); -} From 574ef5203a4cb2c5cfd476323089dd9e9217999a Mon Sep 17 00:00:00 2001 From: Grimdhex <176165533+Grimdhex@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:19:13 +0200 Subject: [PATCH 06/46] chore(Apps/CodeStyle): rewrite Ci-codestyle in python (#19714) * initial version * port most current checks * allow to specify for each checks the exclude files * Update _ci-codestyle.py * fix trailing whitespace check and the error_handler logic * optimize the script to parse all files only one time * restore the error handling after that all checks are passed * fix double blank lines at the end of the file * improve outputs and the codestyle * . * update github workflow to the new script *drop the old ci-codestyle *move and rename the python script * use getcwd instead abspath to define src_directory where the script is launch * test for github workflow * few cleanup * fix the logic with the result output * remove GetTypeId from the output result * restore GetTypeId() check * fix reviews * remove GetTypeId check for gameobjects *not currently fixed in the core * fix type hint for file parameters * remove the test file --- .github/workflows/codestyle.yml | 6 +- apps/ci/ci-codestyle.sh | 40 --------- apps/codestyle/codestyle.py | 148 ++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 41 deletions(-) delete mode 100644 apps/ci/ci-codestyle.sh create mode 100644 apps/codestyle/codestyle.py diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml index ce72ed58f..f24a1d252 100644 --- a/.github/workflows/codestyle.yml +++ b/.github/workflows/codestyle.yml @@ -13,8 +13,12 @@ jobs: if: github.repository == 'azerothcore/azerothcore-wotlk' steps: - uses: actions/checkout@v4 + - name: Setup python + uses: actions/setup-python@v4 + with: + python-version: '3.10' - name: AzerothCore codestyle - run: source ./apps/ci/ci-codestyle.sh + run: python ./apps/codestyle/codestyle.py - name: C++ Advanced run: | sudo apt update -y diff --git a/apps/ci/ci-codestyle.sh b/apps/ci/ci-codestyle.sh deleted file mode 100644 index c96a31df0..000000000 --- a/apps/ci/ci-codestyle.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -set -e - -echo "Codestyle check script:" -echo - -declare -A singleLineRegexChecks=( - ["LOG_.+GetCounter"]="Use ObjectGuid::ToString().c_str() method instead of ObjectGuid::GetCounter() when logging. Check the lines above" - ["[[:blank:]]$"]="Remove whitespace at the end of the lines above" - ["\t"]="Replace tabs with 4 spaces in the lines above" -) - -for check in ${!singleLineRegexChecks[@]}; do - echo " Checking RegEx: '${check}'" - - if grep -P -r -I -n ${check} src; then - echo - echo "${singleLineRegexChecks[$check]}" - exit 1 - fi -done - -declare -A multiLineRegexChecks=( - ["LOG_[^;]+GetCounter"]="Use ObjectGuid::ToString().c_str() method instead of ObjectGuid::GetCounter() when logging. Check the lines above" - ["\n\n\n"]="Multiple blank lines detected, keep only one. Check the files above" -) - -for check in ${!multiLineRegexChecks[@]}; do - echo " Checking RegEx: '${check}'" - - if grep -Pzo -r -I ${check} src; then - echo - echo - echo "${multiLineRegexChecks[$check]}" - exit 1 - fi -done - -echo -echo "Everything looks good" diff --git a/apps/codestyle/codestyle.py b/apps/codestyle/codestyle.py new file mode 100644 index 000000000..8c595d704 --- /dev/null +++ b/apps/codestyle/codestyle.py @@ -0,0 +1,148 @@ +import io +import os +import sys + +# Get the src directory of the project +src_directory = os.path.join(os.getcwd(), 'src') + +# Global variables +error_handler = False +results = { + "Multiple blank lines check": "Passed", + "Trailing whitespace check": "Passed", + "GetCounter() check": "Passed", + "GetTypeId() check": "Passed", + "NpcFlagHelpers check": "Passed" +} + +# Main function to parse all the files of the project +def parsing_file(directory: str) -> None: + for root, _, files in os.walk(directory): + for file in files: + if not file.endswith('.ico'): # Skip .ico files that cannot be read + file_path = os.path.join(root, file) + file_name = file + try: + with open(file_path, 'r', encoding='utf-8') as file: + multiple_blank_lines_check(file, file_path) + trailing_whitespace_check(file, file_path) + get_counter_check(file, file_path) + if file_name != 'Object.h': + get_typeid_check(file, file_path) + if file_name != 'Unit.h': + npcflags_helpers_check(file, file_path) + except UnicodeDecodeError: + print(f"\nCould not decode file {file_path}") + sys.exit(1) + # Output the results + print("") + for check, result in results.items(): + print(f"{check} : {result}") + if error_handler: + print("\nPlease fix the codestyle issues above.") + sys.exit(1) + else: + print(f"\nEverything looks good") + +# Codestyle patterns checking for multiple blank lines +def multiple_blank_lines_check(file: io, file_path: str) -> None: + global error_handler, results + file.seek(0) # Reset file pointer to the beginning + check_failed = False + consecutive_blank_lines = 0 + # Parse all the file + for line_number, line in enumerate(file, start = 1): + if line.strip() == '': + consecutive_blank_lines += 1 + if consecutive_blank_lines > 1: + print(f"Multiple blank lines found in {file_path} at line {line_number - 1}") + check_failed = True + else: + consecutive_blank_lines = 0 + # Additional check for the end of the file + if consecutive_blank_lines >= 1: + print(f"Multiple blank lines found at the end of: {file_path}") + check_failed = True + # Handle the script error and update the result output + if check_failed: + error_handler = True + results["Multiple blank lines check"] = "Failed" + +# Codestyle patterns checking for whitespace at the end of the lines +def trailing_whitespace_check(file: io, file_path: str) -> None: + global error_handler, results + file.seek(0) # Reset file pointer to the beginning + # Parse all the file + for line_number, line in enumerate(file, start = 1): + if line.endswith(' \n'): + print(f"Trailing whitespace found: {file_path} at line {line_number}") + if not error_handler: + error_handler = True + results["Trailing whitespace check"] = "Failed" + +# Codestyle patterns checking for ObjectGuid::GetCounter() +def get_counter_check(file: io, file_path: str) -> None: + global error_handler, results + file.seek(0) # Reset file pointer to the beginning + # Parse all the file + for line_number, line in enumerate(file, start = 1): + if 'ObjectGuid::GetCounter()' in line: + print(f"Please use ObjectGuid::ToString().c_str() instead ObjectGuid::GetCounter(): {file_path} at line {line_number}") + if not error_handler: + error_handler = True + results["GetCounter() check"] = "Failed" + +# Codestyle patterns checking for GetTypeId() +def get_typeid_check(file: io, file_path: str) -> None: + global error_handler, results + file.seek(0) # Reset file pointer to the beginning + check_failed = False + # Parse all the file + for line_number, line in enumerate(file, start = 1): + if 'GetTypeId() == TYPEID_PLAYER' in line: + print(f"Please use IsPlayer() instead GetTypeId(): {file_path} at line {line_number}") + check_failed = True + if 'GetTypeId() == TYPEID_ITEM' in line: + print(f"Please use IsItem() instead GetTypeId(): {file_path} at line {line_number}") + check_failed = True + if 'GetTypeId() == TYPEID_DYNOBJECT' in line: + print(f"Please use IsDynamicObject() instead GetTypeId(): {file_path} at line {line_number}") + check_failed = True + # Handle the script error and update the result output + if check_failed: + error_handler = True + results["GetTypeId() check"] = "Failed" + +# Codestyle patterns checking for NpcFlag helpers +def npcflags_helpers_check(file: io, file_path: str) -> None: + global error_handler, results + file.seek(0) # Reset file pointer to the beginning + check_failed = False + # Parse all the file + for line_number, line in enumerate(file, start = 1): + if 'GetUInt32Value(UNIT_NPC_FLAGS)' in line: + print( + f"Please use GetNpcFlags() instead GetUInt32Value(UNIT_NPC_FLAGS): {file_path} at line {line_number}") + check_failed = True + if 'HasFlag(UNIT_NPC_FLAGS,' in line: + print( + f"Please use HasNpcFlag() instead HasFlag(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}") + check_failed = True + if 'SetUInt32Value(UNIT_NPC_FLAGS,' in line: + print( + f"Please use ReplaceAllNpcFlags() instead SetUInt32Value(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}") + check_failed = True + if 'SetFlag(UNIT_NPC_FLAGS,' in line: + print( + f"Please use SetNpcFlag() instead SetFlag(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}") + check_failed = True + if 'RemoveFlag(UNIT_NPC_FLAGS,' in line: + print( + f"Please use RemoveNpcFlag() instead RemoveFlag(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}") + # Handle the script error and update the result output + if check_failed: + error_handler = True + results["NpcFlagHelpers check"] = "Failed" + +# Main function +parsing_file(src_directory) From 3ea889ac32873cc475a5f52c28e50d74abf8cc30 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Tue, 27 Aug 2024 08:18:15 -0400 Subject: [PATCH 07/46] fix(DB/Creature): Adjust Veras Darkshadow's level. (#19754) Init. --- data/sql/updates/pending_db_world/veras-level.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/sql/updates/pending_db_world/veras-level.sql diff --git a/data/sql/updates/pending_db_world/veras-level.sql b/data/sql/updates/pending_db_world/veras-level.sql new file mode 100644 index 000000000..543d88871 --- /dev/null +++ b/data/sql/updates/pending_db_world/veras-level.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `minlevel` = 73, `maxlevel` = 73 WHERE `entry` = 22952; From 7ca942b3e7e1133021bd9373851225589a1d4b2d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Aug 2024 12:19:12 +0000 Subject: [PATCH 08/46] chore(DB): import pending files Referenced commit(s): 3ea889ac32873cc475a5f52c28e50d74abf8cc30 --- .../veras-level.sql => db_world/2024_08_27_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/veras-level.sql => db_world/2024_08_27_00.sql} (66%) diff --git a/data/sql/updates/pending_db_world/veras-level.sql b/data/sql/updates/db_world/2024_08_27_00.sql similarity index 66% rename from data/sql/updates/pending_db_world/veras-level.sql rename to data/sql/updates/db_world/2024_08_27_00.sql index 543d88871..f682feaa8 100644 --- a/data/sql/updates/pending_db_world/veras-level.sql +++ b/data/sql/updates/db_world/2024_08_27_00.sql @@ -1 +1,2 @@ +-- DB update 2024_08_26_02 -> 2024_08_27_00 UPDATE `creature_template` SET `minlevel` = 73, `maxlevel` = 73 WHERE `entry` = 22952; From 15b9da7fac2e52b674a608f9f6abef6dc171092c Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Tue, 27 Aug 2024 08:34:28 -0400 Subject: [PATCH 09/46] fix(DB/Creature): Adjust Illidan Stormrage's class. (#19755) Init. --- data/sql/updates/pending_db_world/illidan-class.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/sql/updates/pending_db_world/illidan-class.sql diff --git a/data/sql/updates/pending_db_world/illidan-class.sql b/data/sql/updates/pending_db_world/illidan-class.sql new file mode 100644 index 000000000..c91bd8414 --- /dev/null +++ b/data/sql/updates/pending_db_world/illidan-class.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `unit_class` = 1 WHERE `entry` = 22917; From db9fb5f952e7368754c814929d8a023fdd2c2c65 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Aug 2024 12:35:22 +0000 Subject: [PATCH 10/46] chore(DB): import pending files Referenced commit(s): 15b9da7fac2e52b674a608f9f6abef6dc171092c --- .../illidan-class.sql => db_world/2024_08_27_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/illidan-class.sql => db_world/2024_08_27_01.sql} (61%) diff --git a/data/sql/updates/pending_db_world/illidan-class.sql b/data/sql/updates/db_world/2024_08_27_01.sql similarity index 61% rename from data/sql/updates/pending_db_world/illidan-class.sql rename to data/sql/updates/db_world/2024_08_27_01.sql index c91bd8414..1f471d571 100644 --- a/data/sql/updates/pending_db_world/illidan-class.sql +++ b/data/sql/updates/db_world/2024_08_27_01.sql @@ -1 +1,2 @@ +-- DB update 2024_08_27_00 -> 2024_08_27_01 UPDATE `creature_template` SET `unit_class` = 1 WHERE `entry` = 22917; From 8f335bbc2b030e5b4766bbc99167c4af465d9af9 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:17:54 -0400 Subject: [PATCH 11/46] fix(Core/SpellMgr): Remove binary attribute from Drain Soul. (#19760) Init. --- src/server/game/Spells/SpellMgr.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 1c315f532..3511aa90e 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3070,10 +3070,11 @@ void SpellMgr::LoadSpellInfoCustomAttributes() if (spellInfo->SpellFamilyName != SPELLFAMILY_MAGE || !(spellInfo->SpellFamilyFlags[0] & 0x20)) // frostbolt if (spellInfo->Id != 55095) // frost fever if (spellInfo->SpellFamilyName != SPELLFAMILY_WARLOCK || !(spellInfo->SpellFamilyFlags[1] & 0x40000)) // Haunt - { - spellInfo->AttributesCu |= SPELL_ATTR0_CU_BINARY_SPELL; - break; - } + if (spellInfo->SpellFamilyName != SPELLFAMILY_WARLOCK || !(spellInfo->SpellFamilyFlags[0] & 0x4000)) // Drain Soul + { + spellInfo->AttributesCu |= SPELL_ATTR0_CU_BINARY_SPELL; + break; + } continue; } } From c76f2382d935275533479359e2adbb8948e652c8 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:51:47 -0400 Subject: [PATCH 12/46] fix(Scripts/BlackTemple): Improve Illidari Council Empyreal Balance. (#19757) --- .../illidari-empyreal-balance.sql | 10 +++ .../BlackTemple/boss_illidari_council.cpp | 89 ++++++++++++++++--- 2 files changed, 85 insertions(+), 14 deletions(-) create mode 100644 data/sql/updates/pending_db_world/illidari-empyreal-balance.sql diff --git a/data/sql/updates/pending_db_world/illidari-empyreal-balance.sql b/data/sql/updates/pending_db_world/illidari-empyreal-balance.sql new file mode 100644 index 000000000..59edcb74a --- /dev/null +++ b/data/sql/updates/pending_db_world/illidari-empyreal-balance.sql @@ -0,0 +1,10 @@ +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceGroup` = 1 AND `SourceEntry` IN (41333, 41342) AND `SourceId` = 0 AND `ElseGroup` IN (0, 1, 2, 3) AND `ConditionTypeOrReference` = 31 AND `ConditionValue2` IN (22949, 22950, 22951, 22952, 23426); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 41333, 0, 1, 31, 0, 3, 22949, 0, 0, 0, 0, '', 'Spell \'Empyreal Equivalency\' can hit \'Gathios the Shatterer\''), +(13, 1, 41333, 0, 2, 31, 0, 3, 22950, 0, 0, 0, 0, '', 'Spell \'Empyreal Equivalency\' can hit \'High Nethermancer Zerevor\''), +(13, 1, 41333, 0, 3, 31, 0, 3, 22951, 0, 0, 0, 0, '', 'Spell \'Empyreal Equivalency\' can hit \'Lady Malande\''), +(13, 1, 41333, 0, 0, 31, 0, 3, 22952, 0, 0, 0, 0, '', 'Spell \'Empyreal Equivalency\' can hit \'Veras Darkshadow\''), +(13, 1, 41342, 0, 0, 31, 0, 3, 23426, 0, 0, 0, 0, '', 'Spell \'Shared Rule\' can hit \'The illidari Council\''); + +DELETE FROM `spell_script_names` WHERE `spell_id` = 41333; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (41333, 'spell_illidari_council_empyreal_equivalency'); diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp index 73aed25b6..df364b2cd 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp @@ -34,6 +34,8 @@ enum Says enum Spells { + SPELL_EMPYREAL_EQUIVALENCY = 41333, + SPELL_SHARED_RULE = 41342, SPELL_EMPYREAL_BALANCE = 41499, SPELL_BERSERK = 41924, @@ -148,6 +150,14 @@ struct boss_illidari_council : public BossAI me->setActive(true); bool spoken = false; + + me->CastSpell(me, SPELL_EMPYREAL_BALANCE, true); + + ScheduleTimedEvent(3200ms, [&] + { + me->CastSpell(me, SPELL_EMPYREAL_EQUIVALENCY, true); + }, 3200ms); + for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) { if (Creature* member = instance->GetCreature(i)) @@ -179,7 +189,7 @@ struct boss_illidari_council : public BossAI } } - void UpdateAI(uint32 /*diff*/) override + void UpdateAI(uint32 diff) override { if (!me->isActiveObject()) return; @@ -189,8 +199,7 @@ struct boss_illidari_council : public BossAI EnterEvadeMode(EVADE_REASON_NO_HOSTILES); return; } - - me->CastSpell(me, SPELL_EMPYREAL_BALANCE, true); + scheduler.Update(diff); } }; @@ -241,7 +250,7 @@ struct boss_illidari_council_memberAI : public ScriptedAI council->GetAI()->DoAction(ACTION_END_ENCOUNTER); } - void JustEngagedWith(Unit* /*who*/) override + void JustEngagedWith(Unit* /*who*/) override { if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) council->GetAI()->DoAction(ACTION_START_ENCOUNTER); @@ -512,13 +521,28 @@ class spell_illidari_council_balance_of_power_aura : public AuraScript void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) { - // Set absorbtion amount to unlimited (no absorb) + // Set absorption amount to unlimited (no absorb) amount = -1; } + void Absorb(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& /*absorbAmount*/) + { + Unit* councilMember = GetTarget(); + InstanceScript* instance = councilMember->GetInstanceScript(); + if (!instance) + return; + + Creature* target = instance->GetCreature(DATA_ILLIDARI_COUNCIL); + + int32 damage = dmgInfo.GetDamage(); + if (Creature* caster = councilMember->ToCreature()) + caster->CastCustomSpell(target, SPELL_SHARED_RULE, &damage, &damage, &damage, true, nullptr, nullptr, caster->GetGUID()); + } + void Register() override { DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_illidari_council_balance_of_power_aura::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_balance_of_power_aura::Absorb, EFFECT_0); } }; @@ -528,8 +552,6 @@ class spell_illidari_council_empyreal_balance : public SpellScript bool Load() override { - _sharedHealth = 0; - _sharedHealthMax = 0; _targetCount = 0; return GetCaster()->GetTypeId() == TYPEID_UNIT; } @@ -537,11 +559,9 @@ class spell_illidari_council_empyreal_balance : public SpellScript void HandleDummy(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); - if (Unit* target = GetHitUnit()) + if (GetHitUnit()) { _targetCount++; - _sharedHealth += target->GetHealth(); - _sharedHealthMax += target->GetMaxHealth(); } } @@ -553,13 +573,13 @@ class spell_illidari_council_empyreal_balance : public SpellScript return; } - float pct = (_sharedHealth / _sharedHealthMax) * 100.0f; std::list const* targetsInfo = GetSpell()->GetUniqueTargetInfo(); for (std::list::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit) if (Creature* target = ObjectAccessor::GetCreature(*GetCaster(), ihit->targetGUID)) { + target->SetMaxHealth(GetCaster()->GetMaxHealth() / _targetCount); + target->SetHealth(GetCaster()->GetHealth() / _targetCount); target->LowerPlayerDamageReq(target->GetMaxHealth()); - target->SetHealth(CalculatePct(target->GetMaxHealth(), pct)); } } @@ -570,8 +590,48 @@ class spell_illidari_council_empyreal_balance : public SpellScript } private: - float _sharedHealth; - float _sharedHealthMax; + uint8 _targetCount; +}; + +class spell_illidari_council_empyreal_equivalency : public SpellScript +{ + PrepareSpellScript(spell_illidari_council_empyreal_equivalency); + + bool Load() override + { + _targetCount = 0; + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (GetHitUnit()) + { + _targetCount++; + } + } + + void HandleAfterCast() + { + if (_targetCount != 4) + { + return; + } + + std::list const* targetsInfo = GetSpell()->GetUniqueTargetInfo(); + for (std::list::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit) + if (Creature* target = ObjectAccessor::GetCreature(*GetCaster(), ihit->targetGUID)) + target->SetHealth(GetCaster()->GetHealth() / _targetCount); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_equivalency::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + AfterCast += SpellCastFn(spell_illidari_council_empyreal_equivalency::HandleAfterCast); + } + +private: uint8 _targetCount; }; @@ -654,6 +714,7 @@ void AddSC_boss_illidari_council() RegisterBlackTempleCreatureAI(boss_high_nethermancer_zerevor); RegisterSpellScript(spell_illidari_council_balance_of_power_aura); RegisterSpellScript(spell_illidari_council_empyreal_balance); + RegisterSpellScript(spell_illidari_council_empyreal_equivalency); RegisterSpellScript(spell_illidari_council_reflective_shield_aura); RegisterSpellScript(spell_illidari_council_judgement); RegisterSpellScript(spell_illidari_council_deadly_strike_aura); From 4db17e158c83e90c0fffddf8ab2dffdafd7545fd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Aug 2024 18:53:12 +0000 Subject: [PATCH 13/46] chore(DB): import pending files Referenced commit(s): c76f2382d935275533479359e2adbb8948e652c8 --- .../illidari-empyreal-balance.sql => db_world/2024_08_27_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/illidari-empyreal-balance.sql => db_world/2024_08_27_02.sql} (96%) diff --git a/data/sql/updates/pending_db_world/illidari-empyreal-balance.sql b/data/sql/updates/db_world/2024_08_27_02.sql similarity index 96% rename from data/sql/updates/pending_db_world/illidari-empyreal-balance.sql rename to data/sql/updates/db_world/2024_08_27_02.sql index 59edcb74a..ffe48a1c9 100644 --- a/data/sql/updates/pending_db_world/illidari-empyreal-balance.sql +++ b/data/sql/updates/db_world/2024_08_27_02.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_27_01 -> 2024_08_27_02 DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceGroup` = 1 AND `SourceEntry` IN (41333, 41342) AND `SourceId` = 0 AND `ElseGroup` IN (0, 1, 2, 3) AND `ConditionTypeOrReference` = 31 AND `ConditionValue2` IN (22949, 22950, 22951, 22952, 23426); INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES (13, 1, 41333, 0, 1, 31, 0, 3, 22949, 0, 0, 0, 0, '', 'Spell \'Empyreal Equivalency\' can hit \'Gathios the Shatterer\''), From 53e0779ae82332ba965723a6c2d08e5f89260577 Mon Sep 17 00:00:00 2001 From: Jelle Meeus Date: Tue, 27 Aug 2024 22:25:41 +0200 Subject: [PATCH 14/46] fix(Scripts/Spells): General's Heart trinket (#19756) * handle aura with spell_gen_absorb0_hitlimit1 * refactor enscapsulate limit --- .../pending_db_world/rev_1724764338252798941.sql | 3 +++ src/server/scripts/Spells/spell_generic.cpp | 12 +++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1724764338252798941.sql diff --git a/data/sql/updates/pending_db_world/rev_1724764338252798941.sql b/data/sql/updates/pending_db_world/rev_1724764338252798941.sql new file mode 100644 index 000000000..d35775f79 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1724764338252798941.sql @@ -0,0 +1,3 @@ +-- +DELETE FROM `spell_script_names` WHERE `spell_id` = 64765; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (64765, 'spell_gen_absorb0_hitlimit1'); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index d5ca8b153..2f3765c91 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1195,29 +1195,31 @@ class spell_gen_haunted_aura : public AuraScript }; /* 39228 - Argussian Compass - 60218 - Essence of Gossamer */ + 60218 - Essence of Gossamer + 64765 - The General's Heart */ class spell_gen_absorb0_hitlimit1 : public AuraScript { PrepareAuraScript(spell_gen_absorb0_hitlimit1); - uint32 limit; - bool Load() override { // Max absorb stored in 1 dummy effect - limit = GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + _limit = GetSpellInfo()->Effects[EFFECT_1].CalcValue(); return true; } void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& absorbAmount) { - absorbAmount = std::min(limit, absorbAmount); + absorbAmount = std::min(_limit, absorbAmount); } void Register() override { OnEffectAbsorb += AuraEffectAbsorbFn(spell_gen_absorb0_hitlimit1::Absorb, EFFECT_0); } + +private: + uint32 _limit; }; enum AdaptiveWarding From 806d4962cf7881124e0fbfb20f7db69f55dca0cb Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 27 Aug 2024 17:26:05 -0300 Subject: [PATCH 15/46] fix(Scripts/Spells): L1 Arcane Charge should hit 3 targets (#19752) * fix(Scripts/Spells): L1 Arcane Charge should hit 3 targets * Daily Nitpicks --- data/sql/updates/pending_db_world/rev_1724722289062405500.sql | 4 ++++ src/server/scripts/Spells/spell_generic.cpp | 1 + 2 files changed, 5 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1724722289062405500.sql diff --git a/data/sql/updates/pending_db_world/rev_1724722289062405500.sql b/data/sql/updates/pending_db_world/rev_1724722289062405500.sql new file mode 100644 index 000000000..0681e4e6d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1724722289062405500.sql @@ -0,0 +1,4 @@ +-- +DELETE FROM `spell_script_names` WHERE `spell_id` = 41357; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(41357, 'spell_gen_select_target_count_15_3'); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 2f3765c91..42a12e526 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -5347,6 +5347,7 @@ void AddSC_generic_spell_scripts() RegisterSpellScript(spell_gen_area_aura_select_players_and_caster); RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_15_1", TARGET_UNIT_SRC_AREA_ENEMY, 1); RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_15_2", TARGET_UNIT_SRC_AREA_ENEMY, 2); + RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_15_3", TARGET_UNIT_SRC_AREA_ENEMY, 3); RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_15_5", TARGET_UNIT_SRC_AREA_ENEMY, 5); RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_7_1", TARGET_UNIT_SRC_AREA_ENTRY, 1); RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_24_1", TARGET_UNIT_CONE_ENEMY_24, 1); From 2ae22bdd7b71f6fed6c0fbb4e13c8a674aff7670 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Aug 2024 20:26:38 +0000 Subject: [PATCH 16/46] chore(DB): import pending files Referenced commit(s): 53e0779ae82332ba965723a6c2d08e5f89260577 --- .../rev_1724722289062405500.sql => db_world/2024_08_27_03.sql} | 1 + .../rev_1724764338252798941.sql => db_world/2024_08_27_04.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1724722289062405500.sql => db_world/2024_08_27_03.sql} (80%) rename data/sql/updates/{pending_db_world/rev_1724764338252798941.sql => db_world/2024_08_27_04.sql} (79%) diff --git a/data/sql/updates/pending_db_world/rev_1724722289062405500.sql b/data/sql/updates/db_world/2024_08_27_03.sql similarity index 80% rename from data/sql/updates/pending_db_world/rev_1724722289062405500.sql rename to data/sql/updates/db_world/2024_08_27_03.sql index 0681e4e6d..0df605514 100644 --- a/data/sql/updates/pending_db_world/rev_1724722289062405500.sql +++ b/data/sql/updates/db_world/2024_08_27_03.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_27_02 -> 2024_08_27_03 -- DELETE FROM `spell_script_names` WHERE `spell_id` = 41357; INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES diff --git a/data/sql/updates/pending_db_world/rev_1724764338252798941.sql b/data/sql/updates/db_world/2024_08_27_04.sql similarity index 79% rename from data/sql/updates/pending_db_world/rev_1724764338252798941.sql rename to data/sql/updates/db_world/2024_08_27_04.sql index d35775f79..fbca7ecd1 100644 --- a/data/sql/updates/pending_db_world/rev_1724764338252798941.sql +++ b/data/sql/updates/db_world/2024_08_27_04.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_27_03 -> 2024_08_27_04 -- DELETE FROM `spell_script_names` WHERE `spell_id` = 64765; INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (64765, 'spell_gen_absorb0_hitlimit1'); From 7e2ffc2db8010856c4e5b8b9108323f465dd0be1 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 27 Aug 2024 17:28:09 -0300 Subject: [PATCH 17/46] feat(Scripts/Commands): Implement "pct" optional to the damage command (#19745) --- src/server/scripts/Commands/cs_misc.cpp | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 3dbcf6908..b80a48f74 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -2800,7 +2800,7 @@ public: return true; } - static bool HandleDamageCommand(ChatHandler* handler, uint32 damage) + static bool HandleDamageCommand(ChatHandler* handler, uint32 damage, Optional percent) { Unit* target = handler->getSelectedUnit(); if (!target || !handler->GetSession()->GetPlayer()->GetTarget()) @@ -2810,34 +2810,24 @@ public: } if (target->IsPlayer()) - { if (handler->HasLowerSecurity(target->ToPlayer())) - { return false; - } - } - if (!target->IsAlive()) - { + if (!target->IsAlive() || !damage) return true; - } - - if (!damage) - { - return true; - } if (target->GetTypeId() == TYPEID_UNIT && handler->GetSession()->GetSecurity() == SEC_CONSOLE) // pussywizard - { target->ToCreature()->LowerPlayerDamageReq(target->GetMaxHealth()); - } + + if (percent) + if (StringStartsWith("pct", *percent)) + if (damage <= 100) + damage = target->CountPctFromMaxHealth(damage); Unit::DealDamage(handler->GetSession()->GetPlayer(), target, damage, nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false, true); if (target != handler->GetSession()->GetPlayer()) - { handler->GetSession()->GetPlayer()->SendAttackStateUpdate(HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0); - } return true; } From 77c06afb614d05cd8605ec312fc867a020286d24 Mon Sep 17 00:00:00 2001 From: daobashun <49193927+fangshun2004@users.noreply.github.com> Date: Wed, 28 Aug 2024 04:40:17 +0800 Subject: [PATCH 18/46] fix(DB/Creature): Added SmartAi to the creature "Warlord Zim'bo" (26544). (#19731) * Add SmartAi * fix error * fix error --- .../rev_1724552033443919200.sql | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1724552033443919200.sql diff --git a/data/sql/updates/pending_db_world/rev_1724552033443919200.sql b/data/sql/updates/pending_db_world/rev_1724552033443919200.sql new file mode 100644 index 000000000..d17be2def --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1724552033443919200.sql @@ -0,0 +1,22 @@ +-- Warlord Zim'bo smart ai +SET @ENTRY := 26544; +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `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 +(@ENTRY, 0, 0, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'On aggro - Self: Talk 0 to invoker'), +(@ENTRY, 0, 1, 0, 8, 0, 100, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'On any spell hit - Self: Talk 1 to invoker'), +(@ENTRY, 0, 2, 0, 2, 0, 100, 1, 0, 80, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Warlord Zim\'bo - Between 0-80% Health - Say Line 2 (No Repeat)'), +(@ENTRY, 0, 3, 0, 2, 0, 100, 1, 0, 60, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Warlord Zim\'bo - Between 0-60% Health - Say Line 3 (No Repeat)'), +(@ENTRY, 0, 4, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'On death - Self: Talk 4 to invoker'), +(@ENTRY, 0, 5, 0, 0, 0, 100, 0, 30000, 30000, 30000, 30000, 0, 0, 11, 3551, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Warlord Zim\'bo - In Combat - Cast \'Skull Crack\''), +(@ENTRY, 0, 6, 0, 0, 0, 100, 0, 2000, 4000, 2000, 4000, 0, 0, 11, 52283, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Warlord Zim\'bo - In Combat - Cast \'Warlord Roar\''), +(@ENTRY, 0, 7, 0, 5, 0, 100, 0, 0, 0, 1, 0, 0, 0, 1, 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Warlord Zim\'bo - On Killed Unit - Say Line 5'); + +DELETE FROM `creature_text` WHERE `CreatureID` = 26544; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(26544, 0, 0, 'For Drak\'Tharon!', 12, 0, 100, 0, 0, 0, 27331, 0, 'Warlord Zim\'bo'), +(26544, 1, 0, 'Zim\'bo must live to slay our betrayer!', 12, 0, 100, 0, 0, 0, 27332, 0, 'Warlord Zim\'bo'), +(26544, 2, 0, 'Zim\'bo cannot be stopped! Da keep must be liberated!', 12, 0, 100, 0, 0, 0, 27333, 0, 'Warlord Zim\'bo'), +(26544, 3, 0, 'You be dyin\' along with all dese scourge!', 12, 0, 100, 0, 0, 0, 27334, 0, 'Warlord Zim\'bo'), +(26544, 4, 0, 'Betrayed by one of our own we were. Disgraced....', 12, 0, 100, 0, 0, 0, 27335, 0, 'Warlord Zim\'bo'), +(26544, 5, 0, 'Ah, more essence to capture...', 12, 0, 100, 0, 0, 0, 27336, 0, 'Warlord Zim\'bo'); From dccec8764408a58eb01ba85827f8686b196d370c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Aug 2024 20:41:12 +0000 Subject: [PATCH 19/46] chore(DB): import pending files Referenced commit(s): 77c06afb614d05cd8605ec312fc867a020286d24 --- .../rev_1724552033443919200.sql => db_world/2024_08_27_05.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1724552033443919200.sql => db_world/2024_08_27_05.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1724552033443919200.sql b/data/sql/updates/db_world/2024_08_27_05.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1724552033443919200.sql rename to data/sql/updates/db_world/2024_08_27_05.sql index d17be2def..a36fd6b21 100644 --- a/data/sql/updates/pending_db_world/rev_1724552033443919200.sql +++ b/data/sql/updates/db_world/2024_08_27_05.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_27_04 -> 2024_08_27_05 -- Warlord Zim'bo smart ai SET @ENTRY := 26544; UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; From 5ffbfdd5d6a440288e01edbd4a57450ea7f51a38 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Wed, 28 Aug 2024 07:13:06 -0400 Subject: [PATCH 20/46] fix(Core/Creature): Fix grace period for can attack check. (#19763) Init. --- src/server/game/Entities/Creature/Creature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 6cb389301..ff9f03c17 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2629,7 +2629,7 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool skipDistCheck) const return false; // cannot attack if is during 5 second grace period, unless being attacked - if (m_respawnedTime && (GameTime::GetGameTime().count() - m_respawnedTime) < 5 && victim->getAttackers().empty()) + if (m_respawnedTime && (GameTime::GetGameTime().count() - m_respawnedTime) < 5 && !GetLastDamagedTime()) { return false; } From b595586bf053e6638b3e11edca0d97094cd7332d Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Wed, 28 Aug 2024 07:13:42 -0400 Subject: [PATCH 21/46] refactor(Core/SpellMgr): Remove nested ifs for binary evaluation. (#19762) * Init. Co-Authored-By: Anton Popovichenko * Whitespace. * Tiny nitpick. Co-Authored-By: Anton Popovichenko * Tiny nitpick.* Today Bench learns the difference between break and continue. Co-Authored-By: Anton Popovichenko * Parentheses warnings. * Apply suggestion. Co-Authored-By: Anton Popovichenko --------- Co-authored-by: Anton Popovichenko --- src/server/game/Spells/SpellMgr.cpp | 32 +++++++++++++++++++---------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 3511aa90e..2e3c2d2ce 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3065,17 +3065,27 @@ void SpellMgr::LoadSpellInfoCustomAttributes() continue; [[fallthrough]]; /// @todo: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked. default: - if (spellInfo->Effects[j].CalcValue() || ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) && !spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))) - if (spellInfo->Id != 69649 && spellInfo->Id != 71056 && spellInfo->Id != 71057 && spellInfo->Id != 71058 && spellInfo->Id != 73061 && spellInfo->Id != 73062 && spellInfo->Id != 73063 && spellInfo->Id != 73064) // Sindragosa Frost Breath - if (spellInfo->SpellFamilyName != SPELLFAMILY_MAGE || !(spellInfo->SpellFamilyFlags[0] & 0x20)) // frostbolt - if (spellInfo->Id != 55095) // frost fever - if (spellInfo->SpellFamilyName != SPELLFAMILY_WARLOCK || !(spellInfo->SpellFamilyFlags[1] & 0x40000)) // Haunt - if (spellInfo->SpellFamilyName != SPELLFAMILY_WARLOCK || !(spellInfo->SpellFamilyFlags[0] & 0x4000)) // Drain Soul - { - spellInfo->AttributesCu |= SPELL_ATTR0_CU_BINARY_SPELL; - break; - } - continue; + if (!(spellInfo->Effects[j].CalcValue() && + ((spellInfo->Effects[j].Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) && + !spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES)))) + continue; + + if (spellInfo->Id == 69649 || spellInfo->Id == 71056 || spellInfo->Id == 71057 || spellInfo->Id == 71058 || + spellInfo->Id == 73061 || spellInfo->Id == 73062 || spellInfo->Id == 73063 || spellInfo->Id == 73064) + continue; + + if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->SpellFamilyFlags[0] & 0x20)) // Frostbolt + continue; + + if (spellInfo->Id == 55095) // Frost Fever + continue; + + if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && + ((spellInfo->SpellFamilyFlags[1] & 0x40000) || (spellInfo->SpellFamilyFlags[0] & 0x4000))) // Haunt/Drain Soul + continue; + + spellInfo->AttributesCu |= SPELL_ATTR0_CU_BINARY_SPELL; + break; } } } From 9144031ed92e0a1b48f9c7fb2c25ed5438d1fc62 Mon Sep 17 00:00:00 2001 From: Anton Popovichenko Date: Wed, 28 Aug 2024 13:14:08 +0200 Subject: [PATCH 22/46] fix(Core/Pool): Fix degradation of pools over time (#19750) --- src/server/game/Pools/PoolMgr.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index 247cbf343..ed4378aa3 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -330,7 +330,7 @@ void PoolGroup::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 trig // Triggering object is marked as spawned at this time and can be also rolled (respawn case) // so this need explicit check for this case - if (roll < 0 && (/*obj.guid == triggerFrom ||*/ !spawns.IsActiveObject(obj.guid))) + if (roll < 0 && (obj.guid == triggerFrom || !spawns.IsActiveObject(obj.guid))) { rolledObjects.push_back(obj); break; @@ -340,9 +340,9 @@ void PoolGroup::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 trig if (!EqualChanced.empty() && rolledObjects.empty()) { - std::copy_if(EqualChanced.begin(), EqualChanced.end(), std::back_inserter(rolledObjects), [/*triggerFrom, */&spawns](PoolObject const& object) + std::copy_if(EqualChanced.begin(), EqualChanced.end(), std::back_inserter(rolledObjects), [triggerFrom, &spawns](PoolObject const& object) { - return /*object.guid == triggerFrom ||*/ !spawns.IsActiveObject(object.guid); + return object.guid == triggerFrom || !spawns.IsActiveObject(object.guid); }); Acore::Containers::RandomResize(rolledObjects, count); @@ -527,16 +527,18 @@ void PoolGroup::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 // Method that does the respawn job on the specified creature template <> -void PoolGroup::ReSpawn1Object(PoolObject* /*obj*/) +void PoolGroup::ReSpawn1Object(PoolObject* obj) { - // Creature is still on map, nothing to do + Despawn1Object(obj->guid); + Spawn1Object(obj); } // Method that does the respawn job on the specified gameobject template <> -void PoolGroup::ReSpawn1Object(PoolObject* /*obj*/) +void PoolGroup::ReSpawn1Object(PoolObject* obj) { - // Gameobject is still on map, nothing to do + Despawn1Object(obj->guid); + Spawn1Object(obj); } // Nothing to do for a child Pool From e573b5dddf2af29af783c8e5563476d2cd1eaa0a Mon Sep 17 00:00:00 2001 From: Carriola-wotlk <148633595+Carriola-wotlk@users.noreply.github.com> Date: Wed, 28 Aug 2024 13:14:46 +0200 Subject: [PATCH 23/46] fix(DB/Creature): Quest Therylune's Escape - party completion issue (#19734) --- data/sql/updates/pending_db_world/2024_08_25_01.sql | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 data/sql/updates/pending_db_world/2024_08_25_01.sql diff --git a/data/sql/updates/pending_db_world/2024_08_25_01.sql b/data/sql/updates/pending_db_world/2024_08_25_01.sql new file mode 100644 index 000000000..e5536c76c --- /dev/null +++ b/data/sql/updates/pending_db_world/2024_08_25_01.sql @@ -0,0 +1,6 @@ +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 3584) AND (`source_type` = 0) AND (`id` IN (2, 3, 9, 10)); +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 +(3584, 0, 2, 3, 40, 0, 100, 0, 20, 3584, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Therylune - On WP 20 - Say Line 1'), +(3584, 0, 3, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 15, 945, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Therylune - On WP 20 - Quest Credit'), +(3584, 0, 9, 10, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Therylune - On Quest \'Therylune\'s Escape\' Taken - Remove npc flag'), +(3584, 0, 10, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Therylune - On Quest \'Therylune\'s Escape\' Taken - Store Targetlist'); From 3e54dd052637b5ef7820f20320420851bb8ee195 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 28 Aug 2024 11:15:09 +0000 Subject: [PATCH 24/46] chore(DB): import pending files Referenced commit(s): 9144031ed92e0a1b48f9c7fb2c25ed5438d1fc62 --- .../2024_08_25_01.sql => db_world/2024_08_28_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/2024_08_25_01.sql => db_world/2024_08_28_00.sql} (96%) diff --git a/data/sql/updates/pending_db_world/2024_08_25_01.sql b/data/sql/updates/db_world/2024_08_28_00.sql similarity index 96% rename from data/sql/updates/pending_db_world/2024_08_25_01.sql rename to data/sql/updates/db_world/2024_08_28_00.sql index e5536c76c..43d39fc40 100644 --- a/data/sql/updates/pending_db_world/2024_08_25_01.sql +++ b/data/sql/updates/db_world/2024_08_28_00.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_27_05 -> 2024_08_28_00 DELETE FROM `smart_scripts` WHERE (`entryorguid` = 3584) AND (`source_type` = 0) AND (`id` IN (2, 3, 9, 10)); 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 (3584, 0, 2, 3, 40, 0, 100, 0, 20, 3584, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Therylune - On WP 20 - Say Line 1'), From 3463bdd0b42fe7b6da7bad424e9b59851498b11d Mon Sep 17 00:00:00 2001 From: Carriola-wotlk <148633595+Carriola-wotlk@users.noreply.github.com> Date: Wed, 28 Aug 2024 13:15:18 +0200 Subject: [PATCH 25/46] fix(DB/Creature): Quest Escape through Force - party completion issue (#19733) party completion fixed --- data/sql/updates/pending_db_world/2024_08_25_00.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 data/sql/updates/pending_db_world/2024_08_25_00.sql diff --git a/data/sql/updates/pending_db_world/2024_08_25_00.sql b/data/sql/updates/pending_db_world/2024_08_25_00.sql new file mode 100644 index 000000000..0a28e584f --- /dev/null +++ b/data/sql/updates/pending_db_world/2024_08_25_00.sql @@ -0,0 +1,5 @@ +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 3692) AND (`source_type` = 0) AND (`id` IN (0, 3, 11)); +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 +(3692, 0, 0, 1, 19, 0, 100, 512, 994, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Volcor - On Quest \'Escape Through Force\' Taken - Store Targetlist'), +(3692, 0, 3, 4, 19, 0, 100, 512, 995, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Volcor - On Quest \'Escape Through Stealth\' Taken - Store Targetlist'), +(3692, 0, 11, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 11, 6298, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Volcor - On Waypoint 2 Reached (Path 369200) - Cast Spell \'Form of the Moonstalker\''); From bda8de3eb6ef2cc24e8a8ebb59a892be1b03610a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 28 Aug 2024 11:15:39 +0000 Subject: [PATCH 26/46] chore(DB): import pending files Referenced commit(s): e573b5dddf2af29af783c8e5563476d2cd1eaa0a --- .../2024_08_25_00.sql => db_world/2024_08_28_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/2024_08_25_00.sql => db_world/2024_08_28_01.sql} (96%) diff --git a/data/sql/updates/pending_db_world/2024_08_25_00.sql b/data/sql/updates/db_world/2024_08_28_01.sql similarity index 96% rename from data/sql/updates/pending_db_world/2024_08_25_00.sql rename to data/sql/updates/db_world/2024_08_28_01.sql index 0a28e584f..703c0021d 100644 --- a/data/sql/updates/pending_db_world/2024_08_25_00.sql +++ b/data/sql/updates/db_world/2024_08_28_01.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_28_00 -> 2024_08_28_01 DELETE FROM `smart_scripts` WHERE (`entryorguid` = 3692) AND (`source_type` = 0) AND (`id` IN (0, 3, 11)); 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 (3692, 0, 0, 1, 19, 0, 100, 512, 994, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Volcor - On Quest \'Escape Through Force\' Taken - Store Targetlist'), From 375dfae983e968e9944bf92d3f8c92746bd6f8d6 Mon Sep 17 00:00:00 2001 From: Carriola-wotlk <148633595+Carriola-wotlk@users.noreply.github.com> Date: Wed, 28 Aug 2024 13:16:19 +0200 Subject: [PATCH 27/46] fix(DB/Creature):Quest Precarious Predicament does not complete (#19707) * fix(DB/Creature):Quest Precarious Predicament does not complete * refactor: DELETE statement added before insert --- data/sql/updates/pending_db_world/2024_08_23_00.sql | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 data/sql/updates/pending_db_world/2024_08_23_00.sql diff --git a/data/sql/updates/pending_db_world/2024_08_23_00.sql b/data/sql/updates/pending_db_world/2024_08_23_00.sql new file mode 100644 index 000000000..af3ec1fc0 --- /dev/null +++ b/data/sql/updates/pending_db_world/2024_08_23_00.sql @@ -0,0 +1,12 @@ +UPDATE `smart_scripts` +SET `link` = 28 +WHERE `entryorguid` = 9520 AND `source_type` = 0 AND `id` = 3; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 9520) AND (`source_type` = 0) AND (`id` IN (28)); +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 +(9520, 0, 28, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'On Quest Accept - Store Party Targetlist'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 952001) AND (`source_type` = 9) AND (`id` IN (11, 12)); +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 +(952001, 9, 11, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 15, 4121, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Script9 - Complete Quest'), +(952001, 9, 12, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Script9 - Despawn'); From f2e1a9767350a5fb49c9bc2c973a9f95de9466e8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 28 Aug 2024 11:16:35 +0000 Subject: [PATCH 28/46] chore(DB): import pending files Referenced commit(s): bda8de3eb6ef2cc24e8a8ebb59a892be1b03610a --- .../2024_08_23_00.sql => db_world/2024_08_28_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/2024_08_23_00.sql => db_world/2024_08_28_02.sql} (97%) diff --git a/data/sql/updates/pending_db_world/2024_08_23_00.sql b/data/sql/updates/db_world/2024_08_28_02.sql similarity index 97% rename from data/sql/updates/pending_db_world/2024_08_23_00.sql rename to data/sql/updates/db_world/2024_08_28_02.sql index af3ec1fc0..5c9e45c56 100644 --- a/data/sql/updates/pending_db_world/2024_08_23_00.sql +++ b/data/sql/updates/db_world/2024_08_28_02.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_28_01 -> 2024_08_28_02 UPDATE `smart_scripts` SET `link` = 28 WHERE `entryorguid` = 9520 AND `source_type` = 0 AND `id` = 3; From 2f850974135c39e392912512aa44b5cde5bd4b13 Mon Sep 17 00:00:00 2001 From: Grimdhex <176165533+Grimdhex@users.noreply.github.com> Date: Wed, 28 Aug 2024 13:17:24 +0200 Subject: [PATCH 29/46] docs(Core): improve several functions documentation (#19677) * initial release * fix reviews * fix some typo and add new documetations for MotionMaster * new update and fix the cli-codestyle * fix typo * fix reviews --- src/server/game/AI/CoreAI/UnitAI.cpp | 3 + src/server/game/AI/CoreAI/UnitAI.h | 52 +++++++------ .../game/Entities/Creature/Creature.cpp | 60 ++++++++++----- src/server/game/Entities/Creature/Creature.h | 53 +++++++------ src/server/game/Entities/Unit/Unit.cpp | 26 ++++++- src/server/game/Entities/Unit/Unit.h | 11 +-- src/server/game/Movement/MotionMaster.cpp | 77 +++++++++++++++---- 7 files changed, 193 insertions(+), 89 deletions(-) diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 9f08ceb37..5240c88e5 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -253,6 +253,9 @@ SpellCastResult UnitAI::DoCastAOE(uint32 spellId, bool triggered) return me->CastSpell((Unit*)nullptr, spellId, triggered); } +/** + * @brief Cast the spell on a random unit from the threat list + */ SpellCastResult UnitAI::DoCastRandomTarget(uint32 spellId, uint32 threatTablePosition, float dist, bool playerOnly, bool triggered, bool withTank) { if (Unit* target = SelectTarget(SelectTargetMethod::Random, threatTablePosition, dist, playerOnly, withTank)) diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index 2f9bba321..0f7c50163 100644 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -198,14 +198,14 @@ public: virtual ~UnitAI() {} virtual bool CanAIAttack(Unit const* /*target*/) const { return true; } - virtual void AttackStart(Unit* /*target*/); + virtual void AttackStart(Unit* /*target*/); /// @brief Use to start attacking a target. Called just before JustEngagedWith() virtual void UpdateAI(uint32 /*diff*/) = 0; virtual void InitializeAI() { if (!me->isDead()) Reset(); } virtual void Reset() {}; - // Called when unit is charmed + /// @brief Called when unit is charmed virtual void OnCharmed(bool apply) = 0; // Pass parameters between AI @@ -258,16 +258,16 @@ public: } } - // Select the best (up to) targets (in order) from the threat list that fulfill the following: - // - Not among the first entries in order (or SelectTargetMethod::MaxThreat order, - // if is SelectTargetMethod::Random). - // - Within at most yards (if dist > 0.0f) - // - At least - yards away (if dist < 0.0f) - // - Is a player (if playerOnly = true) - // - Not the current tank (if withTank = false) - // - Has aura with ID (if aura > 0) - // - Does not have aura with ID - (if aura < 0) - // The resulting targets are stored in (which is cleared first). + /** @brief Select the best (up to) targets (in order) from the threat list that fulfill the following: + * - Not among the first entries in order (or SelectTargetMethod::MaxThreat order, if is SelectTargetMethod::Random). + * - Within at most yards (if dist > 0.0f) + * - At least - yards away (if dist < 0.0f) + * - Is a player (if playerOnly = true) + * - Not the current tank (if withTank = false) + * - Has aura with ID (if aura > 0) + * - Does not have aura with ID - (if aura < 0) + * The resulting targets are stored in (which is cleared first). + */ void SelectTargetList(std::list& targetList, uint32 num, SelectTargetMethod targetType, uint32 position = 0, float dist = 0.0f, bool playerOnly = false, bool withTank = true, int32 aura = 0); // Select the best (up to) targets (in order) satisfying from the threat list and stores them in (which is cleared first). @@ -345,7 +345,7 @@ public: /** * @brief Called when the unit enters combat - * (NOTE: Creature engage logic should NOT be here, but in JustEngagedWith, which happens once threat is established!) + * @note NOTE: Creature engage logic should NOT be here, but in JustEngagedWith, which happens once threat is established!) * * @todo Never invoked right now. Preparation for Combat Threat refactor */ @@ -358,28 +358,30 @@ public: */ virtual void JustExitedCombat() { } - // Called at any Damage to any victim (before damage apply) + /// @brief Called at any Damage to any victim (before damage apply) virtual void DamageDealt(Unit* /*victim*/, uint32& /*damage*/, DamageEffectType /*damageType*/) { } - // Called at any Damage from any attacker (before damage apply) - // Note: it for recalculation damage or special reaction at damage - // for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also + /** @brief Called at any Damage from any attacker (before damage apply) + * + * @note It use for recalculation damage or special reaction at damage + * for attack reaction use AttackedBy called for non DOT damage in Unit::DealDamage also + */ virtual void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) {} - // Called when the creature receives heal + /// @brief Called when the creature receives heal virtual void HealReceived(Unit* /*done_by*/, uint32& /*addhealth*/) {} - // Called when the creature power updates + /// @brief Called when the creature power updates virtual void OnPowerUpdate(Powers /*power*/, int32 /*updateVal*/, int32 /*gain*/, uint32 /*currPower*/) {} - // Called when the unit heals + /// @brief Called when the unit heals virtual void HealDone(Unit* /*done_to*/, uint32& /*addhealth*/) {} - // Called during damage calculations + /// @brief Called during damage calculations virtual void OnCalculateMeleeDamageReceived(uint32& /*damage*/, Unit* /*attacker*/) {} virtual void OnCalculateSpellDamageReceived(int32& /*damage*/, Unit* /*attacker*/) {} - // Called during calculation when receiving periodic healing or damage (DoT or HoT) + /// @brief Called during calculation when receiving periodic healing or damage (DoT or HoT) virtual void OnCalculatePeriodicTickReceived(uint32& /*damage*/, Unit* /*attacker*/) {} void AttackStartCaster(Unit* victim, float dist); @@ -387,13 +389,13 @@ public: SpellCastResult DoAddAuraToAllHostilePlayers(uint32 spellid); SpellCastResult DoCast(uint32 spellId); SpellCastResult DoCast(Unit* victim, uint32 spellId, bool triggered = false); - SpellCastResult DoCastSelf(uint32 spellId, bool triggered = false) { return DoCast(me, spellId, triggered); } + SpellCastResult DoCastSelf(uint32 spellId, bool triggered = false) { return DoCast(me, spellId, triggered); } /// @brief To specify the caster as target if the spell is self-cast SpellCastResult DoCastToAllHostilePlayers(uint32 spellid, bool triggered = false); SpellCastResult DoCastVictim(uint32 spellId, bool triggered = false); SpellCastResult DoCastAOE(uint32 spellId, bool triggered = false); SpellCastResult DoCastRandomTarget(uint32 spellId, uint32 threatTablePosition = 0, float dist = 0.0f, bool playerOnly = true, bool triggered = false, bool withTank = true); - // Cast spell on the top threat target, which may not be the current victim. + /// @brief Cast spell on the top threat target, which may not be the current victim. SpellCastResult DoCastMaxThreat(uint32 spellId, uint32 threatTablePosition = 0, float dist = 0.0f, bool playerOnly = true, bool triggered = false); float DoGetSpellMaxRange(uint32 spellId, bool positive = false); @@ -405,7 +407,7 @@ public: static AISpellInfoType* AISpellInfo; static void FillAISpellInfo(); - // Called when a summon reaches a waypoint or point movement finished. + /// @brief Called when a summon reaches a waypoint or point movement finished. virtual void SummonMovementInform(Creature* /*creature*/, uint32 /*motionType*/, uint32 /*point*/) { } virtual void sGossipHello(Player* /*player*/) {} diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index ff9f03c17..cae76f330 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1945,11 +1945,21 @@ bool Creature::CanStartAttack(Unit const* who) const return IsWithinLOSInMap(who); } -void Creature::setDeathState(DeathState s, bool despawn) +/** + * @brief A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned. The cycle follows the next order: + * - Alive: The creature is alive and has spawned in the world + * - JustDied: The creature has just died. This is the state just before his body appeared + * - Corpse: The creature has been removed from the world, and this corpse has been spawned + * - JustRespawned: The creature has just respawned. Follow when the corpse disappears and the respawn timer is finished + * + * @param state Specify one of 4 states above + * @param despawn Despawn the creature immediately, without waiting for any movement to finish + */ +void Creature::setDeathState(DeathState state, bool despawn) { - Unit::setDeathState(s, despawn); + Unit::setDeathState(state, despawn); - if (s == DeathState::JustDied) + if (state == DeathState::JustDied) { _lastDamagedTime.reset(); @@ -1960,10 +1970,10 @@ void Creature::setDeathState(DeathState s, bool despawn) if (GetMap()->IsDungeon() || isWorldBoss() || GetCreatureTemplate()->rank >= CREATURE_ELITE_ELITE) SaveRespawnTime(); - SetTarget(); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState) + SetTarget(); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState) ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE); - Dismount(); // if creature is mounted on a virtual mount, remove it at death + Dismount(); // if creature is mounted on a virtual mount, remove it at death setActive(false); @@ -1985,10 +1995,8 @@ void Creature::setDeathState(DeathState s, bool despawn) Unit::setDeathState(DeathState::Corpse, despawn); } - else if (s == DeathState::JustRespawned) + else if (state == DeathState::JustRespawned) { - //if (IsPet()) - // setActive(true); SetFullHealth(); SetLootRecipient(nullptr); ResetPlayerDamageReq(); @@ -2016,6 +2024,9 @@ void Creature::setDeathState(DeathState s, bool despawn) } } +/** + * @param force Force the respawn by killing the creature. + */ void Creature::Respawn(bool force) { if (force) @@ -2040,7 +2051,7 @@ void Creature::Respawn(bool force) } bool allowed = !IsAIEnabled || AI()->CanRespawn(); // First check if there are any scripts that prevent us respawning - if (!allowed && !force) // Will be rechecked on next Update call + if (!allowed && !force) // Will be rechecked on next Update call return; ObjectGuid dbtableHighGuid = ObjectGuid::Create(m_creatureData ? m_creatureData->id1 : GetEntry(), m_spawnId); @@ -2082,8 +2093,7 @@ void Creature::Respawn(bool force) setDeathState(DeathState::JustRespawned); - // MDic - Acidmanifesto - // Do not override transform auras + // MDic - Acidmanifesto: Do not override transform auras if (GetAuraEffectsByType(SPELL_AURA_TRANSFORM).empty()) { CreatureModel display(GetNativeDisplayId(), GetNativeObjectScale(), 1.0f); @@ -2102,7 +2112,7 @@ void Creature::Respawn(bool force) { //reset the AI to be sure no dirty or uninitialized values will be used till next tick AI()->Reset(); - TriggerJustRespawned = true;//delay event to next tick so all creatures are created on the map before processing + TriggerJustRespawned = true; //delay event to next tick so all creatures are created on the map before processing } uint32 poolid = m_spawnId ? sPoolMgr->IsPartOfAPool(m_spawnId) : 0; @@ -2120,7 +2130,7 @@ void Creature::Respawn(bool force) UpdateObjectVisibility(false); } - else // the master is dead + else // the master is dead { ObjectGuid targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid); if (targetGuid == dbtableHighGuid) // if linking self, never respawn (check delayed to next day) @@ -2148,7 +2158,7 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer) if (IsAlive()) setDeathState(DeathState::JustDied, true); - // Xinef: set new respawn time, ignore corpse decay time... + // Xinef: Set new respawn time, ignore corpse decay time... RemoveCorpse(true); if (forceRespawnTimer > Seconds::zero()) @@ -2194,8 +2204,6 @@ void Creature::InitializeReactState() SetReactState(REACT_PASSIVE); else SetReactState(REACT_AGGRESSIVE); - /*else if (IsCivilian()) - SetReactState(REACT_DEFENSIVE);*/ } bool Creature::HasMechanicTemplateImmunity(uint32 mask) const @@ -2357,8 +2365,7 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim) float range = spellInfo->GetMaxRange(true); float minrange = spellInfo->GetMinRange(true); float dist = GetDistance(victim); - //if (!isInFront(victim, range) && spellInfo->AttributesEx) - // continue; + if (dist > range || dist < minrange) continue; if (spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && HasUnitFlag(UNIT_FLAG_SILENCED)) @@ -2370,7 +2377,9 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim) return nullptr; } -// select nearest hostile unit within the given distance (regardless of threat list). +/** + * @brief Select nearest hostile unit within the given distance (regardless of threat list). + */ Unit* Creature::SelectNearestTarget(float dist, bool playerOnly /* = false */) const { if (dist == 0.0f) @@ -2386,7 +2395,9 @@ Unit* Creature::SelectNearestTarget(float dist, bool playerOnly /* = false */) c return target; } -// select nearest hostile unit within the given attack distance (i.e. distance is ignored if > than ATTACK_DISTANCE), regardless of threat list. +/** + * @brief Select nearest hostile unit within the given attack distance (i.e. distance is ignored if > than ATTACK_DISTANCE), regardless of threat list. + */ Unit* Creature::SelectNearestTargetInAttackDistance(float dist) const { if (dist < ATTACK_DISTANCE) @@ -2780,6 +2791,9 @@ void Creature::SendZoneUnderAttackMessage(Player* attacker) sWorld->SendGlobalMessage(&data, nullptr, (attacker->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE)); } +/** + * @brief Set in combat all units in the dungeon/raid. Affect only units with IsAIEnabled. + */ void Creature::SetInCombatWithZone() { if (IsAIEnabled) @@ -3146,6 +3160,9 @@ bool Creature::IsImmuneToKnockback() const return cinfo && (cinfo->flags_extra & CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK); } +/** + * @brief Enable or disable the creature's walk mode by removing: MOVEMENTFLAG_WALKING. Infom also the client + */ bool Creature::SetWalk(bool enable) { if (!Unit::SetWalk(enable)) @@ -3157,6 +3174,9 @@ bool Creature::SetWalk(bool enable) return true; } +/** + * @brief Enable or disable the creature's fly mode by adding or removing: MOVEMENTFLAG_FLYING. Infom also the client + */ bool Creature::SetDisableGravity(bool disable, bool packetOnly /*= false*/, bool updateAnimationTier /*= true*/) { //! It's possible only a packet is sent but moveflags are not updated diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 877f8e2ec..52f51dcdb 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -40,7 +40,7 @@ class CreatureGroup; // max different by z coordinate for creature aggro reaction #define CREATURE_Z_ATTACK_RANGE 3 -#define MAX_VENDOR_ITEMS 150 // Limitation in 3.x.x item count in SMSG_LIST_INVENTORY +#define MAX_VENDOR_ITEMS 150 // Limitation in 3.x.x item count in SMSG_LIST_INVENTORY class Creature : public Unit, public GridObject, public MovableMapObject { @@ -67,7 +67,7 @@ public: [[nodiscard]] ObjectGuid::LowType GetSpawnId() const { return m_spawnId; } - void Update(uint32 time) override; // overwrited Unit::Update + void Update(uint32 time) override; // overwrited Unit::Update void GetRespawnPosition(float& x, float& y, float& z, float* ori = nullptr, float* dist = nullptr) const; void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; } @@ -88,9 +88,15 @@ public: MovementGeneratorType GetDefaultMovementType() const override { return m_defaultMovementType; } void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; } - void SetReactState(ReactStates st) { m_reactState = st; } + /** + * @brief A creature can have 3 ReactStates : Agressive, Passive, Neutral + * - Agressive : The creature will attack any non friend units in sight + * - Passive : The creature will not attack anyone + * - Neutral : The creature will attack only if attacked + */ + void SetReactState(ReactStates state) { m_reactState = state; } [[nodiscard]] ReactStates GetReactState() const { return m_reactState; } - [[nodiscard]] bool HasReactState(ReactStates state) const { return (m_reactState == state); } + [[nodiscard]] bool HasReactState(ReactStates state) const { return (m_reactState == state); } /// @brief Check if the creature has the specified ReactState void InitializeReactState(); ///// @todo RENAME THIS!!!!! @@ -209,14 +215,14 @@ public: // override WorldObject function for proper name localization [[nodiscard]] std::string const& GetNameForLocaleIdx(LocaleConstant locale_idx) const override; - void setDeathState(DeathState s, bool despawn = false) override; // override virtual Unit::setDeathState + void setDeathState(DeathState s, bool despawn = false) override; // override virtual Unit::setDeathState bool LoadFromDB(ObjectGuid::LowType guid, Map* map, bool allowDuplicate = false) { return LoadCreatureFromDB(guid, map, false, allowDuplicate); } bool LoadCreatureFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true, bool allowDuplicate = false); void SaveToDB(); - // overriden in Pet - virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask); - virtual void DeleteFromDB(); // overriden in Pet + + virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask); // overriden in Pet + virtual void DeleteFromDB(); // overriden in Pet Loot loot; [[nodiscard]] ObjectGuid GetLootRecipientGUID() const { return m_lootRecipient; } @@ -224,7 +230,7 @@ public: [[nodiscard]] ObjectGuid::LowType GetLootRecipientGroupGUID() const { return m_lootRecipientGroup; } [[nodiscard]] Group* GetLootRecipientGroup() const; [[nodiscard]] bool hasLootRecipient() const { return m_lootRecipient || m_lootRecipientGroup; } - bool isTappedBy(Player const* player) const; // return true if the creature is tapped by the player or a member of his party. + bool isTappedBy(Player const* player) const; // return true if the creature is tapped by the player or a member of his party. [[nodiscard]] bool CanGeneratePickPocketLoot() const; void SetPickPocketLootTime(); void ResetPickPocketLootTime() { lootPickPocketRestoreTime = 0; } @@ -266,7 +272,7 @@ public: bool _IsTargetAcceptable(Unit const* target) const; [[nodiscard]] bool CanIgnoreFeignDeath() const { return (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_IGNORE_FEIGN_DEATH) != 0; } - // pussywizard: updated at faction change, disable move in line of sight if actual faction is not hostile to anyone + // pussywizard: Updated at faction change, disable move in line of sight if actual faction is not hostile to anyone void UpdateMoveInLineOfSightState(); bool IsMoveInLineOfSightDisabled() { return m_moveInLineOfSightDisabled; } bool IsMoveInLineOfSightStrictlyDisabled() { return m_moveInLineOfSightStrictlyDisabled; } @@ -299,8 +305,8 @@ public: void DoImmediateBoundaryCheck() { m_boundaryCheckTime = 0; } - uint32 m_groupLootTimer; // (msecs)timer used for group loot - uint32 lootingGroupLowGUID; // used to find group which is looting corpse + uint32 m_groupLootTimer; // (msecs)timer used for group loot + uint32 lootingGroupLowGUID; // used to find group which is looting corpse void SendZoneUnderAttackMessage(Player* attacker); @@ -310,8 +316,8 @@ public: [[nodiscard]] bool hasInvolvedQuest(uint32 quest_id) const override; bool isRegeneratingHealth() { return m_regenHealth; } - void SetRegeneratingHealth(bool c) { m_regenHealth = c; } - void SetRegeneratingPower(bool c) { m_regenPower = c; } + void SetRegeneratingHealth(bool enable) { m_regenHealth = enable; } + void SetRegeneratingPower(bool enable) { m_regenPower = enable; } [[nodiscard]] virtual uint8 GetPetAutoSpellSize() const { return MAX_SPELL_CHARM; } [[nodiscard]] virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const { @@ -398,20 +404,17 @@ public: /** * @brief Helper to resume chasing current victim. - * - * */ + */ void ResumeChasingVictim() { GetMotionMaster()->MoveChase(GetVictim()); }; /** * @brief Returns true if the creature is able to cast the spell. - * - * */ + */ bool CanCastSpell(uint32 spellID) const; /** - * @brief Helper to get the creature's summoner GUID, if it is a summon - * - * */ + * @brief Helper to get the creature's summoner GUID, if it is a summon + */ [[nodiscard]] ObjectGuid GetSummonerGUID() const; // Used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims @@ -474,11 +477,11 @@ protected: bool DisableReputationGain; - CreatureTemplate const* m_creatureInfo; // in difficulty mode > 0 can different from sObjectMgr->GetCreatureTemplate(GetEntry()) + CreatureTemplate const* m_creatureInfo; // in difficulty mode > 0 can different from sObjectMgr->GetCreatureTemplate(GetEntry()) CreatureData const* m_creatureData; float m_detectionDistance; - uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable + uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable [[nodiscard]] bool IsInvisibleDueToDespawn() const override; bool CanAlwaysSee(WorldObject const* obj) const override; @@ -489,11 +492,11 @@ private: [[nodiscard]] bool CanPeriodicallyCallForAssistance() const; - //WaypointMovementGenerator vars + // WaypointMovementGenerator variable uint32 m_waypointID; uint32 m_path_id; - //Formation var + // Formation variable CreatureGroup* m_formation; bool TriggerJustRespawned; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f3aa3addf..4884f22e8 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1141,6 +1141,9 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage return damage; } + /** + * @brief Interrupt the unit cast for all the current spells + */ void Unit::CastStop(uint32 except_spellid, bool withInstant) { for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) @@ -3034,6 +3037,10 @@ void Unit::SendMeleeAttackStart(Unit* victim, Player* sendTo) LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTART"); } +/** + * @brief Send to the client SMSG_ATTACKSTOP but doesn't clear UNIT_STATE_MELEE_ATTACKING on server side + * or interrupt spells. Unless you know exactly what you're doing, use AttackStop() or RemoveAllAttackers() instead + */ void Unit::SendMeleeAttackStop(Unit* victim) { // pussywizard: calling SendMeleeAttackStop without clearing UNIT_STATE_MELEE_ATTACKING and then AttackStart the same player may spoil npc rotating! @@ -10331,6 +10338,10 @@ bool Unit::Attack(Unit* victim, bool meleeAttack) return true; } +/** + * @brief Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, + * Interrupt current spell, AI assistance, and call SendMeleeAttackStop() to the client + */ bool Unit::AttackStop() { if (!m_attacking) @@ -10407,6 +10418,9 @@ bool Unit::isAttackingPlayer() const return false; } +/** + * @brief Remove all units in m_attackers list and send them AttackStop() + */ void Unit::RemoveAllAttackers() { while (!m_attackers.empty()) @@ -16600,7 +16614,7 @@ void Unit::ResumeMovement(uint32 timer /* = 0*/, uint8 slot /* = 0*/) movementGenerator->Resume(timer); } -void Unit::StopMovingOnCurrentPos() // pussywizard +void Unit::StopMovingOnCurrentPos() { ClearUnitState(UNIT_STATE_MOVING); @@ -20487,6 +20501,12 @@ bool Unit::SetSwim(bool enable) return true; } +/** + * @brief Add the movement flag: MOVEMENTFLAGCAN_FLY. Generaly only use by players, allowing + * them to fly by pressing space for example. For creatures, please look for DisableGravity(). + * + * Doesn't inform the client. + */ bool Unit::SetCanFly(bool enable, bool /*packetOnly = false */) { if (enable == HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY)) @@ -20505,6 +20525,10 @@ bool Unit::SetCanFly(bool enable, bool /*packetOnly = false */) return true; } +/** + * @brief Allow to walk on water. Doesn't inform the client. + * Need to use SendMovementWaterWalking() if it's for players. + */ bool Unit::SetWaterWalking(bool enable, bool /*packetOnly = false*/) { if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING)) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 97efd9c2f..4e7fc51d1 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -717,6 +717,7 @@ public: return nullptr; } bool Attack(Unit* victim, bool meleeAttack); + void CastStop(uint32 except_spellid = 0, bool withInstant = true); bool AttackStop(); void RemoveAllAttackers(); @@ -821,10 +822,10 @@ public: void SetUInt32Value(uint16 index, uint32 value); UnitFlags GetUnitFlags() const { return UnitFlags(GetUInt32Value(UNIT_FIELD_FLAGS)); } - bool HasUnitFlag(UnitFlags flags) const { return HasFlag(UNIT_FIELD_FLAGS, flags); } - void SetUnitFlag(UnitFlags flags) { SetFlag(UNIT_FIELD_FLAGS, flags); } - void RemoveUnitFlag(UnitFlags flags) { RemoveFlag(UNIT_FIELD_FLAGS, flags); } - void ReplaceAllUnitFlags(UnitFlags flags) { SetUInt32Value(UNIT_FIELD_FLAGS, flags); } + bool HasUnitFlag(UnitFlags flags) const { return HasFlag(UNIT_FIELD_FLAGS, flags); } /// @brief UnitFlags available in UnitDefines.h + void SetUnitFlag(UnitFlags flags) { SetFlag(UNIT_FIELD_FLAGS, flags); } /// @brief UnitFlags available in UnitDefines.h + void RemoveUnitFlag(UnitFlags flags) { RemoveFlag(UNIT_FIELD_FLAGS, flags); } /// @brief Remove the Unit flag specify only + void ReplaceAllUnitFlags(UnitFlags flags) { SetUInt32Value(UNIT_FIELD_FLAGS, flags); } /// @brief Remove all UnitFlags and set new ones. UnitFlags available in UnitDefines.h UnitFlags2 GetUnitFlags2() const { return UnitFlags2(GetUInt32Value(UNIT_FIELD_FLAGS_2)); } bool HasUnitFlag2(UnitFlags2 flags) const { return HasFlag(UNIT_FIELD_FLAGS_2, flags); } @@ -1607,7 +1608,7 @@ public: [[nodiscard]] bool IsStopped() const { return !(HasUnitState(UNIT_STATE_MOVING)); } void StopMoving(); - void StopMovingOnCurrentPos(); + void StopMovingOnCurrentPos(); /// @brief Disable the unit movement by clearing UNIT_STATE_MOVING and stopping the spline. virtual void PauseMovement(uint32 timer = 0, uint8 slot = 0); // timer in ms void ResumeMovement(uint32 timer = 0, uint8 slot = 0); diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 8948c0d46..84167be22 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -236,9 +236,11 @@ void MotionMaster::MoveIdle() Mutate(GetIdleMovementGenerator(), MOTION_SLOT_IDLE); } +/** + * @brief Enable a random movement in desired range around the unit. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveRandom(float wanderDistance) { - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -249,6 +251,11 @@ void MotionMaster::MoveRandom(float wanderDistance) } } +/** + * @brief The unit will return this initial position (owner for pets and summoned creatures). Doesn't work with UNIT_FLAG_DISABLE_MOVE + * + * @param walk The unit will run by default, but you can set it to walk + */ void MotionMaster::MoveTargetedHome(bool walk /*= false*/) { Clear(false); @@ -261,7 +268,7 @@ void MotionMaster::MoveTargetedHome(bool walk /*= false*/) else if (_owner->GetTypeId() == TYPEID_UNIT && _owner->ToCreature()->GetCharmerOrOwnerGUID()) { _owner->ClearUnitState(UNIT_STATE_EVADE); - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE + if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -279,6 +286,9 @@ void MotionMaster::MoveTargetedHome(bool walk /*= false*/) } } +/** + * @brief Enable the confusion movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveConfused() { // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE @@ -297,9 +307,11 @@ void MotionMaster::MoveConfused() } } +/** + * @brief Force the unit to chase this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveChase(Unit* target, std::optional dist, std::optional angle) { - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE // ignore movement request if target not exist if (!target || target == _owner || _owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -391,9 +403,11 @@ void MotionMaster::MoveCircleTarget(Unit* target) init.Launch(); } +/** + * @brief The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot, bool inheritWalkState) { - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE // ignore movement request if target not exist if (!target || target == _owner || _owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) { @@ -415,9 +429,13 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo } } +/** + * @brief The unit will move to a specific point. Doesn't work with UNIT_FLAG_DISABLE_MOVE + * + * For transition movement between the ground and the air, use MoveLand or MoveTakeoff instead. + */ void MotionMaster::MovePoint(uint32 id, float x, float y, float z, bool generatePath, bool forceDestination, MovementSlot slot, float orientation /* = 0.0f*/) { - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -464,9 +482,11 @@ void MotionMaster::MoveSplinePath(uint32 path_id) MoveSplinePath(points); } +/** + * @brief Use to move the unit from the air to the ground. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed /* = 0.0f*/) { - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -488,15 +508,20 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed /* = 0.0 Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE); } +/** + * @brief Use to move the unit from the air to the ground. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveLand(uint32 id, float x, float y, float z, float speed /* = 0.0f*/) { Position pos = {x, y, z, 0.0f}; MoveLand(id, pos, speed); } +/** + * @brief Use to move the unit from the ground to the air. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed /* = 0.0f*/) { - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -518,6 +543,9 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed /* = Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE); } +/** + * @brief Use to move the unit from the air to the ground. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveTakeoff(uint32 id, float x, float y, float z, float speed /* = 0.0f*/) { Position pos = {x, y, z, 0.0f}; @@ -550,6 +578,9 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa Mutate(new EffectMovementGenerator(0), MOTION_SLOT_CONTROLLED); } +/** + * @brief The unit will jump in a specific direction + */ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ) { //this function may make players fall below map @@ -564,6 +595,9 @@ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ) MoveJump(x, y, z, speedXY, speedZ); } +/** + * @brief The unit will jump to a specific point + */ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id, Unit const* target) { LOG_DEBUG("movement.motionmaster", "Unit ({}) jump to point (X: {} Y: {} Z: {})", _owner->GetGUID().ToString(), x, y, z); @@ -584,9 +618,11 @@ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float spee Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); } +/** + * @brief The unit will fall. Used when in the air. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveFall(uint32 id /*=0*/, bool addFlagForNPC) { - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -625,9 +661,11 @@ void MotionMaster::MoveFall(uint32 id /*=0*/, bool addFlagForNPC) Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); } +/** + * @brief The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, const Movement::PointsArray* path, bool generatePath, float orientation /* = 0.0f*/, ObjectGuid targetGUID /*= ObjectGuid::Empty*/) { - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -646,6 +684,9 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, } } +/** + * @brief The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveCharge(PathGenerator const& path, float speed /*= SPEED_CHARGE*/, ObjectGuid targetGUID /*= ObjectGuid::Empty*/) { G3D::Vector3 dest = path.GetActualEndPosition(); @@ -696,12 +737,14 @@ void MotionMaster::MoveSeekAssistanceDistract(uint32 time) } } +/** + * @brief Enable the target's fleeing movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MoveFleeing(Unit* enemy, uint32 time) { if (!enemy) return; - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -745,12 +788,15 @@ void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode) } } +/** + * @brief Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and + * if the unit has MOTION_SLOT_CONTROLLED (generaly apply when the unit is controlled). + */ void MotionMaster::MoveDistract(uint32 timer) { if (Impl[MOTION_SLOT_CONTROLLED]) return; - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -773,7 +819,7 @@ void MotionMaster::Mutate(MovementGenerator* m, MovementSlot slot) { bool delayed = (_top == slot && (_cleanFlag & MMCF_UPDATE)); - // pussywizard: clear slot AND decrease top immediately to avoid crashes when referencing null top in DirectDelete + // clear slot AND decrease top immediately to avoid crashes when referencing null top in DirectDelete Impl[slot] = nullptr; while (!empty() && !top()) --_top; @@ -797,12 +843,14 @@ void MotionMaster::Mutate(MovementGenerator* m, MovementSlot slot) } } +/** + * @brief Move the unit following a specific path. Doesn't work with UNIT_FLAG_DISABLE_MOVE + */ void MotionMaster::MovePath(uint32 path_id, bool repeatable) { if (!path_id) return; - // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) return; @@ -825,6 +873,9 @@ void MotionMaster::MovePath(uint32 path_id, bool repeatable) _owner->IsPlayer() ? "Player" : "Creature", _owner->GetGUID().ToString(), path_id, repeatable ? "YES" : "NO"); } +/** + * @brief Rotate the unit. You can specify the time of the rotation. + */ void MotionMaster::MoveRotate(uint32 time, RotateDirection direction) { if (!time) From 8852f0c74c212d50c7bc767864f8f9fe925691bb Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Wed, 28 Aug 2024 08:18:02 -0300 Subject: [PATCH 30/46] feat(Core/SmartScripts): Implement Scripted Spawn System (#19499) * prespawn2 * pfta * Update rev_1717715555182000500.sql * Update rev_1717715555182000500.sql * Update rev_1717715555182000500.sql * Update rev_1717715555182000500.sql * Update rev_1717715555182000500.sql * Update rev_1717715555182000500.sql --- .../rev_1717715555182000500.sql | 489 ++++++++++++++++++ src/server/game/AI/SmartScripts/SmartAI.cpp | 3 + src/server/game/AI/SmartScripts/SmartAI.h | 5 + .../game/AI/SmartScripts/SmartScript.cpp | 59 ++- .../game/AI/SmartScripts/SmartScriptMgr.cpp | 4 +- .../game/AI/SmartScripts/SmartScriptMgr.h | 9 +- 6 files changed, 560 insertions(+), 9 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1717715555182000500.sql diff --git a/data/sql/updates/pending_db_world/rev_1717715555182000500.sql b/data/sql/updates/pending_db_world/rev_1717715555182000500.sql new file mode 100644 index 000000000..a4530f521 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1717715555182000500.sql @@ -0,0 +1,489 @@ +-- Scryers +SET @CGUID := 12556; + +DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+18 AND `id1` IN (23435, 23440); +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`) VALUES +(@CGUID+0 , 23435, 530, 3520, 3938, 1, 1, 1, -4063.517333984375, 1079.0699462890625, 32.32865142822265625, 5.462880611419677734, 0 /* spawntimesecs */, 0, 0, 19626, 0, 0, 0, 0, 0, 52237), -- 23435 (Area: 3938 - Difficulty: 0) CreateObject2 +(@CGUID+1 , 23435, 530, 3520, 3938, 1, 1, 1, -4086.240478515625, 1060.3443603515625, 31.09149932861328125, 5.305800914764404296, 0 /* spawntimesecs */, 0, 0, 20283, 0, 0, 0, 0, 0, 52237), -- 23435 (Area: 3938 - Difficulty: 0) CreateObject2 +(@CGUID+2 , 23435, 530, 3520, 3938, 1, 1, 1, -4077.014404296875, 1070.7025146484375, 31.12168502807617187, 5.375614166259765625, 0 /* spawntimesecs */, 0, 0, 19626, 0, 0, 0, 0, 0, 52237), -- 23435 (Area: 3938 - Difficulty: 0) CreateObject2 +(@CGUID+3 , 23435, 530, 3520, 3938, 1, 1, 1, -4070.817626953125, 1074.8057861328125, 31.39684104919433593, 5.393067359924316406, 0 /* spawntimesecs */, 0, 0, 20958, 0, 0, 0, 0, 0, 52237), -- 23435 (Area: 3938 - Difficulty: 0) CreateObject2 +(@CGUID+4 , 23435, 530, 3520, 3938, 1, 1, 1, -4084.223876953125, 1066.301025390625, 31.44091796875, 5.427973747253417968, 0 /* spawntimesecs */, 0, 0, 20958, 0, 0, 0, 0, 0, 52237), -- 23435 (Area: 3938 - Difficulty: 0) CreateObject2 +(@CGUID+5 , 23435, 530, 3520, 3938, 1, 1, 1, -4056.84033203125, 1079.5728759765625, 32.50324630737304687, 5.567600250244140625, 0 /* spawntimesecs */, 0, 0, 19626, 0, 0, 0, 0, 0, 52237), -- 23435 (Area: 3938 - Difficulty: 0) CreateObject2 (Auras: ) +(@CGUID+6 , 23435, 530, 3520, 3938, 1, 1, 1, -4074.188720703125, 1076.3873291015625, 31.96249771118164062, 5.358160972595214843, 0 /* spawntimesecs */, 0, 0, 20958, 0, 0, 0, 0, 0, 52237), -- 23435 (Area: 3938 - Difficulty: 0) CreateObject2 +(@CGUID+7 , 23435, 530, 3520, 3938, 1, 1, 1, -4064.421875, 1074.611328125, 31.13295936584472656, 5.323254108428955078, 0 /* spawntimesecs */, 0, 0, 19626, 0, 0, 0, 0, 0, 52237), -- 23435 (Area: 3938 - Difficulty: 0) CreateObject2 +(@CGUID+8 , 23435, 530, 3520, 3938, 1, 1, 1, -4078.46435546875, 1065.28515625, 31.173919677734375, 5.358160972595214843, 0 /* spawntimesecs */, 0, 0, 20283, 0, 0, 0, 0, 0, 52237), -- 23435 (Area: 3938 - Difficulty: 0) CreateObject2 (Auras: ) +(@CGUID+9 , 23435, 530, 3520, 3938, 1, 1, 1, -4071.4462890625, 1070.081787109375, 30.65686798095703125, 5.358160972595214843, 0 /* spawntimesecs */, 0, 0, 19626, 0, 0, 0, 0, 0, 52237), -- 23435 (Area: 3938 - Difficulty: 0) CreateObject2 +(@CGUID+10, 23440, 530, 3520, 3938, 1, 1, 1, -4063.1006, 963.11896, 61.477966, 1.549625277519226074, 0 /* spawntimesecs */, 0, 0, 0, 0, 0, 0, 0, 0, 52237), +(@CGUID+11, 23440, 530, 3520, 3938, 1, 1, 1, -4050.1597, 963.0414, 53.95147, 1.311231613159179687, 0 /* spawntimesecs */, 0, 0, 0, 0, 0, 0, 0, 0, 52237), +(@CGUID+12, 23440, 530, 3520, 3938, 1, 1, 1, -4020.2585, 970.38385, 60.901543, 0.900896310806274414, 0 /* spawntimesecs */, 0, 0, 0, 0, 0, 0, 0, 0, 52237), +(@CGUID+13, 23440, 530, 3520, 3938, 1, 1, 1, -3999.5762, 981.1174, 50.560707, 4.405356407165527343, 0 /* spawntimesecs */, 0, 0, 0, 0, 0, 0, 0, 0, 52237), +(@CGUID+14, 23440, 530, 3520, 3938, 1, 1, 1, -4038.3103, 965.81195, 56.55157, 1.584519624710083007, 0 /* spawntimesecs */, 0, 0, 0, 0, 0, 0, 0, 0, 52237), +(@CGUID+15, 23440, 530, 3520, 3938, 1, 1, 1, -4088.2646, 962.83264, 60.189224, 1.564426898956298828, 0 /* spawntimesecs */, 0, 0, 0, 0, 0, 0, 0, 0, 52237), +(@CGUID+16, 23440, 530, 3520, 3938, 1, 1, 1, -4114.435, 973.54456, 70.249596, 1.752815127372741699, 0 /* spawntimesecs */, 0, 0, 0, 0, 0, 0, 0, 0, 52237), +(@CGUID+17, 23440, 530, 3520, 3938, 1, 1, 1, -4074.8384, 962.56665, 54.436428, 1.432607769966125488, 0 /* spawntimesecs */, 0, 0, 0, 0, 0, 0, 0, 0, 52237), +(@CGUID+18, 23440, 530, 3520, 3938, 1, 1, 1, -4100.3086, 965.0279, 64.35575, 1.525284409523010253, 0 /* spawntimesecs */, 0, 0, 0, 0, 0, 0, 0, 0, 52237); + +DELETE FROM `waypoint_data` WHERE `id` = 234341; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `move_type`, `delay`) VALUES +(234341, 1, -4075.5479, 1081.4083, 33.318653, NULL, 1, 0), +(234341, 2, -4066.6372, 1067.3375, 30.281086, NULL, 1, 0), +(234341, 3, -4066.6372, 1067.3375, 30.281086, 2.234021425247192382, 0, 2400); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 23434); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23434, 0, 0, 'Defenders, show these mongrels the fury of a Scryer!', 14, 0, 100, 22, 0, 0, 21632, 0, 'Commander Hobb'), +(23434, 1, 0, 'Stand tall, soldiers. Show them no quarter!', 14, 0, 100, 1, 0, 0, 0, 0, 'Commander Hobb'), +(23434, 2, 0, 'Victory to the Scryers! The Dragonmaw have been defeated!', 14, 0, 100, 0, 0, 0, 21663, 0, 'Commander Hobb'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23434); +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 +(23434, 0, 0 , 0, 19, 0, 100, 512, 11097, 0, 0, 0, 0, 0, 80, 2343400, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - On Quest \'The Deadliest Trap Ever Laid\' Taken - Run Script (Start Quest Event)'), +(23434, 0, 1 , 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 81, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - On Respawn - Set Npc Flags Questgiver'), +(23434, 0, 2 , 0, 0, 0, 100, 0, 1000, 1000, 2000, 2000, 0, 0, 11, 41440, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - In Combat - Cast \'Shoot\''), +(23434, 0, 3 , 0, 0, 0, 100, 0, 6000, 6000, 12000, 12000, 0, 0, 11, 38370, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - In Combat - Cast \'Aimed Shot\''), +(23434, 0, 4 , 0, 0, 0, 100, 0, 8000, 8000, 15000, 15000, 0, 0, 11, 41448, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - In Combat - Cast \'Multi-Shot\''), +(23434, 0, 5 , 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 39, 15, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - On Aggro - Call For Help'), +(23434, 0, 6 , 7, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2343401, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - On Just Died - Run Script (Fail Quest)'), +(23434, 0, 7 , 8, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 9, 23435, 0, 100, 0, 0, 0, 0, 0, 'Commander Hobb - On Just Died - Disable Quest Creatures'), +(23434, 0, 8 , 9, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 9, 23440, 0, 150, 0, 0, 0, 0, 0, 'Commander Hobb - On Just Died - Disable Quest Creatures'), +(23434, 0, 9 , 10, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 6, 11097, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - On Just Died - Fail Quest \'The Deadliest Trap Ever Laid\''), +(23434, 0, 10, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - On Just Died - Despawn Self Instant (I\'m having issues with Home Pos and Evade)'), +(23434, 0, 11, 0, 77, 0, 100, 0, 1, 20, 0, 0, 0, 0, 80, 2343402, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - On 20 Enemies Killed - Run Script (Complete Quest)'), +(23434, 0, 12, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - On Respawn - Set Sheath Melee'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2343400); +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 +(2343400, 9, 0 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Remove Npc Flags Questgiver'), +(2343400, 9, 1 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 63, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Reset Counter'), +(2343400, 9, 2 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Store Targetlist Party'), +(2343400, 9, 3 , 0, 0, 0, 100, 0, 2200, 2200, 0, 0, 0, 0, 226, 1, 0, 0, 0, 0, 0, 9, 23435, 0, 100, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Spawn In Sanctum Defenders'), +(2343400, 9, 4 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Say Line 0'), +(2343400, 9, 5 , 0, 0, 0, 100, 0, 3200, 3200, 0, 0, 0, 0, 232, 234341, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Start Path 234341'), +(2343400, 9, 6 , 0, 0, 0, 100, 0, 11400, 11400, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Say Line 1'), +(2343400, 9, 7 , 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 5.340707302093506, 'Commander Hobb - Actionlist - Set Orientation'), +(2343400, 9, 8 , 0, 0, 0, 100, 0, 1200, 1200, 0, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Set Sheath Ranged'), +(2343400, 9, 9 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 5, 48, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Play Emote 48 (OneShotReadyBow)'), +(2343400, 9, 10, 0, 0, 0, 100, 0, 2100, 2100, 0, 0, 0, 0, 226, 2, 1, 1, 5, 5, 0, 9, 23440, 0, 150, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Start Spawning Dragonmaw Skybreakers'), +(2343400, 9, 11, 0, 0, 0, 100, 0, 1200, 1200, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 19, 23440, 150, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Say Line 0 (Dragonmaw Skybreaker)'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2343402); +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 +(2343402, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 9, 23435, 0, 100, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Disable Quest Creatures'), +(2343402, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 9, 23440, 0, 150, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Disable Quest Creatures'), +(2343402, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 26, 11097, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Quest Credit \'The Deadliest Trap Ever Laid\''), +(2343402, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Say Line 2'), +(2343402, 9, 4, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Reset Home Position'), +(2343402, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - Actionlist - Evade'), +(2343402, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Hobb - On Just Died - Despawn Self Instant'); + +UPDATE `creature_template_addon` SET `emote` = 376 WHERE (`entry` = 23435); +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23435); +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 +(23435, 0, 0, 0, 0, 0, 100, 0, 1000, 1000, 3500, 3500, 0, 0, 11, 41440, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Sanctum Defender - In Combat - Cast Shoot'), +(23435, 0, 1, 0, 37, 0, 100, 257, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sanctum Defender - On Initialize - Disable Respawn'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23440); +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 +(23440, 0, 0, 0, 0, 0, 100, 0, 1000, 1000, 3500, 3500, 0, 0, 11, 41440, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - In Combat - Cast Shoot'), +(23440, 0, 1, 0, 0, 0, 100, 0, 6000, 6000, 12000, 12000, 0, 0, 11, 38370, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - In Combat - Cast Aimed Shot'), +(23440, 0, 2, 0, 0, 0, 100, 0, 8000, 8000, 15000, 15000, 0, 0, 11, 41448, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - In Combat - Cast Multi-Shot'), +(23440, 0, 3, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 63, 1, 1, 0, 0, 0, 0, 10, 1011, 23434, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Just Died - Add 1 to Commander Hobb Kill Counter'), +(23440, 0, 4, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Aggro - Say Line 1'), +(23440, 0, 5, 0, 37, 0, 100, 257, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Initialize - Disable Respawn'); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 23440); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23440, 0, 0, 'BURN IT DOWN!', 14, 0, 100, 0, 0, 0, 21656, 0, 'Dragonmaw Skybreaker'), +(23440, 0, 1, 'KILL THEM ALL!', 14, 0, 100, 0, 0, 0, 1690, 0, 'Dragonmaw Skybreaker'), +(23440, 1, 0, 'For the Dragonmaw!', 12, 0, 100, 0, 0, 0, 1937, 0, 'Dragonmaw Skybreaker'), +(23440, 1, 1, 'Long live the Dragonmaw! Die you worthless $N!', 12, 0, 100, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker'), +(23440, 1, 2, 'Your bones will break under my boot, $N', 12, 0, 100, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker'); + +DELETE FROM `waypoint_data` WHERE `id` BETWEEN 234401 AND 234409; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `move_type`) VALUES +-- [1] Position: X: -4063.1006 Y: 963.11896 Z: 61.477966 +-- [1] Orientation: 1.549625277519226074 +-- (234401, 1, -4063.3423, 928.9622, 82.92392, NULL, 2), +(234401, 1, -4063.14, 960.33984, 63.31019, NULL, 2), +(234401, 2, -4062.9375, 991.71747, 43.696457, NULL, 2), +(234401, 3, -4068.4714, 1033.1897, 43.69646, NULL, 2), +(234401, 4, -4063.366, 1066.3694, 36.36312, NULL, 2), +(234401, 5, -4063.366, 1066.3694, 36.36312, NULL, 2), + +-- [2] Position: X: -4050.1597 Y: 963.0414 Z: 53.95147 +-- [2] Orientation: 1.311231613159179687 +-- (234402, 1, -4059.524, 924.002, 65.44735, NULL, 2), +(234402, 1, -4050.9375, 959.96356, 54.90167, NULL, 2), +(234402, 2, -4042.351, 995.9251, 44.355988, NULL, 2), +(234402, 3, -4043.5217, 1043.2762, 44.355988, NULL, 2), +(234402, 4, -4053.7783, 1066.186, 35.717106, NULL, 2), +(234402, 5, -4053.7783, 1066.186, 35.717106, NULL, 2), + +-- [3] Position: X: -4020.2585 Y: 970.38385 Z: 60.901543 +-- [3] Orientation: 0.900896310806274414 +-- (234403, 1, -4037.4287, 946.79236, 83.177536, NULL, 2), +(234403, 1, -4021.8472, 968.2917, 63.01559, NULL, 2), +(234403, 2, -4006.2656, 989.791, 42.853645, NULL, 2), +(234403, 3, -3996.3499, 1025.583, 42.853645, NULL, 2), +(234403, 4, -4003.674, 1055.279, 42.853645, NULL, 2), +(234403, 5, -4028.947, 1082.6088, 42.853645, NULL, 2), +(234403, 6, -4045.464, 1078.8114, 39.575867, NULL, 2), +(234403, 7, -4045.464, 1078.8114, 39.575867, NULL, 2), + +-- [4] Position: X: -3999.5762 Y: 981.1174 Z: 50.560707 +-- [4] Orientation: 4.405356407165527343 +-- (234404, 1, -3996.5837, 984.6102, 39.35212, NULL, 2), +(234404, 1, -3998.6301, 983.61804, 49.09008, NULL, 2), +(234404, 2, -3999.1016, 983.38947, 51.333473, NULL, 2), +(234404, 3, -3990.658, 1017.7838, 56.139027, NULL, 2), +(234404, 4, -4006.1025, 1049.133, 55.555695, NULL, 2), +(234404, 5, -4019.0344, 1080.7048, 35.305683, NULL, 2), +(234404, 6, -4053.2844, 1074.483, 33.611267, NULL, 2), +(234404, 7, -4053.2844, 1074.483, 33.611267, NULL, 2), + +-- [5] Position: X: -4038.3103 Y: 965.81195 Z: 56.55157 +-- [5] Orientation: 1.584519624710083007 +-- (234405, 1, -4037.4302, 934.6457, 40.033707, NULL, 2), +(234405, 1, -4038.25, 962.934, 54.8684, NULL, 2), +(234405, 2, -4039.0698, 991.22235, 69.703094, NULL, 2), +(234405, 3, -4044.9453, 1026.4785, 51.564217, NULL, 2), +(234405, 4, -4046.6675, 1054.0055, 34.70309, NULL, 2), +(234405, 5, -4054.3298, 1074.1635, 32.84199, NULL, 2), +(234405, 6, -4054.3298, 1074.1635, 32.84199, NULL, 2), + +-- [6] Position: X: -4088.2646 Y: 962.83264 Z: 60.189224 +-- [6] Orientation: 1.564426898956298828 +-- (234406, 1, -4088.8037, 925.66644, 67.038666, NULL, 2), +(234406, 1, -4088.2986, 959.6094, 60.73994, NULL, 2), +(234406, 2, -4087.7935, 993.5523, 54.441216, NULL, 2), +(234406, 3, -4083.7122, 1036.6643, 35.0801, NULL, 2), +(234406, 4, -4081.1072, 1055.6353, 31.913435, NULL, 2), +(234406, 5, -4081.1072, 1055.6353, 31.913435, NULL, 2), + +-- [7] Position: X: -4114.435 Y: 973.54456 Z: 70.249596 +-- [7] Orientation: 1.752815127372741699 +-- (234407, 1, -4108.9116, 938.1812, 94.50812, NULL, 2), +(234407, 1, -4113.9756, 970.84375, 72.16011, NULL, 2), +(234407, 2, -4119.0396, 1003.5063, 49.8121, NULL, 2), +(234407, 3, -4113.9204, 1050.867, 36.728764, NULL, 2), +(234407, 4, -4099.3726, 1059.4963, 33.645435, NULL, 2), +(234407, 5, -4093.058, 1059.0251, 31.534332, NULL, 2), +(234407, 6, -4093.058, 1059.0251, 31.534332, NULL, 2), + +-- [8] Position: X: -4074.8384 Y: 962.56665 Z: 54.436428 +-- [8] Orientation: 1.432607769966125488 +-- (234408, 1, -4079.2244, 931.53033, 76.49546, NULL, 2), +(234408, 1, -4075.2153, 959.8802, 56.398266, NULL, 2), +(234408, 2, -4071.2063, 988.23004, 36.30107, NULL, 2), +(234408, 3, -4066.255, 1017.4882, 29.634405, NULL, 2), +(234408, 4, -4060.89, 1066.7999, 31.106628, NULL, 2), +(234408, 5, -4060.89, 1066.7999, 31.106628, NULL, 2), + +-- [9] Position: X: -4100.3086 Y: 965.0279 Z: 64.35575 +-- [9] Orientation: 1.525284409523010253 +-- (234409, 1, -4101.632, 942.9062, 58.775528, NULL, 2), +(234409, 1, -4100.46, 962.17706, 63.36372, NULL, 2), +(234409, 2, -4099.288, 981.44794, 67.95191, NULL, 2), +(234409, 3, -4094.4888, 1028.0123, 51.118576, NULL, 2), +(234409, 4, -4088.3276, 1055.0275, 41.36858, NULL, 2), +(234409, 5, -4088.3276, 1055.0275, 41.36858, NULL, 2); + +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|134217728 WHERE (`entry` = 23440); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (-(@CGUID+10),-(@CGUID+11),-(@CGUID+12),-(@CGUID+13),-(@CGUID+14),-(@CGUID+15),-(@CGUID+16),-(@CGUID+17),-(@CGUID+18))) AND (`source_type` = 0) AND (`id` IN (1000)); +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 +(-(@CGUID+10), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234401, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234401'), +(-(@CGUID+11), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234402, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234402'), +(-(@CGUID+12), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234403, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234403'), +(-(@CGUID+13), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234404, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234404'), +(-(@CGUID+14), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234405, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234405'), +(-(@CGUID+15), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234406, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234406'), +(-(@CGUID+16), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234407, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234407'), +(-(@CGUID+17), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234408, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234408'), +(-(@CGUID+18), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234409, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234409'); + +-- Aldor +DELETE FROM `creature_text` WHERE (`CreatureID` = 23441); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23441, 0, 0, 'BURN IT DOWN!', 14, 0, 100, 0, 0, 0, 21656, 0, 'Dragonmaw Skybreaker'), +(23441, 0, 1, 'KILL THEM ALL!', 14, 0, 100, 0, 0, 0, 1690, 0, 'Dragonmaw Skybreaker'), +(23441, 1, 0, 'For the Dragonmaw!', 12, 0, 100, 0, 0, 0, 1937, 0, 'Dragonmaw Skybreaker'), +(23441, 1, 1, 'Long live the Dragonmaw! Die you worthless $N!', 12, 0, 100, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker'), +(23441, 1, 2, 'Your bones will break under my boot, $N', 12, 0, 100, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker'); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 23452); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23452, 0, 0, 'The Dragonmaw must be stopped...', 14, 0, 100, 22, 0, 0, 21685, 0, 'Commander Arcus to Player'), +(23452, 1, 0, 'Stand tall, soldiers. Show them no quarter!', 12, 0, 100, 5, 0, 0, 21633, 0, 'Commander Arcus to Player'), +(23452, 2, 0, 'Victory to the Aldor! The Dragonmaw have been defeated!', 14, 0, 100, 0, 0, 0, 21728, 0, 'Commander Arcus to Commander Arcus'); + +SET @CGUID := 12720; + +DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+18 AND `id1` IN (23453, 23441); +INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(@CGUID+0, 23453, 530, 3520, 3754, 1, -3083.6, 687.388, -17.0363, 3.08923, 0, 55639, 2, NULL), +(@CGUID+1, 23453, 530, 3520, 3754, 1, -3085.62, 692.253, -17.6563, 3.08923, 0, 55639, 2, NULL), +(@CGUID+2, 23453, 530, 3520, 3754, 1, -3088.42, 684.481, -17.5697, 3.14159, 0, 55639, 2, NULL), +(@CGUID+3, 23453, 530, 3520, 3754, 1, -3086.17, 680.568, -15.9425, 2.98451, 0, 55639, 2, NULL), +(@CGUID+4, 23453, 530, 3520, 3754, 1, -3096.63, 667.763, -13.7902, 2.77507, 0, 55639, 2, NULL), +(@CGUID+5, 23453, 530, 3520, 3754, 1, -3093.32, 673.408, -15.203, 2.87979, 0, 55639, 2, NULL), +(@CGUID+6, 23453, 530, 3520, 3754, 1, -3091.12, 678.402, -16.3597, 3.03687, 0, 55639, 2, NULL), +(@CGUID+7, 23453, 530, 3520, 3754, 1, -3094.99, 662.722, -12.762, 2.58309, 0, 55639, 2, NULL), +(@CGUID+8, 23453, 530, 3520, 3754, 1, -3091.11, 668.166, -14.1371, 2.74017, 0, 55639, 2, NULL), +(@CGUID+9, 23453, 530, 3520, 3754, 1, -3088.57, 674.317, -14.8953, 2.75762, 0, 55639, 2, NULL), + +(@CGUID+10, 23441, 530, 3520, 3754, 1, -3259.4226, 708.5354, 38.91116, 6.233379364013671875, 0, 55639, 2, NULL), +(@CGUID+11, 23441, 530, 3520, 3754, 1, -3006.4463, 564.1875, 48.472195, 2.211099624633789062, 0, 55639, 2, NULL), +(@CGUID+12, 23441, 530, 3520, 3754, 1, -3247.2795, 681.7934, 46.758705, 6.047158718109130859, 0, 55639, 2, NULL), +(@CGUID+13, 23441, 530, 3520, 3754, 1, -3271.6199, 722.7448, 48.811226, 6.087714672088623046, 0, 55639, 2, NULL), +(@CGUID+14, 23441, 530, 3520, 3754, 1, -3030.6301, 557.1302, 34.245502, 2.113452434539794921, 0, 55639, 2, NULL), +(@CGUID+15, 23441, 530, 3520, 3754, 1, -3268.5156, 750.7678, 33.435238, 5.964546680450439453, 0, 55639, 2, NULL), +(@CGUID+16, 23441, 530, 3520, 3754, 1, -3268.2517, 731.8698, 32.24829, 6.274892807006835937, 0, 55639, 2, NULL), +(@CGUID+17, 23441, 530, 3520, 3754, 1, -2987.5417, 575.9792, 58.821465, 2.240255117416381835, 0, 55639, 2, NULL), +(@CGUID+18, 23441, 530, 3520, 3754, 1, -3260.4463, 692.08856, 43.37934, 6.01873016357421875, 0, 55639, 2, NULL); + +DELETE FROM `waypoint_data` WHERE `id` = 234521; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`) VALUES +(234521, 1, -3043.0544, 759.7127, -10.093901, NULL, 0, 1), +(234521, 2, -3048.7854, 739.1032, -9.660838, NULL, 0, 1), +(234521, 3, -3047.9675, 718.32794, -10.502778, NULL, 0, 1), +(234521, 4, -3060.013, 682.91296, -13.024189, NULL, 0, 1), +(234521, 5, -3080.6594, 675.9093, -13.976298, NULL, 0, 1), +(234521, 6, -3096.214, 680.7059, -17.963423, NULL, 4200, 1), +(234521, 7, -3096.214, 680.7059, -17.963423, 5.969026088714599609, 4800, 0), +(234521, 8, -3096.214, 680.7059, -17.963423, 2.94960641860961914, 0, 0); + +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|134217728 WHERE (`entry` = 23441); +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (-(@CGUID+10),-(@CGUID+11),-(@CGUID+12),-(@CGUID+13),-(@CGUID+14),-(@CGUID+15),-(@CGUID+16),-(@CGUID+17),-(@CGUID+18))) AND (`source_type` = 0) AND (`id` IN (1000)); +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 +(-(@CGUID+10), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234411, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234411'), +(-(@CGUID+11), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234412, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234412'), +(-(@CGUID+12), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234413, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234413'), +(-(@CGUID+13), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234414, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234414'), +(-(@CGUID+14), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234415, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234415'), +(-(@CGUID+15), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234416, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234416'), +(-(@CGUID+16), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234417, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234417'), +(-(@CGUID+17), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234418, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234418'), +(-(@CGUID+18), 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 232, 234419, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Respawn - Start Path 234419'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23441); +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 +(23441, 0, 0, 0, 0, 0, 100, 0, 1000, 1000, 3500, 3500, 0, 0, 11, 41440, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - In Combat - Cast Shoot'), +(23441, 0, 1, 0, 0, 0, 100, 0, 6000, 6000, 12000, 12000, 0, 0, 11, 38370, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - In Combat - Cast Aimed Shot'), +(23441, 0, 2, 0, 0, 0, 100, 0, 8000, 8000, 15000, 15000, 0, 0, 11, 41448, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - In Combat - Cast Multi-Shot'), +(23441, 0, 3, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 63, 1, 1, 0, 0, 0, 0, 10, 13564, 23452, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Just Died - Add 1 to Commander Arcus Kill Counter'), +(23441, 0, 4, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Aggro - Say Line 1'), +(23441, 0, 5, 0, 37, 0, 100, 257, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Skybreaker - On Initialize - Disable Respawn'); + +UPDATE `creature_template_addon` SET `emote` = 376 WHERE (`entry` = 23453); +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23453); +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 +(23453, 0, 0, 0, 0, 0, 100, 0, 1000, 1000, 3500, 3500, 0, 0, 11, 41440, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Altar Defender - In Combat - Cast Shoot'), +(23453, 0, 1, 0, 37, 0, 100, 257, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Altar Defender - On Initialize - Disable Respawn'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23452); +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 +(23452, 0, 0 , 0, 19, 0, 100, 512, 11101, 0, 0, 0, 0, 0, 80, 2345200, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - On Quest \'The Deadliest Trap Ever Laid\' Taken - Run Script (Start Quest Event)'), +(23452, 0, 1 , 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 81, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - On Respawn - Set Npc Flags Questgiver'), +(23452, 0, 2 , 0, 0, 0, 100, 0, 1000, 1000, 2000, 2000, 0, 0, 11, 41440, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - In Combat - Cast \'Shoot\''), +(23452, 0, 3 , 0, 0, 0, 100, 0, 6000, 6000, 12000, 12000, 0, 0, 11, 38370, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - In Combat - Cast \'Aimed Shot\''), +(23452, 0, 4 , 0, 0, 0, 100, 0, 8000, 8000, 15000, 15000, 0, 0, 11, 41448, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - In Combat - Cast \'Multi-Shot\''), +(23452, 0, 5 , 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 39, 15, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - On Aggro - Call For Help'), +(23452, 0, 6 , 7, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2345201, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - On Just Died - Run Script (Fail Quest)'), +(23452, 0, 7 , 8, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 9, 23453, 0, 100, 0, 0, 0, 0, 0, 'Commander Arcus - On Just Died - Disable Quest Creatures'), +(23452, 0, 8 , 9, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 9, 23441, 0, 200, 0, 0, 0, 0, 0, 'Commander Arcus - On Just Died - Disable Quest Creatures'), +(23452, 0, 9 , 10, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 6, 11101, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - On Just Died - Fail Quest \'The Deadliest Trap Ever Laid\''), +(23452, 0, 10, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - On Just Died - Despawn Self Instant'), +(23452, 0, 11, 0, 77, 0, 100, 0, 1, 20, 0, 0, 0, 0, 80, 2345202, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - On 20 Enemies Killed - Run Script (Complete Quest)'), +(23452, 0, 12, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - On Respawn - Set Sheath Melee'), +(23452, 0, 13, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - On Respawn - Set Emote State 0'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2345200); +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 +(2345200, 9, 0 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Remove Npc Flags Questgiver'), +(2345200, 9, 1 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 63, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Reset Counter'), +(2345200, 9, 2 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Store Targetlist Party'), +(2345200, 9, 3 , 0, 0, 0, 100, 0, 2900, 2900, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Say Line 0'), +(2345200, 9, 4 , 0, 0, 0, 100, 0, 3100, 3100, 0, 0, 0, 0, 232, 234521, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Start Path 234521'), +(2345200, 9, 5 , 0, 0, 0, 100, 0, 26000, 26000, 0, 0, 0, 0, 226, 1, 0, 0, 0, 0, 0, 9, 23453, 0, 100, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Spawn In Altar Defenders'), +(2345200, 9, 6 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Say Line 1'), +(2345200, 9, 7 , 0, 0, 0, 100, 0, 3100, 3100, 0, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Set Sheath Ranged'), +(2345200, 9, 8 , 0, 0, 0, 100, 0, 1600, 1600, 0, 0, 0, 0, 17, 214, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Set EmoteState 214'), +(2345200, 9, 9 , 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 226, 2, 1, 1, 5, 5, 0, 9, 23441, 0, 200, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Start Spawning Dragonmaw Skybreakers'), +(2345200, 9, 10, 0, 0, 0, 100, 0, 1200, 1200, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 19, 23441, 200, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Say Line 0 (Dragonmaw Skybreaker)'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2345202); +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 +(2345202, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 9, 23453, 0, 100, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Disable Quest Creatures'), +(2345202, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 9, 23441, 0, 200, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Disable Quest Creatures'), +(2345202, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 26, 11101, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Quest Credit \'The Deadliest Trap Ever Laid\''), +(2345202, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Say Line 2'), +(2345202, 9, 4, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Reset Home Position'), +(2345202, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - Actionlist - Evade'), +(2345202, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Commander Arcus - On Just Died - Despawn Self Instant'); + +DELETE FROM `waypoint_data` WHERE `id` BETWEEN 234411 AND 234419; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `move_type`) VALUES +-- [0] Position: X: -3259.4226, 708.5354, 38.91116 +-- [0] Orientation: 6.233379364013671875 +(234411, 1, -3242.5364, 707.69366, 52.700848, NULL, 2), +(234411, 2, -3219.2295, 703.29517, 52.700848, NULL, 2), +(234411, 3, -3185.632, 695.4233, 37.25641, NULL, 2), +(234411, 4, -3147.6853, 685.7768, 19.589731, NULL, 2), +(234411, 5, -3107.8901, 674.2289, 6.561962, NULL, 2), +-- [1] Position: X: -3006.4463, 564.1875, 48.472195 +-- [1] Orientation: 2.211099624633789062 +(234412, 1, -3006.4463, 564.1875, 48.472195, NULL, 2), +(234412, 2, -3020.0957, 582.5085, 26.582497, NULL, 2), +(234412, 3, -3037.433, 610.57153, 8.026941, NULL, 2), +(234412, 4, -3054.981, 636.631, 1.888052, NULL, 2), +(234412, 5, -3081.3538, 670.811, -6.723061, NULL, 2), +-- [2] Position: X: -3247.2795, 681.7934, 46.758705 +-- [2] Orientation: 6.047158718109130859 +(234413, 1, -3247.2795, 681.7934, 46.758705, NULL, 2), +(234413, 2, -3224.905, 676.4121, 60.397457, NULL, 2), +(234413, 3, -3197.4385, 662.9752, 60.397453, NULL, 2), +(234413, 4, -3175.9648, 654.6516, 60.397453, NULL, 2), +(234413, 5, -3159.4307, 646.17004, 60.397453, NULL, 2), +(234413, 6, -3121.3748, 624.6077, 37.00856, NULL, 2), +(234413, 7, -3101.5295, 653.33734, 2.008561, NULL, 2), +-- [3] Position: X: -3271.6199, 722.7448, 48.811226 +-- [3] Orientation: 6.087714672088623046 +(234414, 1, -3271.6199, 722.7448, 48.811226, NULL, 2), +(234414, 2, -3255.2827, 719.5101, 46.016747, NULL, 2), +(234414, 3, -3222.5205, 717.1377, 45.511993, NULL, 2), +(234414, 4, -3198.0264, 711.52374, 35.567757, NULL, 2), +(234414, 5, -3167.2495, 706.08527, 16.984415, NULL, 2), +(234414, 6, -3126.632, 691.3753, -8.571138, NULL, 2), +(234414, 7, -3099.939, 682.7796, -15.793356, NULL, 2), +-- [4] Position: X: -3030.6301, 557.1302, 34.245502 +-- [4] Orientation: 2.113452434539794921 +(234415, 1, -3030.6301, 557.1302, 34.245502, NULL, 2), +(234415, 2, -3044.279, 579.7635, 47.477497, NULL, 2), +(234415, 3, -3056.1836, 615.40344, 25.783052, NULL, 2), +(234415, 4, -3071.745, 646.99536, 5.366384, NULL, 2), +(234415, 5, -3085.0522, 661.14874, -9.10583, NULL, 2), +(234415, 6, -3085.0522, 661.14874, -9.10583, NULL, 2), +-- [5] Position: X: -3268.5156, 750.7678, 33.435238 +-- [5] Orientation: 5.964546680450439453 +(234416, 1 , -3268.5156, 750.7678, 33.435238, NULL, 2), +(234416, 2 , -3243.4297, 742.4925, 22.651155, NULL, 2), +(234416, 3 , -3213.966, 746.05066, 22.651155, NULL, 2), +(234416, 4 , -3189.9797, 744.0554, 26.484491, NULL, 2), +(234416, 5 , -3150.6821, 757.67755, 29.956709, NULL, 2), +(234416, 6 , -3120.7246, 761.84796, 35.484493, NULL, 2), +(234416, 7 , -3104.629, 754.38446, 29.567825, NULL, 2), +(234416, 8 , -3082.1396, 720.24805, 3.762264, NULL, 2), +(234416, 9 , -3085.2312, 701.88586, -12.293289, NULL, 2), +(234416, 10, -3089.7302, 692.963, -16.515514, NULL, 2), +-- [6] Position: X: -3268.2517, 731.8698, 32.24829 +-- [6] Orientation: 6.274892807006835937 +(234417, 1, -3268.2517, 731.8698, 32.24829, NULL, 2), +(234417, 2, -3249.601, 731.71515, 36.61551, NULL, 2), +(234417, 3, -3226.119, 729.245, 36.61551, NULL, 2), +(234417, 4, -3200.4783, 728.32074, 36.61551, NULL, 2), +(234417, 5, -3154.492, 724.6342, 28.42106, NULL, 2), +(234417, 6, -3122.896, 709.35486, 13.365505, NULL, 2), +(234417, 7, -3108.9421, 698.5323, 0.143284, NULL, 2), +-- [7] Position: X: -2987.5417, 575.9792, 58.821465 +-- [7] Orientation: 2.240255117416381835 +(234418, 1, -2987.5417, 575.9792, 58.821465, NULL, 2), +(234418, 2, -3021.1553, 618.4541, 25.290438, NULL, 2), +(234418, 3, -3036.0618, 656.704, 4.762658, NULL, 2), +(234418, 4, -3075.4192, 678.96826, -13.154009, NULL, 2), +(234418, 5, -3083.369, 683.91406, -15.12623, NULL, 2), +-- [8] Position: X: -3260.4463, 692.08856, 43.37934 +-- [8] Orientation: 6.01873016357421875 +(234419, 1, -3260.4463, 692.08856, 43.37934, NULL, 2), +(234419, 2, -3243.889, 687.60486, 51.14147, NULL, 2), +(234419, 3, -3202.3489, 669.66095, 51.14147, NULL, 2), +(234419, 4, -3183.1746, 660.77405, 51.14147, NULL, 2), +(234419, 5, -3155.9106, 659.907, 33.113697, NULL, 2), +(234419, 6, -3132.411, 658.95215, 3.419254, NULL, 2), +(234419, 7, -3111.927, 665.25214, -7.941859, NULL, 2), +(234419, 8, -3101.4766, 664.6626, -10.552968, NULL, 2); + +DELETE FROM `creature_template_movement` WHERE (`CreatureId` = 23441); +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`, `InteractionPauseTimer`) VALUES +(23441, 1, 0, 1, 0, 0, 0, 0); + +-- Converting the older systems +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` IN (10, 11)); +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 +(10, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Generic - Actionlist - Set Visibility Off'), +(10, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Generic - Actionlist - Set Flags Immune To Players & Immune To NPC\'s'), +(11, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Generic - Actionlist - Set Visibility On'), +(11, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Generic - Actionlist - Remove Flags Immune To Players & Immune To NPC\'s'); + +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151291 AND `source_type`=0 AND `id`=1000; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151290 AND `source_type`=0 AND `id`=1000; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151289 AND `source_type`=0 AND `id`=1000; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151288 AND `source_type`=0 AND `id`=1000; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151287 AND `source_type`=0 AND `id`=1000; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151286 AND `source_type`=0 AND `id`=1000; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151285 AND `source_type`=0 AND `id`=1000; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151284 AND `source_type`=0 AND `id`=1000; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151034 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151033 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151032 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151031 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151030 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151029 AND `source_type`=0 AND `id`=1006; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151028 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151027 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151026 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151025 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151023 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151022 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151021 AND `source_type`=0 AND `id`=1001; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=10 WHERE `entryorguid`=-151020 AND `source_type`=0 AND `id`=1001; + +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151291 AND `source_type`=0 AND `id`=1001 AND `link`=1002; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151290 AND `source_type`=0 AND `id`=1001 AND `link`=1002; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151289 AND `source_type`=0 AND `id`=1001 AND `link`=1002; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151288 AND `source_type`=0 AND `id`=1001 AND `link`=1002; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151287 AND `source_type`=0 AND `id`=1001 AND `link`=1002; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151286 AND `source_type`=0 AND `id`=1001 AND `link`=1002; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151285 AND `source_type`=0 AND `id`=1001 AND `link`=1002; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151284 AND `source_type`=0 AND `id`=1001 AND `link`=1002; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151034 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151033 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151032 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151031 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151030 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151029 AND `source_type`=0 AND `id`=1008 AND `link`=1009; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151028 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151027 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151026 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151025 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151023 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151022 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151021 AND `source_type`=0 AND `id`=1002 AND `link`=1003; +UPDATE `smart_scripts` SET `action_type`=80, `action_param1`=11 WHERE `entryorguid`=-151020 AND `source_type`=0 AND `id`=1002 AND `link`=1003; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -151019); +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 +(-151019, 0, 1001, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Reset - Set Event Phase 1 (Allow Add to Spawn)'), +(-151019, 0, 1002, 0, 82, 0, 100, 0, 17083, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Summoned Add Dies - Set Event Phase 1 (Allow Add to Spawn)'), +(-151019, 0, 1003, 1004, 38, 1, 100, 0, 1, 1, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Data Set 1 1 - Say Line 6 (Phase 1)'), +(-151019, 0, 1004, 1005, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 12, 17083, 4, 300000, 0, 0, 0, 8, 0, 0, 0, 0, 89.4649, 187.334, -13.1455, 3.39256, 'Shattered Hand Legionnaire - On Data Set 1 1 - Summon Creature \'Fel Orc Convert\' (Phase 1)'), +(-151019, 0, 1005, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Data Set 1 1 - Set Event Phase 2 (Do Not Allow Adds to Spawn)'), +(-151019, 0, 1006, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Respawn - Disable'), +(-151019, 0, 1007, 1008, 77, 0, 100, 0, 1, 2, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Counter 2/2 - Enable'), +(-151019, 0, 1008, 1009, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Counter 2/2 - Enable'), +(-151019, 0, 1009, 1010, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 3, 1, 0, 0, 0, 0, 9, 0, 0, 60, 1, 0, 0, 0, 0, 'Shattered Hand Legionnaire - Linked - Set Data 3 1 to Start Group 1 Spawn'), +(-151019, 0, 1010, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 1670011, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - Linked - Run Script'), +(-151019, 0, 1011, 0, 58, 0, 100, 0, 0, 1670002, 0, 0, 0, 0, 80, 1670013, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Waypoint Finished - Run Script'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -151024); +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 +(-151024, 0, 1001, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Reset - Set Event Phase 1 (Allow Add to Spawn)'), +(-151024, 0, 1002, 0, 82, 0, 100, 0, 17083, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Summoned Add Dies - Set Event Phase 1 (Allow Add to Spawn)'), +(-151024, 0, 1003, 1004, 38, 1, 100, 0, 1, 1, 0, 0, 0, 0, 1, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Data Set 1 1 - Say Line 9 (Phase 1)'), +(-151024, 0, 1004, 1005, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 12, 17083, 4, 300000, 0, 0, 0, 8, 0, 0, 0, 0, 79.7924, 218.84, -13.1506, 3.98455, 'Shattered Hand Legionnaire - On Data Set 1 1 - Summon Creature \'Fel Orc Convert\' (Phase 1)'), +(-151024, 0, 1005, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Data Set 1 1 - Set Event Phase 2 (Do Not Allow Adds to Spawn)'), +(-151024, 0, 1006, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Respawn - Disable'), +(-151024, 0, 1007, 1008, 38, 0, 100, 0, 3, 2, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Data Set 3 2 - Enable'), +(-151024, 0, 1008, 1009, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Data Set 3 2 - Enable'), +(-151024, 0, 1009, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 1670012, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - Linked - Run Script'), +(-151024, 0, 1010, 0, 40, 0, 100, 0, 4, 1670004, 0, 0, 0, 0, 80, 1670014, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Legionnaire - On Waypoint Finished - Run Script'); diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index aa64e7c0a..7110e858d 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -70,6 +70,8 @@ SmartAI::SmartAI(Creature* c) : CreatureAI(c) mJustReset = false; + mcanSpawn = true; + // Xinef: Vehicle conditions m_ConditionsTimer = 0; if (me->GetVehicleKit()) @@ -1166,6 +1168,7 @@ void SmartAI::OnSpellClick(Unit* clicker, bool& /*result*/) void SmartAI::PathEndReached(uint32 /*pathId*/) { GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_DATA_ENDED, nullptr, 0, me->GetWaypointPath()); + me->LoadPath(0); } void SmartGameObjectAI::SummonedCreatureDies(Creature* summon, Unit* /*killer*/) diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index e5a62a859..327f36c06 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -207,6 +207,9 @@ public: void PathEndReached(uint32 pathId) override; + bool CanRespawn() override { return mcanSpawn; }; + void SetCanRespawn(bool canSpawn) { mcanSpawn = canSpawn; } + // Xinef void SetWPPauseTimer(uint32 time) { mWPPauseTimer = time; } @@ -249,6 +252,8 @@ private: uint32 mEscortInvokerCheckTimer; bool mJustReset; + bool mcanSpawn; + // Xinef: Vehicle conditions void CheckConditions(const uint32 diff); ConditionList conditions; diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index e44c03d47..01bab2e9d 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2940,15 +2940,64 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } break; } - case SMART_ACTION_DISABLE: + case SMART_ACTION_SCRIPTED_SPAWN: { - for (WorldObject* target : targets) + // Enable Scripted Spawns + switch (e.action.scriptSpawn.state) { - if (IsUnit(target)) + case 0: // Disable Respawn + { + for (WorldObject* target : targets) { - target->ToUnit()->SetImmuneToAll(!e.action.disable.state); - target->ToUnit()->SetVisible(e.action.disable.state); + if (Creature* c = target->ToCreature()) + { + CAST_AI(SmartAI, c->AI())->SetCanRespawn(false); + if (!e.action.scriptSpawn.dontDespawn) + c->DespawnOrUnsummon(); + } } + break; + } + case 1: // Respawn Once + { + for (WorldObject* target : targets) + { + if (Creature* c = target->ToCreature()) + { + CAST_AI(SmartAI, c->AI())->SetCanRespawn(true); + c->Respawn(true); + CAST_AI(SmartAI, c->AI())->SetCanRespawn(false); + } + } + break; + } + case 2: // Enable Respawning + { + for (WorldObject* target : targets) + { + if (Creature* c = target->ToCreature()) + { + CAST_AI(SmartAI, c->AI())->SetCanRespawn(true); + + // If 0, respawn immediately + if (e.action.scriptSpawn.spawnTimerMax) + c->SetRespawnTime(urand(e.action.scriptSpawn.spawnTimerMin, e.action.scriptSpawn.spawnTimerMax)); + else + c->Respawn(true); + + // If 0, use DB values + if (e.action.scriptSpawn.respawnDelay) + c->SetRespawnDelay(e.action.scriptSpawn.respawnDelay); + + // If 0, use default + if (e.action.scriptSpawn.corpseDelay) + c->SetCorpseDelay(e.action.scriptSpawn.corpseDelay); + } + } + break; + } + default: + break; } break; } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 2d8a1bd30..69e8e5d74 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -766,7 +766,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e) case SMART_ACTION_LOAD_GRID: return NO_PARAMS; case SMART_ACTION_MUSIC: return sizeof(SmartAction::music); case SMART_ACTION_SET_GUID: return sizeof(SmartAction::setGuid); - case SMART_ACTION_DISABLE: return sizeof(SmartAction::disable); + case SMART_ACTION_SCRIPTED_SPAWN: return sizeof(SmartAction::scriptSpawn); case SMART_ACTION_SET_SCALE: return sizeof(SmartAction::setScale); case SMART_ACTION_SUMMON_RADIAL: return sizeof(SmartAction::radialSummon); case SMART_ACTION_PLAY_SPELL_VISUAL: return sizeof(SmartAction::spellVisual); @@ -1949,7 +1949,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_ATTACK_STOP: case SMART_ACTION_PLAY_CINEMATIC: case SMART_ACTION_SET_GUID: - case SMART_ACTION_DISABLE: + case SMART_ACTION_SCRIPTED_SPAWN: case SMART_ACTION_SET_SCALE: case SMART_ACTION_SUMMON_RADIAL: case SMART_ACTION_PLAY_SPELL_VISUAL: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 1d65711e3..73212b424 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -716,7 +716,7 @@ enum SMART_ACTION SMART_ACTION_DO_ACTION = 223, // ActionId SMART_ACTION_ATTACK_STOP = 224, // SMART_ACTION_SET_GUID = 225, // Sends the invoker's or the base object's own ObjectGuid to target - SMART_ACTION_DISABLE = 226, // state + SMART_ACTION_SCRIPTED_SPAWN = 226, // state, spawnTimerMin, spawnTimerMax, respawnDelay, corpseDelay, dontDespawn SMART_ACTION_SET_SCALE = 227, // scale SMART_ACTION_SUMMON_RADIAL = 228, // summonEntry, summonDuration, repetitions, startAngle, stepAngle, dist SMART_ACTION_PLAY_SPELL_VISUAL = 229, // visualId, visualIdImpact @@ -1411,7 +1411,12 @@ struct SmartAction struct { SAIBool state; - } disable; + uint32 spawnTimerMin; + uint32 spawnTimerMax; + uint32 respawnDelay; + uint32 corpseDelay; + SAIBool dontDespawn; + } scriptSpawn; struct { From 558e430349e716b8585efcb66399d9475a45d0d1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 28 Aug 2024 11:18:18 +0000 Subject: [PATCH 31/46] chore(DB): import pending files Referenced commit(s): 2f850974135c39e392912512aa44b5cde5bd4b13 --- .../rev_1717715555182000500.sql => db_world/2024_08_28_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1717715555182000500.sql => db_world/2024_08_28_03.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1717715555182000500.sql b/data/sql/updates/db_world/2024_08_28_03.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1717715555182000500.sql rename to data/sql/updates/db_world/2024_08_28_03.sql index a4530f521..cef3eaaa5 100644 --- a/data/sql/updates/pending_db_world/rev_1717715555182000500.sql +++ b/data/sql/updates/db_world/2024_08_28_03.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_28_02 -> 2024_08_28_03 -- Scryers SET @CGUID := 12556; From 1d56e84fb9d8554d9c6448b18b7f688aa2d42ee0 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Wed, 28 Aug 2024 10:09:50 -0300 Subject: [PATCH 32/46] chore(SQL): Collision in 2024_08_28_03.sql (#19772) Update 2024_08_28_03.sql --- data/sql/updates/db_world/2024_08_28_03.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/sql/updates/db_world/2024_08_28_03.sql b/data/sql/updates/db_world/2024_08_28_03.sql index cef3eaaa5..b6f3a3c54 100644 --- a/data/sql/updates/db_world/2024_08_28_03.sql +++ b/data/sql/updates/db_world/2024_08_28_03.sql @@ -1,6 +1,6 @@ -- DB update 2024_08_28_02 -> 2024_08_28_03 -- Scryers -SET @CGUID := 12556; +SET @CGUID := 52417; DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+18 AND `id1` IN (23435, 23440); 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`) VALUES @@ -218,7 +218,7 @@ INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Lan (23452, 1, 0, 'Stand tall, soldiers. Show them no quarter!', 12, 0, 100, 5, 0, 0, 21633, 0, 'Commander Arcus to Player'), (23452, 2, 0, 'Victory to the Aldor! The Dragonmaw have been defeated!', 14, 0, 100, 0, 0, 0, 21728, 0, 'Commander Arcus to Commander Arcus'); -SET @CGUID := 12720; +SET @CGUID := 52437; DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+18 AND `id1` IN (23453, 23441); INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES From db79c33064caef36d911d5de04506497df65650f Mon Sep 17 00:00:00 2001 From: kasvati <96998760+kasvati@users.noreply.github.com> Date: Wed, 28 Aug 2024 20:20:22 +0200 Subject: [PATCH 33/46] fix(DB/creature_text) Remove Quel'dorei Ghosts/Wraiths broadcast_text 12690 (#19542) * fix(DB) Added missing emote text for text 12690 - Male text was missing for Quel'dorei Ghosts/Wraiths - Closes #19480 * added sql statement * Changed implementation from broadcast_text to creature_text * Added comment for quick explanation * Added new line after SQL statement as per request in comments * changing comments so sql check hopefully passes * changed from delete and insert into single update * Update rev_1722505977523322600.sql --- .../pending_db_world/rev_1722505977523322600.sql | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1722505977523322600.sql diff --git a/data/sql/updates/pending_db_world/rev_1722505977523322600.sql b/data/sql/updates/pending_db_world/rev_1722505977523322600.sql new file mode 100644 index 000000000..3033640ce --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1722505977523322600.sql @@ -0,0 +1,10 @@ +-- Removes creature reference to broadcast text +/* +https://www.azerothcore.org/wiki states that broadcast text table contains only confirmed retail data. +So to avoid polluting the table issue #19480 is being fixed in creature_text table instead. +More info in issue #19480 and PR #19542 +*/ +UPDATE `creature_text` SET +`BroadcastTextId` = 0, +`comment` = CONCAT(`comment`, ', removed BroadcastTextId 12690 (more info in PR#19542)') +WHERE `CreatureID` IN (16325, 16326); From c8c7362a1ec91ba3cdcfaec18cb00d4c907c8c39 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 28 Aug 2024 18:21:15 +0000 Subject: [PATCH 34/46] chore(DB): import pending files Referenced commit(s): db79c33064caef36d911d5de04506497df65650f --- .../rev_1722505977523322600.sql => db_world/2024_08_28_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1722505977523322600.sql => db_world/2024_08_28_04.sql} (91%) diff --git a/data/sql/updates/pending_db_world/rev_1722505977523322600.sql b/data/sql/updates/db_world/2024_08_28_04.sql similarity index 91% rename from data/sql/updates/pending_db_world/rev_1722505977523322600.sql rename to data/sql/updates/db_world/2024_08_28_04.sql index 3033640ce..7ad86845c 100644 --- a/data/sql/updates/pending_db_world/rev_1722505977523322600.sql +++ b/data/sql/updates/db_world/2024_08_28_04.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_28_03 -> 2024_08_28_04 -- Removes creature reference to broadcast text /* https://www.azerothcore.org/wiki states that broadcast text table contains only confirmed retail data. From 39a6dce4c21074dffe38d0153818c48f24bf756b Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:04:49 -0400 Subject: [PATCH 35/46] fix(DB/Waypoints): Set Promenade Sentinels to walk their paths. (#19775) Init. --- data/sql/updates/pending_db_world/promenade-running.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/sql/updates/pending_db_world/promenade-running.sql diff --git a/data/sql/updates/pending_db_world/promenade-running.sql b/data/sql/updates/pending_db_world/promenade-running.sql new file mode 100644 index 000000000..0dd404e68 --- /dev/null +++ b/data/sql/updates/pending_db_world/promenade-running.sql @@ -0,0 +1 @@ +UPDATE `waypoint_data` SET `move_type` = 0 WHERE `id` IN (1486850, 1486860, 1486870, 1486880); From e1692ae5b6f31fe77762b875a1e843c207573b3b Mon Sep 17 00:00:00 2001 From: daobashun <49193927+fangshun2004@users.noreply.github.com> Date: Thu, 29 Aug 2024 03:05:40 +0800 Subject: [PATCH 36/46] fix(scripts/npc_calvin_montague): Convert to SAI, Add emotes when completing quests (#18087) * Magic uses sniffing IDs Use the sniffer timer and factions * Wait 3 minutes if the mission fails * 1. When a task fails, it enters passive mode 2. Add 'quest_details' data to the database * Remove spaces * Delete blank lines * Modify the code as required * Update src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * Remove curly braces * Change the name of a private member variable * Move the c ++ script to smart script * Delete the C++ script Re-add the deleted quest_details data * del blank lines * Delete the C++ script file * Modify the annotation Return to the home pointset phase to 0 Return to the home point to allow the SAI phase reset * Remove spaces * Delete functions that are not in use * Update rev_1704025138911597700.sql * fix merge error - delete zone file --------- Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> --- .../rev_1704025138911597700.sql | 56 ++++++ .../eastern_kingdoms_script_loader.cpp | 2 - .../EasternKingdoms/zone_tirisfal_glades.cpp | 174 ------------------ 3 files changed, 56 insertions(+), 176 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1704025138911597700.sql delete mode 100644 src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp diff --git a/data/sql/updates/pending_db_world/rev_1704025138911597700.sql b/data/sql/updates/pending_db_world/rev_1704025138911597700.sql new file mode 100644 index 000000000..62b410425 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1704025138911597700.sql @@ -0,0 +1,56 @@ +-- Calvin Montague smart ai +SET @ENTRY := 6784; +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY; +DELETE FROM `smart_scripts` WHERE `source_type` = 9 AND `entryOrGuid` IN (678400, 678401); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 0, 0, 1, 19, 0, 100, 0, 590, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'On player accepted quest A Rogue\'s Deal (590) - Set event phase to phase 1'), +(@ENTRY, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'On player accepted quest A Rogue\'s Deal (590) - Self: storedTarget[0] = Player who accepted quest'), +(@ENTRY, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 2, 14, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On player accepted quest A Rogue\'s Deal (590) - Self: Set faction to Monster (14)'), +(@ENTRY, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On player accepted quest A Rogue\'s Deal (590) - Self: Remove npc flags QUESTGIVER'), +(@ENTRY, 0, 4, 5, 61, 0, 100, 0, 0, 0, 0, 0, 19, 256, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On player accepted quest A Rogue\'s Deal (590) - Self: Remove UNIT_FLAGS to IMMUNE_TO_PC'), +(@ENTRY, 0, 5, 6, 61, 0, 100, 0, 0, 0, 0, 0, 18, 2048, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On player accepted quest A Rogue\'s Deal (590) - Self: Set UNIT_FLAGS to PET_IN_COMBAT'), +(@ENTRY, 0, 6, 7, 61, 0, 100, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On player accepted quest A Rogue\'s Deal (590) - Self: Set react state to Aggressive'), +(@ENTRY, 0, 7, 8, 61, 0, 100, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'On player accepted quest A Rogue\'s Deal (590) - Self: Attack Player who accepted quest'), +(@ENTRY, 0, 8, 9, 61, 0, 100, 0, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On player accepted quest A Rogue\'s Deal (590) - Self: Set invincibility to 1 HP'), +(@ENTRY, 0, 9, 0, 61, 0, 100, 0, 0, 0, 0, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'On player accepted quest A Rogue\'s Deal (590) - Self: Disallow SAI phase reset'), +(@ENTRY, 0, 10, 11, 2, 1, 100, 513, 0, 30, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - When health between 0%-30%% (once phase 1) - Set event phase to phase 2'), +(@ENTRY, 0, 11, 12, 61, 0, 100, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - When health between 0%-30%% (once phase 1) - Reset faction'), +(@ENTRY, 0, 12, 13, 61, 0, 100, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - When health between 0%-30%% (once phase 1) - Remove all auras'), +(@ENTRY, 0, 13, 14, 61, 0, 100, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - When health between 0%-30%% (once phase 1) - Stop combat'), +(@ENTRY, 0, 14, 0, 61, 0, 100, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - When health between 0%-30%% (once phase 1) - Evade'), +(@ENTRY, 0, 15, 16, 7, 1, 100, 0, 0, 0, 0, 0, 19, 256, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - On evade(phase 1) - Remove UNIT_FLAGS to IMMUNE_TO_PC'), +(@ENTRY, 0, 16, 0, 61, 0, 100, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - On evade (phase 1)- Set react state to Defensive'), +(@ENTRY, 0, 17, 0, 21, 1, 100, 0, 0, 0, 0, 0, 80, 678400, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - On home reached (phase 1) - Self: Start timed action list id #Calvin Montague #0 (678400) (update out of combat) override existing // -inline'), +(@ENTRY * 100, 9, 0, 0, 0, 0, 100, 0, 150000, 150000, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Reset faction'), +(@ENTRY * 100, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 18, 256, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Set UNIT_FLAGS to IMMUNE_TO_PC'), +(@ENTRY * 100, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 82, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Add npc flags QUESTGIVER'), +(@ENTRY * 100, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Set stand state to STAND'), +(@ENTRY * 100, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Set sheath to Melee'), +(@ENTRY * 100, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - storedTarget[0] = None'), +(@ENTRY * 100, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Set invincibility to 0 HP'), +(@ENTRY * 100, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 211, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Allow SAI phase reset'), +(@ENTRY * 100, 9, 8, 0, 0, 0, 100, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Set event phase to default (0)'), +(@ENTRY, 0, 18, 0, 21, 2, 100, 0, 0, 0, 0, 0, 80, 678401, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - On home reached (phase 2) - Start timed action list id #Calvin Montague #1 (678401) (update out of combat) override existing // -inline'), +(@ENTRY * 100 + 1, 9, 0, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 66, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Look at storedTarget[0]'), +(@ENTRY * 100 + 1, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 5, 14, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Play emote ONESHOT_RUDE(DNR) (14)'), +(@ENTRY * 100 + 1, 9, 2, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Talk 0 to invoker'), +(@ENTRY * 100 + 1, 9, 3, 0, 0, 0, 100, 0, 6300, 6300, 0, 0, 11, 7737, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Cast spell Food(7737) on Self'), +(@ENTRY * 100 + 1, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 26, 590, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - storedTarget[0]: Call group event happened from quest A Rogue\'s Deal (590)'), +(@ENTRY * 100 + 1, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Reset faction'), +(@ENTRY * 100 + 1, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 18, 256, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Set UNIT_FLAGS to IMMUNE_TO_PC'), +(@ENTRY * 100 + 1, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 82, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Add npc flags QUESTGIVER'), +(@ENTRY * 100 + 1, 9, 8, 0, 0, 0, 100, 0, 0, 0, 0, 0, 19, 2048, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Remove UNIT_FLAGS to PET_IN_COMBAT'), +(@ENTRY * 100 + 1, 9, 9, 0, 0, 0, 100, 0, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Remove stand state SIT'), +(@ENTRY * 100 + 1, 9, 10, 0, 0, 0, 100, 0, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Set sheath to Melee'), +(@ENTRY * 100 + 1, 9, 11, 0, 0, 0, 100, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - storedTarget[0] = None'), +(@ENTRY * 100 + 1, 9, 12, 0, 0, 0, 100, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Set invincibility to 0 HP'), +(@ENTRY * 100 + 1, 9, 13, 0, 0, 0, 100, 0, 0, 0, 0, 0, 211, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Allow SAI phase reset'), +(@ENTRY * 100 + 1, 9, 14, 0, 0, 0, 100, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Calvin Montague - action list - Set event phase to default (0)'); + +DELETE +FROM `quest_details` +WHERE `ID` IN (590,8); +INSERT INTO `quest_details` (`ID`, `Emote1`, `Emote2`, `Emote3`, `Emote4`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `EmoteDelay4`, `VerifiedBuild`) VALUES +(8, 2, 1, 1, 0, 0, 0, 0, 0, 52237), +(590, 6, 1, 14, 0, 0, 0, 0, 0, 52237); diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp index 82f3f0d19..67360281a 100644 --- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp +++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp @@ -157,7 +157,6 @@ void AddSC_isle_of_queldanas(); void AddSC_redridge_mountains(); void AddSC_silverpine_forest(); void AddSC_stormwind_city(); -void AddSC_tirisfal_glades(); void AddSC_undercity(); void AddSC_western_plaguelands(); void AddSC_westfall(); @@ -309,7 +308,6 @@ void AddEasternKingdomsScripts() AddSC_redridge_mountains(); AddSC_silverpine_forest(); AddSC_stormwind_city(); - AddSC_tirisfal_glades(); AddSC_undercity(); AddSC_western_plaguelands(); AddSC_westfall(); diff --git a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp deleted file mode 100644 index 976162d5f..000000000 --- a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/* ScriptData -SDName: Tirisfal_Glades -SD%Complete: 100 -SDComment: Quest support: 590, 1819 -SDCategory: Tirisfal Glades -EndScriptData */ - -/* ContentData -npc_calvin_montague -go_mausoleum_door -go_mausoleum_trigger -EndContentData */ - -#include "CreatureScript.h" -#include "Player.h" -#include "ScriptedCreature.h" - -/*###### -## npc_calvin_montague -######*/ - -enum Calvin -{ - SAY_COMPLETE = 0, - SPELL_DRINK = 2639, // possibly not correct spell (but iconId is correct) - QUEST_590 = 590 -}; - -class npc_calvin_montague : public CreatureScript -{ -public: - npc_calvin_montague() : CreatureScript("npc_calvin_montague") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_590) - { - creature->SetFaction(FACTION_ENEMY); - creature->SetImmuneToPC(false); - CAST_AI(npc_calvin_montague::npc_calvin_montagueAI, creature->AI())->AttackStart(player); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_calvin_montagueAI(creature); - } - - struct npc_calvin_montagueAI : public ScriptedAI - { - npc_calvin_montagueAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 m_uiPhase; - uint32 m_uiPhaseTimer; - ObjectGuid m_uiPlayerGUID; - - void Reset() override - { - m_uiPhase = 0; - m_uiPhaseTimer = 5000; - m_uiPlayerGUID.Clear(); - - me->RestoreFaction(); - - if (!me->IsImmuneToPC()) - me->SetImmuneToPC(true); - } - - void JustEngagedWith(Unit* /*who*/) override { } - - void AttackedBy(Unit* pAttacker) override - { - if (me->GetVictim() || me->IsFriendlyTo(pAttacker)) - return; - - AttackStart(pAttacker); - } - - void DamageTaken(Unit* pDoneBy, uint32& uiDamage, DamageEffectType, SpellSchoolMask) override - { - if (!pDoneBy) - return; - - if (uiDamage >= me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage)) - { - uiDamage = 0; - - me->RestoreFaction(); - me->SetImmuneToPC(true); - me->CombatStop(true); - - m_uiPhase = 1; - - if (pDoneBy->IsPlayer()) - { - m_uiPlayerGUID = pDoneBy->GetGUID(); - } - else if (pDoneBy->IsPet()) - { - if (Unit* owner = pDoneBy->GetOwner()) - { - // not sure if this is needed. - if (owner->IsPlayer()) - { - m_uiPlayerGUID = owner->GetGUID(); - } - } - } - } - } - - void UpdateAI(uint32 diff) override - { - if (m_uiPhase) - { - if (m_uiPhaseTimer <= diff) - m_uiPhaseTimer = 7500; - else - { - m_uiPhaseTimer -= diff; - return; - } - - switch (m_uiPhase) - { - case 1: - Talk(SAY_COMPLETE); - ++m_uiPhase; - break; - case 2: - if (Player* player = ObjectAccessor::GetPlayer(*me, m_uiPlayerGUID)) - player->AreaExploredOrEventHappens(QUEST_590); - - DoCast(me, SPELL_DRINK, true); - ++m_uiPhase; - break; - case 3: - EnterEvadeMode(); - break; - } - - return; - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -void AddSC_tirisfal_glades() -{ - new npc_calvin_montague(); -} From 37d601b6c8a466414228d71986beb0689725bfb9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 28 Aug 2024 19:05:46 +0000 Subject: [PATCH 37/46] chore(DB): import pending files Referenced commit(s): 39a6dce4c21074dffe38d0153818c48f24bf756b --- .../promenade-running.sql => db_world/2024_08_28_05.sql} | 1 + .../rev_1704025138911597700.sql => db_world/2024_08_28_06.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/promenade-running.sql => db_world/2024_08_28_05.sql} (68%) rename data/sql/updates/{pending_db_world/rev_1704025138911597700.sql => db_world/2024_08_28_06.sql} (99%) diff --git a/data/sql/updates/pending_db_world/promenade-running.sql b/data/sql/updates/db_world/2024_08_28_05.sql similarity index 68% rename from data/sql/updates/pending_db_world/promenade-running.sql rename to data/sql/updates/db_world/2024_08_28_05.sql index 0dd404e68..1130064f6 100644 --- a/data/sql/updates/pending_db_world/promenade-running.sql +++ b/data/sql/updates/db_world/2024_08_28_05.sql @@ -1 +1,2 @@ +-- DB update 2024_08_28_04 -> 2024_08_28_05 UPDATE `waypoint_data` SET `move_type` = 0 WHERE `id` IN (1486850, 1486860, 1486870, 1486880); diff --git a/data/sql/updates/pending_db_world/rev_1704025138911597700.sql b/data/sql/updates/db_world/2024_08_28_06.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1704025138911597700.sql rename to data/sql/updates/db_world/2024_08_28_06.sql index 62b410425..ce61f90cb 100644 --- a/data/sql/updates/pending_db_world/rev_1704025138911597700.sql +++ b/data/sql/updates/db_world/2024_08_28_06.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_28_05 -> 2024_08_28_06 -- Calvin Montague smart ai SET @ENTRY := 6784; UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; From 92788d5f1150e029711df7460d2886c219749bc6 Mon Sep 17 00:00:00 2001 From: Walter Pagani Date: Thu, 29 Aug 2024 10:33:43 -0300 Subject: [PATCH 38/46] fix(DB/GossipMenu): Dalaran guide guards (#19787) --- data/sql/updates/pending_db_world/rev_1724894325123537700.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1724894325123537700.sql diff --git a/data/sql/updates/pending_db_world/rev_1724894325123537700.sql b/data/sql/updates/pending_db_world/rev_1724894325123537700.sql new file mode 100644 index 000000000..fcd87ecaf --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1724894325123537700.sql @@ -0,0 +1,4 @@ +-- +UPDATE `gossip_menu_option` SET `OptionBroadcastTextID`=5316 WHERE `MenuID`=10043 AND `OptionID`=1; +UPDATE `gossip_menu_option` SET `OptionBroadcastTextID`=3428 WHERE `MenuID`=10043 AND `OptionID`=7; +UPDATE `gossip_menu_option` SET `OptionBroadcastTextID`=4895 WHERE `MenuID`=10043 AND `OptionID`=10; From 070b083c1dd6315cae847d49f3897c573273361e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 29 Aug 2024 13:34:39 +0000 Subject: [PATCH 39/46] chore(DB): import pending files Referenced commit(s): 92788d5f1150e029711df7460d2886c219749bc6 --- .../rev_1724894325123537700.sql => db_world/2024_08_29_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1724894325123537700.sql => db_world/2024_08_29_00.sql} (87%) diff --git a/data/sql/updates/pending_db_world/rev_1724894325123537700.sql b/data/sql/updates/db_world/2024_08_29_00.sql similarity index 87% rename from data/sql/updates/pending_db_world/rev_1724894325123537700.sql rename to data/sql/updates/db_world/2024_08_29_00.sql index fcd87ecaf..0bc1f2fb2 100644 --- a/data/sql/updates/pending_db_world/rev_1724894325123537700.sql +++ b/data/sql/updates/db_world/2024_08_29_00.sql @@ -1,3 +1,4 @@ +-- DB update 2024_08_28_06 -> 2024_08_29_00 -- UPDATE `gossip_menu_option` SET `OptionBroadcastTextID`=5316 WHERE `MenuID`=10043 AND `OptionID`=1; UPDATE `gossip_menu_option` SET `OptionBroadcastTextID`=3428 WHERE `MenuID`=10043 AND `OptionID`=7; From e1c923ff94a4379cc6da95e5ba81e83c42560983 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Thu, 29 Aug 2024 15:10:26 -0400 Subject: [PATCH 40/46] fix(DB/Creature): Correct Promenade Sentinel speed. (#19779) Init. --- data/sql/updates/pending_db_world/promenade-speed.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/sql/updates/pending_db_world/promenade-speed.sql diff --git a/data/sql/updates/pending_db_world/promenade-speed.sql b/data/sql/updates/pending_db_world/promenade-speed.sql new file mode 100644 index 000000000..39963ba53 --- /dev/null +++ b/data/sql/updates/pending_db_world/promenade-speed.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `speed_walk` = 2.5 WHERE `entry` = 23394; From a7d7e78fedbfcaa1381a36c20714cf8eafe89499 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 29 Aug 2024 19:11:20 +0000 Subject: [PATCH 41/46] chore(DB): import pending files Referenced commit(s): e1c923ff94a4379cc6da95e5ba81e83c42560983 --- .../promenade-speed.sql => db_world/2024_08_29_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/promenade-speed.sql => db_world/2024_08_29_01.sql} (62%) diff --git a/data/sql/updates/pending_db_world/promenade-speed.sql b/data/sql/updates/db_world/2024_08_29_01.sql similarity index 62% rename from data/sql/updates/pending_db_world/promenade-speed.sql rename to data/sql/updates/db_world/2024_08_29_01.sql index 39963ba53..3229d8f84 100644 --- a/data/sql/updates/pending_db_world/promenade-speed.sql +++ b/data/sql/updates/db_world/2024_08_29_01.sql @@ -1 +1,2 @@ +-- DB update 2024_08_29_00 -> 2024_08_29_01 UPDATE `creature_template` SET `speed_walk` = 2.5 WHERE `entry` = 23394; From 1fd59e28319847b6665bb6806ba8461da3500811 Mon Sep 17 00:00:00 2001 From: Tereneckla Date: Fri, 30 Aug 2024 10:44:45 +0000 Subject: [PATCH 42/46] feature(Core/Chat): allow fmt-chrono formatting (#19794) --- src/common/Utilities/StringFormat.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/Utilities/StringFormat.h b/src/common/Utilities/StringFormat.h index 1f7ec1090..fa5aeb461 100644 --- a/src/common/Utilities/StringFormat.h +++ b/src/common/Utilities/StringFormat.h @@ -19,6 +19,7 @@ #define _STRING_FORMAT_H_ #include "Define.h" +#include #include #include #include From 2bb45fcd30d3dbf8dac2e4b11faa935674caba54 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Fri, 30 Aug 2024 08:04:08 -0400 Subject: [PATCH 43/46] fix(Scripts/BlackTemple): Adjust handling for Shared Rule spell. (#19770) --- .../updates/pending_db_world/shared-rule.sql | 2 + .../BlackTemple/boss_illidari_council.cpp | 68 ++++++++++++++----- 2 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 data/sql/updates/pending_db_world/shared-rule.sql diff --git a/data/sql/updates/pending_db_world/shared-rule.sql b/data/sql/updates/pending_db_world/shared-rule.sql new file mode 100644 index 000000000..783925bfa --- /dev/null +++ b/data/sql/updates/pending_db_world/shared-rule.sql @@ -0,0 +1,2 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` = 41455; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (41455, 'spell_illidari_council_circle_of_healing'); diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp index df364b2cd..5c20cb1e5 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp @@ -35,7 +35,8 @@ enum Says enum Spells { SPELL_EMPYREAL_EQUIVALENCY = 41333, - SPELL_SHARED_RULE = 41342, + SPELL_SHARED_RULE_DMG = 41342, + SPELL_SHARED_RULE_HEAL = 41343, SPELL_EMPYREAL_BALANCE = 41499, SPELL_BERSERK = 41924, @@ -189,6 +190,15 @@ struct boss_illidari_council : public BossAI } } + void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override + { + if (me->GetHealth() <= damage) + { + damage = me->GetHealth() - 1; + DoAction(ACTION_END_ENCOUNTER); + } + } + void UpdateAI(uint32 diff) override { if (!me->isActiveObject()) @@ -234,6 +244,19 @@ struct boss_illidari_council_memberAI : public ScriptedAI } } + void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override + { + InstanceScript* instance = me->GetInstanceScript(); + + if (me->GetHealth() <= damage) + damage = me->GetHealth() - 1; + + int32 damageTaken = damage; + Creature* target = instance->GetCreature(DATA_ILLIDARI_COUNCIL); + + me->CastCustomSpell(target->ToUnit(), SPELL_SHARED_RULE_DMG, &damageTaken, &damageTaken, &damageTaken, true, nullptr, nullptr, me->GetGUID()); + } + void KilledUnit(Unit*) override { if (events.GetNextEventTime(EVENT_KILL_TALK) == 0) @@ -246,8 +269,6 @@ struct boss_illidari_council_memberAI : public ScriptedAI void JustDied(Unit*) override { Talk(SAY_COUNCIL_DEATH); - if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) - council->GetAI()->DoAction(ACTION_END_ENCOUNTER); } void JustEngagedWith(Unit* /*who*/) override @@ -525,24 +546,9 @@ class spell_illidari_council_balance_of_power_aura : public AuraScript amount = -1; } - void Absorb(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& /*absorbAmount*/) - { - Unit* councilMember = GetTarget(); - InstanceScript* instance = councilMember->GetInstanceScript(); - if (!instance) - return; - - Creature* target = instance->GetCreature(DATA_ILLIDARI_COUNCIL); - - int32 damage = dmgInfo.GetDamage(); - if (Creature* caster = councilMember->ToCreature()) - caster->CastCustomSpell(target, SPELL_SHARED_RULE, &damage, &damage, &damage, true, nullptr, nullptr, caster->GetGUID()); - } - void Register() override { DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_illidari_council_balance_of_power_aura::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_balance_of_power_aura::Absorb, EFFECT_0); } }; @@ -659,6 +665,31 @@ class spell_illidari_council_reflective_shield_aura : public AuraScript AfterEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_reflective_shield_aura::ReflectDamage, EFFECT_0); } }; +class spell_illidari_council_circle_of_healing : public SpellScript +{ + PrepareSpellScript(spell_illidari_council_circle_of_healing); + + void HandleSharedRule(SpellEffIndex /*effIndex*/) + { + Unit* councilMember = GetHitUnit(); + if (!councilMember) + return; + + InstanceScript* instance = councilMember->GetInstanceScript(); + if (!instance) + return; + + Creature* target = instance->GetCreature(DATA_ILLIDARI_COUNCIL); + + int32 heal = GetHitHeal(); + target->CastCustomSpell(target, SPELL_SHARED_RULE_HEAL, &heal, &heal, &heal, true, nullptr, nullptr, target->GetGUID()); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidari_council_circle_of_healing::HandleSharedRule, EFFECT_0, SPELL_EFFECT_HEAL); + } +}; class spell_illidari_council_judgement : public SpellScript { @@ -716,6 +747,7 @@ void AddSC_boss_illidari_council() RegisterSpellScript(spell_illidari_council_empyreal_balance); RegisterSpellScript(spell_illidari_council_empyreal_equivalency); RegisterSpellScript(spell_illidari_council_reflective_shield_aura); + RegisterSpellScript(spell_illidari_council_circle_of_healing); RegisterSpellScript(spell_illidari_council_judgement); RegisterSpellScript(spell_illidari_council_deadly_strike_aura); } From 6b7a61483b9251839014845c4e51a02be480bb55 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 30 Aug 2024 12:05:27 +0000 Subject: [PATCH 44/46] chore(DB): import pending files Referenced commit(s): 2bb45fcd30d3dbf8dac2e4b11faa935674caba54 --- .../shared-rule.sql => db_world/2024_08_30_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/shared-rule.sql => db_world/2024_08_30_00.sql} (80%) diff --git a/data/sql/updates/pending_db_world/shared-rule.sql b/data/sql/updates/db_world/2024_08_30_00.sql similarity index 80% rename from data/sql/updates/pending_db_world/shared-rule.sql rename to data/sql/updates/db_world/2024_08_30_00.sql index 783925bfa..c9da5d584 100644 --- a/data/sql/updates/pending_db_world/shared-rule.sql +++ b/data/sql/updates/db_world/2024_08_30_00.sql @@ -1,2 +1,3 @@ +-- DB update 2024_08_29_01 -> 2024_08_30_00 DELETE FROM `spell_script_names` WHERE `spell_id` = 41455; INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (41455, 'spell_illidari_council_circle_of_healing'); From a83cd03bfb8539f9be77dafc0252018c79bfaeca Mon Sep 17 00:00:00 2001 From: ianmeesters <124554706+ianmeesters@users.noreply.github.com> Date: Fri, 30 Aug 2024 14:06:07 +0200 Subject: [PATCH 45/46] feat(Core/Player): add OnCalculateTalentsPoints hook (#19749) * playerTalentsHook * oeps :# * :# * does this work? * make reference --------- Co-authored-by: Amy Fang --- src/server/game/Entities/Player/Player.cpp | 1 + src/server/game/Scripting/ScriptDefines/PlayerScript.cpp | 5 +++++ src/server/game/Scripting/ScriptDefines/PlayerScript.h | 4 ++++ src/server/game/Scripting/ScriptMgr.h | 1 + 4 files changed, 11 insertions(+) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 6a25a83c2..2f2fec96e 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -13584,6 +13584,7 @@ uint32 Player::CalculateTalentsPoints() const } talentPointsForLevel += m_extraBonusTalentCount; + sScriptMgr->OnCalculateTalentsPoints(this, talentPointsForLevel); return uint32(talentPointsForLevel * sWorld->getRate(RATE_TALENT)); } diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp index 61d6cd18b..022914352 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp @@ -54,6 +54,11 @@ void ScriptMgr::OnPlayerJustDied(Player* player) CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_PLAYER_JUST_DIED, script->OnPlayerJustDied(player)); } +void ScriptMgr::OnCalculateTalentsPoints(Player const* player, uint32& talentPointsForLevel) +{ + CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CALCULATE_TALENTS_POINTS, script->OnCalculateTalentsPoints(player, talentPointsForLevel)); +} + void ScriptMgr::OnPlayerReleasedGhost(Player* player) { CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_PLAYER_RELEASED_GHOST, script->OnPlayerReleasedGhost(player)); diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.h b/src/server/game/Scripting/ScriptDefines/PlayerScript.h index 9495c1b5d..dfe68b18c 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.h +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.h @@ -28,6 +28,7 @@ enum PlayerHook { PLAYERHOOK_ON_PLAYER_JUST_DIED, + PLAYERHOOK_ON_CALCULATE_TALENTS_POINTS, PLAYERHOOK_ON_PLAYER_RELEASED_GHOST, PLAYERHOOK_ON_SEND_INITIAL_PACKETS_BEFORE_ADD_TO_MAP, PLAYERHOOK_ON_BATTLEGROUND_DESERTION, @@ -213,6 +214,9 @@ public: // Called when a player dies virtual void OnPlayerJustDied(Player* /*player*/) { } + // Called player talent points are calculated + virtual void OnCalculateTalentsPoints(Player const* /*player*/, uint32& /*talentPointsForLevel*/) { } + // Called when clicking the release button virtual void OnPlayerReleasedGhost(Player* /*player*/) { } diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index eed0d2f20..5096b9919 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -298,6 +298,7 @@ public: /* PlayerScript */ void OnPlayerUpdate(Player* player, uint32 p_time); void OnSendInitialPacketsBeforeAddToMap(Player* player, WorldPacket& data); void OnPlayerJustDied(Player* player); + void OnCalculateTalentsPoints(Player const* player, uint32& talentPointsForLevel); void OnPlayerReleasedGhost(Player* player); void OnPVPKill(Player* killer, Player* killed); void OnPlayerPVPFlagChange(Player* player, bool state); From 40eb616e1f576de3fd3ca215fc1250ee06953ce8 Mon Sep 17 00:00:00 2001 From: sudlud Date: Fri, 30 Aug 2024 14:08:17 +0200 Subject: [PATCH 46/46] fix(Conf): drop unused options from worldserver.conf.dist (#19725) --- .../apps/worldserver/worldserver.conf.dist | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index cf8af58cf..53038ffde 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -1289,20 +1289,6 @@ Visibility.Distance.Continents = 90 Visibility.Distance.Instances = 120 Visibility.Distance.BGArenas = 180 -# -# Visibility.Notify.Period.OnContinents -# Visibility.Notify.Period.InInstances -# Visibility.Notify.Period.InBGArenas -# Description: Time (in milliseconds) for visibility update period. Lower values may have -# performance impact. -# Default: 1000 - (Visibility.Notify.Period.OnContinents) -# 1000 - (Visibility.Notify.Period.InInstances) -# 1000 - (Visibility.Notify.Period.InBGArenas) - -Visibility.Notify.Period.OnContinents = 1000 -Visibility.Notify.Period.InInstances = 1000 -Visibility.Notify.Period.InBGArenas = 1000 - # # Visibility.ObjectSparkles # Description: Whether or not to display sparkles on gameobjects related to active quests. @@ -1721,15 +1707,6 @@ PlayerStart.MapsExplored = 0 InstantLogout = 1 -# -# CastUnstuck -# Description: Allow casting the Unstuck spell using .start or unstuck button in client -# help options. -# Default: 1 - (Enabled) -# 0 - (Disabled) - -CastUnstuck = 1 - # ################################################################################################### @@ -2103,7 +2080,6 @@ Rate.Talent.Pet = 1 # Rate.RunicPower.Loss # Rate.Focus # Rate.Energy -# Rate.Loyalty # Description: Multiplier to configure health, mana, incoming rage, loss of rage, focus # energy and loyalty increase or decrease. # Default: 1 - (Rate.Health) @@ -2114,7 +2090,6 @@ Rate.Talent.Pet = 1 # 1 - (Rate.RunicPower.Loss) # 1 - (Rate.Focus) # 1 - (Rate.Energy) -# 1 - (Rate.Loyalty) Rate.Health = 1 Rate.Mana = 1