diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml index f38c8b42a..f1658fb24 100644 --- a/.github/workflows/codestyle.yml +++ b/.github/workflows/codestyle.yml @@ -13,8 +13,12 @@ jobs: if: github.repository == 'liyunfan1223/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) 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 diff --git a/data/sql/updates/db_world/2024_08_26_02.sql b/data/sql/updates/db_world/2024_08_26_02.sql new file mode 100644 index 000000000..6fd9a8e14 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_26_02.sql @@ -0,0 +1,47 @@ +-- DB update 2024_08_26_01 -> 2024_08_26_02 +-- 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'); diff --git a/data/sql/updates/db_world/2024_08_27_00.sql b/data/sql/updates/db_world/2024_08_27_00.sql new file mode 100644 index 000000000..f682feaa8 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_27_00.sql @@ -0,0 +1,2 @@ +-- DB update 2024_08_26_02 -> 2024_08_27_00 +UPDATE `creature_template` SET `minlevel` = 73, `maxlevel` = 73 WHERE `entry` = 22952; diff --git a/data/sql/updates/db_world/2024_08_27_01.sql b/data/sql/updates/db_world/2024_08_27_01.sql new file mode 100644 index 000000000..1f471d571 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_27_01.sql @@ -0,0 +1,2 @@ +-- DB update 2024_08_27_00 -> 2024_08_27_01 +UPDATE `creature_template` SET `unit_class` = 1 WHERE `entry` = 22917; diff --git a/data/sql/updates/db_world/2024_08_27_02.sql b/data/sql/updates/db_world/2024_08_27_02.sql new file mode 100644 index 000000000..ffe48a1c9 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_27_02.sql @@ -0,0 +1,11 @@ +-- 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\''), +(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/data/sql/updates/db_world/2024_08_27_03.sql b/data/sql/updates/db_world/2024_08_27_03.sql new file mode 100644 index 000000000..0df605514 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_27_03.sql @@ -0,0 +1,5 @@ +-- 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 +(41357, 'spell_gen_select_target_count_15_3'); diff --git a/data/sql/updates/db_world/2024_08_27_04.sql b/data/sql/updates/db_world/2024_08_27_04.sql new file mode 100644 index 000000000..fbca7ecd1 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_27_04.sql @@ -0,0 +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'); diff --git a/data/sql/updates/db_world/2024_08_27_05.sql b/data/sql/updates/db_world/2024_08_27_05.sql new file mode 100644 index 000000000..a36fd6b21 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_27_05.sql @@ -0,0 +1,23 @@ +-- 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; +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'); diff --git a/data/sql/updates/db_world/2024_08_28_00.sql b/data/sql/updates/db_world/2024_08_28_00.sql new file mode 100644 index 000000000..43d39fc40 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_28_00.sql @@ -0,0 +1,7 @@ +-- 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'), +(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'); diff --git a/data/sql/updates/db_world/2024_08_28_01.sql b/data/sql/updates/db_world/2024_08_28_01.sql new file mode 100644 index 000000000..703c0021d --- /dev/null +++ b/data/sql/updates/db_world/2024_08_28_01.sql @@ -0,0 +1,6 @@ +-- 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'), +(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\''); diff --git a/data/sql/updates/db_world/2024_08_28_02.sql b/data/sql/updates/db_world/2024_08_28_02.sql new file mode 100644 index 000000000..5c9e45c56 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_28_02.sql @@ -0,0 +1,13 @@ +-- 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; + +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'); diff --git a/data/sql/updates/db_world/2024_08_28_03.sql b/data/sql/updates/db_world/2024_08_28_03.sql new file mode 100644 index 000000000..b6f3a3c54 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_28_03.sql @@ -0,0 +1,490 @@ +-- DB update 2024_08_28_02 -> 2024_08_28_03 +-- Scryers +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 +(@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 := 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 +(@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/data/sql/updates/db_world/2024_08_28_04.sql b/data/sql/updates/db_world/2024_08_28_04.sql new file mode 100644 index 000000000..7ad86845c --- /dev/null +++ b/data/sql/updates/db_world/2024_08_28_04.sql @@ -0,0 +1,11 @@ +-- 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. +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); diff --git a/data/sql/updates/db_world/2024_08_28_05.sql b/data/sql/updates/db_world/2024_08_28_05.sql new file mode 100644 index 000000000..1130064f6 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_28_05.sql @@ -0,0 +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/db_world/2024_08_28_06.sql b/data/sql/updates/db_world/2024_08_28_06.sql new file mode 100644 index 000000000..ce61f90cb --- /dev/null +++ b/data/sql/updates/db_world/2024_08_28_06.sql @@ -0,0 +1,57 @@ +-- 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; +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/data/sql/updates/db_world/2024_08_29_00.sql b/data/sql/updates/db_world/2024_08_29_00.sql new file mode 100644 index 000000000..0bc1f2fb2 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_29_00.sql @@ -0,0 +1,5 @@ +-- 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; +UPDATE `gossip_menu_option` SET `OptionBroadcastTextID`=4895 WHERE `MenuID`=10043 AND `OptionID`=10; diff --git a/data/sql/updates/db_world/2024_08_29_01.sql b/data/sql/updates/db_world/2024_08_29_01.sql new file mode 100644 index 000000000..3229d8f84 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_29_01.sql @@ -0,0 +1,2 @@ +-- DB update 2024_08_29_00 -> 2024_08_29_01 +UPDATE `creature_template` SET `speed_walk` = 2.5 WHERE `entry` = 23394; diff --git a/data/sql/updates/db_world/2024_08_30_00.sql b/data/sql/updates/db_world/2024_08_30_00.sql new file mode 100644 index 000000000..c9da5d584 --- /dev/null +++ b/data/sql/updates/db_world/2024_08_30_00.sql @@ -0,0 +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'); 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 diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 507aeb113..321738c7f 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 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/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(); 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 { diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index f51d381e4..ca1be0ccf 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1946,11 +1946,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(); @@ -1961,10 +1971,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); @@ -1986,10 +1996,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(); @@ -2017,6 +2025,9 @@ void Creature::setDeathState(DeathState s, bool despawn) } } +/** + * @param force Force the respawn by killing the creature. + */ void Creature::Respawn(bool force) { if (force) @@ -2041,7 +2052,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); @@ -2083,8 +2094,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); @@ -2103,7 +2113,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; @@ -2121,7 +2131,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) @@ -2149,7 +2159,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()) @@ -2195,8 +2205,6 @@ void Creature::InitializeReactState() SetReactState(REACT_PASSIVE); else SetReactState(REACT_AGGRESSIVE); - /*else if (IsCivilian()) - SetReactState(REACT_DEFENSIVE);*/ } bool Creature::HasMechanicTemplateImmunity(uint32 mask) const @@ -2358,8 +2366,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)) @@ -2371,7 +2378,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) @@ -2387,7 +2396,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) @@ -2630,7 +2641,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; } @@ -2781,6 +2792,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) @@ -3147,6 +3161,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)) @@ -3158,6 +3175,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/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index fbe3820d5..c2493134d 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -13595,6 +13595,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/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2c48d3aa4..2844975d3 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! @@ -10348,6 +10355,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) @@ -10424,6 +10435,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()) @@ -16617,7 +16631,7 @@ void Unit::ResumeMovement(uint32 timer /* = 0*/, uint8 slot /* = 0*/) movementGenerator->Resume(timer); } -void Unit::StopMovingOnCurrentPos() // pussywizard +void Unit::StopMovingOnCurrentPos() { ClearUnitState(UNIT_STATE_MOVING); @@ -20518,6 +20532,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)) @@ -20536,6 +20556,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 20d1e6626..634a84226 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); } @@ -1609,7 +1610,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 002a933c2..710177ab1 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) 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 diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp index b18b64c54..3e4713adb 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 51b54ebb0..0afa8081d 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 10470e178..91fc1f271 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -331,6 +331,7 @@ public: /* PlayerScript */ void OnAfterPlayerUpdate(Player* player, uint32 diff); 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); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 1c315f532..2e3c2d2ce 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3065,16 +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 - { - 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; } } } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 6eeeaa127..debc5af85 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; } 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(); -} 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..5c20cb1e5 --- /dev/null +++ b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp @@ -0,0 +1,753 @@ +/* + * 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_EQUIVALENCY = 41333, + SPELL_SHARED_RULE_DMG = 41342, + SPELL_SHARED_RULE_HEAL = 41343, + 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; + + 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)) + { + 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 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()) + return; + + if (!SelectTargetFromPlayerList(115.0f)) + { + EnterEvadeMode(EVADE_REASON_NO_HOSTILES); + return; + } + scheduler.Update(diff); + } +}; + +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 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) + { + Talk(SAY_COUNCIL_SLAY); + events.ScheduleEvent(EVENT_KILL_TALK, 6000); + } + } + + void JustDied(Unit*) override + { + Talk(SAY_COUNCIL_DEATH); + } + + 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 absorption 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 + { + _targetCount = 0; + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (GetHitUnit()) + { + _targetCount++; + } + } + + void HandleAfterCast() + { + if (_targetCount != 4) + { + GetCaster()->ToCreature()->AI()->EnterEvadeMode(); + 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->SetMaxHealth(GetCaster()->GetMaxHealth() / _targetCount); + target->SetHealth(GetCaster()->GetHealth() / _targetCount); + target->LowerPlayerDamageReq(target->GetMaxHealth()); + } + } + + 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: + 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; +}; + +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_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 +{ + 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_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); +} 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); -} diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index d5ca8b153..42a12e526 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 @@ -5345,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);