diff --git a/.github/workflows/build_dbimport.yml b/.github/workflows/build_dbimport.yml index 34b8f4988792ec..ecc4068d158f9a 100644 --- a/.github/workflows/build_dbimport.yml +++ b/.github/workflows/build_dbimport.yml @@ -23,7 +23,7 @@ jobs: COMPILER: ${{ matrix.compiler }} if: github.repository == 'azerothcore/azerothcore-wotlk' && !github.event.pull_request.draft steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache uses: actions/cache@v3 env: diff --git a/.github/workflows/check_pending_sql.yml b/.github/workflows/check_pending_sql.yml index f75913bb043e62..52ea18acb2a457 100644 --- a/.github/workflows/check_pending_sql.yml +++ b/.github/workflows/check_pending_sql.yml @@ -5,7 +5,8 @@ on: jobs: check-pending-sql: runs-on: ubuntu-latest + if: github.repository == 'azerothcore/azerothcore-wotlk' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Check pending SQL run: source ./apps/ci/ci-pending.sh diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml index 910cd6e490825d..acce90c0dd03cb 100644 --- a/.github/workflows/codestyle.yml +++ b/.github/workflows/codestyle.yml @@ -9,8 +9,9 @@ jobs: matrix: os: [ubuntu-20.04] runs-on: ${{ matrix.os }} + if: github.repository == 'azerothcore/azerothcore-wotlk' name: check codestyle steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Check core codestyle run: source ./apps/ci/ci-codestyle.sh diff --git a/.github/workflows/core_build.yml b/.github/workflows/core_build.yml index b068a80ba5839f..c64f7178dcee28 100644 --- a/.github/workflows/core_build.yml +++ b/.github/workflows/core_build.yml @@ -23,7 +23,7 @@ jobs: COMPILER: ${{ matrix.compiler }} if: github.repository == 'azerothcore/azerothcore-wotlk' && !github.event.pull_request.draft steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache uses: actions/cache@v3 with: diff --git a/.github/workflows/core_matrix_build.yml b/.github/workflows/core_matrix_build.yml index 9dc0595af85131..76ae747e31dffe 100644 --- a/.github/workflows/core_matrix_build.yml +++ b/.github/workflows/core_matrix_build.yml @@ -40,7 +40,7 @@ jobs: || github.event.label.name == 'run-build') ) steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache uses: actions/cache@v3 with: diff --git a/.github/workflows/core_modules_build.yml b/.github/workflows/core_modules_build.yml index 0997b0b53e52d2..586edcfa478cae 100644 --- a/.github/workflows/core_modules_build.yml +++ b/.github/workflows/core_modules_build.yml @@ -34,7 +34,7 @@ jobs: || github.event.label.name == 'run-build') ) steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Checkout modules run: ./apps/ci/ci-install-modules.sh if: matrix.modules == 'with' diff --git a/.github/workflows/cpp-check.yml b/.github/workflows/cpp-check.yml index 7a2cac94d17874..ea1f7adbb3476f 100644 --- a/.github/workflows/cpp-check.yml +++ b/.github/workflows/cpp-check.yml @@ -21,17 +21,14 @@ jobs: if: github.repository == 'azerothcore/azerothcore-wotlk' name: cpp check steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: cpp check run: | sudo apt update -y sudo apt install -y cppcheck - cppcheck --force --inline-suppr \ - -i src/server/game/Achievements/AchievementMgr.cpp \ - -i src/server/game/AuctionHouse/AuctionHouseMgr.cpp \ - -i src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp \ - -i src/server/game/DungeonFinding/LFGMgr.cpp \ - -i src/server/game/Entities/GameObject/GameObject.cpp \ - -i src/server/game/Entities/Pet/Pet.cpp \ - -i src/server/game/Entities/Player/Player.cpp \ - src/ + cppcheck --force --inline-suppr --suppressions-list=./.suppress.cppcheck src/ --output-file=report.txt + + if [ -s report.txt ]; then # if file is not empty + cat report.txt + exit 1 # let github action fails + fi diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 70e658685fc30b..2dfc535eba3d4e 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -40,7 +40,7 @@ jobs: docker --version docker compose version - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # we need the entire history for the ac-dev-server # with: # fetch-depth: 2 @@ -108,7 +108,7 @@ jobs: docker --version docker compose version - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # we need the entire history for the ac-dev-server # with: # fetch-depth: 2 diff --git a/.github/workflows/import_pending.yml b/.github/workflows/import_pending.yml index d4eb1322f8614c..fd5bdf0776215f 100644 --- a/.github/workflows/import_pending.yml +++ b/.github/workflows/import_pending.yml @@ -9,9 +9,10 @@ jobs: strategy: fail-fast: false runs-on: ubuntu-20.04 + permissions: write-all if: github.repository == 'azerothcore/azerothcore-wotlk' && !github.event.pull_request.draft steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: persist-credentials: false # If we're fetching all the history in a later step it makes sense to @@ -26,7 +27,8 @@ jobs: - name: Import and commit pending sql run: | - git config user.email "azerothcorebot@gmail.com" && git config user.name "AzerothCoreBot" + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" # Get the latest changes from git git pull --rebase origin "${{ github.ref_name }}" bash bin/acore-db-pendings @@ -39,7 +41,7 @@ jobs: BRANCH: ${{ github.ref_name }} - name: Push changes - uses: ad-m/github-push-action@fe38f0a751bf9149f0270cc1fe20bf9156854365 + uses: ad-m/github-push-action@master with: github_token: ${{ secrets.AC_GITHUB_TOKEN }} # Noting that the branch name can only be master, as per the event diff --git a/.github/workflows/macos_build.yml b/.github/workflows/macos_build.yml index 63ac5f9833226b..46e3a961812cc9 100644 --- a/.github/workflows/macos_build.yml +++ b/.github/workflows/macos_build.yml @@ -25,7 +25,7 @@ jobs: && !github.event.pull_request.draft && (github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'run-build') || github.event.label.name == 'run-build') steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache uses: actions/cache@v3 with: diff --git a/.github/workflows/pr_labeler.yml b/.github/workflows/pr_labeler.yml index 0c76a2520f02cb..4e231bb0be168d 100644 --- a/.github/workflows/pr_labeler.yml +++ b/.github/workflows/pr_labeler.yml @@ -5,9 +5,14 @@ on: jobs: triage: runs-on: ubuntu-20.04 + permissions: write-all + if: github.repository == 'azerothcore/azerothcore-wotlk' steps: - - uses: actions/labeler@v3 + - uses: actions/checkout@v4 with: - repo-token: ${{ secrets.AC_GITHUB_TOKEN }} + persist-credentials: true + - uses: actions/labeler@v4 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} configuration-path: .github/labeler.yml sync-labels: true diff --git a/.github/workflows/tools_build.yml b/.github/workflows/tools_build.yml index 944e2a38e97454..6044cc03626db8 100644 --- a/.github/workflows/tools_build.yml +++ b/.github/workflows/tools_build.yml @@ -23,7 +23,7 @@ jobs: COMPILER: ${{ matrix.compiler }} if: github.repository == 'azerothcore/azerothcore-wotlk' && !github.event.pull_request.draft steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache uses: actions/cache@v3 env: diff --git a/.github/workflows/windows_build.yml b/.github/workflows/windows_build.yml index 082155b432eaaf..76d78e7e0a6849 100644 --- a/.github/workflows/windows_build.yml +++ b/.github/workflows/windows_build.yml @@ -25,7 +25,7 @@ jobs: && !github.event.pull_request.draft && (github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'run-build') || github.event.label.name == 'run-build') steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.9 - name: Configure OS diff --git a/.suppress.cppcheck b/.suppress.cppcheck new file mode 100644 index 00000000000000..a29d5a58962d35 --- /dev/null +++ b/.suppress.cppcheck @@ -0,0 +1 @@ +cppcheckError diff --git a/apps/docker/docker-cmd.sh b/apps/docker/docker-cmd.sh index 89e41e14a27598..3a75174adc9e62 100644 --- a/apps/docker/docker-cmd.sh +++ b/apps/docker/docker-cmd.sh @@ -79,7 +79,6 @@ while [[ $# -gt 0 ]]; do pull) set -x docker compose --profile local --profile dev --profile dev-build pull - docker image prune -f set +x shift ;; @@ -87,7 +86,6 @@ while [[ $# -gt 0 ]]; do build:nocache) set -x docker compose --profile local --profile dev --profile dev-build build --no-cache - docker image prune -f docker compose run --rm --no-deps ac-dev-build /bin/bash /azerothcore/apps/docker/docker-build-dev.sh set +x shift @@ -95,7 +93,6 @@ while [[ $# -gt 0 ]]; do clean:build) set -x - docker image prune -f docker compose run --rm --no-deps ac-dev-server bash acore.sh compiler clean docker compose run --rm --no-deps ac-dev-server bash acore.sh compiler ccacheClean set +x @@ -141,7 +138,6 @@ while [[ $# -gt 0 ]]; do build:prod|prod:build) set -x docker compose --profile prod build - docker image prune -f set +x shift ;; diff --git a/data/sql/updates/db_characters/2023_09_16_00.sql b/data/sql/updates/db_characters/2023_09_16_00.sql new file mode 100644 index 00000000000000..fbaccf15e77a85 --- /dev/null +++ b/data/sql/updates/db_characters/2023_09_16_00.sql @@ -0,0 +1,7 @@ +-- DB update 2023_05_23_00 -> 2023_09_16_00 +-- +ALTER TABLE `profanity_name` + CHANGE COLUMN `name` `name` VARCHAR(12) NOT NULL COLLATE 'utf8mb4_bin' FIRST; + +ALTER TABLE `reserved_name` + CHANGE COLUMN `name` `name` VARCHAR(12) NOT NULL COLLATE 'utf8mb4_bin' FIRST; diff --git a/data/sql/updates/db_world/2023_09_17_00.sql b/data/sql/updates/db_world/2023_09_17_00.sql new file mode 100644 index 00000000000000..823847a35a5ce8 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_00.sql @@ -0,0 +1,37 @@ +-- DB update 2023_09_15_02 -> 2023_09_17_00 +-- modernize https://github.com/azerothcore/azerothcore-wotlk/pull/9912 + +UPDATE `creature` SET `CreateObject` = 2 WHERE `guid` IN (46438, 46449, 46459, 46461, 46462, 46573, 46586, 46714, 46715, 46912, 46913, 46915, 46916, 46917, 46918, 46919, 46920, 46921, 46922, 46923, 46924, 46925, 46926, 46927, 46928, 46929, 46930, 46931, 46932, 46933, 46934, 46935, 46936, 46937, 46938, 46939, 46940, 46941, 46942, 46943, 46944, 46945, 46946, 46947, 46948, 46949, 46950, 46951, 46952, 46953, 46954, 46955, 46957, 46958, 46971, 46972, 46974, 46981, 46997, 46998, 46999, 47000, 47001, 47002, 47003, 47004, 47006, 47008, 47009, 47010, 47012, 47016, 47017, 47029, 47030, 47031, 47037, 47038, 47039, 47052, 47053, 47054, 47055, 47056, 47057, 47060, 47061, 47062, 47208, 47249, 47262, 47263, 47267, 47268, 47269, 47270, 47271, 47280, 47281, 47282, 47283, 47284, 47285, 47286, 47287, 47288, 47290, 47310, 47312, 47314, 47315, 47316, 47317, 47319, 47320, 47321, 47322, 47324, 47325, 47327, 47328, 47329, 47330, 47331, 47332, 47333, 47334, 47335, 47336, 47337, 47338, 47340, 47341, 47342, 47343, 47344, 47345, 47346, 47350, 47660, 47752, 47863, 47876, 47880, 47883, 47900, 47905, 47907, 47911, 47915, 47921, 47922, 47925, 47926, 47928, 49560, 49561, 49562, 49563, 49564, 49565, 49566, 49567, 49568, 49569, 49570, 49571, 49572, 49610, 49611, 49612, 49613, 49614, 49615, 49616, 49617, 49620, 49621, 49622, 49623, 49626, 49627, 49628, 49629, 49630, 49631, 49632, 49633, 49634, 49635, 49636, 49637, 49638, 49639, 49640, 49641, 49642, 49643, 49644, 49645, 49646, 49648); + +UPDATE `creature` SET `CreateObject` = 1 WHERE `guid` IN (47326, 47339, 47289); + +-- modernize https://github.com/azerothcore/azerothcore-wotlk/pull/9943 + +UPDATE `creature` SET `CreateObject` = 2 WHERE `guid` IN (46439, 47917, 47916, 47931, 47913); +UPDATE `creature` SET `CreateObject` = 1 WHERE `guid` IN (46394, 49845, 49855); + +-- modernize https://github.com/azerothcore/azerothcore-wotlk/pull/10052 +UPDATE `creature` SET `CreateObject` = 2 WHERE `guid` IN (49818, 49850, 49819); + +-- modernize https://github.com/azerothcore/azerothcore-wotlk/pull/10282 +UPDATE `creature` SET `CreateObject` = 2 WHERE `guid` IN (46446, 46452, 46463, 47372, 47373, 47374, 47375, 47376, 47378, 47519, 47520, 47521, 47522, 47523, 47524, 47525, 47531, 47936, 49882, 49883, 49884, 49889, 49897, 49898, 49899); + +-- modernize https://github.com/azerothcore/azerothcore-wotlk/pull/10285 +UPDATE `creature` SET `CreateObject` = 2 WHERE `guid` IN (47527, 46431, 46464, 47352, 47355, 47356, 47361, 47363, 47377, 47379, 47380, 47381, 47382, 47383, 47505, 47516, 47517, 47518, 47633, 47647, 47663, 47857, 47919, 47933, 47937, 49860, 49861, 49862, 49865, 49880, 49881, 49900); + +-- modernize https://github.com/azerothcore/azerothcore-wotlk/pull/12702 +SET @GUID :=88354; +UPDATE `creature` SET `CreateObject` = 2 WHERE `guid` BETWEEN @GUID+0 AND @GUID+96; + +-- modernize https://github.com/azerothcore/azerothcore-wotlk/pull/12751 +SET @GUID :=94862; +UPDATE `creature` SET `CreateObject` = 2 WHERE `guid` BETWEEN @GUID+0 AND @GUID+72; + +-- modernize https://github.com/azerothcore/azerothcore-wotlk/pull/12765 +SET @GUID :=72707; +UPDATE `creature` SET `CreateObject` = 2 WHERE `guid` BETWEEN @GUID+0 AND @GUID+45; + +-- modernize https://github.com/azerothcore/azerothcore-wotlk/pull/12854 +SET @GUID :=132314; +UPDATE `creature` SET `CreateObject` = 2 WHERE `guid` BETWEEN @GUID+0 AND @GUID+83; +UPDATE `creature` SET `CreateObject` = 1 WHERE `guid` IN (@GUID+25, @GUID+38, @GUID+83); diff --git a/data/sql/updates/db_world/2023_09_17_01.sql b/data/sql/updates/db_world/2023_09_17_01.sql new file mode 100644 index 00000000000000..f2e339e641b69d --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_01.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_17_00 -> 2023_09_17_01 +-- +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|256 WHERE (`entry` = 15689); diff --git a/data/sql/updates/db_world/2023_09_17_02.sql b/data/sql/updates/db_world/2023_09_17_02.sql new file mode 100644 index 00000000000000..42fd4eae7a753e --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_02.sql @@ -0,0 +1,10 @@ +-- DB update 2023_09_17_01 -> 2023_09_17_02 +-- +DELETE FROM `waypoint_data` WHERE `id` = 1354890; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(1354890, 1, -11169.11, -1908.5563, 165.76112, NULL, 0, 0, 0, 100, 0), +(1354890, 2, -11184.444, -1887.7946, 158.35687, NULL, 0, 0, 0, 100, 0), +(1354890, 3, -11194.229, -1875.3362, 153.53537, NULL, 0, 0, 0, 100, 0), +(1354890, 4, -11184.444, -1887.7946, 158.35687, NULL, 0, 0, 0, 100, 0), +(1354890, 5, -11169.11, -1908.5563, 165.76112, NULL, 0, 0, 0, 100, 0), +(1354890, 6, -11104.563, -1856.9681, 165.76112, NULL, 0, 0, 0, 100, 0); diff --git a/data/sql/updates/db_world/2023_09_17_03.sql b/data/sql/updates/db_world/2023_09_17_03.sql new file mode 100644 index 00000000000000..d887c86d040f85 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_03.sql @@ -0,0 +1,11 @@ +-- DB update 2023_09_17_02 -> 2023_09_17_03 +-- +DELETE FROM `spell_script_names` WHERE `spell_id` = 30629 AND `ScriptName` = 'spell_magtheridon_debris_target_selector'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(30629, 'spell_magtheridon_debris_target_selector'); + +UPDATE `creature_template` SET `unit_flags` = `unit_flags`|33554432, `AIName` = '', `ScriptName` = 'npc_target_trigger' WHERE `entry` = 17516; + +DELETE FROM `creature_template_movement` WHERE (`CreatureId` = 17516); +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`, `InteractionPauseTimer`) VALUES +(17516, 0, 0, 0, 1, 0, 0, 0); diff --git a/data/sql/updates/db_world/2023_09_17_04.sql b/data/sql/updates/db_world/2023_09_17_04.sql new file mode 100644 index 00000000000000..f117ffd69674f0 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_04.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_17_03 -> 2023_09_17_04 +-- +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|256 WHERE (`entry` = 17521); diff --git a/data/sql/updates/db_world/2023_09_17_05.sql b/data/sql/updates/db_world/2023_09_17_05.sql new file mode 100644 index 00000000000000..03a9400582b6e5 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_05.sql @@ -0,0 +1,56 @@ +-- DB update 2023_09_17_04 -> 2023_09_17_05 +-- +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 21205); +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 +(21205, 0, 0, 0, 0, 0, 100, 0, 0, 5000, 20000, 35000, 0, 0, 11, 38363, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Ravenous Flayer Matriarch - In Combat - Cast \'Gushing Wound\''), +(21205, 0, 1, 0, 0, 0, 100, 0, 0, 3000, 15000, 30000, 0, 0, 11, 36464, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Ravenous Flayer Matriarch - In Combat - Cast \'The Den Mother`s Mark\''), +(21205, 0, 2, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 53, 0, 2120500, 1, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ravenous Flayer Matriarch - On Respawn - Start Patrol Path 2120500'), +(21205, 0, 3, 0, 1, 0, 100, 0, 60000, 180000, 60000, 180000, 0, 0, 80, 2120500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ravenous Flayer Matriarch - Out of Combat - Run Script'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2120500); +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 +(2120500, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 54, 30000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ravenous Flayer Matriarch - Actionlist - Pause Waypoint'), +(2120500, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 36691, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ravenous Flayer Matriarch - Actionlist - Cast \'Serverside - Lay Ravenous Flayer Egg\''), +(2120500, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 89, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ravenous Flayer Matriarch - Actionlist - Start Random Movement'), +(2120500, 9, 3, 0, 0, 0, 100, 0, 20000, 30000, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ravenous Flayer Matriarch - Actionlist - Resume Waypoint'); + +DELETE FROM `creature` WHERE `id1` = 21205 AND `guid` = 85392; +INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(85392, 21205, 530, 3520, 3520, -2730.536376953125, 1150.532958984375, 63.02117919921875, 3.796946525573730468, 300, 48069, 2, 'Scripted Pathing'); + +DELETE FROM `creature_addon` WHERE `guid` = 85392; +DELETE FROM `waypoint_data` WHERE `id` = 853920; + +DELETE FROM `waypoints` WHERE `entry` = 2120500; +INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `point_comment`) VALUES +(2120500, 1 , -2746.24, 1138.448, 54.15343, 'Ravenous Flayer Matriarch'), +(2120500, 2 , -2762.292, 1128.408, 46.53087, 'Ravenous Flayer Matriarch'), +(2120500, 3 , -2729.597, 1104.097, 49.9248, 'Ravenous Flayer Matriarch'), +(2120500, 4 , -2727.395, 1087.502, 48.17071, 'Ravenous Flayer Matriarch'), +(2120500, 5 , -2728.122, 1075.56, 45.84283, 'Ravenous Flayer Matriarch'), +(2120500, 6 , -2710.212, 1072.808, 47.86968, 'Ravenous Flayer Matriarch'), +(2120500, 7 , -2692.166, 1095.084, 51.25895, 'Ravenous Flayer Matriarch'), +(2120500, 8 , -2676.87, 1087.67, 48.08696, 'Ravenous Flayer Matriarch'), +(2120500, 9 , -2651.984, 1074.549, 49.94732, 'Ravenous Flayer Matriarch'), +(2120500, 10, -2634.343, 1060.091, 50.21058, 'Ravenous Flayer Matriarch'), +(2120500, 11, -2619.968, 1053.699, 37.64632, 'Ravenous Flayer Matriarch'), +(2120500, 12, -2598.035, 1047.925, 43.43085, 'Ravenous Flayer Matriarch'), +(2120500, 13, -2571.256, 1035.177, 43.26862, 'Ravenous Flayer Matriarch'), +(2120500, 14, -2563.9033, 1032.3075, 37.875877, 'Ravenous Flayer Matriarch - Decomposed'), +(2120500, 15, -2561.1533, 1031.0575, 33.125877, 'Ravenous Flayer Matriarch - Decomposed'), +(2120500, 16, -2552.076, 1026.859, 37.60755, 'Ravenous Flayer Matriarch'), +(2120500, 17, -2521.413, 1022.475, 42.70882, 'Ravenous Flayer Matriarch'), +(2120500, 18, -2516.2585, 1031.3173, 39.342514, 'Ravenous Flayer Matriarch - Decomposed'), +(2120500, 19, -2508.908, 1042.702, 49.50398, 'Ravenous Flayer Matriarch'), +(2120500, 20, -2502.511, 1057.798, 53.36262, 'Ravenous Flayer Matriarch'), +(2120500, 21, -2518.216, 1084.736, 63.13983, 'Ravenous Flayer Matriarch'), +(2120500, 22, -2519.813, 1103.396, 66.57159, 'Ravenous Flayer Matriarch'), +(2120500, 23, -2526.526, 1123.956, 72.65863, 'Ravenous Flayer Matriarch'), +(2120500, 24, -2555.379, 1145.952, 76.91769, 'Ravenous Flayer Matriarch'), +(2120500, 25, -2574.61, 1140.253, 74.28946, 'Ravenous Flayer Matriarch'), +(2120500, 26, -2581.985, 1117.115, 68.20245, 'Ravenous Flayer Matriarch'), +(2120500, 27, -2606.013, 1116.443, 66.19119, 'Ravenous Flayer Matriarch'), +(2120500, 28, -2631.04, 1119.793, 64.49197, 'Ravenous Flayer Matriarch'), +(2120500, 29, -2661.714, 1119.632, 64.44809, 'Ravenous Flayer Matriarch'), +(2120500, 30, -2698.282, 1122.563, 58.28287, 'Ravenous Flayer Matriarch'), +(2120500, 31, -2731.417, 1141.435, 59.53944, 'Ravenous Flayer Matriarch'); diff --git a/data/sql/updates/db_world/2023_09_17_06.sql b/data/sql/updates/db_world/2023_09_17_06.sql new file mode 100644 index 00000000000000..31eec4635d14ad --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_06.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_17_05 -> 2023_09_17_06 +-- +UPDATE `creature_addon` SET `auras` = '' WHERE `guid` = 39059; diff --git a/data/sql/updates/db_world/2023_09_17_07.sql b/data/sql/updates/db_world/2023_09_17_07.sql new file mode 100644 index 00000000000000..ac2d924da6a77a --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_07.sql @@ -0,0 +1,166 @@ +-- DB update 2023_09_17_06 -> 2023_09_17_07 +-- https://github.com/TrinityCore/TrinityCore/commit/dbcbfaa6c7834507b0eba291b45b3927d73ac6d0 +DELETE FROM `creature_text` WHERE `CreatureID` IN (18318,18319,18320,18321,18322,18323,18325,18326,18327,18328) AND `GroupID` = 0; +INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES +(18318,0,0,'In Terokk\'s name!',12,0,100,0,0,0,16716,0,'Sethekk Halls Trash'), +(18318,0,1,'Protect the Veil!',12,0,100,0,0,0,16717,0,'Sethekk Halls Trash'), +(18318,0,2,'Darkfire -- avenge us!',12,0,100,0,0,0,16718,0,'Sethekk Halls Trash'), +(18318,0,3,'Ssssekk-sara Rith-nealaak!',12,0,100,0,0,0,16719,0,'Sethekk Halls Trash'), +(18318,0,4,'Arak-ha!',12,0,100,0,0,0,16720,0,'Sethekk Halls Trash'), + +(18319,0,0,'In Terokk\'s name!',12,0,100,0,0,0,16716,0,'Sethekk Halls Trash'), +(18319,0,1,'Protect the Veil!',12,0,100,0,0,0,16717,0,'Sethekk Halls Trash'), +(18319,0,2,'Darkfire -- avenge us!',12,0,100,0,0,0,16718,0,'Sethekk Halls Trash'), +(18319,0,3,'Ssssekk-sara Rith-nealaak!',12,0,100,0,0,0,16719,0,'Sethekk Halls Trash'), +(18319,0,4,'Arak-ha!',12,0,100,0,0,0,16720,0,'Sethekk Halls Trash'), + +(18320,0,0,'In Terokk\'s name!',12,0,100,0,0,0,16716,0,'Sethekk Halls Trash'), +(18320,0,1,'Protect the Veil!',12,0,100,0,0,0,16717,0,'Sethekk Halls Trash'), +(18320,0,2,'Darkfire -- avenge us!',12,0,100,0,0,0,16718,0,'Sethekk Halls Trash'), +(18320,0,3,'Ssssekk-sara Rith-nealaak!',12,0,100,0,0,0,16719,0,'Sethekk Halls Trash'), +(18320,0,4,'Arak-ha!',12,0,100,0,0,0,16720,0,'Sethekk Halls Trash'), + +(18321,0,0,'In Terokk\'s name!',12,0,100,0,0,0,16716,0,'Sethekk Halls Trash'), +(18321,0,1,'Protect the Veil!',12,0,100,0,0,0,16717,0,'Sethekk Halls Trash'), +(18321,0,2,'Darkfire -- avenge us!',12,0,100,0,0,0,16718,0,'Sethekk Halls Trash'), +(18321,0,3,'Ssssekk-sara Rith-nealaak!',12,0,100,0,0,0,16719,0,'Sethekk Halls Trash'), +(18321,0,4,'Arak-ha!',12,0,100,0,0,0,16720,0,'Sethekk Halls Trash'), + +(18322,0,0,'In Terokk\'s name!',12,0,100,0,0,0,16716,0,'Sethekk Halls Trash'), +(18322,0,1,'Protect the Veil!',12,0,100,0,0,0,16717,0,'Sethekk Halls Trash'), +(18322,0,2,'Darkfire -- avenge us!',12,0,100,0,0,0,16718,0,'Sethekk Halls Trash'), +(18322,0,3,'Ssssekk-sara Rith-nealaak!',12,0,100,0,0,0,16719,0,'Sethekk Halls Trash'), +(18322,0,4,'Arak-ha!',12,0,100,0,0,0,16720,0,'Sethekk Halls Trash'), + +(18323,0,0,'In Terokk\'s name!',12,0,100,0,0,0,16716,0,'Sethekk Halls Trash'), +(18323,0,1,'Protect the Veil!',12,0,100,0,0,0,16717,0,'Sethekk Halls Trash'), +(18323,0,2,'Darkfire -- avenge us!',12,0,100,0,0,0,16718,0,'Sethekk Halls Trash'), +(18323,0,3,'Ssssekk-sara Rith-nealaak!',12,0,100,0,0,0,16719,0,'Sethekk Halls Trash'), +(18323,0,4,'Arak-ha!',12,0,100,0,0,0,16720,0,'Sethekk Halls Trash'), + +(18325,0,0,'In Terokk\'s name!',12,0,100,0,0,0,16716,0,'Sethekk Halls Trash'), +(18325,0,1,'Protect the Veil!',12,0,100,0,0,0,16717,0,'Sethekk Halls Trash'), +(18325,0,2,'Darkfire -- avenge us!',12,0,100,0,0,0,16718,0,'Sethekk Halls Trash'), +(18325,0,3,'Ssssekk-sara Rith-nealaak!',12,0,100,0,0,0,16719,0,'Sethekk Halls Trash'), +(18325,0,4,'Arak-ha!',12,0,100,0,0,0,16720,0,'Sethekk Halls Trash'), + +(18326,0,0,'In Terokk\'s name!',12,0,100,0,0,0,16716,0,'Sethekk Halls Trash'), +(18326,0,1,'Protect the Veil!',12,0,100,0,0,0,16717,0,'Sethekk Halls Trash'), +(18326,0,2,'Darkfire -- avenge us!',12,0,100,0,0,0,16718,0,'Sethekk Halls Trash'), +(18326,0,3,'Ssssekk-sara Rith-nealaak!',12,0,100,0,0,0,16719,0,'Sethekk Halls Trash'), +(18326,0,4,'Arak-ha!',12,0,100,0,0,0,16720,0,'Sethekk Halls Trash'), + +(18327,0,0,'In Terokk\'s name!',12,0,100,0,0,0,16716,0,'Sethekk Halls Trash'), +(18327,0,1,'Protect the Veil!',12,0,100,0,0,0,16717,0,'Sethekk Halls Trash'), +(18327,0,2,'Darkfire -- avenge us!',12,0,100,0,0,0,16718,0,'Sethekk Halls Trash'), +(18327,0,3,'Ssssekk-sara Rith-nealaak!',12,0,100,0,0,0,16719,0,'Sethekk Halls Trash'), +(18327,0,4,'Arak-ha!',12,0,100,0,0,0,16720,0,'Sethekk Halls Trash'), + +(18328,0,0,'In Terokk\'s name!',12,0,100,0,0,0,16716,0,'Sethekk Halls Trash'), +(18328,0,1,'Protect the Veil!',12,0,100,0,0,0,16717,0,'Sethekk Halls Trash'), +(18328,0,2,'Darkfire -- avenge us!',12,0,100,0,0,0,16718,0,'Sethekk Halls Trash'), +(18328,0,3,'Ssssekk-sara Rith-nealaak!',12,0,100,0,0,0,16719,0,'Sethekk Halls Trash'), +(18328,0,4,'Arak-ha!',12,0,100,0,0,0,16720,0,'Sethekk Halls Trash'); + +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (18318,18319,18320,18321,18322,18323,18325,18326,18327,18328,18701,18703,19203,19204,19205,19206,19428,19429,21891,21904) AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(18318, 0, 0, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Initiate - On Aggro - Say Line 0'), +(18318, 0, 1, 0, 0, 0, 100, 0, 5300, 7100, 10800, 18100, 0, 0, 11, 16145, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Initiate - In Combat - Cast \'Sunder Armor\''), +(18318, 0, 2, 0, 0, 0, 100, 0, 7400, 15700, 27300, 47100, 0, 0, 11, 33961, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Initiate - In Combat - Cast \'Spell Reflection\''), + +(18319, 0, 0, 0, 1, 0, 100, 0, 1000, 1000, 30000, 30000, 0, 0, 11, 32689, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Scryer - Out of Combat - Cast \'Arcane Destruction\''), +(18319, 0, 1, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Scryer - On Aggro - Say Line 0'), +(18319, 0, 2, 0, 0, 0, 100, 0, 3100, 5300, 3100, 5300, 0, 0, 11, 32689, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Scryer - In Combat - Cast \'Arcane Destruction\''), +(18319, 0, 3, 0, 0, 0, 100, 2, 7800, 13300, 10400, 17700, 0, 0, 11, 22272, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Scryer - In Combat - Cast \'Arcane Missiles\' (Normal Dungeon)'), +(18319, 0, 4, 0, 0, 0, 100, 4, 7800, 13300, 10400, 17700, 0, 0, 11, 33988, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Scryer - In Combat - Cast \'Arcane Missiles\' (Heroic Dungeon)'), +(18319, 0, 5, 0, 74, 0, 100, 2, 9600, 15700, 9600, 15700, 75, 40, 11, 17843, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Scryer - On Friendly Between 0-75% Health - Cast \'Flash Heal\' (Normal Dungeon)'), +(18319, 0, 6, 0, 74, 0, 100, 4, 9600, 15700, 9600, 15700, 75, 40, 11, 17138, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Scryer - On Friendly Between 0-75% Health - Cast \'Flash Heal\' (Heroic Dungeon)'), +(18319, 0, 7, 0, 74, 0, 100, 2, 13200, 21700, 13200, 21700, 40, 40, 11, 12160, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Scryer - On Friendly Between 0-40% Health - Cast \'Rejuvenation\' (Normal Dungeon)'), +(18319, 0, 8, 0, 74, 0, 100, 4, 13200, 21700, 13200, 21700, 40, 40, 11, 15981, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Scryer - On Friendly Between 0-40% Health - Cast \'Rejuvenation\' (Heroic Dungeon)'), + +(18320, 0, 0, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Shadowmage - On Aggro - Say Line 0'), +(18320, 0, 1, 0, 0, 0, 100, 2, 6600, 18600, 9300, 21800, 0, 0, 11, 32675, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Shadowmage - In Combat - Cast \'Shadow Missiles\' (Normal Dungeon)'), +(18320, 0, 2, 0, 0, 0, 100, 4, 6600, 18600, 9300, 21800, 0, 0, 11, 38148, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Shadowmage - In Combat - Cast \'Shadow Missiles\' (Heroic Dungeon)'), +(18320, 0, 3, 0, 0, 0, 100, 2, 4800, 9600, 21700, 33800, 0, 0, 11, 32682, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Shadowmage - In Combat - Cast \'Curse of the Dark Talon\' (Normal Dungeon)'), +(18320, 0, 4, 0, 0, 0, 100, 4, 4800, 9600, 21700, 33800, 0, 0, 11, 38149, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Shadowmage - In Combat - Cast \'Curse of the Dark Talon\' (Heroic Dungeon)'), + +(18321, 0, 0, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Talon Lord - On Aggro - Say Line 0'), +(18321, 0, 2, 0, 0, 0, 100, 0, 0, 0, 16300, 24300, 0, 0, 11, 32674, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Talon Lord - In Combat - Cast \'Avenger\'s Shield\''), +(18321, 0, 3, 0, 0, 0, 100, 0, 9300, 16700, 14300, 25400, 0, 0, 11, 32654, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Talon Lord - In Combat - Cast \'Talon of Justice\''), + +(18322, 0, 0, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Ravenguard - On Aggro - Say Line 0'), +(18322, 0, 1, 0, 0, 0, 100, 2, 7200, 20500, 10800, 21700, 0, 0, 11, 33964, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Ravenguard - In Combat - Cast \'Bloodthirst\' (Normal Dungeon)'), +(18322, 0, 2, 0, 0, 0, 100, 4, 7200, 20500, 10800, 21700, 0, 0, 11, 40423, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Ravenguard - In Combat - Cast \'Bloodthirst\' (Heroic Dungeon)'), +(18322, 0, 3, 0, 0, 0, 100, 0, 6100, 17400, 16800, 21700, 0, 0, 11, 32651, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Ravenguard - In Combat - Cast \'Howling Screech\''), +(18322, 0, 4, 0, 38, 0, 100, 0, 0, 1, 0, 0, 0, 0, 11, 34970, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Ravenguard - On Data Set 0 1 - Cast \'Frenzy\''), +(18322, 0, 5, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 19, 18322, 30, 0, 0, 0, 0, 0, 0, 'Sethekk Ravenguard - On Death - Set Data 0 1'), + +(18323, 0, 0, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Guard - On Aggro - Say Line 0'), +(18323, 0, 1, 0, 0, 0, 100, 0, 3600, 15700, 10900, 22100, 0, 0, 11, 33967, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Guard - In Combat - Cast \'Thunderclap\''), + +(18325, 0, 0, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Prophet - On Aggro - Say Line 0'), +(18325, 0, 1, 0, 0, 0, 100, 0, 8700, 17700, 13200, 24100, 0, 0, 11, 27641, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Prophet - In Combat - Cast \'Fear\''), +(18325, 0, 2, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 32692, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Prophet - On Death - Cast \'Summon Arakkoa Spirit\''), + +(18326, 0, 0, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Shaman - On Aggro - Say Line 0'), +(18326, 0, 1, 0, 0, 0, 100, 2, 4300, 9100, 7200, 14500, 0, 0, 11, 15501, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Shaman - In Combat - Cast \'Earth Shock\' (Normal Dungeon)'), +(18326, 0, 2, 0, 0, 0, 100, 4, 4300, 9100, 7200, 14500, 0, 0, 11, 22885, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Shaman - In Combat - Cast \'Earth Shock\' (Heroic Dungeon)'), +(18326, 0, 3, 0, 0, 0, 100, 0, 7900, 14500, 90000, 90000, 0, 0, 11, 32663, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Shaman - In Combat - Cast \'Summon Dark Vortex\''), + +(18327, 0, 0, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Controller - On Aggro - Say Line 0'), +(18327, 0, 1, 0, 0, 0, 100, 0, 9100, 24100, 27800, 48300, 0, 0, 11, 32764, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Controller - In Combat - Cast \'Summon Charming Totem\''), +(18327, 0, 2, 0, 0, 0, 100, 0, 8400, 23200, 9700, 32600, 0, 0, 11, 35013, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Time-Lost Controller - In Combat - Cast \'Shrink\''), + +(18328, 0, 0, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Oracle - On Aggro - Say Line 0'), +(18328, 0, 1, 0, 0, 0, 100, 2, 6100, 12100, 18500, 27700, 0, 0, 11, 32690, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Oracle - In Combat - Cast \'Arcane Lightning\' (Normal Dungeon)'), +(18328, 0, 2, 0, 0, 0, 100, 4, 1200, 12100, 7200, 13300, 0, 0, 11, 38146, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Oracle - In Combat - Cast \'Arcane Lightning\' (Heroic Dungeon)'), +(18328, 0, 3, 0, 0, 0, 100, 0, 2400, 8700, 8400, 19300, 0, 0, 11, 32129, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Oracle - In Combat - Cast \'Faerie Fire\''), + +(18701, 0, 0, 0, 0, 0, 100, 0, 3600, 7200, 8400, 19300, 0, 0, 11, 12471, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dark Vortex - In Combat - Cast \'Shadow Bolt\''), + +(18703, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Spirit - On Just Summoned - Set In Combat With Zone'), +(18703, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 17321, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Spirit - On Link - Cast \'Spirit Spawn-in\''), +(18703, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 24051, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Spirit - On Link - Cast \'Spirit Burst\''), +(18703, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 116, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Spirit - On Link - Set Corpse Delay'), +(18703, 0, 4, 0, 60, 0, 100, 1, 10000, 10000, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sethekk Spirit - On Update - Kill Self (No Repeat)'), + +(19203, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 33610, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Fire Elemental - On Just Summoned - Cast \'Syth A Dummy\''), +(19203, 0, 1, 0, 0, 0, 100, 2, 1600, 7600, 8400, 18100, 0, 0, 11, 33526, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Fire Elemental - In Combat - Cast \'Flame Buffet\' (Normal Dungeon)'), +(19203, 0, 2, 0, 0, 0, 100, 4, 1200, 3600, 6000, 7200, 0, 0, 11, 38141, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Fire Elemental - In Combat - Cast \'Flame Buffet\' (Heroic Dungeon)'), +(19203, 0, 3, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 33621, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Fire Elemental - On Death - Cast \'Syth Dummy\''), + +(19204, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 33611, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Frost Elemental - On Just Summoned - Cast \'Syth B Dummy\''), +(19204, 0, 1, 0, 0, 0, 100, 2, 1600, 7600, 8400, 18100, 0, 0, 11, 33528, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Frost Elemental - In Combat - Cast \'Frost Buffet\' (Normal Dungeon)'), +(19204, 0, 2, 0, 0, 0, 100, 4, 1200, 3600, 6000, 7200, 0, 0, 11, 38142, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Frost Elemental - In Combat - Cast \'Frost Buffet\' (Heroic Dungeon)'), +(19204, 0, 3, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 33621, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Frost Elemental - On Death - Cast \'Syth Dummy\''), + +(19205, 0, 0, 0, 0, 0, 100, 2, 1600, 7600, 8400, 18100, 0, 0, 11, 33527, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Arcane Elemental - In Combat - Cast \'Arcane Buffet\' (Normal Dungeon)'), +(19205, 0, 1, 0, 0, 0, 100, 4, 1200, 3600, 6000, 7200, 0, 0, 11, 38138, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Arcane Elemental - In Combat - Cast \'Arcane Buffet\' (Heroic Dungeon)'), +(19205, 0, 2, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 33621, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Arcane Elemental - On Death - Cast \'Syth Dummy\''), + +(19206, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 33612, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Shadow Elemental - On Just Summoned - Cast \'Syth C Dummy\''), +(19206, 0, 1, 0, 0, 0, 100, 2, 1600, 7600, 8400, 18100, 0, 0, 11, 33529, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Shadow Elemental - In Combat - Cast \'Shadow Buffet\' (Normal Dungeon)'), +(19206, 0, 2, 0, 0, 0, 100, 4, 1200, 3600, 6000, 7200, 0, 0, 11, 38143, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Shadow Elemental - In Combat - Cast \'Shadow Buffet\' (Heroic Dungeon)'), +(19206, 0, 3, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 33621, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Syth Shadow Elemental - On Death - Cast \'Syth Dummy\''), + +(19428, 0, 0, 0, 0, 0, 100, 2, 4800, 14500, 13300, 22900, 0, 0, 11, 17503, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Cobalt Serpent - In Combat - Cast \'Frostbolt\' (Normal Dungeon)'), +(19428, 0, 1, 0, 0, 0, 100, 4, 4800, 14500, 13300, 22900, 0, 0, 11, 38238, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Cobalt Serpent - In Combat - Cast \'Frostbolt\' (Heroic Dungeon)'), +(19428, 0, 2, 0, 0, 0, 100, 2, 5600, 22100, 8400, 25400, 0, 0, 11, 38193, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Cobalt Serpent - In Combat - Cast \'Lightning Breath\' (Normal Dungeon)'), +(19428, 0, 3, 0, 0, 0, 100, 4, 3600, 22100, 7200, 14400, 0, 0, 11, 38133, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Cobalt Serpent - In Combat - Cast \'Lightning Breath\' (Heroic Dungeon)'), +(19428, 0, 4, 0, 0, 0, 100, 0, 6200, 21700, 12100, 22800, 0, 0, 11, 38110, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Cobalt Serpent - In Combat - Cast \'Wing Buffet\''), + +(19429, 0, 0, 0, 9, 0, 100, 3, 0, 0, 0, 0, 8, 25, 11, 38059, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avian Darkhawk - Within 8-25 Range - Cast \'Sonic Charge\' (Normal Dungeon) (No Repeat)'), +(19429, 0, 1, 0, 9, 0, 100, 5, 0, 0, 0, 0, 8, 25, 11, 39197, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avian Darkhawk - Within 8-25 Range - Cast \'Sonic Charge\' (Heroic Dungeon) (No Repeat)'), +(19429, 0, 2, 0, 0, 0, 100, 2, 4800, 13600, 10900, 24100, 0, 0, 11, 32901, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avian Darkhawk - In Combat - Cast \'Carnivorous Bite\' (Normal Dungeon)'), +(19429, 0, 3, 0, 0, 0, 100, 4, 4800, 13600, 10900, 24100, 0, 0, 11, 39198, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avian Darkhawk - In Combat - Cast \'Carnivorous Bite\' (Heroic Dungeon)'), + +(21891, 0, 0, 0, 0, 0, 100, 0, 4300, 12100, 15600, 19300, 0, 0, 11, 38056, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avian Ripper - In Combat - Cast \'Flesh Rip\''), + +(21904, 0, 0, 0, 9, 0, 100, 3, 0, 0, 0, 0, 8, 25, 11, 38059, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avian Warhawk - Within 8-25 Range - Cast \'Sonic Charge\' (Normal Dungeon) (No Repeat)'), +(21904, 0, 1, 0, 9, 0, 100, 5, 0, 0, 0, 0, 8, 25, 11, 39197, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avian Warhawk - Within 8-25 Range - Cast \'Sonic Charge\' (Heroic Dungeon) (No Repeat)'), +(21904, 0, 2, 0, 0, 0, 100, 2, 3800, 11100, 10900, 21700, 0, 0, 11, 32901, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avian Warhawk - In Combat - Cast \'Carnivorous Bite\' (Normal Dungeon)'), +(21904, 0, 3, 0, 0, 0, 100, 4, 3800, 11100, 10900, 21700, 0, 0, 11, 39198, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avian Warhawk - In Combat - Cast \'Carnivorous Bite\' (Heroic Dungeon)'), +(21904, 0, 4, 0, 0, 0, 100, 0, 6200, 25500, 12100, 24100, 0, 0, 11, 18144, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Avian Warhawk - In Combat - Cast \'Swoop\''); + +-- Ravenguard ImmuneMask +UPDATE `creature_template` SET `mechanic_immune_mask` = 71698 WHERE (`entry` IN (18322, 20696)); diff --git a/data/sql/updates/db_world/2023_09_17_08.sql b/data/sql/updates/db_world/2023_09_17_08.sql new file mode 100644 index 00000000000000..fba22485e8bbb6 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_08.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_17_07 -> 2023_09_17_08 +-- +UPDATE `creature_template` SET `unit_flags2` = 0 WHERE (`entry` = 15691); diff --git a/data/sql/updates/db_world/2023_09_17_09.sql b/data/sql/updates/db_world/2023_09_17_09.sql new file mode 100644 index 00000000000000..ec7b40263aaaad --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_09.sql @@ -0,0 +1,5 @@ +-- DB update 2023_09_17_08 -> 2023_09_17_09 +-- +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_q10190_battery_recharging_blaster'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(34219, 'spell_q10190_battery_recharging_blaster'); diff --git a/data/sql/updates/db_world/2023_09_17_10.sql b/data/sql/updates/db_world/2023_09_17_10.sql new file mode 100644 index 00000000000000..a2b8bfc16d9008 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_10.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_17_09 -> 2023_09_17_10 +DELETE FROM `game_event_creature` WHERE `guid` IN (245648,245645,245649); +DELETE FROM `creature` WHERE `guid` IN (245648,245645,245649); diff --git a/data/sql/updates/db_world/2023_09_17_11.sql b/data/sql/updates/db_world/2023_09_17_11.sql new file mode 100644 index 00000000000000..ec10522abce1d0 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_11.sql @@ -0,0 +1,5 @@ +-- DB update 2023_09_17_10 -> 2023_09_17_11 +-- +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_malchezaar_enfeeble' AND `spell_id` = 30843; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(30843, 'spell_malchezaar_enfeeble'); diff --git a/data/sql/updates/db_world/2023_09_17_12.sql b/data/sql/updates/db_world/2023_09_17_12.sql new file mode 100644 index 00000000000000..7d82cc77294966 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_12.sql @@ -0,0 +1,184 @@ +-- DB update 2023_09_17_11 -> 2023_09_17_12 +-- ---------------------creature_template ------------------- +-- fairbanks Use gossip_menu_id 7283 +-- add gossip menu flag Prevent red errors when the server starts +UPDATE `creature_template` SET `gossip_menu_id` = 7283, `npcflag` = 1 +WHERE (`entry` = 4542); + +-- ----gossip_menu----- +-- cmangos and vmangos gossip_menuID-- +DELETE +FROM `gossip_menu` +WHERE `MenuID` BETWEEN 7268 AND 7284; +INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES +(7268, 8610), +(7269, 8609), +(7270, 8608), +(7271, 8607), +(7272, 8606), +(7273, 8605), +(7274, 8604), +(7275, 8603), +(7276, 8602), +(7277, 8601), +(7278, 8600), +(7279, 8599), +(7280, 8598), +(7281, 8597), +(7282, 8596), +(7283, 8595), +(7284, 8612); + +-- -----gossip_menu_option----- +-- Using the MenuID in vmangos and cmangos +DELETE +FROM `gossip_menu_option` +WHERE `MenuID` BETWEEN 7268 AND 7283; +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES +(7268, 0, 0, 'But his son is dead.', 12511, 1, 1, 7284, 0, 0, 0, '', 0, 0), +(7269, 0, 0, 'You tell an incredible tale, Fairbanks. What of the blade? Is it beyond redemption?', 12509, 1, 1, 7268, 0, 0, 0, '', 0, 0), +(7270, 0, 0, 'And you did...', 12507, 1, 1, 7269, 0, 0, 0, '', 0, 0), +(7271, 0, 0, 'You were right, Fairbanks. That is tragic.', 12505, 1, 1, 7270, 0, 0, 0, '', 0, 0), +(7272, 0, 0, 'You mean...', 12503, 1, 1, 7271, 0, 0, 0, '', 0, 0), +(7273, 0, 0, 'Continue please, Fairbanks.', 12501, 1, 1, 7272, 0, 0, 0, '', 0, 0), +(7274, 0, 0, 'And did he?', 12499, 1, 1, 7273, 0, 0, 0, '', 0, 0), +(7275, 0, 0, 'Yet? Yet what??', 12497, 1, 1, 7274, 0, 0, 0, '', 0, 0), +(7276, 0, 0, 'A thousand? For one man?', 12495, 1, 1, 7275, 0, 0, 0, '', 0, 0), +(7277, 0, 0, 'How do you know all of this?', 12493, 1, 1, 7276, 0, 0, 0, '', 0, 0), +(7278, 0, 0, 'You mean...', 12491, 1, 1, 7277, 0, 0, 0, '', 0, 0), +(7279, 0, 0, 'Incredible story. So how did he die?', 12489, 1, 1, 7278, 0, 0, 0, '', 0, 0), +(7280, 0, 0, 'I still do not fully understand.', 12487, 1, 1, 7279, 0, 0, 0, '', 0, 0), +(7281, 0, 0, 'What do you mean?', 12485, 1, 1, 7280, 0, 0, 0, '', 0, 0), +(7282, 0, 0, 'Mograine?', 12483, 1, 1, 7281, 0, 0, 0, '', 0, 0), +(7283, 0, 0, 'Curse? What\'s going ON here, Fairbanks?', 12481, 1, 1, 7282, 0, 0, 0, '', 0, 0); + +-- ---------npc_text----------- +-- cmangos npc_text_broa*dcast_text +DELETE FROM `npc_text` WHERE `ID` BETWEEN 8595 AND 8610; +INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES +(8595, '\r\nAT LAST, the curse IS lifted. Thank you, hero.', NULL, 12480, 0, 1, 0, 1, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +(8596, 'You mean, you don\'t know? The sword that you carry on your back - it is known as Ashbringer; named after its original owner.', NULL, 12482, 0, 1, 0, 6, 0, 1, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), + +-- Emoji 273 Holding a weapon in your hand is different from the Blizzard plan +(8597, 'Aye, the Highlord Mograine: A founder of the original order of the Scarlet Crusade. A knight of unwavering faith and purity; Mograine would be betrayed by his own son and slain by Kel\'Thuzad\'s forces inside Stratholme. It is how I ended up here...', NULL, 12484, 0, 1, 0, 273, 0, 1, 0, 1, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), + +(8598, 'It was High General Abbendis, High Inquisitor Isillien, and Highlord Mograine that formed the Crusade. In its infancy, the Crusade was a noble order. The madness and insane zealotry that you see now did not exist. It was not until the one known as the Grand Crusader appeared that the wheels of corruption were set in motion.', NULL, 12486, 0, 1, 0, 1, 0, 1, 0, 1, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), + +-- Emoji 273 Holding a weapon in your hand is different from the Blizzard plan +(8599, 'The Highlord was the lynchpin of the Crusade. Aye, Mograine was called the Ashbringer because of his exploits versus the armies of the Lich King. With only blade and faith, Mograine would walk into whole battalions of undead and emerge unscathed - the ashes of his foes being the only indication that he had been there at all. Do you not understand? The very face of death feared him! It trembled in his presence!', NULL, 12488, 0, 1, 0, 1, 0, 273, 0, 5, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), + +(8600, 'The only way a hero can die, $r: Through tragedy. The Grand Crusader struck a deal with Kel\'Thuzad himself! An ambush would be staged that would result in the death of Mograine. The TYPE of betrayal that could only be a result of the actions of one\'s most trusted and loved companions.', NULL, 12490, 0, 1, 0, 1, 0, 1, 0, 1, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +-- Emoji 273 Holding a weapon in your hand is different from the Blizzard plan +(8601, '$B$BAye, the lesser Mograine, the one known as the Scarlet Commander, through - what I suspect - the dealings of the Grand Crusader. He led his father to the ambush like a lamb to the slaughter.', NULL, 12492, 0, 1, 0, 273, 0, 1, 0, 1, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +(8602, '$B$BBecause I was there... I was the Highlord\'s most trusted advisor. I should have known... I felt that something was amiss yet I allowed it TO happen. Would you believe that there were a thousand OR more Scourge?', NULL, 12494, 0, 1, 0, 1, 0, 1, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +(8603, 'This was the Ashbringer, fool! AS the Scourge began TO materialize around us, Mograine\'s blade began to glow... to hum... the younger Mograine would take that as a sign to make his escape. They descended upon us with a hunger the likes of which I had never seen. Yet...', NULL, 12496, 0, 1, 0, 5, 0, 1, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +(8604, 'It was not enough.$B$B$B$BA thousand came and a thousand died. By the Light! By the might of Mograine! He would smite them down as fast as they could come. Through the chaos, I noticed that the lesser Mograine was still there, off in the distance. I called to him, " HELP us, Renault! HELP your father, boy!"', NULL, 12498, 0, 1, 0, 1, 0, 22, 0, 22, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +-- Emoji 274 Holding a weapon in your hand is different from the Blizzard plan +(8605, '$B$BNo... He stood in the background, watching as the legion of undead descended upon us. Soon after, my powers were exhausted. I was the first to fall... Surely they would tear me limb from limb as I lay there unconscious; but they ignored me completely, focusing all of their attention on the Highlord. ', NULL, 12500, 0, 1, 0, 274, 0, 1, 0, 1, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +(8606, 'It was all I could do to feign death as the corpses of the Scourge piled upon me. There was darkness and only the muffled sounds of the battle above me. The clashing of iron, the gnashing and grinding... gruesome, terrible sounds. And then there was silence. He called to me! "Fairbanks! Fairbanks\r\nWHERE are you? Talk TO me Fairbanks!" And then came the sound of incredulousness. The bite of betrayal, $r...', NULL, 12502, 0, 1, 0, 1, 0, 1, 0, 1, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +(8607, 'The boy had picked up the Ashbringer and driven it through his father\'s heart AS his back was turned. His LAST words will haunt me forever: "What have you done, Renault? Why would you do this?"', NULL, 12504, 0, 1, 0, 1, 0, 1, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +(8608, 'The blade AND Mograine were a singular entity. DO you understand? This act corrupted the blade AND LEAD TO Mograine\'s own corruption as a death knight of Kel\'Thuzad. I swore that if I lived, I would expose the perpetrators of this heinous crime. FOR two days I remained under the rot AND contagion of Scourge - gathering AS much strength AS possible TO ESCAPE the razed city.\n', NULL, 12506, 0, 1, 0, 1, 0, 1, 0, 1, NULL, NULL, 0, 0, 100, 1, 1, 1, 0, 0, 0, NULL, NULL, 0, 0, 100, 1, 1, 1, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +(8609, 'Aye, I did. Much TO the dismay of the lesser Mograine, I made my way back TO the Scarlet Monastery. I shouted AND screamed. I told the tale TO ANY that would listen. AND I would be murdered in cold blood FOR my actions, dragged TO this chamber - the dark secret of the order. But SOME did listen... SOME heard my words. Thus was born the Argent Dawn...', NULL, 12508, 0, 1, 0, 1, 0, 1, 0, 1, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL), +(8610, 'I\'m afraid that the blade which you hold in your hands is beyond saving. The hatred runs too deep. But do not lose hope, $c. Where one chapter has ended, a new one begins.$B$BFind his son - a more devout and pious man you may never meet. It is rumored that he is able to build the Ashbringer anew, without requiring the old, tainted blade.', NULL, 12510, 0, 1, 0, 1, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); + +-- Emoji 274 and 397 Holding a weapon in your hand is different from the Blizzard plan +DELETE FROM `npc_text` WHERE `ID`=8612; +INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES +(8612, '$B$BNo, $r; only one of his sons is dead. The other lives...$B$B$B$BThe Outland... Find him there... ', NULL, 12512, 0, 1, 0, 271, 0, 1, 0, 397, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); + +-- ---------npc_text----------- +-- Get ready to trigger emoticons with SmartAI +-- use smart_ai emto 8597 8599 8601 8605 8612 +UPDATE `npc_text` SET `em0_1`=0,`em0_3`=0, `em0_5`=0 +WHERE `ID`=8597; +UPDATE `npc_text` SET `em0_1`=0,`em0_3`=0, `em0_5`=0 +WHERE `ID`=8599; +UPDATE `npc_text` SET `em0_1`=0,`em0_3`=0, `em0_5`=0 +WHERE `ID`=8601; +UPDATE `npc_text` SET `em0_1`=0,`em0_3`=0, `em0_5`=0 +WHERE `ID`=8605; +UPDATE `npc_text` SET `em0_1`=0,`em0_3`=0, `em0_5`=0 +WHERE `ID`=8612; + +-- -------------------SMARTSCRIPT START--------------- +-- --------------------------------------------------- +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 4542; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 4542); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(4542, 0, 0, 0, 0, 0, 100, 0, 7000, 11000, 30000, 40000, 0, 11, 8282, 0, 0, 0, 0, 0, 5, 20, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Fairbanks - In Combat - Cast Curse of Blood'), +(4542, 0, 1, 0, 0, 0, 100, 0, 6000, 11000, 15000, 20000, 0, 11, 15090, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Fairbanks - In Combat - Cast Dispel Magic'), +(4542, 0, 2, 0, 0, 0, 100, 0, 0, 3000, 20000, 20000, 0, 11, 11647, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Fairbanks - In Combat - Cast Power Word: Shield'), +(4542, 0, 3, 0, 0, 0, 100, 0, 10000, 15000, 20000, 20000, 0, 11, 12039, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Fairbanks - In Combat - Cast Heal'), +(4542, 0, 4, 5, 37, 0, 100, 1, 0, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'fairbanks - initializes -Remove UNIT_NPC_FLAG_GOSSIP'), +(4542, 0, 5, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'fairbanks - initializes - set_sheath ‘SHEATH_STATE_MELEE’'), + +-- Do not hold a weapon in your hand when making expressions +(4542, 0, 6, 0, 62, 0, 100, 0, 7282, 0, 0, 0, 0, 80, 454200, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'fairbanks- Gossip_Select 7282 - emto (273 ,1,1)'), +(4542, 0, 7, 0, 62, 0, 100, 0, 7280, 0, 0, 0, 0, 80, 454201, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'fairbanks - Gossip_Select 7280 -emto (1,273,5)'), +(4542, 0, 8, 0, 62, 0, 100, 0, 7278, 0, 0, 0, 0, 80, 454202, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'fairbanks - Gossip_Select 7278 - emto (273,1,1)'), +(4542, 0, 9, 0, 62, 0, 100, 0, 7274, 0, 0, 0, 0, 80, 454203, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'fairbanks - Gossip_Select 7274 - emto (274,1,1)'), +(4542, 0, 10, 0, 62, 0, 100, 0, 7268, 0, 0, 0, 0, 80, 454204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'fairbanks - Gossip_Select 7268 - emto (274,1,397)'); + +-- -------- TIMED_ACTIONLIST EMOTE +-- fairbanks - Menuid - 7282 emto(273, 1, 1) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 454200); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(454200, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_UNARMED’'), +(454200, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 5, 273, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fairbanks - On Script - Play Emote 273'), +(454200, 9, 3, 0, 0, 0, 100, 0, 2200, 2200, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_MELEE’'), +(454200, 9, 4, 0, 0, 0, 100, 0, 700, 700, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fairbanks - On Script - Play Emote 1'), +(454200, 9, 6, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fairbanks - On Script - Play Emote 1'); + +-- fairbanks - Menuid - 7280 emto(1, 273, 5) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 454201); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(454201, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Play Emote 1'), +(454201, 9, 1, 0, 0, 0, 100, 0, 2500, 2500, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_UNARMED’'), +(454201, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 5, 273, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Play Emote 273'), +(454201, 9, 3, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_MELEE’'), +(454201, 9, 5, 0, 0, 0, 100, 0, 700, 700, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_UNARMED’'), +(454201, 9, 6, 0, 0, 0, 100, 0, 200, 200, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fairbanks - On Script - Play Emote 5'), +(454201, 9, 7, 0, 0, 0, 100, 0, 2200, 2200, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_MELEE’'); + +-- fairbanks - Menuid - 7278 emto(273, 1, 1) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 454202); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(454202, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath‘SHEATH_STATE_UNARMED’'), +(454202, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 5, 273, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Play Emote 273'), +(454202, 9, 2, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_MELEE’'), +(454202, 9, 3, 0, 0, 0, 100, 0, 700, 700, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Play Emote 1'), +(454202, 9, 4, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Play Emote 1'); + +-- fairbanks - Menuid - 7274 emto(274, 1, 1) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 454203); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(454203, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_UNARMED’'), +(454203, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 5, 274, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fairbanks - On Script - Play Emote 274'), +(454203, 9, 2, 0, 0, 0, 100, 0, 3500, 3500, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_MELEE’'), +(454203, 9, 3, 0, 0, 0, 100, 0, 700, 700, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Play Emote 1'), +(454203, 9, 4, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Play Emote 1'); + +-- fairbanks - Menuid - 7268(END) emto(274, 1, 397) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 454204); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(454204, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_UNARMED’'), +(454204, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 5, 274, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Play Emote 274'), +(454204, 9, 2, 0, 0, 0, 100, 0, 3500, 3500, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_MELEE’'), +(454204, 9, 3, 0, 0, 0, 100, 0, 700, 700, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Play Emote 1'), +(454204, 9, 4, 0, 0, 0, 100, 0, 2500, 2500, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_UNARMED’'), +(454204, 9, 5, 0, 0, 0, 100, 0, 200, 200, 0, 0, 0, 5, 397, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Play Emote 397'), +(454204, 9, 6, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' Fairbanks - On Script - Set Sheath ‘SHEATH_STATE_MELEE’'); + + +-- ----------conditions------------ +-- cmangos and vmangos conditions +DELETE +FROM `conditions` +WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` = 7283) AND (`SourceEntry` = 0) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 2) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 22691) AND (`ConditionValue2` = 1) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(15, 7283, 0, 0, 0, 2, 0, 22691, 1, 0, 0, 0, 0, '', 'the gossip menu is only displayed if the player inventory "ASHBRINGER"--ASHBRINGER'); + +-- Clean up 100100 - 100116 data +DELETE +FROM `npc_text` +WHERE `ID` BETWEEN 100100 AND 100116; \ No newline at end of file diff --git a/data/sql/updates/db_world/2023_09_17_13.sql b/data/sql/updates/db_world/2023_09_17_13.sql new file mode 100644 index 00000000000000..e7398b6d9fbd9e --- /dev/null +++ b/data/sql/updates/db_world/2023_09_17_13.sql @@ -0,0 +1,20 @@ +-- DB update 2023_09_17_12 -> 2023_09_17_13 +SET @ENTRY := 17433; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,1,20,0,100,0,9567,0,0,0,80,@ENTRY*100,2,0,0,0,0,1,0,0,0,0,0,0,0,'Vindicator Aalesia - On Quest \'Know Thine Enemy\' Finished - Run Script'), +(@ENTRY,0,1,0,61,0,100,0,0,0,0,0,64,1,0,0,0,0,0,7,0,0,0,0,0,0,0,'Vindicator Aalesia - On Quest \'Know Thine Enemy\' Finished - Store Targetlist'); + +-- Actionlist SAI +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY*100 AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`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*100,9,0,0,0,0,100,0,0,0,0,0,83,2,0,0,0,0,0,1,0,0,0,0,0,0,0,'Vindicator Aalesia - On Script - Remove Npc Flag Questgiver'), +(@ENTRY*100,9,1,0,0,0,100,0,0,0,0,0,17,69,0,0,0,0,0,1,0,0,0,0,0,0,0,'Vindicator Aalesia - On Script - Set Emote State 69'), +(@ENTRY*100,9,2,0,0,0,100,0,4000,4000,0,0,17,26,0,0,0,0,0,1,0,0,0,0,0,0,0,'Vindicator Aalesia - On Script - Set Emote State 26'), +(@ENTRY*100,9,3,0,0,0,100,0,0,0,0,0,1,0,4000,0,0,0,0,1,0,0,0,0,0,0,0,'Vindicator Aalesia - On Script - Say Line 0'), +(@ENTRY*100,9,4,0,0,0,100,0,4000,4000,0,0,1,1,4000,0,0,0,0,1,0,0,0,0,0,0,0,'Vindicator Aalesia - On Script - Say Line 1'), +(@ENTRY*100,9,5,0,0,0,100,0,4000,4000,0,0,1,2,2000,0,0,0,0,12,1,0,0,0,0,0,0,'Vindicator Aalesia - On Script - Say Line 2'), +(@ENTRY*100,9,6,0,0,0,100,0,2000,2000,0,0,82,2,0,0,0,0,0,1,0,0,0,0,0,0,0,'Vindicator Aalesia - On Script - Add Npc Flag Questgiver'); + +UPDATE `creature_text` SET `Text`='No, this can\'t be... It says this creature willingly became a servant of the Legion. He transforms into a satyr and receives the Legion\'s "blessing."' WHERE `CreatureID`=@ENTRY AND `GroupID` = 2; diff --git a/data/sql/updates/db_world/2023_09_18_00.sql b/data/sql/updates/db_world/2023_09_18_00.sql new file mode 100644 index 00000000000000..b3a1a99bacffc7 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_18_00.sql @@ -0,0 +1,51 @@ +-- DB update 2023_09_17_13 -> 2023_09_18_00 +-- Hearts of the Pure Rp ------------- + +-- The orientation of the initial NPC This is roughly towards the coordinates that need to be sniffed +-- UPDATE `creature` SET `orientation`=4.41048 WHERE `guid`=41833; + +-- Use SmatAI +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 5693; + +-- Update emoticons +UPDATE `creature_text` SET `Emote`=25 WHERE `CreatureID`=5693 AND `GroupID`=0 AND `ID`=0;-- EMOTE_ONESHOT_POINT +UPDATE `creature_text` SET `Emote`=1 WHERE `CreatureID`=5693 AND `GroupID`=1 AND `ID`=0;-- EMOTE_ONESHOT_TALK +UPDATE `creature_text` SET `Emote`=25 WHERE `CreatureID`=5693 AND `GroupID`=2 AND `ID`=0;-- EMOTE_ONESHOT_POINT +UPDATE `creature_text` SET `Emote`=1 WHERE `CreatureID`=5693 AND `GroupID`=3 AND `ID`=0;-- EMOTE_ONESHOT_TALK +UPDATE `creature_text` SET `Emote`=11 WHERE `CreatureID`=5693 AND `GroupID`=4 AND `ID`=0;-- EMOTE_ONESHOT_LAUGH + +-- Update unit_flags Make summoned NPCs unattackable and unselectable +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 5692; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 5692); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(5692, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 18, 256|512|33554432, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Comar Villard Projection - Just_Summoned - set_unit_flag'); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 5691; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 5691); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(5691, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 18, 256|512|33554432, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Comar Villard Projection - Just_Summoned - set_unit_flag'); + +-- SmatAI Start------------------------------------- +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 5693; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 5693); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(5693, 0, 0, 0, 19, 0, 100, 0, 1476, 0, 0, 0, 0, 80, 569300, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Godrick Farsan - On Quest \'Hearts of the Pure\' Taken - Run Script'), +(5693, 0, 1, 0, 20, 0, 100, 0, 1472, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Godrick Farsan - reward quest emote'); + +-- Timed events +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 569300); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(569300, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Set Active'), +(569300, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Remove Quest Giver npc flags from self.'), +(569300, 9, 2, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 12, 5691, 3, 28000, 0, 0, 0, 8, 0, 0, 0, 0, 1781.16, 61.13, -61.4065, 4.869, 'Hearts of the Pure - Godrick Farsan - Spawn NPC'), +(569300, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 12, 5692, 3, 28000, 0, 0, 0, 8, 0, 0, 0, 0, 1785.77, 60.27, -61.4065, 3.961, 'Hearts of the Pure - Godrick Farsan - Spawn NPC'), +(569300, 9, 4, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 5691, 10, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Face NPC'), +(569300, 9, 5, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Talk'), +(569300, 9, 6, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Talk'), +(569300, 9, 7, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 5692, 5, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Face NPC'), +(569300, 9, 8, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Talk'), +(569300, 9, 9, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Talk'), +(569300, 9, 10, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Face Player'), +(569300, 9, 11, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Talk'), +(569300, 9, 12, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Remove Active'), +(569300, 9, 13, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 82, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hearts of the Pure - Godrick Farsan - Add NPC Flags'); diff --git a/data/sql/updates/db_world/2023_09_18_01.sql b/data/sql/updates/db_world/2023_09_18_01.sql new file mode 100644 index 00000000000000..3de84f595c71e8 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_18_01.sql @@ -0,0 +1,22 @@ +-- DB update 2023_09_18_00 -> 2023_09_18_01 +-- +-- Pathing for Kalecgos Entry: 24844 'TDB FORMAT' +SET @NPC := 24844; +SET @PATH := @NPC * 10; +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1,163.9735,-398.0906,2.083333,0,0,0,0,100,0), -- 16:16:43 +(@PATH,2,164.3802,-397.1771,2.083333,0,0,0,0,100,0), -- 16:16:43 +(@PATH,3,162.7923,-386.1964,15.67094,0,0,0,0,100,0), -- 16:16:43 +(@PATH,4,151.5555,-345.349,5.92646,0,0,0,0,100,0), -- 16:16:43 +(@PATH,5,162.2416,-299.8032,-5.436685,0,0,0,0,100,0), -- 16:16:43 +(@PATH,6,199.7482,-272.3315,-7.186677,0,0,0,0,100,0), -- 16:16:43 +(@PATH,7,199.7482,-272.3315,-7.186677,0,0,0,0,100,0), -- 16:16:43 +(@PATH,8,199.7482,-272.3315,-7.186677,0.06981317,0,0,0,100,0); -- 16:16:54 +-- 0x1C2F2C4920184300001F1D000038BF6E .go 163.9735 -398.0906 2.083333 + +DELETE FROM `event_scripts` WHERE `id` = 16547; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 24844; + +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_kalecgos' WHERE `entry` = 24844; +UPDATE `creature_template` SET `AIName` = '' WHERE `entry` = 24848; diff --git a/data/sql/updates/db_world/2023_09_18_02.sql b/data/sql/updates/db_world/2023_09_18_02.sql new file mode 100644 index 00000000000000..e3a85dcbebb338 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_18_02.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_18_01 -> 2023_09_18_02 +-- +UPDATE `smart_scripts` SET `event_param5` = 1, `action_param3` = 1 WHERE `source_type` = 0 AND `entryorguid` IN (28994,29523,28989,28721,28725,28726); diff --git a/data/sql/updates/db_world/2023_09_18_03.sql b/data/sql/updates/db_world/2023_09_18_03.sql new file mode 100644 index 00000000000000..f2e780a1374b18 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_18_03.sql @@ -0,0 +1,5 @@ +-- DB update 2023_09_18_02 -> 2023_09_18_03 +-- +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 29967); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 29967, 0, 0, 31, 0, 3, 17176, 0, 0, 0, 0, '', 'Shade of Aran Blink (29967) can only target Shade of Aran Teleport Center (17176)'); diff --git a/data/sql/updates/db_world/2023_09_18_04.sql b/data/sql/updates/db_world/2023_09_18_04.sql new file mode 100644 index 00000000000000..eed902135f5a99 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_18_04.sql @@ -0,0 +1,15 @@ +-- DB update 2023_09_18_03 -> 2023_09_18_04 +-- +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 17265; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 17265) AND (`source_type` = 0) AND (`id` IN (0)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(17265, 0, 0, 0, 60, 0, 100, 0, 2400, 8000, 2400, 8000, 0, 11, 30184, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fiendish Portal - On Update - Cast \'Summon Fiendish Imp\''); + +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 17267; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 17267) AND (`source_type` = 0) AND (`id` IN (0)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(17267, 0, 0, 0, 0, 0, 100, 0, 2000, 2000, 2000, 2200, 0, 11, 30050, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Fiendish Imp - In Combat - Cast \'Firebolt\''); + +UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|1 WHERE `entry` = 17229; diff --git a/data/sql/updates/db_world/2023_09_19_00.sql b/data/sql/updates/db_world/2023_09_19_00.sql new file mode 100644 index 00000000000000..b7f6347c49f5c9 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_19_00.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_18_04 -> 2023_09_19_00 +-- +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|128 WHERE `entry` IN (17168, 17169, 17170, 17171, 17172, 17173, 17174, 17175, 17176, 17260, 17459); diff --git a/data/sql/updates/db_world/2023_09_19_01.sql b/data/sql/updates/db_world/2023_09_19_01.sql new file mode 100644 index 00000000000000..35de258e16dad1 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_19_01.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_19_00 -> 2023_09_19_01 +-- +UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|16 WHERE `entry` = 17543; diff --git a/data/sql/updates/db_world/2023_09_20_00.sql b/data/sql/updates/db_world/2023_09_20_00.sql new file mode 100644 index 00000000000000..4c4d27924b6bad --- /dev/null +++ b/data/sql/updates/db_world/2023_09_20_00.sql @@ -0,0 +1,7 @@ +-- DB update 2023_09_19_01 -> 2023_09_20_00 +-- +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 17167; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 17167) AND (`source_type` = 0) AND (`id` IN (0)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(17167, 0, 0, 0, 0, 0, 100, 0, 2000, 2000, 2000, 2000, 2000, 11, 31012, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Conjured Elemental - In Combat - Cast \'Water Bolt\''); diff --git a/data/sql/updates/db_world/2023_09_20_01.sql b/data/sql/updates/db_world/2023_09_20_01.sql new file mode 100644 index 00000000000000..a805c570ffe1c6 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_20_01.sql @@ -0,0 +1,46 @@ +-- DB update 2023_09_20_00 -> 2023_09_20_01 +UPDATE `quest_poi` SET `WorldMapAreaId` = 24 WHERE (`QuestID` = 7321) AND (`id` IN (0,1,2,3)); +UPDATE `quest_poi` SET `id` = 4, `ObjectiveIndex` = -1 WHERE (`QuestID` = 7321) AND (`id` = 0); +UPDATE `quest_poi` SET `id` = 5, `Flags` = 3 WHERE (`QuestID` = 7321) AND (`id` = 1); +UPDATE `quest_poi` SET `id` = 6, `Flags` = 3 WHERE (`QuestID` = 7321) AND (`id` = 2); +UPDATE `quest_poi` SET `id` = 7, `ObjectiveIndex` = 4, `Flags` = 3 WHERE (`QuestID` = 7321) AND (`id` = 3); +UPDATE `quest_poi_points` SET `Idx1` = 4, `Idx2` = 0, `X` = -852, `Y` = -594 WHERE (`QuestID` = 7321) AND (`Idx1` = 0) AND (`Idx2` = 0); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 0, `X` = -662, `Y` = -755 WHERE (`QuestID` = 7321) AND (`Idx1` = 0) AND (`Idx2` = 1); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 1, `X` = -646, `Y` = -742 WHERE (`QuestID` = 7321) AND (`Idx1` = 0) AND (`Idx2` = 2); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 2, `X` = -657, `Y` = -731 WHERE (`QuestID` = 7321) AND (`Idx1` = 0) AND (`Idx2` = 3); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 3, `X` = -672, `Y` = -723 WHERE (`QuestID` = 7321) AND (`Idx1` = 0) AND (`Idx2` = 4); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 4, `X` = -688, `Y` = -718 WHERE (`QuestID` = 7321) AND (`Idx1` = 0) AND (`Idx2` = 5); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 5, `X` = -714, `Y` = -710 WHERE (`QuestID` = 7321) AND (`Idx1` = 1) AND (`Idx2` = 0); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 6, `X` = -901, `Y` = -658 WHERE (`QuestID` = 7321) AND (`Idx1` = 1) AND (`Idx2` = 1); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 7, `X` = -919, `Y` = -668 WHERE (`QuestID` = 7321) AND (`Idx1` = 1) AND (`Idx2` = 2); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 8, `X` = -917, `Y` = -676 WHERE (`QuestID` = 7321) AND (`Idx1` = 2) AND (`Idx2` = 0); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 9, `X` = -904, `Y` = -689 WHERE (`QuestID` = 7321) AND (`Idx1` = 2) AND (`Idx2` = 1); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 10, `X` = -875, `Y` = -716 WHERE (`QuestID` = 7321) AND (`Idx1` = 2) AND (`Idx2` = 2); +UPDATE `quest_poi_points` SET `Idx1` = 5, `Idx2` = 11, `X` = -854, `Y` = -726 WHERE (`QuestID` = 7321) AND (`Idx1` = 2) AND (`Idx2` = 3); +UPDATE `quest_poi_points` SET `Idx1` = 6, `Idx2` = 0, `X` = -480, `Y` = -989 WHERE (`QuestID` = 7321) AND (`Idx1` = 2) AND (`Idx2` = 4); +UPDATE `quest_poi_points` SET `Idx1` = 6, `Idx2` = 1, `X` = -475, `Y` = -963 WHERE (`QuestID` = 7321) AND (`Idx1` = 2) AND (`Idx2` = 5); +UPDATE `quest_poi_points` SET `Idx1` = 6, `Idx2` = 2, `X` = -480, `Y` = -936 WHERE (`QuestID` = 7321) AND (`Idx1` = 2) AND (`Idx2` = 6); +UPDATE `quest_poi_points` SET `Idx1` = 6, `Idx2` = 3, `X` = -543, `Y` = -781 WHERE (`QuestID` = 7321) AND (`Idx1` = 2) AND (`Idx2` = 7); +UPDATE `quest_poi_points` SET `Idx1` = 6, `Idx2` = 4, `X` = -557, `Y` = -763 WHERE (`QuestID` = 7321) AND (`Idx1` = 3) AND (`Idx2` = 0); +DELETE FROM `quest_poi_points` WHERE `QuestID` = 7321 AND `Idx1` = 6 AND `Idx2` IN (5,6,7,8,9,10,11); +DELETE FROM `quest_poi_points` WHERE `QuestID` = 7321 AND `Idx1` = 7 AND `Idx2` IN (0,1,2,3,4,5,6,7,8,9,10,11); +INSERT INTO `quest_poi_points` (`QuestID`, `Idx1`, `Idx2`, `X`, `Y`, `VerifiedBuild`) VALUES +(7321, 6, 5, -575, -742, 0), +(7321, 6, 6, -596, -747, 0), +(7321, 6, 7, -614, -784, 0), +(7321, 6, 8, -609, -797, 0), +(7321, 6, 9, -549, -926, 0), +(7321, 6, 10, -528, -965, 0), +(7321, 6, 11, -512, -984, 0), +(7321, 7, 0, -238, -1121, 0), +(7321, 7, 1, -254, -1107, 0), +(7321, 7, 2, -380, -1010, 0), +(7321, 7, 3, -415, -986, 0), +(7321, 7, 4, -428, -981, 0), +(7321, 7, 5, -438, -1021, 0), +(7321, 7, 6, -423, -1042, 0), +(7321, 7, 7, -373, -1084, 0), +(7321, 7, 8, -349, -1099, 0), +(7321, 7, 9, -296, -1128, 0), +(7321, 7, 10, -286, -1131, 0), +(7321, 7, 11, -249, -1142, 0); diff --git a/data/sql/updates/db_world/2023_09_20_02.sql b/data/sql/updates/db_world/2023_09_20_02.sql new file mode 100644 index 00000000000000..5c6ad932a32efa --- /dev/null +++ b/data/sql/updates/db_world/2023_09_20_02.sql @@ -0,0 +1,68 @@ +-- DB update 2023_09_20_01 -> 2023_09_20_02 + + -- Sir Wendell's Grave smart ai +SET @ENTRY := 194537; +DELETE FROM `smart_scripts` WHERE `source_type` = 1 AND `entryOrGuid` = @ENTRY; +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 1, 0, 0, 71, 0, 100, 0, 21077, 0, 0, 0, 12, 33439, 3, 19000, 0, 0, 0, 8, 0, 0, 0, 8461.727, 468.7472, 596.2335, 4.729842, 'Sir Wendell\'s Grave - On Event 21077 Inform - Summon Creature \'Sir Wendell Balfour\''); + + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 194537 AND `SourceId` = 1; + + -- Sir Wendell Balfour smart ai +SET @ENTRY := 33439; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY; +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 11, 51195, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Sir Wendell Balfour - On Just Summoned - Cast \'Cosmetic - Low Poly Fire\''), +(@ENTRY, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 75, 29266, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Sir Wendell Balfour - On Just Summoned - Add Aura \'Permanent Feign Death\''), +(@ENTRY, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 67, 1, 200, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Sir Wendell Balfour - On Just Summoned - Create Timed Event'), +(@ENTRY, 0, 3, 0, 59, 0, 100, 0, 1, 0, 0, 0, 11, 10389, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Sir Wendell Balfour - On Timed Event 1 Triggered - Cast \'Spawn Smoke\''); + + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 33439 AND `SourceId` = 0; + + -- Lorien's Grave smart ai +SET @ENTRY := 194539; +DELETE FROM `smart_scripts` WHERE `source_type` = 1 AND `entryOrGuid` = @ENTRY; +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 1, 0, 0, 71, 0, 100, 0, 21075, 0, 0, 0, 12, 33455, 3, 19000, 0, 0, 0, 8, 0, 0, 0, 8441.864, 452.88184, 596.1657, 1.850049, 'Lorien\'s Grave - On Event 21075 Inform - Summon Creature \'Lorien Sunblaze\''); + + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 194539 AND `SourceId` = 1; + + -- Lorien Sunblaze smart ai +SET @ENTRY := 33455; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY; +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 11, 41290, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Lorien Sunblaze - On Just Summoned - Cast \'Disease Cloud\''), +(@ENTRY, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 11, 29266, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Lorien Sunblaze - On Just Summoned - Cast \'Permanent Feign Death\''), +(@ENTRY, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 11, 61894, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Lorien Sunblaze - On Just Summoned - Cast \'Spirit Particles (green - Base)\''); + + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 33455 AND `SourceId` = 0; + + -- Connall's Grave smart ai +SET @ENTRY := 194538; +DELETE FROM `smart_scripts` WHERE `source_type` = 1 AND `entryOrGuid` = @ENTRY; +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 1, 0, 0, 71, 0, 100, 0, 21076, 0, 0, 0, 12, 33457, 3, 19000, 0, 0, 0, 8, 0, 0, 0, 8471.436, 452.21744, 596.1551, 4.7822022, 'Connall\'s Grave - On Event 21076 Inform - Summon Creature \'Conall Irongrip\''); + + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 194538 AND `SourceId` = 1; + + -- Conall Irongrip smart ai +SET @ENTRY := 33457; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY; +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 11, 29266, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Conall Irongrip - On Just Summoned - Cast \'Permanent Feign Death\''); + + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 33457 AND `SourceId` = 0; + + diff --git a/data/sql/updates/db_world/2023_09_20_03.sql b/data/sql/updates/db_world/2023_09_20_03.sql new file mode 100644 index 00000000000000..7c673d65c7f302 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_20_03.sql @@ -0,0 +1,2 @@ +-- DB update 2023_09_20_02 -> 2023_09_20_03 +UPDATE `quest_offer_reward` SET `RewardText` = 'You brought the picks. Great! I\'ll get these to my mining students. I\'m sure they\'re eager to use them on the ore deposits of Loch Modan.$B$BThank you for your help, $N. I am in your debt, but I hope this money will at least cover your travel costs.' WHERE (`ID` = 6392); diff --git a/data/sql/updates/db_world/2023_09_20_04.sql b/data/sql/updates/db_world/2023_09_20_04.sql new file mode 100644 index 00000000000000..608fa777d6950e --- /dev/null +++ b/data/sql/updates/db_world/2023_09_20_04.sql @@ -0,0 +1,14 @@ +-- DB update 2023_09_20_03 -> 2023_09_20_04 + +DELETE FROM `creature_text` WHERE `CreatureID` = 16833; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(16833, 0, 0, 'No! Not... Sedai! The orcs must pay!', 12, 0, 100, 0, 0, 0, 13997, 0, 'Makuru // Makuru'); + + -- Anchorite Obadei smart ai +SET @ENTRY := 16834; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY; +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 0, 0, 0, 20, 0, 100, 0, 9423, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10, 57906, 16833, 0, 0, 0, 0, 0, 'Anchorite Obadei - On Quest \'Return to Obadei\' Finished - Say Line 0'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 16834 AND `SourceId` = 0; diff --git a/data/sql/updates/db_world/2023_09_20_05.sql b/data/sql/updates/db_world/2023_09_20_05.sql new file mode 100644 index 00000000000000..234af3e23759ec --- /dev/null +++ b/data/sql/updates/db_world/2023_09_20_05.sql @@ -0,0 +1,7 @@ +-- DB update 2023_09_20_04 -> 2023_09_20_05 +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 21246; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 21246); +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 +(21246, 0, 0, 0, 0, 0, 100, 0, 4850, 19400, 10900, 14500, 0, 0, 11, 38461, 0, 0, 0, 0, 0, 5, 25, 0, 0, 0, 0, 0, 0, 0, 'Serpentshrine Sporebat - In Combat - Cast Sonic Charge'), +(21246, 0, 1, 0, 0, 0, 100, 0, 0, 0, 24000, 36800, 0, 0, 11, 38471, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Serpentshrine Sporebat - In Combat - Cast \'Spore Burst\''); diff --git a/data/sql/updates/db_world/2023_09_20_06.sql b/data/sql/updates/db_world/2023_09_20_06.sql new file mode 100644 index 00000000000000..da7ec5487ab599 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_20_06.sql @@ -0,0 +1,33 @@ +-- DB update 2023_09_20_05 -> 2023_09_20_06 +-- Summoned Succubus +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 5677; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 5677); +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 +(5677, 0, 0, 0, 54, 0, 100, 513, 0, 0, 0, 0, 0, 0, 80, 567700, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Succubus - On Just Summoned - Run Script (No Repeat)'), +(5677, 0, 1, 0, 0, 0, 100, 0, 3000, 5000, 7000, 11000, 0, 0, 11, 16583, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Succubus - In Combat - Cast \'Shadow Shock\''), +(5677, 0, 2, 0, 21, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 1000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Succubus - On Reached Home - Despawn In 1000 ms'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 567700); +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 +(567700, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 2, 35, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Succubus - Actionlist - Set Faction 35'), +(567700, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 7741, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Succubus - Actionlist - Cast \'Summoned Demon\''), +(567700, 9, 2, 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, 'Summoned Succubus - Actionlist - Say Line 0'), +(567700, 9, 3, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 2, 14, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Succubus - Actionlist - Set Faction 14'), +(567700, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Succubus - Actionlist - Start Attacking'); + +-- Summoned Voidwalker +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 5676; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 5676); +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 +(5676, 0, 0, 0, 54, 0, 100, 1, 0, 0, 0, 0, 0, 0, 80, 567600, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Voidwalker - On Just Summoned - Run Script (No Repeat)'), +(5676, 0, 1, 0, 2, 0, 100, 1, 0, 30, 0, 0, 0, 0, 11, 7750, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Voidwalker - Between 0-30% Health - Cast \'Consuming Rage\' (No Repeat)'), +(5676, 0, 2, 0, 4, 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, 'Summoned Voidwalker - On Aggro - Say Line 1'), +(5676, 0, 3, 0, 21, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 1000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Voidwalker - On Reached Home - Despawn In 1000 ms'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 567600); +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 +(567600, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 2, 35, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Voidwalker - Actionlist - Set Faction 35'), +(567600, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 7741, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Voidwalker - Actionlist - Cast \'Summoned Demon\''), +(567600, 9, 2, 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, 'Summoned Voidwalker - Actionlist - Say Line 0'), +(567600, 9, 3, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 2, 14, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Voidwalker - Actionlist - Set Faction 14'), +(567600, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Summoned Voidwalker - Actionlist - Start Attacking'); diff --git a/data/sql/updates/db_world/2023_09_20_07.sql b/data/sql/updates/db_world/2023_09_20_07.sql new file mode 100644 index 00000000000000..b2a6df41e963f0 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_20_07.sql @@ -0,0 +1,72 @@ +-- DB update 2023_09_20_06 -> 2023_09_20_07 +SET @Agility := 3; +SET @Strength := 4; +SET @Intellect := 5; +SET @Spirit := 6; +SET @Stamina := 7; +SET @Crit := 32; +SET @Resilience := 35; +SET @AttackPower := 38; +SET @MP5 := 43; +Set @SpellPower := 45; + +-- General's Ornamented Bracers 32983 113 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 22, `stat_type2` = @Intellect, `stat_value2` = 12, `stat_type3` = @SpellPower, `stat_value3` = 20, `stat_type4` = @Crit, `stat_value4` = 14, `stat_type5` = @Resilience, `stat_value5` = 13, `armor` = 624, `AllowableClass` = 3 WHERE `entry` = 32983; +-- Marshal's Ornamented Bracers 32986 113 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 22, `stat_type2` = @Intellect, `stat_value2` = 12, `stat_type3` = @SpellPower, `stat_value3` = 20, `stat_type4` = @Crit, `stat_value4` = 14, `stat_type5` = @Resilience, `stat_value5` = 13, `armor` = 624, `AllowableClass` = 3 WHERE `entry` = 32986; +-- General's Ringmail Bracers 32991 113 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 22, `stat_type2` = @Intellect, `stat_value2` = 12, `stat_type3` = @SpellPower, `stat_value3` = 20, `stat_type4` = @Crit, `stat_value4` = 14, `stat_type5` = @Resilience, `stat_value5` = 13, `armor` = 349, `AllowableClass` = 68 WHERE `entry` = 32991; +-- Marshal's Ringmail Bracers 32994 113 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 22, `stat_type2` = @Intellect, `stat_value2` = 12, `stat_type3` = @SpellPower, `stat_value3` = 20, `stat_type4` = @Crit, `stat_value4` = 14, `stat_type5` = @Resilience, `stat_value5` = 13, `armor` = 349, `AllowableClass` = 68 WHERE `entry` = 32994; +-- General's Mooncloth Cuffs 32973 113 +UPDATE `item_template` SET `StatsCount` = 4, `stat_type1` = @Stamina, `stat_value1` = 25, `stat_type2` = @Intellect, `stat_value2` = 14, `stat_type3` = @SpellPower, `stat_value3` = 22, `stat_type4` = @Resilience, `stat_value4` = 14, `armor` = 84, `AllowableClass` = 400 WHERE `entry` = 32973; +-- Marshal's Mooncloth Cuffs 32977 113 +UPDATE `item_template` SET `StatsCount` = 4, `stat_type1` = @Stamina, `stat_value1` = 25, `stat_type2` = @Intellect, `stat_value2` = 14, `stat_type3` = @SpellPower, `stat_value3` = 22, `stat_type4` = @Resilience, `stat_value4` = 14, `armor` = 84, `AllowableClass` = 400 WHERE `entry` = 32977; +-- General's Plate Greaves Tier 2 30491 123 +UPDATE `item_template` SET `StatsCount` = 4, `stat_type1` = @Strength, `stat_value1` = 27, `stat_type2` = @Stamina, `stat_value2` = 40, `stat_type3` = @Crit, `stat_value3` = 27, `stat_type4` = @Resilience, `stat_value4` = 27, `armor` = 1063, `AllowableClass` = 3 WHERE `entry` = 30491; +-- General's Ornamented Belt 32982 123 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 34, `stat_type2` = @Intellect, `stat_value2` = 23, `stat_type3` = @SpellPower, `stat_value3` = 28, `stat_type4` = @Crit, `stat_value4` = 23, `stat_type5` = @Resilience, `stat_value5` = 24, `armor` = 870, `AllowableClass` = 3 WHERE `entry` = 32982; +-- General's Ornamented Greaves 32984 123 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 34, `stat_type2` = @Intellect, `stat_value2` = 23, `stat_type3` = @SpellPower, `stat_value3` = 28, `stat_type4` = @Crit, `stat_value4` = 23, `stat_type5` = @Resilience, `stat_value5` = 24, `armor` = 1063, `AllowableClass` = 3 WHERE `entry` = 32984; +-- Marshal's Ornamented Belt 32985 123 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 34, `stat_type2` = @Intellect, `stat_value2` = 23, `stat_type3` = @SpellPower, `stat_value3` = 28, `stat_type4` = @Crit, `stat_value4` = 23, `stat_type5` = @Resilience, `stat_value5` = 24, `armor` = 870, `AllowableClass` = 3 WHERE `entry` = 32985; +-- Marshal's Ornamented Greaves 32987 123 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 34, `stat_type2` = @Intellect, `stat_value2` = 23, `stat_type3` = @SpellPower, `stat_value3` = 28, `stat_type4` = @Crit, `stat_value4` = 23, `stat_type5` = @Resilience, `stat_value5` = 24, `armor` = 1063, `AllowableClass` = 3 WHERE `entry` = 32987; +-- General's Ringmail Girdle 32992 123 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 34, `stat_type2` = @Intellect, `stat_value2` = 23, `stat_type3` = @SpellPower, `stat_value3` = 28, `stat_type4` = @Crit, `stat_value4` = 24, `stat_type5` = @Resilience, `stat_value5` = 23, `armor` = 487, `AllowableClass` = 68 WHERE `entry` = 32992; +-- General's Ringmail Sabatons 32993 123 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 34, `stat_type2` = @Intellect, `stat_value2` = 23, `stat_type3` = @SpellPower, `stat_value3` = 28, `stat_type4` = @Crit, `stat_value4` = 24, `stat_type5` = @Resilience, `stat_value5` = 23, `armor` = 595, `AllowableClass` = 68 WHERE `entry` = 32993; +-- Marshal's Ringmail Girdle 32995 123 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 34, `stat_type2` = @Intellect, `stat_value2` = 23, `stat_type3` = @SpellPower, `stat_value3` = 28, `stat_type4` = @Crit, `stat_value4` = 24, `stat_type5` = @Resilience, `stat_value5` = 23, `armor` = 487, `AllowableClass` = 68 WHERE `entry` = 32995; +-- Marshal's Ringmail Sabatons 32996 123 +UPDATE `item_template` SET `StatsCount` = 5, `stat_type1` = @Stamina, `stat_value1` = 34, `stat_type2` = @Intellect, `stat_value2` = 23, `stat_type3` = @SpellPower, `stat_value3` = 28, `stat_type4` = @Crit, `stat_value4` = 24, `stat_type5` = @Resilience, `stat_value5` = 23, `armor` = 595, `AllowableClass` = 68 WHERE `entry` = 32996; +-- General's Mooncloth Belt 32974 123 +UPDATE `item_template` SET `StatsCount` = 4, `stat_type1` = @Stamina, `stat_value1` = 39, `stat_type2` = @Intellect, `stat_value2` = 27, `stat_type3` = @SpellPower, `stat_value3` = 32, `stat_type4` = @Resilience, `stat_value4` = 27, `armor` = 117, `AllowableClass` = 400 WHERE `entry` = 32974; +-- General's Mooncloth Slippers 32975 123 +UPDATE `item_template` SET `StatsCount` = 4, `stat_type1` = @Stamina, `stat_value1` = 40, `stat_type2` = @Intellect, `stat_value2` = 27, `stat_type3` = @SpellPower, `stat_value3` = 32, `stat_type4` = @Resilience, `stat_value4` = 27, `armor` = 142, `AllowableClass` = 400 WHERE `entry` = 32975; +-- Marshal's Mooncloth Belt 32976 123 +UPDATE `item_template` SET `StatsCount` = 4, `stat_type1` = @Stamina, `stat_value1` = 39, `stat_type2` = @Intellect, `stat_value2` = 27, `stat_type3` = @SpellPower, `stat_value3` = 32, `stat_type4` = @Resilience, `stat_value4` = 27, `armor` = 117, `AllowableClass` = 400 WHERE `entry` = 32976; +-- Marshal's Mooncloth Slippers 32978 123 +UPDATE `item_template` SET `StatsCount` = 4, `stat_type1` = @Stamina, `stat_value1` = 40, `stat_type2` = @Intellect, `stat_value2` = 27, `stat_type3` = @SpellPower, `stat_value3` = 32, `stat_type4` = @Resilience, `stat_value4` = 27, `armor` = 142, `AllowableClass` = 400 WHERE `entry` = 32978; + +UPDATE `item_template` SET `Flags` = `Flags`|32768, `FlagsExtra` = `FlagsExtra`&~8192, `BuyPrice` = 0, `SellPrice` = 0, `AllowableRace` = 32767, `VerifiedBuild` = 0 WHERE `entry` IN ( +32983, -- General's Ornamented Bracers +32986, -- Marshal's Ornamented Bracers +32991, -- General's Ringmail Bracers +32994, -- Marshal's Ringmail Bracers +32973, -- General's Mooncloth Cuffs +32977, -- Marshal's Mooncloth Cuffs +30491, -- General's Plate Greaves Tier 2 +32982, -- General's Ornamented Belt +32984, -- General's Ornamented Greaves +32985, -- Marshal's Ornamented Belt +32987, -- Marshal's Ornamented Greaves +32992, -- General's Ringmail Girdle +32993, -- General's Ringmail Sabatons +32995, -- Marshal's Ringmail Girdle +32996, -- Marshal's Ringmail Sabatons +32974, -- General's Mooncloth Belt +32975, -- General's Mooncloth Slippers +32976, -- Marshal's Mooncloth Belt +32978 -- Marshal's Mooncloth Slippers +); diff --git a/data/sql/updates/db_world/2023_09_24_00.sql b/data/sql/updates/db_world/2023_09_24_00.sql new file mode 100644 index 00000000000000..2651315b4c0fa1 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_24_00.sql @@ -0,0 +1,2 @@ +-- DB update 2023_09_20_07 -> 2023_09_24_00 +UPDATE `quest_template` SET `AllowableRaces` = 1101 WHERE (`ID` IN (9474,9446)); diff --git a/data/sql/updates/db_world/2023_09_24_01.sql b/data/sql/updates/db_world/2023_09_24_01.sql new file mode 100644 index 00000000000000..1f7f081aabd74f --- /dev/null +++ b/data/sql/updates/db_world/2023_09_24_01.sql @@ -0,0 +1,5 @@ +-- DB update 2023_09_24_00 -> 2023_09_24_01 +-- +UPDATE `acore_string` SET `content_default` = '%d - (entry: %d) |cffffffff|Hcreature:%d|h[%s X:%f Y:%f Z:%f MapId:%d]|h|r', +`locale_deDE` = '%d - (entry: %d) |cffffffff|Hcreature:%d|h[%s X:%f Y:%f Z:%f MapId:%d]|h|r', +`locale_zhCN` = '%d%s - (entry: %d) |cffffffff|H生物:%d|h[%s X:%f Y:%f Z:%f 地图号:%d]|h|r' WHERE `entry` = 515; diff --git a/data/sql/updates/db_world/2023_09_24_02.sql b/data/sql/updates/db_world/2023_09_24_02.sql new file mode 100644 index 00000000000000..a58cd048f6d960 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_24_02.sql @@ -0,0 +1,8 @@ +-- DB update 2023_09_24_01 -> 2023_09_24_02 +-- +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 17) AND (`SourceGroup` = 0) AND (`SourceEntry` = 41621) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 31) AND (`ConditionTarget` = 1) AND (`ConditionValue1` = 3) AND (`ConditionValue2` = 23487) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(17, 0, 41621, 0, 0, 31, 1, 3, 23487, 0, 0, 0, 0, '', 'Throw a net at a wild wolpertinger, which will allow you to capture it and place it in your pack.'); + +-- both missions are for the horde and alliance factions +UPDATE `spell_script_names` SET `ScriptName`='spell_catch_the_wild_wolpertinger' WHERE `spell_id`=41621 AND `ScriptName`='spell_q11117_catch_the_wild_wolpertinger'; diff --git a/data/sql/updates/db_world/2023_09_25_00.sql b/data/sql/updates/db_world/2023_09_25_00.sql new file mode 100644 index 00000000000000..69afe7231de365 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_25_00.sql @@ -0,0 +1,4 @@ +-- DB update 2023_09_24_02 -> 2023_09_25_00 +-- +-- fix Malchezaar event door not being interactable with players +UPDATE `gameobject_template_addon` SET `flags` = `flags`|16 WHERE `entry` = 185134; diff --git a/data/sql/updates/db_world/2023_09_25_01.sql b/data/sql/updates/db_world/2023_09_25_01.sql new file mode 100644 index 00000000000000..ef08575726355f --- /dev/null +++ b/data/sql/updates/db_world/2023_09_25_01.sql @@ -0,0 +1,8 @@ +-- DB update 2023_09_25_00 -> 2023_09_25_01 +-- +DELETE FROM `spell_script_names` WHERE `spell_id` IN (67486, 67489, 67487, 67490); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(67486, 'spell_item_healing_injector'), +(67489, 'spell_item_healing_injector'), +(67487, 'spell_item_mana_injector'), +(67490, 'spell_item_mana_injector'); diff --git a/data/sql/updates/db_world/2023_09_25_02.sql b/data/sql/updates/db_world/2023_09_25_02.sql new file mode 100644 index 00000000000000..2659f7d8d04c89 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_25_02.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_25_01 -> 2023_09_25_02 +-- +UPDATE `gameobject_template_addon` SET `faction` = 1375, `flags` = 32 WHERE (`entry` = 184277); diff --git a/data/sql/updates/db_world/2023_09_25_03.sql b/data/sql/updates/db_world/2023_09_25_03.sql new file mode 100644 index 00000000000000..9f8d0a39635dc8 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_25_03.sql @@ -0,0 +1,41 @@ +-- DB update 2023_09_25_02 -> 2023_09_25_03 +-- +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` IN (29962, 37051, 37052, 37053, 29969)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 29962, 0, 0, 31, 0, 3, 17172, 0, 0, 0, 0, '', 'Summon Water Elementals (29962) can only target Shade of Aran Teleport NE (17172)'), +(13, 1, 37051, 0, 0, 31, 0, 3, 17175, 0, 0, 0, 0, '', 'Summon Water Elementals (37051) can only target Shade of Aran Teleport NW (17175)'), +(13, 1, 37052, 0, 0, 31, 0, 3, 17174, 0, 0, 0, 0, '', 'Summon Water Elementals (37052) can only target Shade of Aran Teleport SW (17174)'), +(13, 1, 37053, 0, 0, 31, 0, 3, 17173, 0, 0, 0, 0, '', 'Summon Water Elementals (37053) can only target Shade of Aran Teleport SE (17173)'), +(13, 1, 29969, 0, 0, 31, 0, 3, 17161, 0, 0, 0, 0, '', 'Summon Blizzard (29969) can only target Blizzard (Shade of Aran) (17161)'); + +SET @NPC := 135127; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `wander_distance`=0,`MovementType`=2,`position_x`=-11179.069,`position_y`=-1903.9922,`position_z`=231.99551 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`visibilityDistanceType`,`auras`) VALUES (@NPC,@PATH,0,0,1,0,0, ''); +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1,-11179.069,-1903.9922,231.99551,NULL,0,0,0,100,0), +(@PATH,2,-11175.637,-1898.6766,231.99551,NULL,0,0,0,100,0), +(@PATH,3,-11170.077,-1896.4208,231.99551,NULL,0,0,0,100,0), +(@PATH,4,-11163.756,-1896.4015,231.99551,NULL,0,0,0,100,0), +(@PATH,5,-11157.39,-1897.875,231.99551,NULL,0,0,0,100,0), +(@PATH,6,-11152.051,-1901.6866,231.99551,NULL,0,0,0,100,0), +(@PATH,7,-11148.58,-1906.875,231.99551,NULL,0,0,0,100,0), +(@PATH,8,-11148.341,-1914.24,231.99551,NULL,0,0,0,100,0), +(@PATH,9,-11149.94,-1919.9163,231.99551,NULL,0,0,0,100,0), +(@PATH,10,-11154.768,-1924.6886,231.99551,NULL,0,0,0,100,0), +(@PATH,11,-11160.866,-1927.3403,231.99551,NULL,0,0,0,100,0), +(@PATH,12,-11166.848,-1927.012,231.99551,NULL,0,0,0,100,0), +(@PATH,13,-11173.295,-1925.4417,231.99551,NULL,0,0,0,100,0), +(@PATH,14,-11178.082,-1922.4479,231.99551,NULL,0,0,0,100,0), +(@PATH,15,-11180.802,-1915.3156,231.99551,NULL,0,0,0,100,0), +(@PATH,16,-11181.109,-1909.6647,231.99551,NULL,0,0,0,100,0); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 17161; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 17161) AND (`source_type` = 0) AND (`id` IN (0, 1, 2)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(17161, 0, 0, 0, 8, 0, 100, 0, 29969, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blizzard (Shade of Aran) - On Spellhit \'Summon Blizzard\' - Set Event Phase 1'), +(17161, 0, 1, 0, 60, 1, 100, 0, 1000, 1000, 2000, 2000, 0, 11, 29951, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blizzard (Shade of Aran) - On Update - Cast \'Blizzard\' (Phase 1)'), +(17161, 0, 2, 0, 60, 1, 100, 0, 20000, 20000, 20000, 20000, 0, 22, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blizzard (Shade of Aran) - On Update - Set Event Phase 0 (Phase 1)'); diff --git a/data/sql/updates/db_world/2023_09_25_04.sql b/data/sql/updates/db_world/2023_09_25_04.sql new file mode 100644 index 00000000000000..4d161db7609078 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_25_04.sql @@ -0,0 +1,6 @@ +-- DB update 2023_09_25_03 -> 2023_09_25_04 +-- +DELETE FROM `creature_text` WHERE `CreatureId` = 15689; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(15689, 0, 0, '%s goes into a nether-fed rage!', 41, 0, 100, 19877, 3, 'Netherspite EMOTE_PHASE_BANISH'), +(15689, 1, 0, '%s cries out in withdrawal, opening gates to the nether.', 41, 0, 100, 19880, 3, 'Netherspite EMOTE_PHASE_PORTAL'); diff --git a/data/sql/updates/db_world/2023_09_25_05.sql b/data/sql/updates/db_world/2023_09_25_05.sql new file mode 100644 index 00000000000000..6ab5b3910cb7cd --- /dev/null +++ b/data/sql/updates/db_world/2023_09_25_05.sql @@ -0,0 +1,4 @@ +-- DB update 2023_09_25_04 -> 2023_09_25_05 +-- +UPDATE `conditions` SET `ConditionValue1` = 6, `ConditionValue3` = 2 WHERE `SourceTypeOrReferenceId` = 15 AND `SourceGroup` = 7139 AND `SourceEntry` = 3; +UPDATE `spell_target_position` SET `PositionX` = -11165.2, `PositionY` = -1911.95, `PositionZ` = 232.009, `Orientation` = 2.14352, VerifiedBuild = 51845 WHERE `ID` = 39567; diff --git a/data/sql/updates/db_world/2023_09_25_06.sql b/data/sql/updates/db_world/2023_09_25_06.sql new file mode 100644 index 00000000000000..27331db4f1d7b1 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_25_06.sql @@ -0,0 +1,5 @@ +-- DB update 2023_09_25_05 -> 2023_09_25_06 +-- +DELETE FROM `spelldifficulty_dbc` WHERE `ID`=34780; +INSERT INTO `spelldifficulty_dbc` VALUES +(34780,34780,39340,0,0); diff --git a/data/sql/updates/db_world/2023_09_25_07.sql b/data/sql/updates/db_world/2023_09_25_07.sql new file mode 100644 index 00000000000000..25279d51c60063 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_25_07.sql @@ -0,0 +1,5 @@ +-- DB update 2023_09_25_06 -> 2023_09_25_07 +-- +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_warl_glyph_of_voidwalker' AND `spell_id` = 56247; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(56247, 'spell_warl_glyph_of_voidwalker'); diff --git a/data/sql/updates/db_world/2023_09_25_08.sql b/data/sql/updates/db_world/2023_09_25_08.sql new file mode 100644 index 00000000000000..366134a83e8dc7 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_25_08.sql @@ -0,0 +1,141 @@ +-- DB update 2023_09_25_07 -> 2023_09_25_08 +/* +################################################## +Argent Dawn Vendors: +- Argent Quartermaster Hasana (10856) +- Argent Quartermaster Lightspark (10857) +- Quartermaster Miranda Breechlock (11536) + +Quests: +- Mantles of the Dawn (5504) +- Mantles of the Dawn (5507) +- Mantles of the Dawn (5513) + +Shoulder Enchants: +- Flame Mantle of the Dawn (18169) +- Frost Mantle of the Dawn (18170) +- Arcane Mantle of the Dawn (18171) +- Nature Mantle of the Dawn (18172) +- Shadow Mantle of the Dawn (18173) + +Follow-up Quests: +- Chromatic Mantle of the Dawn (5517) +- Chromatic Mantle of the Dawn (5521) +- Chromatic Mantle of the Dawn (5524) + +Shoulder Enchant: +- Chromatic Mantle of the Dawn (18182) + +Vendor should only sell shoulder enchants if the player has completed the appropriate quest. +################################################## +*/ + +-- Add the Mantle of the Dawn quests (5504, 5507, 5513) to an ExclusiveGroup +DELETE FROM `quest_template_addon` WHERE `ID` in (5504, 5507, 5513); +INSERT INTO `quest_template_addon` (`ID`, `MaxLevel`, `AllowableClasses`, `SourceSpellID`, `PrevQuestID`, `NextQuestID`, `ExclusiveGroup`, `RewardMailTemplateID`, `RewardMailDelay`, `RequiredSkillID`, `RequiredSkillPoints`, `RequiredMinRepFaction`, `RequiredMaxRepFaction`, `RequiredMinRepValue`, `RequiredMaxRepValue`, `ProvidedItemCount`, `SpecialFlags`) VALUES +(5504, 0, 0, 0, 0, 0, 5504, 0, 0, 0, 0, 529, 0, 21000, 0, 0, 0), +(5507, 0, 0, 0, 0, 0, 5504, 0, 0, 0, 0, 529, 0, 21000, 0, 0, 0), +(5513, 0, 0, 0, 0, 0, 5504, 0, 0, 0, 0, 529, 0, 21000, 0, 0, 0); + +-- Add the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) to an ExclusiveGroup, and remove the repeatable flag +DELETE FROM `quest_template_addon` WHERE `ID` in (5517, 5521, 5524); +INSERT INTO `quest_template_addon` (`ID`, `MaxLevel`, `AllowableClasses`, `SourceSpellID`, `PrevQuestID`, `NextQuestID`, `ExclusiveGroup`, `RewardMailTemplateID`, `RewardMailDelay`, `RequiredSkillID`, `RequiredSkillPoints`, `RequiredMinRepFaction`, `RequiredMaxRepFaction`, `RequiredMinRepValue`, `RequiredMaxRepValue`, `ProvidedItemCount`, `SpecialFlags`) VALUES +(5517, 0, 0, 0, 0, 0, 5517, 0, 0, 0, 0, 529, 0, 42000, 0, 0, 0), +(5521, 0, 0, 0, 0, 0, 5517, 0, 0, 0, 0, 529, 0, 42000, 0, 0, 0), +(5524, 0, 0, 0, 0, 0, 5517, 0, 0, 0, 0, 529, 0, 42000, 0, 0, 0); + +-- Make the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) require one of the Mantle of the Dawn quests (5504, 5507, 5513) +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 19 AND `SourceEntry` IN (5517, 5521, 5524)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(19, 0, 5517, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Chromatic Mantle of the Dawn (5517) - Requires one of the Mantle of the Dawn quests (5504, 5507, 5513) rewarded'), +(19, 0, 5517, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Chromatic Mantle of the Dawn (5517) - Requires one of the Mantle of the Dawn quests (5504, 5507, 5513) rewarded'), +(19, 0, 5517, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Chromatic Mantle of the Dawn (5517) - Requires one of the Mantle of the Dawn quests (5504, 5507, 5513) rewarded'), + +(19, 0, 5521, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Chromatic Mantle of the Dawn (5521) - Requires one of the Mantle of the Dawn quests (5504, 5507, 5513) rewarded'), +(19, 0, 5521, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Chromatic Mantle of the Dawn (5521) - Requires one of the Mantle of the Dawn quests (5504, 5507, 5513) rewarded'), +(19, 0, 5521, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Chromatic Mantle of the Dawn (5521) - Requires one of the Mantle of the Dawn quests (5504, 5507, 5513) rewarded'), + +(19, 0, 5524, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Chromatic Mantle of the Dawn (5524) - Requires one of the Mantle of the Dawn quests (5504, 5507, 5513) rewarded'), +(19, 0, 5524, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Chromatic Mantle of the Dawn (5524) - Requires one of the Mantle of the Dawn quests (5504, 5507, 5513) rewarded'), +(19, 0, 5524, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Chromatic Mantle of the Dawn (5524) - Requires one of the Mantle of the Dawn quests (5504, 5507, 5513) rewarded'); + +-- Argent QuarterMaster Hasana (10856) Conditions +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 23 AND `SourceGroup` = 10856 AND `SourceEntry` IN (18169, 18170, 18171, 18172, 18173, 18182)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(23, 10856, 18169, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Flame Mantle of the Dawn (18169) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10856, 18169, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Flame Mantle of the Dawn (18169) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10856, 18169, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Flame Mantle of the Dawn (18169) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 10856, 18170, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Frost Mantle of the Dawn (18170) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10856, 18170, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Frost Mantle of the Dawn (18170) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10856, 18170, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Frost Mantle of the Dawn (18170) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 10856, 18171, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Arcane Mantle of the Dawn (18171) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10856, 18171, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Arcane Mantle of the Dawn (18171) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10856, 18171, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Arcane Mantle of the Dawn (18171) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 10856, 18172, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Nature Mantle of the Dawn (18172) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10856, 18172, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Nature Mantle of the Dawn (18172) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10856, 18172, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Nature Mantle of the Dawn (18172) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 10856, 18173, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Shadow Mantle of the Dawn (18173) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10856, 18173, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Shadow Mantle of the Dawn (18173) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10856, 18173, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Shadow Mantle of the Dawn (18173) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 10856, 18182, 0, 1, 47, 0, 5517, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Chromatic Mantle of the Dawn (18182) if one of the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) is rewarded.'), +(23, 10856, 18182, 0, 2, 47, 0, 5521, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Chromatic Mantle of the Dawn (18182) if one of the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) is rewarded.'), +(23, 10856, 18182, 0, 3, 47, 0, 5524, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Hasana (10856) - Only sell Chromatic Mantle of the Dawn (18182) if one of the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) is rewarded.'); + +-- Argent QuarterMaster Lightspark (10857) Conditions +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 23 AND `SourceGroup` = 10857 AND `SourceEntry` IN (18169, 18170, 18171, 18172, 18173, 18182)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(23, 10857, 18169, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Flame Mantle of the Dawn (18169) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10857, 18169, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Flame Mantle of the Dawn (18169) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10857, 18169, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Flame Mantle of the Dawn (18169) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 10857, 18170, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Frost Mantle of the Dawn (18170) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10857, 18170, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Frost Mantle of the Dawn (18170) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10857, 18170, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Frost Mantle of the Dawn (18170) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 10857, 18171, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Arcane Mantle of the Dawn (18171) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10857, 18171, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Arcane Mantle of the Dawn (18171) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10857, 18171, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Arcane Mantle of the Dawn (18171) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 10857, 18172, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Nature Mantle of the Dawn (18172) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10857, 18172, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Nature Mantle of the Dawn (18172) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10857, 18172, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Nature Mantle of the Dawn (18172) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 10857, 18173, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Shadow Mantle of the Dawn (18173) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10857, 18173, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Shadow Mantle of the Dawn (18173) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 10857, 18173, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Shadow Mantle of the Dawn (18173) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 10857, 18182, 0, 1, 47, 0, 5517, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Chromatic Mantle of the Dawn (18182) if one of the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) is rewarded.'), +(23, 10857, 18182, 0, 2, 47, 0, 5521, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Chromatic Mantle of the Dawn (18182) if one of the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) is rewarded.'), +(23, 10857, 18182, 0, 3, 47, 0, 5524, 64, 0, 0, 0, 0, '', 'Argent Quartermaster Lightspark (10857) - Only sell Chromatic Mantle of the Dawn (18182) if one of the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) is rewarded.'); + +-- Quartermaster Miranda Breechlock (11536) Conditions +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 23 AND `SourceGroup` = 11536 AND `SourceEntry` IN (18169, 18170, 18171, 18172, 18173, 18182)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(23, 11536, 18169, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Flame Mantle of the Dawn (18169) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 11536, 18169, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Flame Mantle of the Dawn (18169) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 11536, 18169, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Flame Mantle of the Dawn (18169) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 11536, 18170, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Frost Mantle of the Dawn (18170) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 11536, 18170, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Frost Mantle of the Dawn (18170) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 11536, 18170, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Frost Mantle of the Dawn (18170) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 11536, 18171, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Arcane Mantle of the Dawn (18171) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 11536, 18171, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Arcane Mantle of the Dawn (18171) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 11536, 18171, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Arcane Mantle of the Dawn (18171) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 11536, 18172, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Nature Mantle of the Dawn (18172) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 11536, 18172, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Nature Mantle of the Dawn (18172) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 11536, 18172, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Nature Mantle of the Dawn (18172) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 11536, 18173, 0, 1, 47, 0, 5504, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Shadow Mantle of the Dawn (18173) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 11536, 18173, 0, 2, 47, 0, 5507, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Shadow Mantle of the Dawn (18173) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), +(23, 11536, 18173, 0, 3, 47, 0, 5513, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Shadow Mantle of the Dawn (18173) if one of the Mantle of the Dawn quests (5504, 5507, 5513) is rewarded.'), + +(23, 11536, 18182, 0, 1, 47, 0, 5517, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Chromatic Mantle of the Dawn (18182) if one of the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) is rewarded.'), +(23, 11536, 18182, 0, 2, 47, 0, 5521, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Chromatic Mantle of the Dawn (18182) if one of the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) is rewarded.'), +(23, 11536, 18182, 0, 3, 47, 0, 5524, 64, 0, 0, 0, 0, '', 'Quartermaster Miranda Breechlock (11536) - Only sell Chromatic Mantle of the Dawn (18182) if one of the Chromatic Mantle of the Dawn quests (5517, 5521, 5524) is rewarded.'); diff --git a/data/sql/updates/db_world/2023_09_26_00.sql b/data/sql/updates/db_world/2023_09_26_00.sql new file mode 100644 index 00000000000000..6e7eea892e870e --- /dev/null +++ b/data/sql/updates/db_world/2023_09_26_00.sql @@ -0,0 +1,7 @@ +-- DB update 2023_09_25_08 -> 2023_09_26_00 +-- +DELETE FROM `spell_script_names` WHERE `spell_id`= -24604 AND `ScriptName` = 'spell_hun_furious_howl'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(-24604, 'spell_hun_furious_howl'); + +DELETE FROM `spell_dbc` WHERE `ID` IN (24604, 64491, 64492, 64493, 64494, 64495, 53434); diff --git a/data/sql/updates/db_world/2023_09_26_01.sql b/data/sql/updates/db_world/2023_09_26_01.sql new file mode 100644 index 00000000000000..dc0500e06e2fa2 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_26_01.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_26_00 -> 2023_09_26_01 +-- +UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask`|33554432 WHERE `entry` = 15690; diff --git a/data/sql/updates/db_world/2023_09_26_02.sql b/data/sql/updates/db_world/2023_09_26_02.sql new file mode 100644 index 00000000000000..5d9b41a93fbf4a --- /dev/null +++ b/data/sql/updates/db_world/2023_09_26_02.sql @@ -0,0 +1,5 @@ +-- DB update 2023_09_26_01 -> 2023_09_26_02 +-- #12145 midsummer add spell script spell_midsummer_ribbon_pole_visual +DELETE FROM `spell_script_names` WHERE `spell_id` = 29172; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(29172, 'spell_midsummer_ribbon_pole_visual'); diff --git a/data/sql/updates/db_world/2023_09_26_03.sql b/data/sql/updates/db_world/2023_09_26_03.sql new file mode 100644 index 00000000000000..29deae6229ab30 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_26_03.sql @@ -0,0 +1,22 @@ +-- DB update 2023_09_26_02 -> 2023_09_26_03 +-- +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` IN (22486, 22487); + +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (22091, 22486, 22487); +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 +(22091, 0, 0, 0, 0, 0, 100, 0, 0, 0, 3000, 3000, 0, 0, 11, 38296, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Spitfire Totem - In Combat - Cast Attack'), +(22091, 0, 1, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 9, 21965, 0, 100, 1, 0, 0, 0, 0, 'Spitfire Totem - On Death - Do Action on Fathom-Guard Tidalvess'), +(22486, 0, 0, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 223, 2, 0, 0, 0, 0, 0, 9, 21965, 0, 100, 1, 0, 0, 0, 0, 'Greater Earthbind Totem - On Death - Do Action on Fathom-Guard Tidalvess'), +(22487, 0, 0, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 223, 3, 0, 0, 0, 0, 0, 9, 21965, 0, 100, 1, 0, 0, 0, 0, 'Greater Poison Cleansing Totem - On Death - Do Action on Fathom-Guard Tidalvess'); + +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (21964, 21965, 21966) AND `source_type` = 0; + +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'boss_fathomguard_caribdis' WHERE `entry` = 21964; +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'boss_fathomguard_tidalvess' WHERE `entry` = 21965; +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'boss_fathomguard_sharkkis' WHERE `entry` = 21966; + +DELETE FROM `creature_template_movement` WHERE `CreatureId` IN (22091, 22486, 22487); +INSERT INTO `creature_template_movement` (`CreatureId`, `Flight`, `Rooted`) VALUES +(22091, 1, 1), +(22486, 1, 1), +(22487, 1, 1); diff --git a/data/sql/updates/db_world/2023_09_27_00.sql b/data/sql/updates/db_world/2023_09_27_00.sql new file mode 100644 index 00000000000000..f7627aad79a702 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_27_00.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_26_03 -> 2023_09_27_00 +-- +UPDATE `reference_loot_template` SET `Item` = 30559, `Comment` = 'Etched Fire Opal' WHERE `Entry` = 43010 AND `Item` = 30556; diff --git a/data/sql/updates/db_world/2023_09_27_01.sql b/data/sql/updates/db_world/2023_09_27_01.sql new file mode 100644 index 00000000000000..78786bdecc6bb7 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_27_01.sql @@ -0,0 +1,2 @@ +-- DB update 2023_09_27_00 -> 2023_09_27_01 +DELETE FROM `npc_vendor` WHERE `entry` = 31580 AND `item` IN(42943, 42944, 42945, 42946, 42947, 42948, 42949, 42950, 42951, 42952, 42984, 42985, 42991, 42992, 48677, 48683, 48685, 48687, 48689, 48691, 48716, 48718); diff --git a/data/sql/updates/db_world/2023_09_27_02.sql b/data/sql/updates/db_world/2023_09_27_02.sql new file mode 100644 index 00000000000000..503859d21009f5 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_27_02.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_27_01 -> 2023_09_27_02 +-- +ALTER TABLE `quest_template` MODIFY COLUMN `AllowableRaces` INT UNSIGNED NOT NULL DEFAULT 0; diff --git a/data/sql/updates/db_world/2023_09_29_00.sql b/data/sql/updates/db_world/2023_09_29_00.sql new file mode 100644 index 00000000000000..01f923c0ad8974 --- /dev/null +++ b/data/sql/updates/db_world/2023_09_29_00.sql @@ -0,0 +1,3 @@ +-- DB update 2023_09_27_02 -> 2023_09_29_00 +-- +UPDATE `conditions` SET `ConditionTypeOrReference` = 8 WHERE `SourceGroup` = 8441 AND `ConditionTypeOrReference` = 9; diff --git a/data/sql/updates/db_world/2023_10_01_00.sql b/data/sql/updates/db_world/2023_10_01_00.sql new file mode 100644 index 00000000000000..c218082b9ce087 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_01_00.sql @@ -0,0 +1,5 @@ +-- DB update 2023_09_29_00 -> 2023_10_01_00 +-- +DELETE FROM `creature_text` WHERE `CreatureId` = 16524 AND `GroupID` = 10; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(16524, 10, 0, '%s begins channelling his mana into a powerful arcane spell.', 16, 0, 100, 13515, 3, 'Shade of Aran EMOTE_ARCANE_EXPLOSION'); diff --git a/data/sql/updates/db_world/2023_10_01_01.sql b/data/sql/updates/db_world/2023_10_01_01.sql new file mode 100644 index 00000000000000..1dc33533db8cb4 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_01_01.sql @@ -0,0 +1,5 @@ +-- DB update 2023_10_01_00 -> 2023_10_01_01 +-- +DELETE FROM `creature_template_movement` WHERE `CreatureId` = 17265; +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Rooted`) VALUES +(17265, 1, 1); diff --git a/data/sql/updates/db_world/2023_10_01_02.sql b/data/sql/updates/db_world/2023_10_01_02.sql new file mode 100644 index 00000000000000..2f1cdcc1aa447d --- /dev/null +++ b/data/sql/updates/db_world/2023_10_01_02.sql @@ -0,0 +1,3 @@ +-- DB update 2023_10_01_01 -> 2023_10_01_02 +-- +UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask`|33554432 WHERE `entry` = 17535; diff --git a/data/sql/updates/db_world/2023_10_01_03.sql b/data/sql/updates/db_world/2023_10_01_03.sql new file mode 100644 index 00000000000000..7bb3d7f5c9326e --- /dev/null +++ b/data/sql/updates/db_world/2023_10_01_03.sql @@ -0,0 +1,95 @@ +-- DB update 2023_10_01_02 -> 2023_10_01_03 +-- +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (21218, 21220, 21221, 21224, 21225, 21226, 21228, 21229, 21230, 21231, 21232, 21251, 21263, 21298, 21299, 21301, 21339, 21806, 21863, 21865, 21873, 21920, 22009, 22055, 22056, 22250) AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(21218, 0, 0, 0, 0, 0, 100, 0, 16300, 19300, 10090, 19400, 0, 0, 11, 38572, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Vashj\'ir Honor Guard - In Combat - Cast Mortal Cleave'),-- fully sniffed +(21218, 0, 1, 0, 105, 0, 100, 0, 15750, 16850, 15750, 16850, 0, 5, 11, 38576, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Vashj\'ir Honor Guard - Victim Casting - Cast Knockback'),-- fully sniffed +(21218, 0, 2, 3, 2, 0, 100, 1, 0, 50, 0, 0, 0, 0, 11, 38947, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Vashj\'ir Honor Guard - Between Health 0-50% - Cast Frenzy'),-- fully sniffed +(21218, 0, 3, 0, 61, 0, 50, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Vashj\'ir Honor Guard - Between Health 0-50% - Talk'), +(21218, 0, 4, 0, 12, 0, 100, 0, 0, 20, 15000, 15000, 0, 0, 11, 38959, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Vashj\'ir Honor Guard - Target Health 0-20% - Cast Execute'),-- not sniffed thus unchanged +(21220, 0, 0, 0, 0, 0, 100, 0, 4800, 6900, 3650, 14750, 0, 0, 11, 38582, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Priestess - In Combat - Cast Holy Smite'),-- fully sniffed +(21220, 0, 1, 0, 0, 0, 100, 0, 6050, 12850, 6050, 17050, 0, 0, 11, 38585, 0, 0, 0, 0, 0, 5, 40, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Priestess - In Combat - Cast Holy Fire'),-- fully sniffed +(21220, 0, 2, 0, 14, 0, 100, 0, 25000, 35, 8500, 16100, 0, 0, 11, 38580, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Priestess - Friendly Missing Health - Cast Greater Heal'),-- fully sniffed +(21220, 0, 3, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 39, 20, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Priestess - On Aggro - Call For Help'), +(21221, 0, 0, 0, 0, 0, 100, 0, 0, 2000, 2000, 2000, 0, 0, 11, 38904, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Beast-Tamer - In Combat - Cast Throw'),-- not sniffed thus unchanged +(21221, 0, 1, 0, 0, 0, 100, 0, 6050, 10850, 6050, 12950, 0, 0, 11, 38474, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Beast-Tamer - In Combat - Cast Cleave'),-- fully sniffed +(21221, 0, 2, 0, 0, 0, 100, 0, 6050, 7250, 15800, 19200, 0, 0, 11, 38484, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Beast-Tamer - In Combat - Cast Bestial Wrath'),-- fully sniffed +(21224, 0, 0, 0, 14, 0, 100, 0, 8000, 40, 8000, 10000, 0, 0, 11, 38658, 64, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Depth-Seer - Friendly Missing Health - Cast Healing Touch'),-- not sniffed thus unchanged +(21224, 0, 1, 0, 16, 1, 100, 0, 38657, 40, 7000, 10000, 0, 0, 11, 38657, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Depth-Seer - Friendly Missing Buff - Cast Rejuvenation'),-- not sniffed thus unchanged +(21224, 0, 2, 0, 0, 0, 100, 0, 8450, 8450, 25000, 35000, 0, 0, 11, 38659, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Depth-Seer - In Combat - Cast Tranquility'),-- repeat timer not sniffed +(21224, 0, 3, 0, 4, 0, 100, 512, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Depth-Seer - On Aggro - Set Event Phase'), +(21225, 0, 0, 0, 0, 0, 100, 0, 8650, 8850, 18000, 25000, 0, 0, 11, 39070, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Warrior - In Combat - Cast Bloodthirst'),-- repeat timer not sniffed +(21225, 0, 1, 0, 0, 0, 100, 0, 10000, 15000, 25000, 30000, 0, 0, 11, 38664, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Warrior - In Combat - Cast Enrage'),-- not sniffed thus unchanged +(21225, 0, 2, 0, 0, 0, 100, 0, 3000, 10000, 10000, 15000, 0, 0, 11, 39069, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Warrior - In Combat - Cast Uppercut'),-- not sniffed thus unchanged +(21226, 0, 0, 0, 0, 0, 100, 0, 7250, 8850, 3000, 4000, 0, 0, 11, 39065, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Shaman - In Combat - Cast Lightning Bolt'),-- repeat timer not sniffed +(21226, 0, 1, 0, 0, 0, 100, 0, 0, 0, 60000, 60000, 0, 0, 11, 39067, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Shaman - In Combat - Cast Lightning Shield'),-- not sniffed thus unchanged +(21226, 0, 2, 0, 0, 0, 100, 0, 3000, 10000, 10000, 15000, 0, 0, 11, 39066, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Shaman - In Combat - Cast Chain Lightning'),-- not sniffed thus unchanged +(21228, 0, 0, 0, 0, 0, 100, 0, 0, 1000, 2000, 2200, 0, 0, 11, 39064, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Hydromancer - In Combat - Cast FrostBolt'),-- not sniffed correctly thus unchanged +(21228, 0, 1, 0, 0, 0, 100, 0, 5000, 10000, 10000, 15000, 0, 0, 11, 39062, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Hydromancer - In Combat - Cast Frost Shock'),-- not sniffed thus unchanged +(21228, 0, 2, 0, 106, 0, 100, 0, 10000, 15000, 10000, 15000, 0, 10, 11, 39063, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Hydromancer - Within Range 0-10yd - Cast Frost Nova'),-- not sniffed correctly thus unchanged +(21229, 0, 0, 0, 0, 0, 100, 0, 10900, 21200, 120000, 120000, 0, 0, 11, 39027, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Tidecaller - In Combat - Cast Poison Shield'),-- repeat unchanged due to logical timer +(21229, 0, 1, 0, 0, 0, 100, 0, 5200, 11900, 35150, 35150, 0, 0, 11, 38624, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Tidecaller - In Combat - Cast Water Elemental Totem'), +(21230, 0, 0, 0, 4, 0, 100, 512, 0, 0, 0, 0, 0, 0, 30, 1, 2, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - On Aggro - Set Event Phase Random'), +(21230, 0, 1, 0, 0, 1, 100, 0, 1550, 9550, 2400, 8700, 0, 0, 11, 38641, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Fireball'),-- fully sniffed +(21230, 0, 2, 0, 0, 1, 100, 0, 1200, 2000, 60000, 60000, 0, 0, 11, 38648, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Fire Destruction'),-- repeat timer not sniffed +(21230, 0, 3, 0, 0, 1, 100, 0, 12100, 22000, 10950, 18150, 0, 0, 11, 38635, 0, 0, 0, 0, 0, 5, 40, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Rain of Fire'),-- fully sniffed +(21230, 0, 4, 0, 0, 1, 100, 0, 8500, 12300, 6050, 20850, 0, 0, 11, 38636, 0, 0, 0, 0, 0, 5, 30, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Scorch'),-- fully sniffed +(21230, 0, 5, 0, 0, 2, 100, 0, 4800, 10900, 1200, 6700, 0, 0, 11, 38645, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Frostbolt'),-- fully sniffed +(21230, 0, 6, 0, 0, 2, 100, 0, 1200, 9600, 60000, 60000, 0, 0, 11, 38649, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Frost Destruction'),-- repeat timer not sniffed +(21230, 0, 7, 0, 0, 2, 100, 0, 21750, 35150, 14000, 17000, 0, 0, 11, 38644, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Cone of Cold'),-- repeat timer not sniffed +(21230, 0, 8, 0, 0, 2, 100, 1, 7250, 24250, 0, 0, 0, 0, 11, 38646, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Blizzard'),-- new added spell +(21230, 0, 9, 0, 0, 4, 100, 0, 7250, 12950, 13500, 14900, 0, 0, 11, 38633, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Arcane Volley'),-- fully sniffed +(21230, 0, 10, 0, 0, 4, 100, 0, 350, 4650, 60000, 60000, 0, 0, 11, 38647, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Arcane Destruction'),-- repeat timer not sniffed +(21230, 0, 11, 0, 0, 4, 100, 0, 17350, 21400, 14550, 15350, 0, 0, 11, 38634, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Arcane Lightning'),-- fully sniffed +(21230, 0, 12, 0, 0, 4, 100, 0, 8450, 12550, 12100, 22800, 0, 0, 11, 38642, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Nether-Mage - In Combat - Cast Blink'),-- new added spell +(21231, 0, 0, 0, 0, 0, 100, 0, 5000, 12000, 10000, 15000, 0, 0, 11, 38631, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Shield-Bearer - In Combat - Cast Avenger\'s Shield'),-- not sniffed correctly thus unchanged +(21231, 0, 1, 9, 0, 0, 100, 0, 8, 25, 10000, 15000, 0, 0, 11, 38630, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Shield-Bearer - In Combat - Cast Shield Charge'),-- not sniffed correctly thus unchanged +(21232, 0, 0, 0, 25, 0, 100, 257, 0, 0, 0, 0, 0, 0, 11, 29651, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Skulker - On Reset - Cast Dual Wield'), +(21232, 0, 1, 0, 105, 0, 100, 0, 4800, 13100, 4850, 9050, 0, 5, 11, 38625, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Skulker - Victim Casting - Cast Kick'),-- fully sniffed +(21251, 0, 0, 0, 4, 0, 100, 512, 0, 0, 0, 0, 0, 0, 30, 1, 2, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - On Aggro - Set Random Phase'), +(21251, 0, 1, 0, 0, 1, 100, 0, 19400, 19400, 13350, 16950, 0, 0, 11, 39031, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - In Combat - Cast Enrage (Phase 1)'),-- fully sniffed +(21251, 0, 2, 0, 0, 1, 100, 1, 0, 0, 0, 0, 0, 0, 11, 39014, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - In Combat - Cast Atrophic Blow (Phase 1)'),-- not sniffed thus unchanged +(21251, 0, 3, 0, 0, 2, 100, 0, 16950, 16950, 25500, 29100, 0, 0, 11, 38971, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - In Combat - Cast Acid Geyser (Phase 2)'),-- fully sniffed +(21251, 0, 4, 0, 0, 2, 100, 0, 25450, 25450, 29150, 29150, 0, 0, 11, 39044, 0, 0, 0, 0, 0, 5, 40, 1, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - In Combat - Cast Serpentshrine Parasite (Phase 2)'),-- fully sniffed +(21251, 0, 5, 0, 0, 4, 100, 0, 19450, 19450, 25450, 25450, 0, 0, 11, 38976, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - In Combat - Cast Spore Quake (Phase 3)'),-- fully sniffed +(21251, 0, 6, 0, 0, 4, 100, 0, 27900, 27900, 29100, 29100, 0, 0, 11, 39032, 0, 0, 0, 0, 0, 5, 40, 1, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - In Combat - Cast Initial Infection (Phase 3)'),-- fully sniffed +(21251, 0, 7, 0, 6, 0, 80, 512, 0, 0, 0, 0, 0, 0, 125, 1, 4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - On Death - Run Random Timed Event'), +(21251, 0, 8, 0, 59, 0, 100, 512, 1, 0, 0, 0, 0, 0, 11, 38718, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - On Timed Event - Cast Toxic Pool'),-- unchanged +(21251, 0, 9, 0, 59, 0, 100, 512, 2, 0, 0, 0, 0, 0, 11, 38922, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - On Timed Event - Cast Summon Colossus Lurkers'),-- unchanged +(21251, 0, 10, 0, 59, 0, 100, 512, 3, 0, 0, 0, 0, 0, 11, 38928, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - On Timed Event - Cast Summon Colossus Ragers'),-- unchanged +(21251, 0, 11, 0, 59, 0, 100, 512, 4, 0, 0, 0, 0, 0, 11, 38726, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Underbog Colossus - On Timed Event - Cast Summon Serpentshrine Mushroom'),-- unchanged +(21263, 0, 0, 0, 0, 0, 100, 0, 6050, 17850, 7250, 16350, 0, 0, 11, 38995, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Technician - In Combat - Cast Hamstring'),-- fully sniffed +(21298, 0, 0, 0, 0, 0, 80, 0, 10850, 17550, 10900, 17000, 0, 0, 11, 38599, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Serpentguard - In Combat - Cast \'Spell Reflection\''),-- fully sniffed +(21298, 0, 1, 0, 0, 0, 100, 0, 0, 0, 59000, 60000, 0, 0, 11, 38603, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Serpentguard - In Combat - Cast \'Corrupt Devotion Aura\''),-- not sniffed thus unchanged +(21299, 0, 0, 0, 0, 0, 80, 0, 10900, 16000, 22900, 32900, 0, 0, 11, 38626, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Fathom-Witch - In Combat - Cast \'Domination\''),-- repeat timer not sniffed +(21299, 0, 1, 0, 0, 0, 100, 0, 14700, 18500, 66300, 89300, 0, 0, 11, 38627, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Fathom-Witch - In Combat - Cast \'Shadow Nova\''),-- repeat timer not sniffed +(21299, 0, 2, 0, 0, 0, 100, 0, 4450, 5850, 3650, 8450, 0, 0, 11, 38628, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Fathom-Witch - In Combat - Cast \'Shadow Bolt\''),-- fully sniffed +(21301, 0, 0, 0, 0, 0, 100, 0, 6850, 12350, 19400, 27400, 0, 0, 11, 38591, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Shatterer - In Combat - Cast Shatter Armor'),-- fully sniffed +(21301, 0, 1, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 39, 20, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Shatterer - On Aggro - Call For Help'), +(21339, 0, 0, 0, 0, 0, 100, 0, 9700, 22400, 13350, 40050, 0, 0, 11, 38491, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Hate-Screamer - In Combat - Cast Silence'),-- fully sniffed +(21339, 0, 1, 0, 0, 0, 100, 0, 3600, 10900, 4850, 12950, 0, 0, 11, 38496, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Hate-Screamer - In Combat - Cast Sonic Scream'),-- fully sniffed +(21806, 0, 0, 0, 0, 0, 100, 0, 6050, 9250, 8500, 11600, 0, 0, 11, 37531, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Spellbinder - In Combat - Cast Mind Blast'),-- fully sniffed +(21806, 0, 1, 0, 105, 0, 100, 0, 6050, 6050, 8000, 10000, 0, 45, 11, 39076, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Spellbinder - In Combat - Cast Spell Shock'),-- repeat timer not sniffed +(21806, 0, 2, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 39, 20, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Spellbinder - On Aggro - Call For Help'), +(21806, 0, 3, 0, 1, 0, 100, 1, 1000, 1000, 0, 0, 0, 0, 11, 37626, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Spellbinder - Out of Combat - Cast Green Beam'), +(21863, 0, 0, 0, 0, 0, 100, 0, 9650, 15750, 12150, 15750, 0, 0, 11, 38650, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Serpentshrine Lurker - In Combat - Cast Rancid Mushroom'),-- fully sniffed +(21863, 0, 1, 0, 0, 0, 100, 0, 12150, 18150, 15000, 22000, 0, 0, 11, 38655, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Serpentshrine Lurker - In Combat - Cast Poison Bolt Volley'),-- repeat timer not sniffed +(21865, 0, 0, 0, 0, 0, 100, 0, 1200, 9500, 3200, 11400, 0, 0, 11, 37770, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Ambusher - In Combat - Cast Shoot'),-- fully sniffed +(21865, 0, 1, 0, 0, 0, 100, 0, 7250, 14850, 12100, 16000, 0, 0, 11, 37790, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Ambusher - In Combat - Cast Spread Shot'),-- fully sniffed +(21873, 0, 0, 0, 0, 0, 100, 0, 1000, 5000, 9000, 12000, 0, 0, 11, 28168, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Guardian - In Combat - Cast Arcing Smash'),-- not sniffed correctly +(21873, 0, 1, 0, 0, 0, 100, 0, 8000, 12000, 14000, 18000, 0, 0, 11, 9080, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Guardian - In Combat - Cast Hamstring'),-- not sniffed but weird ID +(21920, 0, 0, 0, 0, 0, 100, 0, 7650, 26050, 7250, 26950, 0, 0, 11, 41932, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tidewalker Lurker - In Combat - Cast Carnivorous Bite'),-- fully sniffed +(22009, 0, 0, 0, 60, 0, 100, 1, 100, 100, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tainted Elemental - On Reset - Set In Combat With Zone'), +(22009, 0, 1, 0, 60, 0, 100, 0, 100, 500, 2350, 2650, 0, 0, 11, 38253, 0, 0, 0, 0, 0, 5, 200, 0, 0, 0, 0, 0, 0, 0, 'Tainted Elemental - In Combat - Cast Poison Bolt'),-- fully sniffed +(22009, 0, 2, 0, 60, 0, 100, 769, 15000, 15000, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tainted Elemental - On Update - Despawn'), +(22055, 0, 0, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Elite - On Aggro - Set In Combat With Zone'), +(22055, 0, 1, 0, 0, 0, 100, 0, 6850, 17250, 1250, 15750, 0, 0, 11, 38260, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Elite - In Combat - Cast Cleave'),-- fully sniffed +(22055, 0, 2, 0, 0, 0, 100, 0, 15350, 17750, 8000, 10000, 0, 0, 11, 38262, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Elite - In Combat - Cast Hamstring'),-- repeat not sniffed +(22055, 0, 3, 0, 34, 0, 100, 0, 8, 1, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Elite - Movement Inform - Set In Combat With Zone'), +(22056, 0, 0, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Strider - On Aggro - Set In Combat With Zone'), +(22056, 0, 1, 0, 0, 0, 100, 0, 15700, 15700, 10850, 13350, 0, 0, 11, 38259, 0, 0, 0, 0, 0, 5, 40, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Strider - In Combat - Cast Mind Blast'),-- fully sniffed +(22056, 0, 2, 0, 34, 0, 100, 0, 8, 1, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Strider - Movement Inform - Set In Combat With Zone'), +(22250, 0, 0, 0, 25, 0, 100, 769, 0, 0, 0, 0, 0, 0, 41, 21000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Rancid Mushroom - On Reset - Despawn'), +(22250, 0, 1, 0, 0, 0, 100, 0, 1150, 1150, 1200, 3400, 0, 0, 11, 31698, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Rancid Mushroom - In Combat - Cast Grow'),-- fully sniffed +(22250, 0, 2, 3, 0, 0, 100, 1, 22950, 22950, 0, 0, 0, 0, 11, 38652, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Rancid Mushroom - In Combat - Cast Spore Cloud (no repeat)'),-- fully sniffed +(22250, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Rancid Mushroom - In Combat - Die'); diff --git a/data/sql/updates/db_world/2023_10_01_04.sql b/data/sql/updates/db_world/2023_10_01_04.sql new file mode 100644 index 00000000000000..a8dd6809a795ce --- /dev/null +++ b/data/sql/updates/db_world/2023_10_01_04.sql @@ -0,0 +1,8 @@ +-- DB update 2023_10_01_03 -> 2023_10_01_04 +-- #12145 midsummer add spell script spell_midsummer_ribbon_pole_visual +DELETE FROM `spell_script_names` WHERE `spell_id` IN (29531, 29705, 29726, 29727); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(29531, 'spell_midsummer_ribbon_pole_visual'), +(29705, 'spell_midsummer_ribbon_pole_visual'), +(29726, 'spell_midsummer_ribbon_pole_visual'), +(29727, 'spell_midsummer_ribbon_pole_visual'); diff --git a/data/sql/updates/db_world/2023_10_05_00.sql b/data/sql/updates/db_world/2023_10_05_00.sql new file mode 100644 index 00000000000000..aa13f0dacae9e6 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_05_00.sql @@ -0,0 +1,3 @@ +-- DB update 2023_10_01_04 -> 2023_10_05_00 +-- +DELETE FROM `spell_threat` WHERE `entry`=29166; diff --git a/data/sql/updates/db_world/2023_10_07_00.sql b/data/sql/updates/db_world/2023_10_07_00.sql new file mode 100644 index 00000000000000..ba64915231ad9f --- /dev/null +++ b/data/sql/updates/db_world/2023_10_07_00.sql @@ -0,0 +1,5 @@ +-- DB update 2023_10_05_00 -> 2023_10_07_00 +-- Banner of Provocation +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 17 AND `SourceGroup` = 0 AND `SourceEntry` = 27517; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(17, 0, 27517, 0, 0, 30, 0, 181058, 20, 0, 1, 25, 0, '', 'Allow using "Banner of Provocation" if there are no other banners within 20y.'); diff --git a/data/sql/updates/db_world/2023_10_07_01.sql b/data/sql/updates/db_world/2023_10_07_01.sql new file mode 100644 index 00000000000000..9dc34a2ac654f6 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_07_01.sql @@ -0,0 +1,8 @@ +-- DB update 2023_10_07_00 -> 2023_10_07_01 +-- Lord Valthalak's Amulet +DELETE FROM `spell_script_names` WHERE `spell_id`=27360; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (27360, 'spell_gen_valthalak_amulet'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 17 AND `SourceGroup` = 0 AND `SourceEntry` = 27360; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(17, 0, 27360, 0, 0, 29, 0, 16073, 50, 0, 1, 0, 0, '', 'Allow using Lord Valthalak\'s Amulet only if there is no Spirit of Lord Valthalak within 50 yards.'); diff --git a/data/sql/updates/db_world/2023_10_07_02.sql b/data/sql/updates/db_world/2023_10_07_02.sql new file mode 100644 index 00000000000000..6df8940c639584 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_07_02.sql @@ -0,0 +1,44 @@ +-- DB update 2023_10_07_01 -> 2023_10_07_02 +-- Stone Fury from Trinity +UPDATE `creature_template` SET `MovementType` = 2 WHERE (`entry` = 2258); + +DELETE FROM `creature_template_addon` WHERE (`entry` = 2258); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(2258, 639130, 0, 0, 1, 0, 0, ''); + +DELETE FROM `creature` WHERE (`id1` = 2258) AND (`guid` IN (63913)); +INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `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`, `ScriptName`, `VerifiedBuild`) VALUES +(63913, 2258, 0, 0, 0, 0, 0, 1, 1, 0, 664.315, -1027.59, 160.39, 5.21757, 72000, 0, 0, 1536, 0, 2, 0, 0, 0, '', 0); + +DELETE FROM `waypoint_data` WHERE `id` = 639130; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(639130, 1, 664.315, -1027.59, 160.39, NULL, 0, 0, 0, 100, 0), +(639130, 2, 654.02, -1032.34, 163.127, NULL, 0, 0, 0, 100, 0), +(639130, 3, 634.638, -1041.36, 163.816, NULL, 0, 0, 0, 100, 0), +(639130, 4, 622.304, -1055.48, 163.186, NULL, 0, 0, 0, 100, 0), +(639130, 5, 620.168, -1114.91, 160.186, NULL, 0, 0, 0, 100, 0), +(639130, 6, 627.218, -1131.61, 159.535, NULL, 0, 0, 0, 100, 0), +(639130, 7, 631.939, -1149.35, 155.421, NULL, 0, 0, 0, 100, 0), +(639130, 8, 629.934, -1192.34, 145.181, NULL, 0, 0, 0, 100, 0), +(639130, 9, 633.981, -1229.12, 136.877, NULL, 0, 0, 0, 100, 0), +(639130, 10, 634.73, -1271.43, 121.429, NULL, 0, 0, 0, 100, 0), +(639130, 11, 627.306, -1321.81, 106.197, NULL, 0, 0, 0, 100, 0), +(639130, 12, 629.422, -1375.57, 93.9589, NULL, 0, 0, 0, 100, 0), +(639130, 13, 643.925, -1408.88, 87.1831, NULL, 0, 0, 0, 100, 0), +(639130, 14, 668.443, -1437.6, 81.8552, NULL, 0, 0, 0, 100, 0), +(639130, 15, 708.689, -1455.94, 81.4619, NULL, 0, 0, 0, 100, 0), +(639130, 16, 745.689, -1459.7, 80.3421, NULL, 0, 0, 0, 100, 0), +(639130, 17, 708.769, -1455.86, 81.4599, NULL, 0, 0, 0, 100, 0), +(639130, 18, 667.903, -1437.37, 81.9153, NULL, 0, 0, 0, 100, 0), +(639130, 19, 643.733, -1408.63, 87.2146, NULL, 0, 0, 0, 100, 0), +(639130, 20, 629.19, -1375.19, 94.0446, NULL, 0, 0, 0, 100, 0), +(639130, 21, 627.374, -1321.59, 106.257, NULL, 0, 0, 0, 100, 0), +(639130, 22, 634.783, -1271.27, 121.478, NULL, 0, 0, 0, 100, 0), +(639130, 23, 633.98, -1228.57, 137.007, NULL, 0, 0, 0, 100, 0), +(639130, 24, 629.947, -1191.76, 145.328, NULL, 0, 0, 0, 100, 0), +(639130, 25, 631.939, -1148.87, 155.504, NULL, 0, 0, 0, 100, 0), +(639130, 26, 627.116, -1131.07, 159.662, NULL, 0, 0, 0, 100, 0), +(639130, 27, 620.092, -1114.7, 160.189, NULL, 0, 0, 0, 100, 0), +(639130, 28, 622.218, -1054.98, 163.22, NULL, 0, 0, 0, 100, 0), +(639130, 29, 634.789, -1041.15, 163.826, NULL, 0, 0, 0, 100, 0), +(639130, 30, 653.802, -1032.34, 163.225, NULL, 0, 0, 0, 100, 0); diff --git a/data/sql/updates/db_world/2023_10_08_00.sql b/data/sql/updates/db_world/2023_10_08_00.sql new file mode 100644 index 00000000000000..c5717a04a1daf9 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_08_00.sql @@ -0,0 +1,4 @@ +-- DB update 2023_10_07_02 -> 2023_10_08_00 +-- +DELETE FROM `command` WHERE `name`='commentator'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES ('commentator', 2, 'Syntax: .commentator [on/off]\r\n\r\nEnable or Disable in game Commentator tag or show current state if on/off not provided.'); diff --git a/data/sql/updates/db_world/2023_10_08_01.sql b/data/sql/updates/db_world/2023_10_08_01.sql new file mode 100644 index 00000000000000..4b238a56ecf24f --- /dev/null +++ b/data/sql/updates/db_world/2023_10_08_01.sql @@ -0,0 +1,77 @@ +-- DB update 2023_10_08_00 -> 2023_10_08_01 +-- Blackrock Depths - Dark Iron Deposit(s) +DELETE FROM `gameobject` WHERE `id` = 165658 AND `map` = 230; +DELETE FROM `pool_template` WHERE `entry` BETWEEN 11700 AND 11705; +DELETE FROM `pool_gameobject` WHERE `pool_entry` BETWEEN 11700 AND 11705 AND `guid` BETWEEN 10601 and 10626; + +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(10601, 165658, 230, 0, 0, 1, 1, 884.448, -410.508, -48.2044, 4.34587, 0, 0, -0.824126, 0.566406, 604800, 100, 1), +(10602, 165658, 230, 0, 0, 1, 1, 1215.01, -384.236, -98.9694, 1.79769, 0, 0, 0.782608, 0.622515, 604800, 100, 1), +(10603, 165658, 230, 0, 0, 1, 1, 418.63, -158.696, -63.1528, 0.226893, 0, 0, 0.113203, 0.993572, 604800, 100, 1), +(10604, 165658, 230, 0, 0, 1, 1, 980.556, -419.592, -59.3434, 4.4855, 0, 0, -0.782608, 0.622515, 604800, 100, 1), +(10605, 165658, 230, 0, 0, 1, 1, 756.207, 158.727, -72.2169, -1.23918, 0, 0, -0.580703, 0.814116, 604800, 100, 1), +(10606, 165658, 230, 0, 0, 1, 1, 640.727, 28.869, -74.0452, 1.8675, 0, 0, 0.803857, 0.594823, 604800, 100, 1), +(10607, 165658, 230, 0, 0, 1, 1, 1002.0756, -395.6539, -64.0793, 0.15708, 0, 0, 0.0784591, 0.996917, 604800, 100, 1), +(10608, 165658, 230, 0, 0, 1, 1, 646.092, 193.607, -72.1246, 0.523598, 0, 0, 0.258819, 0.965926, 604800, 100, 1), +(10609, 165658, 230, 0, 0, 1, 1, 670.734, -201.308, -78.1551, 3.75246, 0, 0, -0.953716, 0.300708, 604800, 100, 1), +(10610, 165658, 230, 0, 0, 1, 1, 673.099, -21.6642, -73.7605, 2.74016, 0, 0, 0.979924, 0.19937, 604800, 100, 1), +(10611, 165658, 230, 0, 0, 1, 1, 313.624, -211.422, -77.3546, -0.663223, 0, 0, -0.325567, 0.945519, 604800, 100, 1), +(10612, 165658, 230, 0, 0, 1, 1, 1014.22, -356.364, -65.7033, 1.13446, 0, 0, 0.537299, 0.843392, 604800, 100, 1), +(10613, 165658, 230, 0, 0, 1, 1, 637.928, -162.775, -70.9528, -2.75761, 0, 0, -0.981627, 0.190812, 604800, 100, 1), +(10614, 165658, 230, 0, 0, 1, 1, 545.169, -128.195, -60.3184, -1.72788, 0, 0, 0.760406, -0.649448, 604800, 100, 1), +(10615, 165658, 230, 0, 0, 1, 1, 977.641, -316.468, -70.6036, 1.79769, 0, 0, 0.782608, 0.622515, 604800, 100, 1), +(10616, 165658, 230, 0, 0, 1, 1, 636.57, -274.759, -83.7882, 4.01426, 0, 0, -0.906307, 0.422619, 604800, 100, 1), +(10617, 165658, 230, 0, 0, 1, 1, 679.721, 102.181, -73.2564, -1.18682, 0, 0, 0.559193, -0.829037, 604800, 100, 1), +(10618, 165658, 230, 0, 0, 1, 1, 634.768, -56.406, -73.6264, 2.96704, 0, 0, 0.996194, 0.087165, 604800, 100, 1), +(10619, 165658, 230, 0, 0, 1, 1, 327.184, -58.5715, -71.3615, 0.715585, 0, 0, 0.350207, 0.936672, 604800, 100, 1), +(10620, 165658, 230, 0, 0, 1, 1, 1204.1, -350.158, -93.6315, 0.59341, 0, 0, 0.292371, 0.956305, 604800, 100, 1), +(10621, 165658, 230, 0, 0, 1, 1, 918.903, -447.008, -53.8907, 0.261798, 0, 0, 0.130526, 0.991445, 604800, 100, 1), +(10622, 165658, 230, 0, 0, 1, 1, 748.476, -53.7894, -71.278, 2.96706, 0, 0, 0.996195, 0.0871558, 604800, 100, 1), +(10623, 165658, 230, 0, 0, 1, 1, 291.891, -122.786, -69.1713, 1.41372, 0, 0, 0.649447, 0.760406, 604800, 100, 1), +(10624, 165658, 230, 0, 0, 1, 1, 503.193, -190.118, -59.3156, -0.401426, 0, 0, 0.199368, -0.979925, 604800, 100, 1), +(10625, 165658, 230, 0, 0, 1, 1, 643.342, 144.62, -73.8284, 0.523598, 0, 0, 0.258819, 0.965926, 604800, 100, 1), +(10626, 165658, 230, 0, 0, 1, 1, 964.466, -436.64, -54.6864, 5.96903, 0, 0, -0.156434, 0.987688, 604800, 100, 1); + +SET +@Bridge = 11700, +@Prison = 11701, +@Arena = 11702, +@Gar = 11703, +@Highway = 11704, +@City = 11705; + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@Bridge, 1, 'BRD - Dark Iron Deposit - Bridge'), +(@Prison, 1, 'BRD - Dark Iron Deposit - Prison'), +(@Arena, 1, 'BRD - Dark Iron Deposit - Arena'), +(@Gar, 1, 'BRD - Dark Iron Deposit - Gar'), +(@Highway, 1, 'BRD - Dark Iron Deposit - Highway'), +(@City, 1, 'BRD - Dark Iron Deposit - City'); + +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(10602, @Bridge, 0, 'Dark Iron Deposit - Bridge'), +(10620, @Bridge, 0, 'Dark Iron Deposit - Bridge'), +(10619, @Prison, 0, 'Dark Iron Deposit - Prison'), +(10623, @Prison, 0, 'Dark Iron Deposit - Prison'), +(10611, @Prison, 0, 'Dark Iron Deposit - Prison'), +(10603, @Prison, 0, 'Dark Iron Deposit - Prison'), +(10624, @Arena, 0, 'Dark Iron Deposit - Arena'), +(10616, @Arena, 0, 'Dark Iron Deposit - Arena'), +(10609, @Arena, 0, 'Dark Iron Deposit - Arena'), +(10613, @Arena, 0, 'Dark Iron Deposit - Arena'), +(10614, @Arena, 0, 'Dark Iron Deposit - Arena'), +(10608, @Gar, 0, 'Dark Iron Deposit - Gar'), +(10625, @Gar, 0, 'Dark Iron Deposit - Gar'), +(10617, @Gar, 0, 'Dark Iron Deposit - Gar'), +(10605, @Gar, 0, 'Dark Iron Deposit - Gar'), +(10606, @Highway, 0, 'Dark Iron Deposit - Highway'), +(10610, @Highway, 0, 'Dark Iron Deposit - Highway'), +(10618, @Highway, 0, 'Dark Iron Deposit - Highway'), +(10622, @Highway, 0, 'Dark Iron Deposit - Highway'), +(10615, @City, 0, 'Dark Iron Deposit - City'), +(10612, @City, 0, 'Dark Iron Deposit - City'), +(10607, @City, 0, 'Dark Iron Deposit - City'), +(10604, @City, 0, 'Dark Iron Deposit - City'), +(10626, @City, 0, 'Dark Iron Deposit - City'), +(10621, @City, 0, 'Dark Iron Deposit - City'), +(10601, @City, 0, 'Dark Iron Deposit - City'); diff --git a/data/sql/updates/db_world/2023_10_08_02.sql b/data/sql/updates/db_world/2023_10_08_02.sql new file mode 100644 index 00000000000000..6ac627e48cdf3b --- /dev/null +++ b/data/sql/updates/db_world/2023_10_08_02.sql @@ -0,0 +1,3 @@ +-- DB update 2023_10_08_01 -> 2023_10_08_02 +-- Ghostweave Patterns +DELETE FROM `reference_loot_template` WHERE `Entry` IN (24708,24709) AND `Item` IN (14495,14480,14473,14477); diff --git a/data/sql/updates/db_world/2023_10_08_03.sql b/data/sql/updates/db_world/2023_10_08_03.sql new file mode 100644 index 00000000000000..d9c55b36062d2e --- /dev/null +++ b/data/sql/updates/db_world/2023_10_08_03.sql @@ -0,0 +1,19 @@ +-- DB update 2023_10_08_02 -> 2023_10_08_03 +-- "Dirty" Michael Crowe +DELETE FROM `waypoint_data` WHERE `id`=306490; +DELETE FROM `waypoint_scripts` WHERE `id`=23; +DELETE FROM `creature_addon` WHERE `guid` = 30649; +UPDATE `creature` SET `MovementType` = 0 WHERE `id1` = 23896 AND `guid` = 30649; + +DELETE FROM `creature_template_addon` WHERE (`entry` = 23896); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(23896, 0, 0, 0, 1, 0, 0, ''); + +DELETE FROM `creature_text` WHERE `CreatureID`=23896; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23896, 0, 0, 'You might wanna stand back. Fish guttin\' is a dirty job.', 12, 0, 100, 1, 0, 0, 22392, 0, '"Dirty" Michael Crowe'); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23896; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23896); +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 +(23896, 0, 0, 0, 1, 0, 100, 0, 60000, 120000, 60000, 120000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Dirty" Michael Crowe - Out of Combat - Say Line 0'); diff --git a/data/sql/updates/db_world/2023_10_08_04.sql b/data/sql/updates/db_world/2023_10_08_04.sql new file mode 100644 index 00000000000000..4a672363aba3b2 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_08_04.sql @@ -0,0 +1,18 @@ +-- DB update 2023_10_08_03 -> 2023_10_08_04 +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (1561,3643) AND `source_type` = 1; +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 +-- Sealed Crate +(1561, 1, 0, 0, 19, 0, 100, 0, 74, 0, 0, 0, 0, 0, 12, 2044, 1, 30000, 0, 0, 0, 8, 0, 0, 0, 0, -8841.93, 985.171, 98.6999, 6.00926, 'Sealed Crate - On Quest \'The Legend of Stalvan\' Taken - Summon Creature \'Forlorn Spirit\''), +-- Old Footlocker +(3643, 1, 0, 0, 20, 0, 100, 0, 67, 0, 0, 0, 0, 0, 12, 2044, 2, 30000, 0, 0, 0, 8, 0, 0, 0, 0, -10951.4, 1568.86, 46.9779, 3.75142, 'Old Footlocker - On Quest \'The Legend of Stalvan\' Finished - Summon Creature \'Forlorn Spirit\''); + +-- Forlorn Spirit +DELETE FROM `smart_scripts` WHERE `entryorguid` = 2044 AND `source_type` = 0; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 204400 AND `source_type` = 9; + +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(2044, 0, 0, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 204400, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Forlorn Spirit - On Respawn - Run Script'), +(2044, 0, 1, 0, 0, 0, 100, 0, 2000, 2000, 2000, 2000, 0, 0, 11, 3105, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Forlorn Spirit - In Combat - Cast \'Curse of Stalvan\''), +(2044, 0, 2, 0, 0, 0, 100, 0, 10000, 15000, 18500, 27000, 0, 0, 11, 118, 32, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 'Forlorn Spirit - In Combat - Cast \'Polymorph\' (Skip Tank)'), +(204400, 9, 0, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 21, 15, 0, 0, 0, 0, 0, 0, 0, 'Forlorn Spirit - Actionlist - Say Line 0'), +(204400, 9, 1, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 21, 15, 0, 0, 0, 0, 0, 0, 0, 'Forlorn Spirit - Actionlist - Start Attacking'); diff --git a/data/sql/updates/db_world/2023_10_08_05.sql b/data/sql/updates/db_world/2023_10_08_05.sql new file mode 100644 index 00000000000000..67652182310e7c --- /dev/null +++ b/data/sql/updates/db_world/2023_10_08_05.sql @@ -0,0 +1,9 @@ +-- DB update 2023_10_08_04 -> 2023_10_08_05 +-- Terrorclaw +DELETE FROM `creature_template_addon` WHERE (`entry` = 20477); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(20477, 0, 0, 0, 0, 0, 0, '35408'); + +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryorguid` = 20477; +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 +(20477, 0, 0, 0, 0, 0, 100, 0, 2000, 2000, 5000, 9000, 0, 0, 11, 40504, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Terrorclaw - In Combat - Cast \'Cleave\''); diff --git a/data/sql/updates/db_world/2023_10_08_06.sql b/data/sql/updates/db_world/2023_10_08_06.sql new file mode 100644 index 00000000000000..469665ba9a7955 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_08_06.sql @@ -0,0 +1,10 @@ +-- DB update 2023_10_08_05 -> 2023_10_08_06 +-- Pamela's Doll +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 10926; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 10926); +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 1092600); +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 +(10926, 0, 0, 0, 20, 0, 100, 0, 5149, 0, 0, 0, 0, 0, 80, 1092600, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pamela Redpath - On Quest \'Pamela\'s Doll\' Finished - Run Script'), +(1092600, 9, 0, 0, 0, 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, 'Pamela Redpath - Actionlist - Say Line 4'), +(1092600, 9, 1, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pamela Redpath - Actionlist - Say Line 5'); diff --git a/data/sql/updates/db_world/2023_10_08_07.sql b/data/sql/updates/db_world/2023_10_08_07.sql new file mode 100644 index 00000000000000..786453f9b381e3 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_08_07.sql @@ -0,0 +1,4 @@ +-- DB update 2023_10_08_06 -> 2023_10_08_07 +-- 64930 - Electrified | Shaman T8 Elemental 4P Bonus +DELETE FROM `spell_script_names` WHERE `spell_id` = 64928; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (64928, 'spell_sha_t8_electrified'); diff --git a/data/sql/updates/db_world/2023_10_08_08.sql b/data/sql/updates/db_world/2023_10_08_08.sql new file mode 100644 index 00000000000000..bc9f01ec57d7df --- /dev/null +++ b/data/sql/updates/db_world/2023_10_08_08.sql @@ -0,0 +1,8 @@ +-- DB update 2023_10_08_07 -> 2023_10_08_08 +-- Annihilator - Armor Shatter +DELETE FROM `spell_custom_attr` WHERE `spell_id`=16928; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (16928, 4194304); + +-- Bashguuder & Bashguuder - Puncture Armor +DELETE FROM `spell_custom_attr` WHERE `spell_id`=17315; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (17315, 4194304); diff --git a/data/sql/updates/db_world/2023_10_10_00.sql b/data/sql/updates/db_world/2023_10_10_00.sql new file mode 100644 index 00000000000000..2050f08cb29d42 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_00.sql @@ -0,0 +1,14 @@ +-- DB update 2023_10_08_08 -> 2023_10_10_00 +-- Eridan Bluewind +DELETE FROM `smart_scripts` WHERE `entryorguid` = 9116 AND `source_type` = 0 AND `id` = 2; +DELETE FROM `smart_scripts` WHERE `source_type` = 9 AND `entryorguid` = 911600; + +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 +(9116, 0, 2, 0, 19, 0, 100, 0, 4442, 0, 0, 0, 0, 0, 80, 911600, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Eridan Bluewind - On Quest \'Purified!\' Taken - Run Script'), +(911600, 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, 'Eridan Bluewind - On Script - Remove Npc Flags Questgiver'), +(911600, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Eridan Bluewind - On Script - Say Line 0'), +(911600, 9, 2, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 2.59669, 'Eridan Bluewind - On Script - Set Orientation 2,59669'), +(911600, 9, 3, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 11, 28892, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Eridan Bluewind - On Script - Cast \'Nature Channeling\''), +(911600, 9, 4, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 2.72271, 'Eridan Bluewind - On Script - Set Orientation 2,72271'), +(911600, 9, 5, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Eridan Bluewind - On Script - Say Line 1'), +(911600, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 82, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Eridan Bluewind - On Script - Add Npc Flags Questgiver'); diff --git a/data/sql/updates/db_world/2023_10_10_01.sql b/data/sql/updates/db_world/2023_10_10_01.sql new file mode 100644 index 00000000000000..0fb82308a96d31 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_01.sql @@ -0,0 +1,6 @@ +-- DB update 2023_10_10_00 -> 2023_10_10_01 +-- Place Draenei Banner +UPDATE `conditions` SET `Comment` = '\'Place Draenei Banner\' - Target only Lord Xiz' WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 30988) AND (`ConditionTypeOrReference` = 31) AND (`ConditionValue1` = 3) AND (`ConditionValue2` = 17701); +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 17) AND (`SourceGroup` = 0) AND (`SourceEntry` = 30988) AND (`ConditionTypeOrReference` = 29) AND (`ConditionValue1` = 17701) AND (`ConditionValue2` = 5) AND (`ConditionValue3` = 1); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(17, 0, 30988, 0, 0, 29, 0, 17701, 5, 1, 0, 0, 0, '', 'Allow casting \'Place Draenei Banner\' only if Lord Xiz is within 5 yards and dead.'); diff --git a/data/sql/updates/db_world/2023_10_10_02.sql b/data/sql/updates/db_world/2023_10_10_02.sql new file mode 100644 index 00000000000000..8316f204de5972 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_02.sql @@ -0,0 +1,3 @@ +-- DB update 2023_10_10_01 -> 2023_10_10_02 +-- Ores and Herbs should be visible in visible in all phases +UPDATE `gameobject` SET `phaseMask`='255' WHERE `id` IN(1617,1618,1619,3724,3725,3726,1620,1621,3727,3729,1622,1623,1624,2045,3730,2041,2046,1628,2044,2041,2043,176636,176642,142140,142141,142142,142143,142144,180165,183046,180164,176641,176640,176639,176638,176637,142145,176583,176584,176586,176587,176588,176589,180166,180167, 180168,183043,183044,183045,181270,181271,181275,181276,181277,181278,183385,181279,181282,181281,189973,190169,190173,190175,190174,190170,190172,191019,190171,190176,1731,181248,103713,2055,3763,1732,3764,103711,181249,2054,1733,1735,105569,73939,1734,2040,123310,150079,150080,176645,181109,2047,123309,150081,150082,181108,176643,123848,175404,181555,181556,181557,181569,181570,189978,189979,189980,189981,191133) AND `map` IN(0,1,530,571); diff --git a/data/sql/updates/db_world/2023_10_10_03.sql b/data/sql/updates/db_world/2023_10_10_03.sql new file mode 100644 index 00000000000000..d1e031ecaf4d80 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_03.sql @@ -0,0 +1,29 @@ +-- DB update 2023_10_10_02 -> 2023_10_10_03 +-- J.D. Collie +UPDATE `smart_scripts` SET `comment` = 'J.D. Collie - On Quest \'Making Sense of It\' Taken - Run Script' WHERE `entryorguid` = 9117 AND `source_type` = 0 AND `id` = 0; + +DELETE FROM `smart_scripts` WHERE `entryorguid`=9117 AND `source_type`=0 AND `id` IN (2,3,4); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (911701,911702,911703) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(9117, 0, 2, 0, 20, 0, 100, 0, 3941, 0, 0, 0, 0, 0, 80, 911701, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Quest \'A Gnome\'s Assistance\' Finished - Run Script'), +(9117, 0, 3, 0, 40, 0, 100, 0, 1, 911700, 0, 0, 0, 0, 80, 911702, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Waypoint 1 Reached - Run Script'), +(9117, 0, 4, 0, 40, 0, 100, 0, 2, 911700, 0, 0, 0, 0, 80, 911703, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Waypoint 2 Reached - Run Script'), +(911701, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 83, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Remove Npc Flag Questgiver & Gossip'), +(911701, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 1, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Say Line 8'), +(911701, 9, 2, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 53, 1, 911700, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Start Waypoint'), +(911702, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 54, 16000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Pause Waypoint'), +(911702, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 5.86, 'J.D. Collie - Actionlist - Set Orientation'), +(911702, 9, 2, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 1, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Say Line 9'), +(911702, 9, 3, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Say Line 4'), +(911702, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 32990, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Cast \'Enchanting Cast Visual\''), +(911702, 9, 5, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Say Line 5'), +(911702, 9, 6, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Say Line 6'), +(911702, 9, 7, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 1, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Say Line 7'), +(911703, 9, 0, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0.872665, 'J.D. Collie - On Script - Set Orientation'), +(911703, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 82, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Add Npc Flag Questgiver & Gossip'), +(911703, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'J.D. Collie - On Script - Say Line 3'); + +DELETE FROM `waypoints` WHERE `entry`=911700; +INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `point_comment`) VALUES +(911700, 1, -6027.85, -1020.16, -217.056, NULL, 0, ''), +(911700, 2, -6033.25, -1017.56, -217.055, NULL, 0, ''); diff --git a/data/sql/updates/db_world/2023_10_10_04.sql b/data/sql/updates/db_world/2023_10_10_04.sql new file mode 100644 index 00000000000000..395a7b001b46b2 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_04.sql @@ -0,0 +1,3 @@ +-- DB update 2023_10_10_03 -> 2023_10_10_04 +-- Shellfish +UPDATE `gameobject_loot_template` SET `MaxCount` = 2 WHERE `Entry` = 13944 and `Item` = 13545; diff --git a/data/sql/updates/db_world/2023_10_10_05.sql b/data/sql/updates/db_world/2023_10_10_05.sql new file mode 100644 index 00000000000000..54698aa70d0b44 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_05.sql @@ -0,0 +1,3 @@ +-- DB update 2023_10_10_04 -> 2023_10_10_05 +-- Hex Lord Malacrass +UPDATE `creature_template_addon` SET `bytes2` = 1 WHERE `entry` = 24239; diff --git a/data/sql/updates/db_world/2023_10_10_06.sql b/data/sql/updates/db_world/2023_10_10_06.sql new file mode 100644 index 00000000000000..0664c1f96deaec --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_06.sql @@ -0,0 +1,71 @@ +-- DB update 2023_10_10_05 -> 2023_10_10_06 +-- Quest: Cuergo's Gold +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI', `ScriptName` = '' WHERE `entry` = 142189; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 1 AND `entryorguid` = 142189); +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 +(142189, 1, 0, 0, 70, 0, 100, 0, 2, 0, 0, 0, 0, 0, 80, 14218900, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Inconspicuous Landmark - On Gameobject State Changed - Run Script'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 14218900); +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 +(14218900, 9, 0, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 50, 142194, 300, 0, 0, 0, 0, 1, 0, 0, 0, 0, -2, -3, 0, 0, 'Inconspicuous Landmark - Actionlist - Summon Gameobject \'Pirate\'s Treasure!\''), +(14218900, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 12, 7898, 3, 5000, 0, 0, 0, 1, 0, 0, 0, 0, -2, -3, 0, 0, 'Inconspicuous Landmark - Actionlist - Summon Creature \'Pirate treasure trigger mob\''); + +DELETE FROM `gameobject` WHERE `id` = 142189; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES +(17231, 142189, 1, 0, 0, 1, 1, -10249.2, -3981.8, 1.66783, -0.750491, 0, 0, -0.366501, 0.930418, 600, 100, 1, '', NULL, NULL), +(17232, 142189, 1, 0, 0, 1, 1, -10119.7, -4052.46, 5.33005, -0.366519, 0, 0, -0.182235, 0.983255, 600, 100, 1, '', NULL, NULL), +(17233, 142189, 1, 0, 0, 1, 1, -10050.8, -3717.16, 5.44262, 2.65289, 0, 0, 0.970295, 0.241925, 600, 100, 1, '', NULL, NULL), +(17234, 142189, 1, 0, 0, 1, 1, -10154.2, -3948.64, 7.74473, 2.65289, 0, 0, 0, 0, 600, 100, 1, '', NULL, NULL), +(17235, 142189, 1, 0, 0, 1, 1, -10285.8, -3881.83, 1.07085, -2.26893, 0, 0, -0.906307, 0.422619, 600, 100, 1, '', NULL, NULL), +(17236, 142189, 1, 0, 0, 1, 1, -10217, -3817.65, 1.35298, 2.65289, 0, 0, 0.970295, 0.241925, 600, 100, 1, '', NULL, NULL); + +DELETE FROM `pool_template` WHERE `entry` IN (355,112); +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES (112, 1, 'Tanaris - Inconspicuous Landmark Pool'); + +DELETE FROM `pool_gameobject` WHERE `pool_entry` IN (355,112); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(17231, 112, 0, 'Inconspicuous Landmark'), +(17232, 112, 0, 'Inconspicuous Landmark'), +(17233, 112, 0, 'Inconspicuous Landmark'), +(17234, 112, 0, 'Inconspicuous Landmark'), +(17235, 112, 0, 'Inconspicuous Landmark'), +(17236, 112, 0, 'Inconspicuous Landmark'); + +-- Pirate treasure trigger mob +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|128 WHERE `entry` = 7898; +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 7898) AND (`source_type` = 0); +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 789800) AND (`source_type` = 9); + +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(7898, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 12, 7899, 1, 300000, 0, 0, 0, 202, 25, 2, 1, 0, 0, 0, 0, 0, 'Pirate treasure trigger mob - On Just Summoned - Summon Creature \'Treasure Hunting Pirate\''), +(7898, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 12, 7902, 1, 300000, 0, 0, 0, 202, 25, 2, 1, 0, 0, 0, 0, 0, 'Pirate treasure trigger mob - On Just Summoned - Summon Creature \'Treasure Hunting Buccaneer\''), +(7898, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 12, 7901, 1, 300000, 0, 0, 0, 202, 25, 1, 1, 0, 0, 0, 0, 0, 'Pirate treasure trigger mob - On Just Summoned - Summon Creature \'Treasure Hunting Swashbuckler\''); + +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (7899,7901,7902); +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryorguid` IN (7899,7901,7902); +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 +-- Treasure Hunting Pirate +(7899, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 1, 3, 0, 0, 20, 142194, 0, 0, 0, 0, 0, 0, 0, 'Treasure Hunting Pirate - On Just Summoned - Move To Closest Creature \'Pirate\'s Treasure!\''), +(7899, 0, 1, 0, 34, 0, 100, 0, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Treasure Hunting Pirate - On Reached Point 0 - Say Line 0'), +(7899, 0, 2, 0, 0, 0, 100, 0, 3000, 7000, 8200, 18100, 0, 0, 11, 11976, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Treasure Hunting Pirate - In Combat - Cast \'Strike\''), +-- Treasure Hunting Swashbuckler +(7901, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 1, 3, 0, 0, 20, 142194, 0, 0, 0, 0, 0, 0, 0, 'Treasure Hunting Swashbuckler - On Just Summoned - Move To Closest Creature \'Pirate\'s Treasure!\''), +(7901, 0, 1, 0, 34, 0, 100, 0, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Treasure Hunting Swashbuckler - On Reached Point 0 - Say Line 0'), +(7901, 0, 2, 0, 0, 0, 100, 0, 10200, 23100, 21900, 28400, 0, 0, 11, 6713, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Treasure Hunting Swashbuckler - In Combat - Cast \'Disarm\''), +-- Treasure Hunting Buccaneer +(7902, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 1, 3, 0, 0, 20, 142194, 0, 0, 0, 0, 0, 0, 0, 'Treasure Hunting Buccaneer - On Just Summoned - Move To Closest Creature \'Pirate\'s Treasure!\''), +(7902, 0, 1, 0, 34, 0, 100, 0, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Treasure Hunting Buccaneer - On Reached Point 0 - Say Line 0'), +(7902, 0, 2, 0, 0, 0, 100, 0, 3000, 7000, 8200, 18100, 0, 0, 11, 11976, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Treasure Hunting Buccaneer - In Combat - Cast \'Strike\''); + +DELETE FROM `creature_text` WHERE `CreatureID` IN (7899,7901,7902); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(7899,0,0,'Hey! Get away from our treasure!',12,0,100,0,0,0,3931,0,'Treasure Hunting Pirate'), +(7899,0,1,'That\'s our treasure, you lubber!',12,0,100,0,0,0,3931,0,'Treasure Hunting Pirate'), +(7899,0,2,'We didn\'t hide this stuff just you could steal it!',12,0,100,0,0,0,3931,0,'Treasure Hunting Pirate'), +(7901,0,0,'Hey! Get away from our treasure!',12,0,100,0,0,0,3931,0,'Treasure Hunting Swashbuckler'), +(7901,0,1,'That\'s our treasure, you lubber!',12,0,100,0,0,0,3931,0,'Treasure Hunting Swashbuckler'), +(7901,0,2,'We didn\'t hide this stuff just you could steal it!',12,0,100,0,0,0,3931,0,'Treasure Hunting Swashbuckler'), +(7902,0,0,'Hey! Get away from our treasure!',12,0,100,0,0,0,3931,0,'Treasure Hunting Buccaneer'), +(7902,0,1,'That\'s our treasure, you lubber!',12,0,100,0,0,0,3931,0,'Treasure Hunting Buccaneer'), +(7902,0,2,'We didn\'t hide this stuff just you could steal it!',12,0,100,0,0,0,3931,0,'Treasure Hunting Buccaneer'); diff --git a/data/sql/updates/db_world/2023_10_10_07.sql b/data/sql/updates/db_world/2023_10_10_07.sql new file mode 100644 index 00000000000000..6e6bb450fef13f --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_07.sql @@ -0,0 +1,18 @@ +-- DB update 2023_10_10_06 -> 2023_10_10_07 +-- Change from 150 minutes to 5 +UPDATE `event_scripts` SET `datalong2` = 300000 WHERE `id` = 3084 AND `command` = 10; + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 17) AND (`SourceGroup` = 0) AND (`SourceEntry` = 12283); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(17, 0, 12283, 0, 0, 29, 0, 8392, 20, 0, 1, 0, 0, '', 'Allow using Standard Issue Flare Gun only if no Pilot Xiggs Fuselighter is within 20 yards.'); + +-- Pilot Xiggs Fuselighter +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 8392; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 8392) AND (`source_type` = 0); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(8392, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Pilot Xiggs Fuselighter - On Just Summoned - Say Line 0'); + +DELETE FROM `creature_text` WHERE `CreatureID`=8392; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(8392, 0, 1, 'Been waitin\' for ya, $n. Glad to see you\'ve come through. Do you have the shipment?', 12, 7, 100, 3, 0, 0, 4406, 0, 'Pilot Xiggs Fuselighter - Greet on summon'); diff --git a/data/sql/updates/db_world/2023_10_10_08.sql b/data/sql/updates/db_world/2023_10_10_08.sql new file mode 100644 index 00000000000000..0c1ce794ebcc36 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_08.sql @@ -0,0 +1,4 @@ +-- DB update 2023_10_10_07 -> 2023_10_10_08 +-- Plague Wagon Empty +DELETE FROM `gameobject` WHERE `guid`=242285; +DELETE FROM `game_event_gameobject` WHERE `guid`=242285; diff --git a/data/sql/updates/db_world/2023_10_10_09.sql b/data/sql/updates/db_world/2023_10_10_09.sql new file mode 100644 index 00000000000000..eb015e3056b142 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_09.sql @@ -0,0 +1,26 @@ +-- DB update 2023_10_10_08 -> 2023_10_10_09 +-- +DELETE FROM `gameobject` WHERE `guid` IN (9266,9268,9270,9272,9273,9274); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES +(9266, 2040, 1, 405, 598, 1, 1, -1774, 2968.79, 37.432, 4.232, 0, 0, 0, 0, 2700, 100, 1, '', 0, NULL), +(9268, 2040, 1, 405, 598, 1, 1, -1778, 2997.54, 35.715, 4.76, 0, 0, 0, 0, 2700, 100, 1, '', 0, NULL), +(9270, 2040, 1, 405, 598, 1, 1, -1765, 2986.9, 40.316, 5.803, 0, 0, 0, 0, 2700, 100, 1, '', 0, NULL), +(9272, 1735, 1, 405, 598, 1, 1, -1774, 2968.79, 37.432, 4.232, 0, 0, 0, 0, 2700, 100, 1, '', 0, NULL), +(9273, 1735, 1, 405, 598, 1, 1, -1778, 2997.54, 35.715, 4.76, 0, 0, 0, 0, 2700, 100, 1, '', 0, NULL), +(9274, 1735, 1, 405, 598, 1, 1, -1765, 2986.9, 40.316, 5.803, 0, 0, 0, 0, 2700, 100, 1, '', 0, NULL); + +DELETE FROM `pool_template` WHERE `entry` = 11699; +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(11699, 1, 'Desolace Mithril Deposit Pool'); + +DELETE FROM `pool_gameobject` WHERE `guid` IN (9256,9257,9258,9266,9268,9270,9272,9273,9274); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(9256, 11699, 3.3, 'Spawn Point 1 - Truesilver'), +(9266, 11699, 0, 'Spawn Point 1 - Mithril'), +(9272, 11699, 8.3, 'Spawn Point 1 - Iron'), +(9257, 11699, 3.3, 'Spawn Point 2 - Truesilver'), +(9268, 11699, 0, 'Spawn Point 2 - Mithril'), +(9273, 11699, 8.3, 'Spawn Point 2 - Iron'), +(9258, 11699, 3.3, 'Spawn Point 3 - Truesilver'), +(9270, 11699, 0, 'Spawn Point 3 - Mithril'), +(9274, 11699, 8.3, 'Spawn Point 3 - Iron'); diff --git a/data/sql/updates/db_world/2023_10_10_10.sql b/data/sql/updates/db_world/2023_10_10_10.sql new file mode 100644 index 00000000000000..13b81390127224 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_10.sql @@ -0,0 +1,9 @@ +-- DB update 2023_10_10_09 -> 2023_10_10_10 +-- Mrs. Dalson's Diary +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 1) AND (`SourceGroup` = 10816) AND (`SourceEntry` = 12738); +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 14) AND (`SourceGroup` = 3001) AND (`SourceEntry` = 3694); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(1, 10816, 12738, 0, 0, 8, 0, 5058, 0, 0, 0, 0, 0, '', 'Drop Dalson Outhouse Key from Wandering Skeletons only if quest Mrs. Dalson\'s Diary has been rewarded.'), +(14, 3001, 3694, 0, 0, 8, 0, 5058, 0, 0, 0, 0, 0, '', 'Show Mrs. Dalson\'s Diary\'s gossip menu only if quest Mrs. Dalson\'s Diary has been rewarded.'); +-- Repeatable flag (also messes with condition quest_rewarded for some reason) +UPDATE `quest_template_addon` SET `SpecialFlags` = `SpecialFlags`&~1 WHERE (`ID` = 5058); diff --git a/data/sql/updates/db_world/2023_10_10_11.sql b/data/sql/updates/db_world/2023_10_10_11.sql new file mode 100644 index 00000000000000..33e9e739ece948 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_11.sql @@ -0,0 +1,30 @@ +-- DB update 2023_10_10_10 -> 2023_10_10_11 +-- Venomhide Hatchling feed items +DELETE FROM `spell_script_names` WHERE `spell_id` IN (65200,65258,65265,68359,68358,68360); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(65200, 'spell_item_venomhide_feed'), +(65258, 'spell_item_venomhide_feed'), +(65265, 'spell_item_venomhide_feed'), +(68359, 'spell_item_venomhide_feed'), +(68358, 'spell_item_venomhide_feed'), +(68360, 'spell_item_venomhide_feed'); + +-- Mor'vek +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 11701; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 11701); +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 +(11701, 0, 0, 0, 20, 0, 100, 0, 13906, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 19, 34320, 10, 0, 0, 0, 0, 0, 0, 'Mor\'vek - On Quest \'They Grow Up So Fast\' Finished - Despawn Closest Venomhide Hatchling'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceGroup` = 1 AND `SourceEntry` IN (65200,65258,65265); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 19 AND `SourceGroup` = 0 AND `ConditionTypeOrReference` = 9 AND `ConditionValue1` = 13906; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(19, 0, 13903, 0, 0, 9, 0, 13906, 0, 0, 0, 0, 0, '', 'Show quest \'Gorishi Grub\' only if on quest \'They Grow Up So Fast\''), +(19, 0, 13917, 0, 0, 9, 0, 13906, 0, 0, 0, 0, 0, '', 'Show quest \'Gorishi Grub\' only if on quest \'They Grow Up So Fast\''), +(19, 0, 13889, 0, 0, 9, 0, 13906, 0, 0, 0, 0, 0, '', 'Show quest \'Hungry, Hungry Hatchling\' only if on quest \'They Grow Up So Fast\''), +(19, 0, 13915, 0, 0, 9, 0, 13906, 0, 0, 0, 0, 0, '', 'Show quest \'Hungry, Hungry Hatchling\' only if on quest \'They Grow Up So Fast\''), +(19, 0, 13904, 0, 0, 9, 0, 13906, 0, 0, 0, 0, 0, '', 'Show quest \'Poached, Scrambled, Or Raw?\' only if on quest \'They Grow Up So Fast\''), +(19, 0, 13916, 0, 0, 9, 0, 13906, 0, 0, 0, 0, 0, '', 'Show quest \'Poached, Scrambled, Or Raw?\' only if on quest \'They Grow Up So Fast\''), +(19, 0, 13905, 0, 0, 9, 0, 13906, 0, 0, 0, 0, 0, '', 'Show quest \'Searing Roc Feathers\' only if on quest \'They Grow Up So Fast\''), +(19, 0, 13914, 0, 0, 9, 0, 13906, 0, 0, 0, 0, 0, '', 'Show quest \'Searing Roc Feathers\' only if on quest \'They Grow Up So Fast\''); diff --git a/data/sql/updates/db_world/2023_10_10_12.sql b/data/sql/updates/db_world/2023_10_10_12.sql new file mode 100644 index 00000000000000..98ed927dad9ec8 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_12.sql @@ -0,0 +1,51 @@ +-- DB update 2023_10_10_11 -> 2023_10_10_12 +-- Witchbane Torch +SET @GUID := 5448; +DELETE FROM `gameobject` WHERE `guid`=@GUID; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES +(@GUID, 186425, 1, 0, 0, 1, 1, -2967.03, -3872.18, 33.0928, 2.24779, 0, 0, -0.90179, -0.432175, -20, 255, 1, '', 0, ''); + +DELETE FROM `event_scripts` WHERE `id`=15452; +INSERT INTO `event_scripts` (`id`, `delay`, `command`, `datalong`, `datalong2`, `dataint`, `x`, `y`, `z`, `o`) VALUES +(15452,0,9,@GUID,20,0,0,0,0,0); + +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` = 186425; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 1 AND `entryorguid` = 186425); +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 +(186425, 1, 0, 0, 70, 0, 100, 0, 1, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 19, 4792, 0, 0, 0, 0, 0, 0, 0, 'Witchbane Torch - On Gameobject State Changed - Set Data 1 1 to \'Swamp Eye\' Jarl'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (42517,42515); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13,1,42517,0,0,31,0,3,23869,0,0,0,0,'','Spell \'Beam to Zelfrax\' can only target \'Invis Zelfrax Origin\''), +(13,1,42515,0,0,31,0,3,23868,0,0,0,0,'','Spell \'Jarl Beam\' can only target \'Invis Zelfrax Target\''); + +-- "Swamp Eye" Jarl +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=4792; +DELETE FROM `smart_scripts` WHERE `entryorguid`=4792 AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid`=479200 AND `source_type`=9; + +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(4792, 0, 0, 0, 38, 0, 100, 0, 1, 1, 0, 0, 0, 0, 80, 479200, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '\'Swamp Eye\' Jarl - On Data Set 1 1 - Run Script'), +(479200, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 42515, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '\'Swamp Eye\' Jarl - Actionlist - Cast \'Jarl Beam\''), +(479200, 9, 1, 0, 0, 0, 100, 0, 8000, 8000, 0, 0, 0, 0, 86, 42517, 0, 19, 23868, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '\'Swamp Eye\' Jarl - Actionlist - Cross Cast \'Beam to Zelfrax\''), +(479200, 9, 2, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 12, 23864, 3, 300000, 0, 0, 0, 8, 0, 0, 0, 0, -2984.98, -3853.72, 45.7142, 5.44525, '\'Swamp Eye\' Jarl - Actionlist - Summon Creature \'Zelfrax\''); + +-- Zelfrax +DELETE FROM `waypoints` WHERE `entry` = 23864; +INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `point_comment`) VALUES +(23864, 1, -2965.74, -3873.83, 33.3183, NULL, 0, ''); + +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' ,`unit_flags` = `unit_flags`&~(768) WHERE `entry` = 23864; +DELETE FROM `smart_scripts` WHERE `entryorguid`=23864 AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (2386400,2386401) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(23864, 0, 0, 1, 54, 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, 'Zelfrax - On Just Summoned - Set Flags Immune To Players & Immune To NPC\'s'), +(23864, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2386400, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Zelfrax - On Just Summoned - Run Script'), +(23864, 0, 2, 0, 40, 0, 100, 0, 1, 23864, 0, 0, 0, 0, 80, 2386401, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Zelfrax - On Point 1 of Path 23864 Reached - Run Script'), +(2386400, 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, 'Zelfrax - Actionlist - Say Line 0'), +(2386400, 9, 1, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Zelfrax - Actionlist - Say Line 1'), +(2386400, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 53, 1, 23864, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Zelfrax - Actionlist - Start Waypoint Path 23864'), +(2386401, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Zelfrax - Actionlist - Set Home Position'), +(2386401, 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, 'Zelfrax - Actionlist - Remove Flags Immune To Players & Immune To NPC\'s'), +(2386401, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 21, 30, 0, 0, 0, 0, 0, 0, 0, 'Zelfrax - Actionlist - Start Attacking'); diff --git a/data/sql/updates/db_world/2023_10_10_13.sql b/data/sql/updates/db_world/2023_10_10_13.sql new file mode 100644 index 00000000000000..a18a9610fdb4c2 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_13.sql @@ -0,0 +1,3 @@ +-- DB update 2023_10_10_12 -> 2023_10_10_13 +-- Alliance / Horde Cleric +UPDATE `smart_scripts` SET `event_param5` = 1 WHERE `source_type` = 0 AND `entryorguid` IN (26805,26803) AND `id` IN (0,1); diff --git a/data/sql/updates/db_world/2023_10_10_14.sql b/data/sql/updates/db_world/2023_10_10_14.sql new file mode 100644 index 00000000000000..a6a6b183325298 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_10_14.sql @@ -0,0 +1,6 @@ +-- DB update 2023_10_10_13 -> 2023_10_10_14 +-- Zeppelin Power Core +UPDATE `creature_template_addon` SET `auras` = '42491' WHERE (`entry` = 23832); +UPDATE `creature_template` SET `AIName` = '' WHERE `entry` = 23832; +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 23832) AND (`source_type` = 0); +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2383200) AND (`source_type` = 9); diff --git a/data/sql/updates/db_world/2023_10_11_00.sql b/data/sql/updates/db_world/2023_10_11_00.sql new file mode 100644 index 00000000000000..7fc078bdbc71f5 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_11_00.sql @@ -0,0 +1,4 @@ +-- DB update 2023_10_10_14 -> 2023_10_11_00 +-- Bad Attitude +UPDATE `creature_template` SET `AIName` = '' WHERE `entry` IN (1082,1084,1400,1417); +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryorguid` IN (1082,1084,1400,1417); diff --git a/data/sql/updates/db_world/2023_10_11_01.sql b/data/sql/updates/db_world/2023_10_11_01.sql new file mode 100644 index 00000000000000..9486fda66885ba --- /dev/null +++ b/data/sql/updates/db_world/2023_10_11_01.sql @@ -0,0 +1,6 @@ +-- DB update 2023_10_11_00 -> 2023_10_11_01 +-- Call of the Wild +DELETE FROM `spell_script_names` WHERE `spell_id` IN (-24604,53434); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-24604, 'spell_hun_target_self_and_pet'), +(53434, 'spell_hun_target_self_and_pet'); diff --git a/data/sql/updates/db_world/2023_10_12_00.sql b/data/sql/updates/db_world/2023_10_12_00.sql new file mode 100644 index 00000000000000..7b96b319da15d6 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_12_00.sql @@ -0,0 +1,569 @@ +-- DB update 2023_10_11_01 -> 2023_10_12_00 +-- +-- Remove existing Durotar Herbalism Nodes: +DELETE FROM `pool_gameobject` WHERE `pool_entry` BETWEEN 498 AND 501; +DELETE FROM `pool_template` WHERE `entry` BETWEEN 498 AND 501; + +-- Lets work on Mageroyal first. There are 16 Nodes and all have been captured and parsed succesfully into 4 pools (pools are also blizzlike in this case, rest are estimates) +-- Remove Existing Mageroyal: +DELETE FROM `gameobject` where `guid` IN (43887, 43898, 43900, 43901, 43902, 43904, 43897, 43899, 43903, 43905, 43906, 43987, 44064, 44065, 44066); + +-- Insert Durotar Mageroyal from packets: +SET @OGUID := 10601; +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+15; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`, `Comment`) VALUES +(@OGUID+5, 1620, 1, 14, 0, 1, 255, 933.9453125, -4606.53271484375, 18.46714210510253906, 0.663223206996917724, 0, 0, 0.325567245483398437, 0.945518851280212402, 360, 255, 1, 46779, '6/16 all known Durotar Mageroyal sniffed'), +(@OGUID+1, 1620, 1, 14, 0, 1, 255, 1208.466552734375, -5022.59423828125, 9.973286628723144531, 4.1538848876953125, 0, 0, -0.8746194839477539, 0.484810054302215576, 360, 255, 1, 46779, '2/16 all known Durotar Mageroyal sniffed'), +(@OGUID+14, 1620, 1, 14, 0, 1, 255, 65.1474609375, -4306.45166015625, 62.99754714965820312, 3.316144466400146484, 0, 0, -0.99619388580322265, 0.087165042757987976, 360, 255, 1, 46779, '15/16 all known Durotar Mageroyal sniffed'), +(@OGUID+10, 1620, 1, 14, 0, 1, 255, 816.496826171875, -4099.66064453125, -13.1231689453125, 4.398232460021972656, 0, 0, -0.80901622772216796, 0.587786316871643066, 360, 255, 1, 46779, '11/16 all known Durotar Mageroyal sniffed'), +(@OGUID+4, 1620, 1, 14, 0, 1, 255, 1131.9041748046875, -4685.81005859375, 20.08868789672851562, 4.223697185516357421, 0, 0, -0.85716724395751953, 0.515038192272186279, 360, 255, 1, 46779, '5/16 all known Durotar Mageroyal sniffed'), +(@OGUID+11, 1620, 1, 14, 0, 1, 255, 868.1712646484375, -4209.015625, -13.5084400177001953, 5.35816192626953125, 0, 0, -0.446197509765625, 0.894934535026550292, 360, 255, 1, 46779, '12/16 all known Durotar Mageroyal sniffed'), +(@OGUID+7, 1620, 1, 14, 0, 1, 255, 1001.31341552734375, -4820.7255859375, 16.75281143188476562, 6.09120035171508789, 0, 0, -0.09584522247314453, 0.995396256446838378, 360, 255, 1, 46779, '8/16 all known Durotar Mageroyal sniffed'), +(@OGUID+13, 1620, 1, 14, 0, 1, 255, 12.62858104705810546, -4112.0380859375, 68.98575592041015625, 4.380776405334472656, 0, 0, -0.81411552429199218, 0.580702960491180419, 360, 255, 1, 46779, '14/16 all known Durotar Mageroyal sniffed'), +(@OGUID+6, 1620, 1, 14, 0, 1, 255, 969.2032470703125, -4704.16748046875, 30.33428573608398437, 4.834563255310058593, 0, 0, -0.66261959075927734, 0.748956084251403808, 360, 255, 1, 46779, '7/16 all known Durotar Mageroyal sniffed'), +(@OGUID+3, 1620, 1, 14, 0, 1, 255, 607.72735595703125, -4524.541015625, 11.38043594360351562, 2.251473426818847656, 0, 0, 0.902585029602050781, 0.430511653423309326, 360, 255, 1, 46779, '4/16 all known Durotar Mageroyal sniffed'), +(@OGUID+9, 1620, 1, 14, 0, 1, 255, 962.67132568359375, -4245.0693359375, -8.28712177276611328, 3.298687219619750976, 0, 0, -0.99691677093505859, 0.078466430306434631, 360, 255, 1, 46779, '10/16 all known Durotar Mageroyal sniffed'), +(@OGUID+12, 1620, 1, 14, 0, 1, 255, -157.146484375, -3992.43310546875, 57.29217529296875, 4.660029888153076171, 0, 0, -0.72537422180175781, 0.688354730606079101, 360, 255, 1, 46779, '13/16 all known Durotar Mageroyal sniffed'), +(@OGUID+2, 1620, 1, 14, 0, 1, 255, 763.56890869140625, -5037.0380859375, 7.180908203125, 0.366517573595046997, 0, 0, 0.182234764099121093, 0.98325502872467041, 360, 255, 1, 46779, '3/16 all known Durotar Mageroyal sniffed'), +(@OGUID+8, 1620, 1, 14, 0, 1, 255, 931.2001953125, -4038.233154296875, -13.346710205078125, 3.9793548583984375, 0, 0, -0.9135446548461914, 0.406738430261611938, 360, 255, 1, 46779, '9/16 all known Durotar Mageroyal sniffed'), +(@OGUID+0, 1620, 1, 14, 0, 1, 255, 1450.59326171875, -4902.47802734375, 9.712756156921386718, 3.839725255966186523, 0, 0, -0.93969249725341796, 0.34202045202255249, 360, 255, 1, 46779, '1/16 all known Durotar Mageroyal sniffed'), +(@OGUID+15, 1620, 1, 14, 0, 1, 255, 122.14996337890625, -4474.04931640625, 37.63466262817382812, 2.076939344406127929, 0, 0, 0.861628532409667968, 0.50753939151763916, 360, 255, 1, 46779, '16/16 all known Durotar Mageroyal sniffed'); + +-- Make Mageroyal Pooling: +SET @OBJECTPOOLS :=112; +DELETE FROM `pool_gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+15; +DELETE FROM `pool_template` WHERE `entry` BETWEEN @OBJECTPOOLS+0 AND @OBJECTPOOLS+3; + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+0, 1, 'Durotar Mageroyal A Pool 1/4'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+0, @OBJECTPOOLS+0, 0, 'Durotar Mageroyal A 1/4'), +(@OGUID+1, @OBJECTPOOLS+0, 0, 'Durotar Mageroyal A 2/4'), +(@OGUID+2, @OBJECTPOOLS+0, 0, 'Durotar Mageroyal A 3/4'), +(@OGUID+3, @OBJECTPOOLS+0, 0, 'Durotar Mageroyal A 4/4'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+1, 1, 'Durotar Mageroyal Razorwind Canyon Pool 2/4'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+4, @OBJECTPOOLS+1, 0, 'Durotar Mageroyal Razorwind Canyon 1/4'), +(@OGUID+5, @OBJECTPOOLS+1, 0, 'Durotar Mageroyal Razorwind Canyon 2/4'), +(@OGUID+6, @OBJECTPOOLS+1, 0, 'Durotar Mageroyal Razorwind Canyon 3/4'), +(@OGUID+7, @OBJECTPOOLS+1, 0, 'Durotar Mageroyal Razorwind Canyon 4/4'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+2, 1, 'Durotar Mageroyal Thunder Ridge 3/4'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+8, @OBJECTPOOLS+2, 0, 'Durotar Mageroyal Thunder Ridge 1/4'), +(@OGUID+9, @OBJECTPOOLS+2, 0, 'Durotar Mageroyal Thunder Ridge 2/4'), +(@OGUID+10, @OBJECTPOOLS+2, 0, 'Durotar Mageroyal Thunder Ridge 3/4'), +(@OGUID+11, @OBJECTPOOLS+2, 0, 'Durotar Mageroyal Thunder Ridge 4/4'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+3, 1, 'Durotar Mageroyal Razormane Grounds 4/4'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+12, @OBJECTPOOLS+3, 0, 'Durotar Mageroyal Razormane Grounds 1/4'), +(@OGUID+13, @OBJECTPOOLS+3, 0, 'Durotar Mageroyal Razormane Grounds 2/4'), +(@OGUID+14, @OBJECTPOOLS+3, 0, 'Durotar Mageroyal Razormane Grounds 3/4'), +(@OGUID+15, @OBJECTPOOLS+3, 0, 'Durotar Mageroyal Razormane Grounds 4/4'); + +-- Earthroot has all known 45 spawns captured and one orientation extra +-- Remove existing Earthroot from Durotar: +DELETE FROM `gameobject` where `guid` IN (43855, 43856, 43868, 43873, 43874, 43877, 43880, 43883, 43885, 43886, 43895, 43896, 43981, 43982, 43992, 43999, 44000, 44011, 44012, 44024, 44025, 44026, 44027, 44029, 44041, 44042, 44043, 44045, 44050, 44051, 44054, 44055, 44058, 44059, 44061, 44062); + +-- Insert Durotar Earthroot from packets: +SET @OGUID := 21871; +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+45; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`, `Comment`) VALUES +(@OGUID+3, 1619, 1, 14, 0, 1, 255, 1118.32080078125, -4499.89794921875, 20.3045196533203125, 1.85004889965057373, 0, 0, 0.798635482788085937, 0.60181504487991333, 360, 255, 1, 46779, '4/46 all known Durotar Earthroot sniffed'), +(@OGUID+20, 1619, 1, 14, 0, 1, 255, 1256.7501220703125, -4683.24072265625, 16.37722587585449218, 2.565631866455078125, 0, 0, 0.958819389343261718, 0.284016460180282592, 360, 255, 1, 46779, '21/46 all known Durotar Earthroot sniffed'), +(@OGUID+26, 1619, 1, 14, 0, 1, 255, 223.0199737548828125, -5020.4990234375, 15.02139472961425781, 1.815141916275024414, 0, 0, 0.788010597229003906, 0.615661680698394775, 360, 255, 1, 46779, '27/46 all known Durotar Earthroot sniffed'), +(@OGUID+36, 1619, 1, 14, 0, 1, 255, -94.275390625, -5147.6259765625, 26.58465576171875, 0.663223206996917724, 0, 0, 0.325567245483398437, 0.945518851280212402, 360, 255, 1, 46779, '37/46 all known Durotar Earthroot sniffed'), +(@OGUID+41, 1619, 1, 14, 0, 1, 255, -675.49847412109375, -4823.72802734375, 35.99216842651367187, 2.234017848968505859, 0, 0, 0.898793220520019531, 0.438372820615768432, 360, 255, 1, 46779, '42/46 all known Durotar Earthroot sniffed'), +(@OGUID+38, 1619, 1, 14, 0, 1, 255, -233.734161376953125, -4837.064453125, 28.83690834045410156, 0.733038187026977539, 0, 0, 0.358367919921875, 0.933580458164215087, 360, 255, 1, 46779, '39/46 all known Durotar Earthroot sniffed'), +(@OGUID+31, 1619, 1, 14, 0, 1, 255, 52.99175262451171875, -4088.75048828125, 59.79741668701171875, 2.740161895751953125, 0, 0, 0.979924201965332031, 0.199370384216308593, 360, 255, 1, 46779, '32/46 all known Durotar Earthroot sniffed'), +(@OGUID+15, 1619, 1, 14, 0, 1, 255, 432.176116943359375, -3955.28564453125, 29.58817291259765625, 3.90954136848449707, 0, 0, -0.92718315124511718, 0.37460830807685852, 360, 255, 1, 46779, '16/46 all known Durotar Earthroot sniffed'), +(@OGUID+12, 1619, 1, 14, 0, 1, 255, 659.61102294921875, -4089.32421875, 16.22521209716796875, 1.780233979225158691, 0, 0, 0.7771453857421875, 0.629321098327636718, 360, 255, 1, 46779, '13/46 all known Durotar Earthroot sniffed'), +(@OGUID+13, 1619, 1, 14, 0, 1, 255, 574.80999755859375, -4254.13720703125, 14.17972564697265625, 0.610863447189331054, 0, 0, 0.3007049560546875, 0.953717231750488281, 360, 255, 1, 46779, '14/46 all known Durotar Earthroot sniffed'), +(@OGUID+7, 1619, 1, 14, 0, 1, 255, 942.25665283203125, -4404.73046875, 18.45261383056640625, 0.383971005678176879, 0, 0, 0.190808296203613281, 0.981627285480499267, 360, 255, 1, 46779, '8/46 all known Durotar Earthroot sniffed'), +(@OGUID+2, 1619, 1, 14, 0, 1, 255, 1101.1954345703125, -4333.6513671875, 25.76436996459960937, 4.328419685363769531, 0, 0, -0.82903671264648437, 0.559194147586822509, 360, 255, 1, 46779, '3/46 all known Durotar Earthroot sniffed'), +(@OGUID+1, 1619, 1, 14, 0, 1, 255, 1150.2880859375, -4129.90478515625, 20.5688934326171875, 1.012289404869079589, 0, 0, 0.484808921813964843, 0.87462007999420166, 360, 255, 1, 46779, '2/46 all known Durotar Earthroot sniffed'), +(@OGUID+40, 1619, 1, 14, 0, 1, 255, -460.1573486328125, -4712.15087890625, 37.342041015625, 5.672322273254394531, 0, 0, -0.3007049560546875, 0.953717231750488281, 360, 255, 1, 46779, '41/46 all known Durotar Earthroot sniffed'), +(@OGUID+25, 1619, 1, 14, 0, 1, 255, 225.31207275390625, -4230.01708984375, 41.82802200317382812, 4.537858963012695312, 0, 0, -0.76604366302490234, 0.642788589000701904, 360, 255, 1, 46779, '26/46 all known Durotar Earthroot sniffed'), +(@OGUID+42, 1619, 1, 14, 0, 1, 255, -759.6065673828125, -4672.27978515625, 39.17332077026367187, 3.735006093978881835, 0, 0, -0.95630455017089843, 0.292372345924377441, 360, 255, 1, 46779, '43/46 all known Durotar Earthroot sniffed'), +(@OGUID+43, 1619, 1, 14, 0, 1, 255, -734.75152587890625, -4977.02978515625, 22.22920608520507812, 6.073746204376220703, 0, 0, -0.10452842712402343, 0.994521915912628173, 360, 255, 1, 46779, '44/46 all known Durotar Earthroot sniffed'), +(@OGUID+35, 1619, 1, 14, 0, 1, 255, -74.4194869995117187, -4801.1376953125, 25.06105232238769531, 5.044002056121826171, 0, 0, -0.58070278167724609, 0.814115643501281738, 360, 255, 1, 46779, '36/46 all known Durotar Earthroot sniffed'), +(@OGUID+24, 1619, 1, 14, 0, 1, 255, 341.038970947265625, -5138.8828125, 6.930376052856445312, 4.939284324645996093, 0, 0, -0.6225137710571289, 0.78260880708694458, 360, 255, 1, 46779, '25/46 all known Durotar Earthroot sniffed'), +(@OGUID+37, 1619, 1, 14, 0, 1, 255, -116.038627624511718, -4694.84228515625, 29.52692413330078125, 5.323255538940429687, 0, 0, -0.46174812316894531, 0.887011110782623291, 360, 255, 1, 46779, '38/46 all known Durotar Earthroot sniffed'), +(@OGUID+29, 1619, 1, 14, 0, 1, 255, 141.170135498046875, -4584.783203125, 65.2907867431640625, 1.902408957481384277, 0, 0, 0.814115524291992187, 0.580702960491180419, 360, 255, 1, 46779, '30/46 all known Durotar Earthroot sniffed'), +(@OGUID+39, 1619, 1, 14, 0, 1, 255, -318.69769287109375, -4857.83935546875, 40.7213134765625, 0.087265998125076293, 0, 0, 0.043619155883789062, 0.999048233032226562, 360, 255, 1, 46779, '40/46 all known Durotar Earthroot sniffed'), +(@OGUID+23, 1619, 1, 14, 0, 1, 255, 663.150390625, -4806.96875, 26.246063232421875, 4.136432647705078125, 0, 0, -0.87881660461425781, 0.477159708738327026, 360, 255, 1, 46779, '24/46 all known Durotar Earthroot sniffed'), +(@OGUID+9, 1619, 1, 14, 0, 1, 255, 820.78009033203125, -4342.0625, 16.78577995300292968, 5.497788906097412109, 0, 0, -0.38268280029296875, 0.923879802227020263, 360, 255, 1, 46779, '10/46 all known Durotar Earthroot sniffed'), +(@OGUID+0, 1619, 1, 14, 0, 1, 255, 1234.4581298828125, -4130.6484375, 26.204437255859375, 1.064649581909179687, 0, 0, 0.507537841796875, 0.861629426479339599, 360, 255, 1, 46779, '1/46 all known Durotar Earthroot sniffed'), +(@OGUID+5, 1619, 1, 14, 0, 1, 255, 958.55010986328125, -4054.565673828125, -11.1735868453979492, 3.961898565292358398, 0, 0, -0.91705989837646484, 0.398749500513076782, 360, 255, 1, 46779, '6/46 all known Durotar Earthroot sniffed'), +(@OGUID+18, 1619, 1, 14, 0, 1, 255, 1150.2882080078125, -4129.90478515625, 20.65157508850097656, 1.012289404869079589, 0, 0, 0.484808921813964843, 0.87462007999420166, 360, 255, 1, 46779, '19/46 all known Durotar Earthroot sniffed, duplicate orientation found'), +(@OGUID+19, 1619, 1, 14, 0, 1, 255, 1313.9761962890625, -4928.82861328125, 9.163771629333496093, 1.919861555099487304, 0, 0, 0.819151878356933593, 0.573576688766479492, 360, 255, 1, 46779, '20/46 all known Durotar Earthroot sniffed'), +(@OGUID+8, 1619, 1, 14, 0, 1, 255, 912.63800048828125, -4033.7822265625, -11.5388202667236328, 3.351046562194824218, 0, 0, -0.99452114105224609, 0.104535527527332305, 360, 255, 1, 46779, '9/46 all known Durotar Earthroot sniffed'), +(@OGUID+44, 1619, 1, 14, 0, 1, 255, -861.29559326171875, -4725.5048828125, 28.71560096740722656, 2.321286916732788085, 0, 0, 0.917059898376464843, 0.398749500513076782, 360, 255, 1, 46779, '45/46 all known Durotar Earthroot sniffed'), +(@OGUID+16, 1619, 1, 14, 0, 1, 255, 399.1748046875, -4201.98193359375, 26.73043632507324218, 5.427974700927734375, 0, 0, -0.41469287872314453, 0.909961462020874023, 360, 255, 1, 46779, '17/46 all known Durotar Earthroot sniffed'), +(@OGUID+11, 1619, 1, 14, 0, 1, 255, 749.328369140625, -4482.91357421875, 22.01276588439941406, 6.230826377868652343, 0, 0, -0.02617645263671875, 0.999657332897186279, 360, 255, 1, 46779, '12/46 all known Durotar Earthroot sniffed'), +(@OGUID+6, 1619, 1, 14, 0, 1, 255, 944.3758544921875, -4231.93603515625, -6.23416709899902343, 1.361356139183044433, 0, 0, 0.629320144653320312, 0.77714616060256958, 360, 255, 1, 46779, '7/46 all known Durotar Earthroot sniffed'), +(@OGUID+10, 1619, 1, 14, 0, 1, 255, 765.45294189453125, -3869.986083984375, 24.05956268310546875, 1.169368624687194824, 0, 0, 0.551936149597167968, 0.833886384963989257, 360, 255, 1, 46779, '11/46 all known Durotar Earthroot sniffed'), +(@OGUID+21, 1619, 1, 14, 0, 1, 255, 1138.760498046875, -4902.47314453125, 17.50710487365722656, 6.09120035171508789, 0, 0, -0.09584522247314453, 0.995396256446838378, 360, 255, 1, 46779, '22/46 all known Durotar Earthroot sniffed'), +(@OGUID+17, 1619, 1, 14, 0, 1, 255, 459.593963623046875, -4523.13818359375, 50.90013504028320312, 2.44346022605895996, 0, 0, 0.939692497253417968, 0.34202045202255249, 360, 255, 1, 46779, '18/46 all known Durotar Earthroot sniffed'), +(@OGUID+4, 1619, 1, 14, 0, 1, 255, 934.80511474609375, -3918.829833984375, 19.61922836303710937, 1.658061861991882324, 0, 0, 0.737277030944824218, 0.67559051513671875, 360, 255, 1, 46779, '5/46 all known Durotar Earthroot sniffed'), +(@OGUID+14, 1619, 1, 14, 0, 1, 255, 515.15960693359375, -3927.331298828125, 22.48749732971191406, 1.553341388702392578, 0, 0, 0.700908660888671875, 0.713251054286956787, 360, 255, 1, 46779, '15/46 all known Durotar Earthroot sniffed'), +(@OGUID+30, 1619, 1, 14, 0, 1, 255, 37.111328125, -3984.507080078125, 48.36726760864257812, 3.717553615570068359, 0, 0, -0.95881938934326171, 0.284016460180282592, 360, 255, 1, 46779, '31/46 all known Durotar Earthroot sniffed'), +(@OGUID+28, 1619, 1, 14, 0, 1, 255, 159.86285400390625, -3927.96142578125, 45.60350418090820312, 1.431168079376220703, 0, 0, 0.656058311462402343, 0.754710197448730468, 360, 255, 1, 46779, '29/46 all known Durotar Earthroot sniffed'), +(@OGUID+34, 1619, 1, 14, 0, 1, 255, -61.41796875, -4616.05615234375, 42.88976669311523437, 5.096362113952636718, 0, 0, -0.55919265747070312, 0.829037725925445556, 360, 255, 1, 46779, '35/46 all known Durotar Earthroot sniffed'), +(@OGUID+45, 1619, 1, 14, 0, 1, 255, -1004.580322265625, -4805.931640625, 12.89675140380859375, 4.939284324645996093, 0, 0, -0.6225137710571289, 0.78260880708694458, 360, 255, 1, 46779, '46/46 all known Durotar Earthroot sniffed'), +(@OGUID+32, 1619, 1, 14, 0, 1, 255, 34.8250885009765625, -4923.9091796875, 13.55170345306396484, 0, 0, 0, 0, 1, 360, 255, 1, 46779, '33/46 all known Durotar Earthroot sniffed'), +(@OGUID+27, 1619, 1, 14, 0, 1, 255, 191.5199737548828125, -4436.94140625, 33.908660888671875, 1.029743075370788574, 0, 0, 0.492423057556152343, 0.870355963706970214, 360, 255, 1, 46779, '28/46 all known Durotar Earthroot sniffed'), +(@OGUID+22, 1619, 1, 14, 0, 1, 255, 944.28863525390625, -4952.1572265625, 10.04678821563720703, 3.874631166458129882, 0, 0, -0.93358039855957031, 0.358368009328842163, 360, 255, 1, 46779, '23/46 all known Durotar Earthroot sniffed'), +(@OGUID+33, 1619, 1, 14, 0, 1, 255, -114.458106994628906, -3897.579345703125, 44.01530838012695312, 0.785396754741668701, 0, 0, 0.38268280029296875, 0.923879802227020263, 360, 255, 1, 46779, '34/46 all known Durotar Earthroot sniffed'); + +-- Make Durotar Earthroot Pooling: +SET @OBJECTPOOLS :=116; +DELETE FROM `pool_gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+45; +DELETE FROM `pool_template` WHERE `entry` BETWEEN @OBJECTPOOLS+0 AND @OBJECTPOOLS+4; + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+0, 1, 'Durotar Earthroot Northmost Pool 1/5'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+0, @OBJECTPOOLS+0, 0, 'Durotar Earthroot Northmost 1/5'), +(@OGUID+1, @OBJECTPOOLS+0, 0, 'Durotar Earthroot Northmost 2/5'), +(@OGUID+2, @OBJECTPOOLS+0, 0, 'Durotar Earthroot Northmost 3/5'), +(@OGUID+3, @OBJECTPOOLS+0, 0, 'Durotar Earthroot Northmost 4/5'), +(@OGUID+18, @OBJECTPOOLS+0, 0, 'Durotar Earthroot Northmost 5/5'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+1, 5, 'Durotar Earthroot NW Pool 2/5'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+4, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 1/14'), +(@OGUID+5, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 2/14'), +(@OGUID+6, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 3/14'), +(@OGUID+7, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 4/14'), +(@OGUID+8, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 5/14'), +(@OGUID+9, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 6/14'), +(@OGUID+10, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 7/14'), +(@OGUID+11, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 8/14'), +(@OGUID+12, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 9/14'), +(@OGUID+13, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 10/14'), +(@OGUID+14, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 11/14'), +(@OGUID+15, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 12/14'), +(@OGUID+16, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 13/14'), +(@OGUID+17, @OBJECTPOOLS+1, 0, 'Durotar Earthroot NW 14/14'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+2, 2, 'Durotar Earthroot NE Pool 3/5'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+19, @OBJECTPOOLS+2, 0, 'Durotar Earthroot NE 1/5'), +(@OGUID+20, @OBJECTPOOLS+2, 0, 'Durotar Earthroot NE 2/5'), +(@OGUID+21, @OBJECTPOOLS+2, 0, 'Durotar Earthroot NE 3/5'), +(@OGUID+22, @OBJECTPOOLS+2, 0, 'Durotar Earthroot NE 4/5'), +(@OGUID+23, @OBJECTPOOLS+2, 0, 'Durotar Earthroot NE 5/5'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+3, 6, 'Durotar Earthroot Center Pool 4/5'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+24, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 1/17'), +(@OGUID+25, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 2/17'), +(@OGUID+26, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 3/17'), +(@OGUID+27, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 4/17'), +(@OGUID+28, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 5/17'), +(@OGUID+29, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 6/17'), +(@OGUID+30, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 7/17'), +(@OGUID+31, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 8/17'), +(@OGUID+32, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 9/17'), +(@OGUID+33, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 10/17'), +(@OGUID+34, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 11/17'), +(@OGUID+35, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 12/17'), +(@OGUID+36, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 13/17'), +(@OGUID+37, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 14/17'), +(@OGUID+38, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 15/17'), +(@OGUID+39, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 16/17'), +(@OGUID+40, @OBJECTPOOLS+3, 0, 'Durotar Earthroot Center 17/17'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+4, 2, 'Durotar Earthroot South Pool 5/5'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+41, @OBJECTPOOLS+4, 0, 'Durotar Earthroot South 1/5'), +(@OGUID+42, @OBJECTPOOLS+4, 0, 'Durotar Earthroot South 2/5'), +(@OGUID+43, @OBJECTPOOLS+4, 0, 'Durotar Earthroot South 3/5'), +(@OGUID+44, @OBJECTPOOLS+4, 0, 'Durotar Earthroot South 4/5'), +(@OGUID+45, @OBJECTPOOLS+4, 0, 'Durotar Earthroot South 5/5'); + +-- Peacebloom has presumed all known 76 spawns captured +-- Remove existing Peacebloom from Durotar: +DELETE FROM `gameobject` where `guid` IN (43735, 43736, 43737, 43738, 43763, 43775, 43780, 43796, 43801, 43832, 43808, 43817, 43829, 43834, 43836, 43841, 43847, 43980, 43983, 43984, 43985, 43986, 44001, 44002, 44003, 44008, 44009, 44010, 44013, 44016, 44017, 44020, 44021, 44022, 44023, 44028, 44030, 44031, 44110, 44111, 44122, 44125, 44126, 44127, 44128, 44130, 44132, 44136, 44140, 44141, 44142, 44144, 44145, 44146, 44148, 44149, 44377, 44475, 44476); + +-- Insert Durotar Peacebloom from packets: +SET @OGUID :=64519; +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+75; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`, `Comment`) VALUES +(@OGUID+24, 1618, 1, 14, 0, 1, 255, 576.44012451171875, -4645.88134765625, 31.64385986328125, 4.834563255310058593, 0, 0, -0.66261959075927734, 0.748956084251403808, 360, 255, 1, 46779, '24/76 all known Durotar Peacebloom sniffed'), +(@OGUID+75, 1618, 1, 14, 0, 1, 255, 872.485595703125, -4636.94775390625, 14.79042530059814453, 5.637413978576660156, 0, 0, -0.31730461120605468, 0.948323667049407958, 360, 255, 1, 46779, '75/76 all known Durotar Peacebloom sniffed'), +(@OGUID+13, 1618, 1, 14, 0, 1, 255, 1153.5992431640625, -4530.12255859375, 19.53768539428710937, 1.745326757431030273, 0, 0, 0.766043663024902343, 0.642788589000701904, 360, 255, 1, 46779, '13/76 all known Durotar Peacebloom sniffed'), +(@OGUID+11, 1618, 1, 14, 0, 1, 255, 1235.6951904296875, -4640.08251953125, 17.40758895874023437, 5.794494152069091796, 0, 0, -0.24192142486572265, 0.970295846462249755, 360, 255, 1, 46779, '11/76 all known Durotar Peacebloom sniffed'), +(@OGUID+7, 1618, 1, 14, 0, 1, 255, 1351.0560302734375, -4764.1064453125, 26.99089622497558593, 0, 0, 0, 0, 1, 360, 255, 1, 46779, '7/76 all known Durotar Peacebloom sniffed'), +(@OGUID+18, 1618, 1, 14, 0, 1, 255, 950.41864013671875, -4981.32666015625, 9.415129661560058593, 5.515241622924804687, 0, 0, -0.37460613250732421, 0.927184045314788818, 360, 255, 1, 46779, '18/76 all known Durotar Peacebloom sniffed'), +(@OGUID+71, 1618, 1, 14, 0, 1, 255, -721.23626708984375, -5611.30712890625, 25.56131935119628906, 4.694936752319335937, 0, 0, -0.71325016021728515, 0.700909554958343505, 360, 255, 1, 46779, '71/76 all known Durotar Peacebloom sniffed'), +(@OGUID+74, 1618, 1, 14, 0, 1, 255, -1190.880126953125, -5502.5244140625, 5.268311977386474609, 1.134462952613830566, 0, 0, 0.537299156188964843, 0.843391716480255126, 360, 255, 1, 46779, '74/76 all known Durotar Peacebloom sniffed'), +(@OGUID+68, 1618, 1, 14, 0, 1, 255, -945.416015625, -4816.14697265625, 13.898681640625, 3.804818391799926757, 0, 0, -0.94551849365234375, 0.325568377971649169, 360, 255, 1, 46779, '68/76 all known Durotar Peacebloom sniffed'), +(@OGUID+67, 1618, 1, 14, 0, 1, 255, -1007.18267822265625, -4740.14697265625, 14.23654556274414062, 4.852017402648925781, 0, 0, -0.65605831146240234, 0.754710197448730468, 360, 255, 1, 46779, '67/76 all known Durotar Peacebloom sniffed'), +(@OGUID+63, 1618, 1, 14, 0, 1, 255, -582.867431640625, -4845.39501953125, 35.45242691040039062, 3.892086982727050781, 0, 0, -0.93041706085205078, 0.366502493619918823, 360, 255, 1, 46779, '63/76 all known Durotar Peacebloom sniffed'), +(@OGUID+62, 1618, 1, 14, 0, 1, 255, -453.350250244140625, -4824.06396484375, 38.12348175048828125, 1.640606880187988281, 0, 0, 0.731352806091308593, 0.6819993257522583, 360, 255, 1, 46779, '62/76 all known Durotar Peacebloom sniffed'), +(@OGUID+41, 1618, 1, 14, 0, 1, 255, 122.60546875, -4414.103515625, 37.66838836669921875, 0.209439441561698913, 0, 0, 0.104528427124023437, 0.994521915912628173, 360, 255, 1, 46779, '41/76 all known Durotar Peacebloom sniffed'), +(@OGUID+40, 1618, 1, 14, 0, 1, 255, 79.77994537353515625, -4245.79150390625, 59.7068023681640625, 3.735006093978881835, 0, 0, -0.95630455017089843, 0.292372345924377441, 360, 255, 1, 46779, '40/76 all known Durotar Peacebloom sniffed'), +(@OGUID+43, 1618, 1, 14, 0, 1, 255, 51.63259506225585937, -4151.8984375, 63.73382568359375, 4.677483558654785156, 0, 0, -0.71933937072753906, 0.694658815860748291, 360, 255, 1, 46779, '43/76 all known Durotar Peacebloom sniffed'), +(@OGUID+39, 1618, 1, 14, 0, 1, 255, 106.3723983764648437, -4009.619873046875, 46.37731170654296875, 5.829400539398193359, 0, 0, -0.22495079040527343, 0.974370121955871582, 360, 255, 1, 46779, '39/76 all known Durotar Peacebloom sniffed'), +(@OGUID+32, 1618, 1, 14, 0, 1, 255, 481.166229248046875, -3884.92529296875, 20.675811767578125, 2.583080768585205078, 0, 0, 0.961260795593261718, 0.275640487670898437, 360, 255, 1, 46779, '32/76 all known Durotar Peacebloom sniffed'), +(@OGUID+6, 1618, 1, 14, 0, 1, 255, 587.15203857421875, -4016.65625, 10.35272407531738281, 0.034906249493360519, 0, 0, 0.017452239990234375, 0.999847710132598876, 360, 255, 1, 46779, '6/76 all known Durotar Peacebloom sniffed'), +(@OGUID+26, 1618, 1, 14, 0, 1, 255, 544.14190673828125, -4190.08935546875, 16.03062057495117187, 5.096362113952636718, 0, 0, -0.55919265747070312, 0.829037725925445556, 360, 255, 1, 46779, '26/76 all known Durotar Peacebloom sniffed'), +(@OGUID+27, 1618, 1, 14, 0, 1, 255, 552.92218017578125, -4382.99072265625, 25.674591064453125, 4.415683269500732421, 0, 0, -0.80385684967041015, 0.594822824001312255, 360, 255, 1, 46779, '27/76 all known Durotar Peacebloom sniffed'), +(@OGUID+2, 1618, 1, 14, 0, 1, 255, 979.56207275390625, -3922.735595703125, 18.49326515197753906, 5.777040958404541015, 0, 0, -0.25037956237792968, 0.968147754669189453, 360, 255, 1, 46779, '2/76 all known Durotar Peacebloom sniffed'), +(@OGUID+61, 1618, 1, 14, 0, 1, 255, -427.984161376953125, -4721.78515625, 39.59911346435546875, 4.1538848876953125, 0, 0, -0.8746194839477539, 0.484810054302215576, 360, 255, 1, 46779, '61/76 all known Durotar Peacebloom sniffed'), +(@OGUID+35, 1618, 1, 14, 0, 1, 255, 209.837890625, -4051.300048828125, 44.49655532836914062, 2.268925428390502929, 0, 0, 0.906307220458984375, 0.422619491815567016, 360, 255, 1, 46779, '35/76 all known Durotar Peacebloom sniffed'), +(@OGUID+36, 1618, 1, 14, 0, 1, 255, 211.5045623779296875, -4300.72265625, 43.43696975708007812, 5.602506637573242187, 0, 0, -0.33380699157714843, 0.942641437053680419, 360, 255, 1, 46779, '36/76 all known Durotar Peacebloom sniffed'), +(@OGUID+51, 1618, 1, 14, 0, 1, 255, 111.74609375, -5011.83349609375, 9.826634407043457031, 1.448621988296508789, 0, 0, 0.662619590759277343, 0.748956084251403808, 360, 255, 1, 46779, '51/76 all known Durotar Peacebloom sniffed'), +(@OGUID+58, 1618, 1, 14, 0, 1, 255, -237.703567504882812, -4733.990234375, 30.96081161499023437, 4.817109584808349609, 0, 0, -0.66913032531738281, 0.74314504861831665, 360, 255, 1, 46779, '58/76 all known Durotar Peacebloom sniffed'), +(@OGUID+33, 1618, 1, 14, 0, 1, 255, 410.00152587890625, -3984.354736328125, 30.216949462890625, 2.862335443496704101, 0, 0, 0.990267753601074218, 0.139175355434417724, 360, 255, 1, 46779, '33/76 all known Durotar Peacebloom sniffed'), +(@OGUID+55, 1618, 1, 14, 0, 1, 255, -146.132156372070312, -4716.8251953125, 29.02817153930664062, 5.305802345275878906, 0, 0, -0.46947097778320312, 0.882947921752929687, 360, 255, 1, 46779, '55/76 all known Durotar Peacebloom sniffed'), +(@OGUID+60, 1618, 1, 14, 0, 1, 255, -315.7734375, -4749.27197265625, 36.00954818725585937, 1.832594871520996093, 0, 0, 0.793353080749511718, 0.608761727809906005, 360, 255, 1, 46779, '60/76 all known Durotar Peacebloom sniffed'), +(@OGUID+54, 1618, 1, 14, 0, 1, 255, -55.2087669372558593, -5059.32275390625, 10.38722896575927734, 1.221729278564453125, 0, 0, 0.573575973510742187, 0.819152355194091796, 360, 255, 1, 46779, '54/76 all known Durotar Peacebloom sniffed'), +(@OGUID+53, 1618, 1, 14, 0, 1, 255, 22.66449737548828125, -5074.466796875, 8.78829193115234375, 0.174532130360603332, 0, 0, 0.087155342102050781, 0.996194720268249511, 360, 255, 1, 46779, '53/76 all known Durotar Peacebloom sniffed'), +(@OGUID+56, 1618, 1, 14, 0, 1, 255, -146.28277587890625, -4849.16162109375, 19.79057884216308593, 3.194002151489257812, 0, 0, -0.99965667724609375, 0.026201646775007247, 360, 255, 1, 46779, '56/76 all known Durotar Peacebloom sniffed'), +(@OGUID+70, 1618, 1, 14, 0, 1, 255, -808.89044189453125, -5355.294921875, 2.164660930633544921, 4.607671737670898437, 0, 0, -0.74314403533935546, 0.669131457805633544, 360, 255, 1, 46779, '70/76 all known Durotar Peacebloom sniffed'), +(@OGUID+46, 1618, 1, 14, 0, 1, 255, -174.129348754882812, -3886.43017578125, 41.30976486206054687, 3.996806621551513671, 0, 0, -0.90996074676513671, 0.414694398641586303, 360, 255, 1, 46779, '46/76 all known Durotar Peacebloom sniffed'), +(@OGUID+20, 1618, 1, 14, 0, 1, 255, 772.42034912109375, -4337.3681640625, 17.64434814453125, 1.588248729705810546, 0, 0, 0.713250160217285156, 0.700909554958343505, 360, 255, 1, 46779, '20/76 all known Durotar Peacebloom sniffed'), +(@OGUID+22, 1618, 1, 14, 0, 1, 255, 740.525390625, -4847.93359375, 32.43145370483398437, 3.071766138076782226, 0, 0, 0.999390602111816406, 0.034906134009361267, 360, 255, 1, 46779, '22/76 all known Durotar Peacebloom sniffed'), +(@OGUID+15, 1618, 1, 14, 0, 1, 255, 1080.1187744140625, -4207.169921875, 20.04167938232421875, 5.375615119934082031, 0, 0, -0.4383707046508789, 0.898794233798980712, 360, 255, 1, 46779, '15/76 all known Durotar Peacebloom sniffed'), +(@OGUID+5, 1618, 1, 14, 0, 1, 255, 687.802001953125, -3908.257080078125, 15.48861503601074218, 5.95157480239868164, 0, 0, -0.16504669189453125, 0.986285746097564697, 360, 255, 1, 46779, '5/76 all known Durotar Peacebloom sniffed'), +(@OGUID+14, 1618, 1, 14, 0, 1, 255, 1166.1929931640625, -4927.8125, 16.59576416015625, 4.136432647705078125, 0, 0, -0.87881660461425781, 0.477159708738327026, 360, 255, 1, 46779, '14/76 all known Durotar Peacebloom sniffed'), +(@OGUID+8, 1618, 1, 14, 0, 1, 255, 1317.8629150390625, -4986.07373046875, 2.624479055404663085, 2.460912704467773437, 0, 0, 0.942641258239746093, 0.333807557821273803, 360, 255, 1, 46779, '8/76 all known Durotar Peacebloom sniffed'), +(@OGUID+65, 1618, 1, 14, 0, 1, 255, -726.66131591796875, -4810.6435546875, 25.44516754150390625, 2.932138919830322265, 0, 0, 0.994521141052246093, 0.104535527527332305, 360, 255, 1, 46779, '65/76 all known Durotar Peacebloom sniffed'), +(@OGUID+29, 1618, 1, 14, 0, 1, 255, 456.34320068359375, -4551.5546875, 52.29912948608398437, 5.829400539398193359, 0, 0, -0.22495079040527343, 0.974370121955871582, 360, 255, 1, 46779, '29/76 all known Durotar Peacebloom sniffed'), +(@OGUID+66, 1618, 1, 14, 0, 1, 255, -713.90667724609375, -5020.736328125, 17.04654502868652343, 0.820303261280059814, 0, 0, 0.398748397827148437, 0.917060375213623046, 360, 255, 1, 46779, '66/76 all known Durotar Peacebloom sniffed'), +(@OGUID+21, 1618, 1, 14, 0, 1, 255, 710.62469482421875, -4209.046875, 16.87834548950195312, 6.14356088638305664, 0, 0, -0.06975555419921875, 0.997564136981964111, 360, 255, 1, 46779, '21/76 all known Durotar Peacebloom sniffed'), +(@OGUID+0, 1618, 1, 14, 0, 1, 255, 1192.5826416015625, -4006.66064453125, 17.00342559814453125, 4.276057243347167968, 0, 0, -0.84339141845703125, 0.537299633026123046, 360, 255, 1, 46779, '76/76 all known Durotar Peacebloom sniffed'), +(@OGUID+4, 1618, 1, 14, 0, 1, 255, 808.3974609375, -3849.423583984375, 18.24977493286132812, 0.610863447189331054, 0, 0, 0.3007049560546875, 0.953717231750488281, 360, 255, 1, 46779, '4/76 all known Durotar Peacebloom sniffed'), +(@OGUID+9, 1618, 1, 14, 0, 1, 255, 1267.2899169921875, -4862.4521484375, 15.57356643676757812, 4.433136463165283203, 0, 0, -0.79863548278808593, 0.60181504487991333, 360, 255, 1, 46779, '9/76 all known Durotar Peacebloom sniffed'), +(@OGUID+17, 1618, 1, 14, 0, 1, 255, 1049.1593017578125, -4971.99072265625, 15.59623908996582031, 0.15707901120185852, 0, 0, 0.078458786010742187, 0.996917366981506347, 360, 255, 1, 46779, '17/76 all known Durotar Peacebloom sniffed'), +(@OGUID+10, 1618, 1, 14, 0, 1, 255, 1217.0572509765625, -4204.306640625, 26.21006393432617187, 5.270895957946777343, 0, 0, -0.48480892181396484, 0.87462007999420166, 360, 255, 1, 46779, '10/76 all known Durotar Peacebloom sniffed'), +(@OGUID+37, 1618, 1, 14, 0, 1, 255, 185.3385467529296875, -4189.9609375, 44.99439239501953125, 4.049167633056640625, 0, 0, -0.89879322052001953, 0.438372820615768432, 360, 255, 1, 46779, '37/76 all known Durotar Peacebloom sniffed'), +(@OGUID+45, 1618, 1, 14, 0, 1, 255, -79.995880126953125, -3888.22314453125, 46.93803787231445312, 5.93412017822265625, 0, 0, -0.17364788055419921, 0.984807789325714111, 360, 255, 1, 46779, '45/76 all known Durotar Peacebloom sniffed'), +(@OGUID+64, 1618, 1, 14, 0, 1, 255, -727.39410400390625, -4670.90478515625, 36.80979537963867187, 3.926995515823364257, 0, 0, -0.92387866973876953, 0.38268551230430603, 360, 255, 1, 46779, '64/76 all known Durotar Peacebloom sniffed'), +(@OGUID+50, 1618, 1, 14, 0, 1, 255, 81.68120574951171875, -4855.02734375, 16.23387908935546875, 4.572763919830322265, 0, 0, -0.75470924377441406, 0.656059443950653076, 360, 255, 1, 46779, '50/76 all known Durotar Peacebloom sniffed'), +(@OGUID+73, 1618, 1, 14, 0, 1, 255, -1229.1939697265625, -5419.7578125, 4.692111015319824218, 1.500982880592346191, 0, 0, 0.681998252868652343, 0.731353819370269775, 360, 255, 1, 46779, '73/76 all known Durotar Peacebloom sniffed'), +(@OGUID+72, 1618, 1, 14, 0, 1, 255, -1123.9193115234375, -5132.35791015625, 2.308864116668701171, 0.069811686873435974, 0, 0, 0.034898757934570312, 0.999390840530395507, 360, 255, 1, 46779, '72/76 all known Durotar Peacebloom sniffed'), +(@OGUID+23, 1618, 1, 14, 0, 1, 255, 621.03289794921875, -4322.41064453125, 18.90568351745605468, 1.239183306694030761, 0, 0, 0.580702781677246093, 0.814115643501281738, 360, 255, 1, 46779, '23/76 all known Durotar Peacebloom sniffed'), +(@OGUID+1, 1618, 1, 14, 0, 1, 255, 1123.47412109375, -4109.10791015625, 18.93925666809082031, 3.543023586273193359, 0, 0, -0.97992420196533203, 0.199370384216308593, 360, 255, 1, 46779, '1/76 all known Durotar Peacebloom sniffed'), +(@OGUID+25, 1618, 1, 14, 0, 1, 255, 590.79327392578125, -4870.73046875, 24.64709281921386718, 4.764749526977539062, 0, 0, -0.6883544921875, 0.725374460220336914, 360, 255, 1, 46779, '25/76 all known Durotar Peacebloom sniffed'), +(@OGUID+3, 1618, 1, 14, 0, 1, 255, 871.44091796875, -3921.874267578125, 20.81670379638671875, 4.799657344818115234, 0, 0, -0.67558956146240234, 0.737277925014495849, 360, 255, 1, 46779, '3/76 all known Durotar Peacebloom sniffed'), +(@OGUID+44, 1618, 1, 14, 0, 1, 255, -17.5935325622558593, -4018.5361328125, 59.22353744506835937, 2.600535154342651367, 0, 0, 0.963629722595214843, 0.26724100112915039, 360, 255, 1, 46779, '44/76 all known Durotar Peacebloom sniffed'), +(@OGUID+38, 1618, 1, 14, 0, 1, 255, 139.2584686279296875, -3887.162353515625, 39.86974334716796875, 3.752462387084960937, 0, 0, -0.95371627807617187, 0.300707906484603881, 360, 255, 1, 46779, '38/76 all known Durotar Peacebloom sniffed'), +(@OGUID+49, 1618, 1, 14, 0, 1, 255, 115.5776901245117187, -4686.57373046875, 27.42041015625, 1.186823248863220214, 0, 0, 0.559192657470703125, 0.829037725925445556, 360, 255, 1, 46779, '49/76 all known Durotar Peacebloom sniffed'), +(@OGUID+12, 1618, 1, 14, 0, 1, 255, 1153.6693115234375, -4312.61328125, 21.21240806579589843, 3.682650327682495117, 0, 0, -0.96362972259521484, 0.26724100112915039, 360, 255, 1, 46779, '12/76 all known Durotar Peacebloom sniffed'), +(@OGUID+34, 1618, 1, 14, 0, 1, 255, 482.284393310546875, -4083.93310546875, 30.25545310974121093, 2.879789113998413085, 0, 0, 0.991444587707519531, 0.130528271198272705, 360, 255, 1, 46779, '34/76 all known Durotar Peacebloom sniffed'), +(@OGUID+28, 1618, 1, 14, 0, 1, 255, 481.5009765625, -4376.1796875, 36.150115966796875, 0.087265998125076293, 0, 0, 0.043619155883789062, 0.999048233032226562, 360, 255, 1, 46779, '28/76 all known Durotar Peacebloom sniffed'), +(@OGUID+42, 1618, 1, 14, 0, 1, 255, 41.62065887451171875, -3916.78076171875, 44.42875289916992187, 4.747295856475830078, 0, 0, -0.69465827941894531, 0.719339847564697265, 360, 255, 1, 46779, '42/76 all known Durotar Peacebloom sniffed'), +(@OGUID+59, 1618, 1, 14, 0, 1, 255, -249.421493530273437, -4915.39306640625, 26.49920463562011718, 3.403396368026733398, 0, 0, -0.99144458770751953, 0.130528271198272705, 360, 255, 1, 46779, '59/76 all known Durotar Peacebloom sniffed'), +(@OGUID+52, 1618, 1, 14, 0, 1, 255, -15.9546985626220703, -4872.8359375, 19.71653938293457031, 1.972219824790954589, 0, 0, 0.83388519287109375, 0.55193793773651123, 360, 255, 1, 46779, '52/76 all known Durotar Peacebloom sniffed'), +(@OGUID+48, 1618, 1, 14, 0, 1, 255, 188.7855987548828125, -5087.7841796875, 10.83263683319091796, 5.881760597229003906, 0, 0, -0.19936752319335937, 0.979924798011779785, 360, 255, 1, 46779, '48/76 all known Durotar Peacebloom sniffed'), +(@OGUID+16, 1618, 1, 14, 0, 1, 255, 1022.24871826171875, -4360.6435546875, 17.70088958740234375, 2.740161895751953125, 0, 0, 0.979924201965332031, 0.199370384216308593, 360, 255, 1, 46779, '16/76 all known Durotar Peacebloom sniffed'), +(@OGUID+31, 1618, 1, 14, 0, 1, 255, 411.253570556640625, -4226.1591796875, 25.42971992492675781, 5.794494152069091796, 0, 0, -0.24192142486572265, 0.970295846462249755, 360, 255, 1, 46779, '31/76 all known Durotar Peacebloom sniffed'), +(@OGUID+57, 1618, 1, 14, 0, 1, 255, -125.188812255859375, -4933.2470703125, 19.89044380187988281, 2.879789113998413085, 0, 0, 0.991444587707519531, 0.130528271198272705, 360, 255, 1, 46779, '57/76 all known Durotar Peacebloom sniffed'), +(@OGUID+69, 1618, 1, 14, 0, 1, 255, -1340.7806396484375, -5140.3271484375, 3.484854936599731445, 2.740161895751953125, 0, 0, 0.979924201965332031, 0.199370384216308593, 360, 255, 1, 46779, '69/76 all known Durotar Peacebloom sniffed'), +(@OGUID+19, 1618, 1, 14, 0, 1, 255, 809.23101806640625, -5008.37353515625, 10.34244728088378906, 0.436331570148468017, 0, 0, 0.216439247131347656, 0.976296067237854003, 360, 255, 1, 46779, '19/76 all known Durotar Peacebloom sniffed'), +(@OGUID+30, 1618, 1, 14, 0, 1, 255, 458.79547119140625, -4891.96435546875, 20.88724708557128906, 0.680676698684692382, 0, 0, 0.333806037902832031, 0.942641794681549072, 360, 255, 1, 46779, '30/76 all known Durotar Peacebloom sniffed'), +(@OGUID+47, 1618, 1, 14, 0, 1, 255, 280.476348876953125, -5047.20166015625, 11.75045204162597656, 0.820303261280059814, 0, 0, 0.398748397827148437, 0.917060375213623046, 360, 255, 1, 46779, '47/76 all known Durotar Peacebloom sniffed'); + +-- Make Durotar Peacebloom Pooling: +SET @OBJECTPOOLS :=121; +DELETE FROM `pool_gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+75; +DELETE FROM `pool_template` WHERE `entry` BETWEEN @OBJECTPOOLS+0 AND @OBJECTPOOLS+7; + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+0, 3, 'Durotar Peacebloom NW Pool 1/8'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+0, @OBJECTPOOLS+0, 0, 'Durotar Peacebloom 1/7'), +(@OGUID+1, @OBJECTPOOLS+0, 0, 'Durotar Peacebloom 2/7'), +(@OGUID+2, @OBJECTPOOLS+0, 0, 'Durotar Peacebloom 3/7'), +(@OGUID+3, @OBJECTPOOLS+0, 0, 'Durotar Peacebloom 4/7'), +(@OGUID+4, @OBJECTPOOLS+0, 0, 'Durotar Peacebloom 5/7'), +(@OGUID+5, @OBJECTPOOLS+0, 0, 'Durotar Peacebloom 6/7'), +(@OGUID+6, @OBJECTPOOLS+0, 0, 'Durotar Peacebloom 7/7'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+1, 4, 'Durotar Peacebloom NE Pool 2/8'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+7, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 1/13'), +(@OGUID+8, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 2/13'), +(@OGUID+9, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 3/13'), +(@OGUID+10, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 4/13'), +(@OGUID+11, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 5/13'), +(@OGUID+12, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 6/13'), +(@OGUID+13, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 7/13'), +(@OGUID+14, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 8/13'), +(@OGUID+15, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 9/13'), +(@OGUID+16, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 10/13'), +(@OGUID+17, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 11/13'), +(@OGUID+18, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 12/13'), +(@OGUID+75, @OBJECTPOOLS+1, 0, 'Durotar Peacebloom NE 13/13'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+2, 5, 'Durotar Peacebloom East Valley Pool 3/8'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+19, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 1/13'), +(@OGUID+20, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 2/13'), +(@OGUID+21, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 3/13'), +(@OGUID+22, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 4/13'), +(@OGUID+23, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 5/13'), +(@OGUID+24, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 6/13'), +(@OGUID+25, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 7/13'), +(@OGUID+26, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 8/13'), +(@OGUID+27, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 9/13'), +(@OGUID+28, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 10/13'), +(@OGUID+29, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 11/13'), +(@OGUID+30, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 12/13'), +(@OGUID+31, @OBJECTPOOLS+2, 0, 'Durotar Peacebloom East Valley 13/13'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+3, 2, 'Durotar Peacebloom West Zone Exit Pool 4/8'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+32, @OBJECTPOOLS+3, 0, 'Durotar Peacebloom West Zone Exit 1/4'), +(@OGUID+33, @OBJECTPOOLS+3, 0, 'Durotar Peacebloom West Zone Exit 2/4'), +(@OGUID+34, @OBJECTPOOLS+3, 0, 'Durotar Peacebloom West Zone Exit 3/4'), +(@OGUID+35, @OBJECTPOOLS+3, 0, 'Durotar Peacebloom West Zone Exit 4/4'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+4, 4, 'Durotar Peacebloom Southern Razormane Pool 5/8'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+36, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 1/11'), +(@OGUID+37, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 2/11'), +(@OGUID+38, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 3/11'), +(@OGUID+39, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 4/11'), +(@OGUID+40, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 5/11'), +(@OGUID+41, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 6/11'), +(@OGUID+42, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 7/11'), +(@OGUID+43, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 8/11'), +(@OGUID+44, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 9/11'), +(@OGUID+45, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 10/11'), +(@OGUID+46, @OBJECTPOOLS+4, 0, 'Durotar Peacebloom Southern Razormane 11/11'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+5, 5, 'Durotar Peacebloom Eastern Stretch Pool 6/8'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+47, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 1/16'), +(@OGUID+48, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 2/16'), +(@OGUID+49, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 3/16'), +(@OGUID+50, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 4/16'), +(@OGUID+51, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 5/16'), +(@OGUID+52, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 6/16'), +(@OGUID+53, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 7/16'), +(@OGUID+54, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 8/16'), +(@OGUID+55, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 9/16'), +(@OGUID+56, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 10/16'), +(@OGUID+57, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 11/16'), +(@OGUID+58, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 12/16'), +(@OGUID+59, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 13/16'), +(@OGUID+60, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 14/16'), +(@OGUID+61, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 15/16'), +(@OGUID+62, @OBJECTPOOLS+5, 0, 'Durotar Peacebloom Eastern Stretch 16/16'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+6, 3, 'Durotar Peacebloom Senjin Echos Pool 7/8'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+63, @OBJECTPOOLS+6, 0, 'Durotar Peacebloom Senjin Echos 1/7'), +(@OGUID+64, @OBJECTPOOLS+6, 0, 'Durotar Peacebloom Senjin Echos 2/7'), +(@OGUID+65, @OBJECTPOOLS+6, 0, 'Durotar Peacebloom Senjin Echos 3/7'), +(@OGUID+66, @OBJECTPOOLS+6, 0, 'Durotar Peacebloom Senjin Echos 4/7'), +(@OGUID+67, @OBJECTPOOLS+6, 0, 'Durotar Peacebloom Senjin Echos 5/7'), +(@OGUID+68, @OBJECTPOOLS+6, 0, 'Durotar Peacebloom Senjin Echos 6/7'), +(@OGUID+69, @OBJECTPOOLS+6, 0, 'Durotar Peacebloom Senjin Echos 7/7'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+7, 1, 'Durotar Peacebloom Echo Isles Pool 8/8'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+70, @OBJECTPOOLS+7, 0, 'Durotar Peacebloom Echo Isles 1/5'), +(@OGUID+71, @OBJECTPOOLS+7, 0, 'Durotar Peacebloom Echo Isles 2/5'), +(@OGUID+72, @OBJECTPOOLS+7, 0, 'Durotar Peacebloom Echo Isles 3/5'), +(@OGUID+73, @OBJECTPOOLS+7, 0, 'Durotar Peacebloom Echo Isles 4/5'), +(@OGUID+74, @OBJECTPOOLS+7, 0, 'Durotar Peacebloom Echo Isles 5/5'); + +-- Silverleaf has presumed 68 spawns captured +-- Remove existing Silverleaf from Durotar: +DELETE FROM `gameobject` where `guid` IN (43526, 43530, 43534, 43539, 43541, 43542, 43544, 43545, 43549, 43556, 43558, 43559, 43560, 43562, 43565, 43572, 43573, 43574, 43577, 43578, 43579, 43580, 43581, 43591, 43594, 43595, 43598, 43599, 43602, 43603, 43606, 43607, 43608, 43610, 43611, 43612, 43615, 43618, 43619, 43620, 43621, 43624, 43625, 43630, 43631, 43633, 43634, 43635, 43636, 43640, 43641, 43642, 43643, 43646, 43651, 43654, 43655, 43658, 43661, 43662, 43663, 43664, 43665, 43670, 43671, 43679, 43680, 43681, 43688, 43690, 43691, 43696, 43697, 43698, 43699, 43701, 43702, 43704, 43712, 43715, 43716, 43718, 43720, 43721, 43722, 43724, 43725, 43730, 43732, 43733, 43933, 43936, 43937, 43938, 43979, 43988, 43989, 43990, 43991, 43993, 43994, 43995, 43996, 43997, 43998, 44004, 44005, 44006, 44007, 44014, 44015, 44018, 44019, 44032, 44152, 44153, 44154, 44155, 44163, 44164, 44165, 44169, 44170, 44171, 44172, 44173, 44174, 44178, 44183, 44187, 44188, 44189, 44192, 44196); + +-- Insert Durotar Silverleaf from packets: +SET @OGUID :=55775; +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+67; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`, `Comment`) VALUES +(@OGUID+5, 1617, 1, 14, 0, 1, 255, 1199.12255859375, -4974.04443359375, 11.18363094329833984, 1.413715124130249023, 0, 0, 0.649447441101074218, 0.760406434535980224, 360, 255, 1, 46779, '5/68 all known Durotar Silverleaf sniffed'), +(@OGUID+6, 1617, 1, 14, 0, 1, 255, 1226.707763671875, -5050.54541015625, 4.648762226104736328, 3.682650327682495117, 0, 0, -0.96362972259521484, 0.26724100112915039, 360, 255, 1, 46779, '6/68 all known Durotar Silverleaf sniffed'), +(@OGUID+2, 1617, 1, 14, 0, 1, 255, 1428.4954833984375, -4748.66650390625, 30.07084465026855468, 2.879789113998413085, 0, 0, 0.991444587707519531, 0.130528271198272705, 360, 255, 1, 46779, '2/68 all known Durotar Silverleaf sniffed'), +(@OGUID+1, 1617, 1, 14, 0, 1, 255, 1402.1968994140625, -4671.181640625, 32.9783782958984375, 2.024578809738159179, 0, 0, 0.848047256469726562, 0.529920578002929687, 360, 255, 1, 46779, '1/68 all known Durotar Silverleaf sniffed'), +(@OGUID+24, 1617, 1, 14, 0, 1, 255, 881.399658203125, -4937.3671875, 11.08956336975097656, 1.832594871520996093, 0, 0, 0.793353080749511718, 0.608761727809906005, 360, 255, 1, 46779, '24/68 all known Durotar Silverleaf sniffed'), +(@OGUID+28, 1617, 1, 14, 0, 1, 255, 654.6025390625, -4906.94287109375, 25.16013526916503906, 4.642575740814208984, 0, 0, -0.731353759765625, 0.681998312473297119, 360, 255, 1, 46779, '28/68 all known Durotar Silverleaf sniffed'), +(@OGUID+30, 1617, 1, 14, 0, 1, 255, 478.513031005859375, -4947.251953125, 33.46242523193359375, 1.797688722610473632, 0, 0, 0.7826080322265625, 0.622514784336090087, 360, 255, 1, 46779, '30/68 all known Durotar Silverleaf sniffed'), +(@OGUID+32, 1617, 1, 14, 0, 1, 255, 332.682281494140625, -4996.80908203125, 19.57125663757324218, 0.034906249493360519, 0, 0, 0.017452239990234375, 0.999847710132598876, 360, 255, 1, 46779, '32/68 all known Durotar Silverleaf sniffed'), +(@OGUID+41, 1617, 1, 14, 0, 1, 255, -116.260200500488281, -5164.296875, 19.90396499633789062, 5.881760597229003906, 0, 0, -0.19936752319335937, 0.979924798011779785, 360, 255, 1, 46779, '41/68 all known Durotar Silverleaf sniffed'), +(@OGUID+45, 1617, 1, 14, 0, 1, 255, -224.297958374023437, -5066.6650390625, 21.06113243103027343, 2.617989301681518554, 0, 0, 0.965925216674804687, 0.258821308612823486, 360, 255, 1, 46779, '45/68 all known Durotar Silverleaf sniffed'), +(@OGUID+46, 1617, 1, 14, 0, 1, 255, -236.168182373046875, -5203.22509765625, 20.0912322998046875, 5.462882041931152343, 0, 0, -0.39874839782714843, 0.917060375213623046, 360, 255, 1, 46779, '46/68 all known Durotar Silverleaf sniffed'), +(@OGUID+62, 1617, 1, 14, 0, 1, 255, -836.31915283203125, -5351.60986328125, 3.831897974014282226, 4.258606910705566406, 0, 0, -0.84804725646972656, 0.529920578002929687, 360, 255, 1, 46779, '62/68 all known Durotar Silverleaf sniffed'), +(@OGUID+60, 1617, 1, 14, 0, 1, 255, -925.78167724609375, -4689.3427734375, 25.75434494018554687, 2.373644113540649414, 0, 0, 0.927183151245117187, 0.37460830807685852, 360, 255, 1, 46779, '60/68 all known Durotar Silverleaf sniffed'), +(@OGUID+47, 1617, 1, 14, 0, 1, 255, -293.876739501953125, -4903.55712890625, 31.53289222717285156, 5.009094715118408203, 0, 0, -0.59482288360595703, 0.80385679006576538, 360, 255, 1, 46779, '47/68 all known Durotar Silverleaf sniffed'), +(@OGUID+37, 1617, 1, 14, 0, 1, 255, 10.69900226593017578, -4619.18017578125, 44.09099578857421875, 5.480334281921386718, 0, 0, -0.39073085784912109, 0.920504987239837646, 360, 255, 1, 46779, '37/68 all known Durotar Silverleaf sniffed'), +(@OGUID+22, 1617, 1, 14, 0, 1, 255, 64.93099212646484375, -4331.1171875, 61.72869110107421875, 3.22885894775390625, 0, 0, -0.99904823303222656, 0.043619260191917419, 360, 255, 1, 46779, '22/68 all known Durotar Silverleaf sniffed'), +(@OGUID+67, 1617, 1, 14, 0, 1, 255, 20.90711784362792968, -4266.0341796875, 72.0731048583984375, 6.265733242034912109, 0, 0, -0.00872611999511718, 0.999961912631988525, 360, 255, 1, 46779, '67/68 all known Durotar Silverleaf sniffed'), +(@OGUID+20, 1617, 1, 14, 0, 1, 255, 101.7131118774414062, -4080.67529296875, 54.75529098510742187, 1.221729278564453125, 0, 0, 0.573575973510742187, 0.819152355194091796, 360, 255, 1, 46779, '20/68 all known Durotar Silverleaf sniffed'), +(@OGUID+15, 1617, 1, 14, 0, 1, 255, 794.43817138671875, -4269.77783203125, 18.87027931213378906, 2.146752834320068359, 0, 0, 0.878816604614257812, 0.477159708738327026, 360, 255, 1, 46779, '15/68 all known Durotar Silverleaf sniffed'), +(@OGUID+11, 1617, 1, 14, 0, 1, 255, 1098.228271484375, -4026.997314453125, 17.61180686950683593, 5.270895957946777343, 0, 0, -0.48480892181396484, 0.87462007999420166, 360, 255, 1, 46779, '11/68 all known Durotar Silverleaf sniffed'), +(@OGUID+10, 1617, 1, 14, 0, 1, 255, 1303.82275390625, -4208.95361328125, 27.4298095703125, 2.809975385665893554, 0, 0, 0.986285209655761718, 0.165049895644187927, 360, 255, 1, 46779, '10/68 all known Durotar Silverleaf sniffed'), +(@OGUID+17, 1617, 1, 14, 0, 1, 255, 540.0294189453125, -4440.9404296875, 36.00847244262695312, 4.956737518310546875, 0, 0, -0.61566066741943359, 0.788011372089385986, 360, 255, 1, 46779, '17/68 all known Durotar Silverleaf sniffed'), +(@OGUID+51, 1617, 1, 14, 0, 1, 255, -496.944671630859375, -4685.08056640625, 38.02862930297851562, 4.293513298034667968, 0, 0, -0.8386697769165039, 0.544640243053436279, 360, 255, 1, 46779, '51/68 all known Durotar Silverleaf sniffed'), +(@OGUID+55, 1617, 1, 14, 0, 1, 255, -665.78558349609375, -5000.4169921875, 24.34447669982910156, 4.555310726165771484, 0, 0, -0.76040554046630859, 0.649448513984680175, 360, 255, 1, 46779, '55/68 all known Durotar Silverleaf sniffed'), +(@OGUID+64, 1617, 1, 14, 0, 1, 255, -1100.570556640625, -5415.5537109375, 12.51249217987060546, 5.829400539398193359, 0, 0, -0.22495079040527343, 0.974370121955871582, 360, 255, 1, 46779, '64/68 all known Durotar Silverleaf sniffed'), +(@OGUID+49, 1617, 1, 14, 0, 1, 255, -410.6124267578125, -4662.3447265625, 42.35511016845703125, 4.607671737670898437, 0, 0, -0.74314403533935546, 0.669131457805633544, 360, 255, 1, 46779, '49/68 all known Durotar Silverleaf sniffed'), +(@OGUID+53, 1617, 1, 14, 0, 1, 255, -547.2413330078125, -4659.25537109375, 40.40694046020507812, 0.471238493919372558, 0, 0, 0.233445167541503906, 0.972369968891143798, 360, 255, 1, 46779, '53/68 all known Durotar Silverleaf sniffed'), +(@OGUID+38, 1617, 1, 14, 0, 1, 255, -62.4102668762207031, -5153.82666015625, 9.282894134521484375, 0.820303261280059814, 0, 0, 0.398748397827148437, 0.917060375213623046, 360, 255, 1, 46779, '38/68 all known Durotar Silverleaf sniffed'), +(@OGUID+43, 1617, 1, 14, 0, 1, 255, -168.53515625, -5166.66943359375, 24.97609519958496093, 0, 0, 0, 0, 1, 360, 255, 1, 46779, '43/68 all known Durotar Silverleaf sniffed'), +(@OGUID+48, 1617, 1, 14, 0, 1, 255, -334.918182373046875, -5162.35498046875, 20.76618766784667968, 3.647741317749023437, 0, 0, -0.96814727783203125, 0.250381410121917724, 360, 255, 1, 46779, '48/68 all known Durotar Silverleaf sniffed'), +(@OGUID+40, 1617, 1, 14, 0, 1, 255, -119.825958251953125, -4860.9248046875, 21.40077590942382812, 4.014260292053222656, 0, 0, -0.90630722045898437, 0.422619491815567016, 360, 255, 1, 46779, '40/68 all known Durotar Silverleaf sniffed'), +(@OGUID+39, 1617, 1, 14, 0, 1, 255, -109.583770751953125, -4607.2548828125, 46.388336181640625, 5.340708732604980468, 0, 0, -0.45398998260498046, 0.891006767749786376, 360, 255, 1, 46779, '39/68 all known Durotar Silverleaf sniffed'), +(@OGUID+34, 1617, 1, 14, 0, 1, 255, 145.64874267578125, -4619.6201171875, 29.96367835998535156, 0.610863447189331054, 0, 0, 0.3007049560546875, 0.953717231750488281, 360, 255, 1, 46779, '34/68 all known Durotar Silverleaf sniffed'), +(@OGUID+21, 1617, 1, 14, 0, 1, 255, 135.734161376953125, -4484.05078125, 36.53779983520507812, 6.12610626220703125, 0, 0, -0.07845878601074218, 0.996917366981506347, 360, 255, 1, 46779, '21/68 all known Durotar Silverleaf sniffed'), +(@OGUID+57, 1617, 1, 14, 0, 1, 255, -801.76409912109375, -4569.8369140625, 49.57865524291992187, 2.967041015625, 0, 0, 0.996193885803222656, 0.087165042757987976, 360, 255, 1, 46779, '57/68 all known Durotar Silverleaf sniffed'), +(@OGUID+58, 1617, 1, 14, 0, 1, 255, -783.00457763671875, -4813.3828125, 20.22387313842773437, 0.680676698684692382, 0, 0, 0.333806037902832031, 0.942641794681549072, 360, 255, 1, 46779, '58/68 all known Durotar Silverleaf sniffed'), +(@OGUID+23, 1617, 1, 14, 0, 1, 255, 62.31228256225585937, -4479.89306640625, 47.769866943359375, 1.588248729705810546, 0, 0, 0.713250160217285156, 0.700909554958343505, 360, 255, 1, 46779, '23/68 all known Durotar Silverleaf sniffed'), +(@OGUID+26, 1617, 1, 14, 0, 1, 255, 758.82586669921875, -4728.86474609375, 37.44508743286132812, 3.961898565292358398, 0, 0, -0.91705989837646484, 0.398749500513076782, 360, 255, 1, 46779, '26/68 all known Durotar Silverleaf sniffed'), +(@OGUID+12, 1617, 1, 14, 0, 1, 255, 1053.7669677734375, -4301.228515625, 17.49706840515136718, 1.274088263511657714, 0, 0, 0.594821929931640625, 0.80385744571685791, 360, 255, 1, 46779, '12/68 all known Durotar Silverleaf sniffed'), +(@OGUID+8, 1617, 1, 14, 0, 1, 255, 1285.0394287109375, -4064.3291015625, 33.28411102294921875, 4.223697185516357421, 0, 0, -0.85716724395751953, 0.515038192272186279, 360, 255, 1, 46779, '8/68 all known Durotar Silverleaf sniffed'), +(@OGUID+7, 1617, 1, 14, 0, 1, 255, 1056.9949951171875, -5000.04345703125, 17.49074172973632812, 4.9218292236328125, 0, 0, -0.62932014465332031, 0.77714616060256958, 360, 255, 1, 46779, '7/68 all known Durotar Silverleaf sniffed'), +(@OGUID+3, 1617, 1, 14, 0, 1, 255, 1429.0692138671875, -4813.3798828125, 24.61579322814941406, 3.769911527633666992, 0, 0, -0.95105648040771484, 0.309017121791839599, 360, 255, 1, 46779, '3/68 all known Durotar Silverleaf sniffed'), +(@OGUID+0, 1617, 1, 14, 0, 1, 255, 1358.301025390625, -4569.46337890625, 37.89192581176757812, 5.969027042388916015, 0, 0, -0.1564340591430664, 0.987688362598419189, 360, 255, 1, 46779, '68/68 all known Durotar Silverleaf sniffed'), +(@OGUID+19, 1617, 1, 14, 0, 1, 255, 295.77886962890625, -4322.27490234375, 33.3949127197265625, 0.488691210746765136, 0, 0, 0.241921424865722656, 0.970295846462249755, 360, 255, 1, 46779, '19/68 all known Durotar Silverleaf sniffed'), +(@OGUID+59, 1617, 1, 14, 0, 1, 255, -840.15277099609375, -4632.03271484375, 40.95009231567382812, 2.164205789566040039, 0, 0, 0.882946968078613281, 0.469472706317901611, 360, 255, 1, 46779, '59/68 all known Durotar Silverleaf sniffed'), +(@OGUID+16, 1617, 1, 14, 0, 1, 255, 776.60968017578125, -4406.03759765625, 18.81634330749511718, 5.532694816589355468, 0, 0, -0.3665008544921875, 0.93041771650314331, 360, 255, 1, 46779, '16/68 all known Durotar Silverleaf sniffed'), +(@OGUID+9, 1617, 1, 14, 0, 1, 255, 1292.541259765625, -4168.68701171875, 27.76622772216796875, 0.226892471313476562, 0, 0, 0.113203048706054687, 0.993571877479553222, 360, 255, 1, 46779, '9/68 all known Durotar Silverleaf sniffed'), +(@OGUID+14, 1617, 1, 14, 0, 1, 255, 763.7265625, -3959.33544921875, 19.37665939331054687, 1.134462952613830566, 0, 0, 0.537299156188964843, 0.843391716480255126, 360, 255, 1, 46779, '14/68 all known Durotar Silverleaf sniffed'), +(@OGUID+25, 1617, 1, 14, 0, 1, 255, 821.03125, -4890.18310546875, 35.38489151000976562, 1.047197580337524414, 0, 0, 0.5, 0.866025388240814208, 360, 255, 1, 46779, '25/68 all known Durotar Silverleaf sniffed'), +(@OGUID+4, 1617, 1, 14, 0, 1, 255, 1216.4288330078125, -4797.841796875, 15.94697761535644531, 1.675513744354248046, 0, 0, 0.743144035339355468, 0.669131457805633544, 360, 255, 1, 46779, '4/68 all known Durotar Silverleaf sniffed'), +(@OGUID+36, 1617, 1, 14, 0, 1, 255, 92.46224212646484375, -4616.64794921875, 49.78679275512695312, 5.044002056121826171, 0, 0, -0.58070278167724609, 0.814115643501281738, 360, 255, 1, 46779, '36/68 all known Durotar Silverleaf sniffed'), +(@OGUID+56, 1617, 1, 14, 0, 1, 255, -690.43206787109375, -5610.8916015625, 26.65709304809570312, 2.129300594329833984, 0, 0, 0.874619483947753906, 0.484810054302215576, 360, 255, 1, 46779, '56/68 all known Durotar Silverleaf sniffed'), +(@OGUID+29, 1617, 1, 14, 0, 1, 255, 553.1600341796875, -4918.81494140625, 27.35105705261230468, 3.857182979583740234, 0, 0, -0.93667125701904296, 0.350209832191467285, 360, 255, 1, 46779, '29/68 all known Durotar Silverleaf sniffed'), +(@OGUID+31, 1617, 1, 14, 0, 1, 255, 429.8603515625, -4974.40625, 36.593505859375, 5.270895957946777343, 0, 0, -0.48480892181396484, 0.87462007999420166, 360, 255, 1, 46779, '31/68 all known Durotar Silverleaf sniffed'), +(@OGUID+33, 1617, 1, 14, 0, 1, 255, 364.98675537109375, -5048.28564453125, 21.98761177062988281, 4.625123500823974609, 0, 0, -0.73727703094482421, 0.67559051513671875, 360, 255, 1, 46779, '33/68 all known Durotar Silverleaf sniffed'), +(@OGUID+18, 1617, 1, 14, 0, 1, 255, 385.5419921875, -4081.228271484375, 32.075347900390625, 4.031712055206298828, 0, 0, -0.90258502960205078, 0.430511653423309326, 360, 255, 1, 46779, '18/68 all known Durotar Silverleaf sniffed'), +(@OGUID+42, 1617, 1, 14, 0, 1, 255, -194.91168212890625, -4635.5029296875, 42.44704055786132812, 3.403396368026733398, 0, 0, -0.99144458770751953, 0.130528271198272705, 360, 255, 1, 46779, '42/68 all known Durotar Silverleaf sniffed'), +(@OGUID+52, 1617, 1, 14, 0, 1, 255, -513.9561767578125, -4869.1884765625, 35.99258041381835937, 6.03883981704711914, 0, 0, -0.12186908721923828, 0.9925462007522583, 360, 255, 1, 46779, '52/68 all known Durotar Silverleaf sniffed'), +(@OGUID+13, 1617, 1, 14, 0, 1, 255, 859.83758544921875, -4397.94384765625, 16.41344642639160156, 4.572763919830322265, 0, 0, -0.75470924377441406, 0.656059443950653076, 360, 255, 1, 46779, '13/68 all known Durotar Silverleaf sniffed'), +(@OGUID+50, 1617, 1, 14, 0, 1, 255, -424.18792724609375, -4871.5634765625, 40.11857986450195312, 0.680676698684692382, 0, 0, 0.333806037902832031, 0.942641794681549072, 360, 255, 1, 46779, '50/68 all known Durotar Silverleaf sniffed'), +(@OGUID+61, 1617, 1, 14, 0, 1, 255, -1028.3353271484375, -4863.8994140625, 8.512418746948242187, 5.567600727081298828, 0, 0, -0.35020732879638671, 0.936672210693359375, 360, 255, 1, 46779, '61/68 all known Durotar Silverleaf sniffed'), +(@OGUID+44, 1617, 1, 14, 0, 1, 255, -255.429473876953125, -4707.501953125, 34.32258224487304687, 3.804818391799926757, 0, 0, -0.94551849365234375, 0.325568377971649169, 360, 255, 1, 46779, '44/68 all known Durotar Silverleaf sniffed'), +(@OGUID+54, 1617, 1, 14, 0, 1, 255, -609.551025390625, -4933.75146484375, 37.45981979370117187, 1.291541695594787597, 0, 0, 0.60181427001953125, 0.798636078834533691, 360, 255, 1, 46779, '54/68 all known Durotar Silverleaf sniffed'), +(@OGUID+35, 1617, 1, 14, 0, 1, 255, 117.1783828735351562, -4960.396484375, 9.156251907348632812, 2.024578809738159179, 0, 0, 0.848047256469726562, 0.529920578002929687, 360, 255, 1, 46779, '35/68 all known Durotar Silverleaf sniffed'), +(@OGUID+66, 1617, 1, 14, 0, 1, 255, -1390.3603515625, -5156.8828125, 2.4388580322265625, 2.809975385665893554, 0, 0, 0.986285209655761718, 0.165049895644187927, 360, 255, 1, 46779, '66/68 all known Durotar Silverleaf sniffed'), +(@OGUID+27, 1617, 1, 14, 0, 1, 255, 716.880126953125, -5005.5654296875, 15.14517402648925781, 6.265733242034912109, 0, 0, -0.00872611999511718, 0.999961912631988525, 360, 255, 1, 46779, '27/68 all known Durotar Silverleaf sniffed'), +(@OGUID+65, 1617, 1, 14, 0, 1, 255, -1244.3306884765625, -5499.28369140625, 5.331966876983642578, 1.535889506340026855, 0, 0, 0.694658279418945312, 0.719339847564697265, 360, 255, 1, 46779, '65/68 all known Durotar Silverleaf sniffed'), +(@OGUID+63, 1617, 1, 14, 0, 1, 255, -1118.697509765625, -5156.806640625, 1.814450979232788085, 0.802850961685180664, 0, 0, 0.390730857849121093, 0.920504987239837646, 360, 255, 1, 46779, '63/68 all known Durotar Silverleaf sniffed'); + +-- Make Durotar Silverleaf Pooling: +SET @OBJECTPOOLS :=129; +DELETE FROM `pool_gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+67; +DELETE FROM `pool_template` WHERE `entry` BETWEEN @OBJECTPOOLS+0 AND @OBJECTPOOLS+7; + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+0, 4, 'Durotar Silverleaf NW Pool 1/7'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+0, @OBJECTPOOLS+0, 0, 'Durotar Silverleaf NW 1/7'), +(@OGUID+1, @OBJECTPOOLS+0, 0, 'Durotar Silverleaf NW 2/8'), +(@OGUID+2, @OBJECTPOOLS+0, 0, 'Durotar Silverleaf NW 3/8'), +(@OGUID+3, @OBJECTPOOLS+0, 0, 'Durotar Silverleaf NW 4/8'), +(@OGUID+4, @OBJECTPOOLS+0, 0, 'Durotar Silverleaf NW 5/8'), +(@OGUID+5, @OBJECTPOOLS+0, 0, 'Durotar Silverleaf NW 6/8'), +(@OGUID+6, @OBJECTPOOLS+0, 0, 'Durotar Silverleaf NW 7/8'), +(@OGUID+7, @OBJECTPOOLS+0, 0, 'Durotar Silverleaf NW 8/8'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+1, 3, 'Durotar Silverleaf NW Pool 2/7'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+8, @OBJECTPOOLS+1, 0, 'Durotar Silverleaf NW 1/5'), +(@OGUID+9, @OBJECTPOOLS+1, 0, 'Durotar Silverleaf NW 2/5'), +(@OGUID+10, @OBJECTPOOLS+1, 0, 'Durotar Silverleaf NW 3/5'), +(@OGUID+11, @OBJECTPOOLS+1, 0, 'Durotar Silverleaf NW 4/5'), +(@OGUID+12, @OBJECTPOOLS+1, 0, 'Durotar Silverleaf NW 5/5'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+2, 4, 'Durotar Silverleaf West Pool 3/7'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+13, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 1/12'), +(@OGUID+14, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 2/12'), +(@OGUID+15, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 3/12'), +(@OGUID+16, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 4/12'), +(@OGUID+17, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 5/12'), +(@OGUID+18, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 6/12'), +(@OGUID+19, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 7/12'), +(@OGUID+20, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 8/12'), +(@OGUID+21, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 9/12'), +(@OGUID+22, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 10/12'), +(@OGUID+23, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 11/12'), +(@OGUID+67, @OBJECTPOOLS+2, 0, 'Durotar Silverleaf West 12/12'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+3, 5, 'Durotar Silverleaf East Valley Pool 4/7'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+24, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 1/14'), +(@OGUID+25, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 2/14'), +(@OGUID+26, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 3/14'), +(@OGUID+27, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 4/14'), +(@OGUID+28, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 5/14'), +(@OGUID+29, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 6/14'), +(@OGUID+30, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 7/14'), +(@OGUID+31, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 8/14'), +(@OGUID+32, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 9/14'), +(@OGUID+33, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 10/14'), +(@OGUID+34, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 11/14'), +(@OGUID+35, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 12/14'), +(@OGUID+36, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 13/14'), +(@OGUID+37, @OBJECTPOOLS+3, 0, 'Durotar Silverleaf East Valley 14/14'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+4, 8, 'Durotar Silverleaf East Coast Pool 5/7'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+38, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 1/17'), +(@OGUID+39, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 2/17'), +(@OGUID+40, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 3/17'), +(@OGUID+41, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 4/17'), +(@OGUID+42, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 5/17'), +(@OGUID+43, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 6/17'), +(@OGUID+44, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 7/17'), +(@OGUID+45, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 8/17'), +(@OGUID+46, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 9/17'), +(@OGUID+47, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 10/17'), +(@OGUID+48, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 11/17'), +(@OGUID+49, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 12/17'), +(@OGUID+50, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 13/17'), +(@OGUID+51, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 14/17'), +(@OGUID+52, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 15/17'), +(@OGUID+53, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 16/17'), +(@OGUID+54, @OBJECTPOOLS+4, 0, 'Durotar Silverleaf East Coast 17/17'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+5, 2, 'Durotar Silverleaf Senjin Echo Pool 6/7'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+55, @OBJECTPOOLS+5, 0, 'Durotar Silverleaf Senjin Echo 1/7'), +(@OGUID+56, @OBJECTPOOLS+5, 0, 'Durotar Silverleaf Senjin Echo 2/7'), +(@OGUID+57, @OBJECTPOOLS+5, 0, 'Durotar Silverleaf Senjin Echo 3/7'), +(@OGUID+58, @OBJECTPOOLS+5, 0, 'Durotar Silverleaf Senjin Echo 4/7'), +(@OGUID+59, @OBJECTPOOLS+5, 0, 'Durotar Silverleaf Senjin Echo 5/7'), +(@OGUID+60, @OBJECTPOOLS+5, 0, 'Durotar Silverleaf Senjin Echo 6/7'), +(@OGUID+61, @OBJECTPOOLS+5, 0, 'Durotar Silverleaf Senjin Echo 7/7'); + +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(@OBJECTPOOLS+6, 1, 'Durotar Silverleaf Echo Isles Pool 7/7'); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(@OGUID+62, @OBJECTPOOLS+6, 0, 'Durotar Silverleaf Echo Isles 1/5'), +(@OGUID+63, @OBJECTPOOLS+6, 0, 'Durotar Silverleaf Echo Isles 2/5'), +(@OGUID+64, @OBJECTPOOLS+6, 0, 'Durotar Silverleaf Echo Isles 3/5'), +(@OGUID+65, @OBJECTPOOLS+6, 0, 'Durotar Silverleaf Echo Isles 4/5'), +(@OGUID+66, @OBJECTPOOLS+6, 0, 'Durotar Silverleaf Echo Isles 5/5'); diff --git a/data/sql/updates/db_world/2023_10_12_01.sql b/data/sql/updates/db_world/2023_10_12_01.sql new file mode 100644 index 00000000000000..3425796661766a --- /dev/null +++ b/data/sql/updates/db_world/2023_10_12_01.sql @@ -0,0 +1,8 @@ +-- DB update 2023_10_12_00 -> 2023_10_12_01 +-- Item - Chamber of Aspects 25 Nuker Trinket +DELETE FROM `spell_proc_event` WHERE `entry` = 75465; +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `procPhase`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(75465,0,0,0,0,0,0,0,0,0,0,45000); + +-- Item - Chamber of Aspects 25 Heroic Nuker Trinket +UPDATE `spell_proc_event` SET `Cooldown` = 45000 WHERE `entry` = 75474; diff --git a/data/sql/updates/db_world/2023_10_12_02.sql b/data/sql/updates/db_world/2023_10_12_02.sql new file mode 100644 index 00000000000000..af24c967f81664 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_12_02.sql @@ -0,0 +1,8 @@ +-- DB update 2023_10_12_01 -> 2023_10_12_02 +-- 37565 - Flexibility | Item - Priest T4 Holy/Discipline 4P Bonus +DELETE FROM `spell_script_names` WHERE `spell_id`=37565; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (37565, 'spell_pri_t4_4p_bonus'); + +DELETE FROM `spell_proc_event` WHERE `entry`=37565; +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `procPhase`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(37565, 0, 6, 4096, 0, 0, 16384, 0, 1, 0, 0, 0); diff --git a/data/sql/updates/db_world/2023_10_12_03.sql b/data/sql/updates/db_world/2023_10_12_03.sql new file mode 100644 index 00000000000000..159bffee92347c --- /dev/null +++ b/data/sql/updates/db_world/2023_10_12_03.sql @@ -0,0 +1,3 @@ +-- DB update 2023_10_12_02 -> 2023_10_12_03 +-- Seeking the Kor Gem, Bailor's Ore Shipment +UPDATE `quest_template_addon` SET `PrevQuestID` = 1653 WHERE `ID` IN (1442,1655); diff --git a/data/sql/updates/db_world/2023_10_12_04.sql b/data/sql/updates/db_world/2023_10_12_04.sql new file mode 100644 index 00000000000000..c2bd265995fe74 --- /dev/null +++ b/data/sql/updates/db_world/2023_10_12_04.sql @@ -0,0 +1,12 @@ +-- DB update 2023_10_12_03 -> 2023_10_12_04 +-- Gor'mul RP +DELETE FROM `smart_scripts` WHERE `entryorguid` = 2792 AND `source_type` = 0; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 279200 AND `source_type` = 9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(2792, 0, 0, 0, 20, 0, 100, 0, 702, 0, 0, 0, 0, 0, 80, 279200, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Gor\'mul - On Quest \'Guile of the Raptor (Part 2)\' finished - Run Script'), +(279200, 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, 'Gor\'mul - On Script - Remove Npc Flag Questgiver'), +(279200, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 4153, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Gor\'mul - On Script - Cast Guile of the Raptor'), +(279200, 9, 2, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Gor\'mul - On Script - Say Line 0'), +(279200, 9, 3, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Gor\'mul - On Script - Say Line 1'), +(279200, 9, 4, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Gor\'mul - On Script - Say Line 2'), +(279200, 9, 5, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 82, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Gor\'mul - On Script - Add Npc Flag Questgiver'); diff --git a/pull_request_template.md b/pull_request_template.md index 7f6c343dcc411c..269f0d8dbd3122 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -1,13 +1,12 @@ ## Changes Proposed: + This PR proposes changes to: - [ ] Core (units, players, creatures, game systems). - [ ] Scripts (bosses, spell scripts, creature scripts). - [ ] Database (SAI, creatures, etc). -If your pull request promotes complex changes that require a detailed explanation, please describe them in detail specifying what your solution is and what is it meant to address. - ## Issues Addressed: - Closes diff --git a/src/cmake/compiler/clang/settings.cmake b/src/cmake/compiler/clang/settings.cmake index 93e85762e08702..92b95cb476e808 100644 --- a/src/cmake/compiler/clang/settings.cmake +++ b/src/cmake/compiler/clang/settings.cmake @@ -131,7 +131,7 @@ if(BUILD_SHARED_LIBS) -fvisibility=hidden) # --no-undefined to throw errors when there are undefined symbols - # (caused through missing WARHEAD_*_API macros). + # (caused through missing ACORE_*_API macros). set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --no-undefined") message(STATUS "Clang: Disallow undefined symbols") diff --git a/src/cmake/compiler/gcc/settings.cmake b/src/cmake/compiler/gcc/settings.cmake index a5fe2c33e4d61e..8723a6043c130e 100644 --- a/src/cmake/compiler/gcc/settings.cmake +++ b/src/cmake/compiler/gcc/settings.cmake @@ -67,7 +67,7 @@ if(BUILD_SHARED_LIBS) INTERFACE -fvisibility=hidden) - # Should break the build when there are WARHEAD_*_API macros missing + # Should break the build when there are ACORE_*_API macros missing # but it complains about missing references in precompiled headers. # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--no-undefined") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined") diff --git a/src/cmake/macros/ConfigInstall.cmake b/src/cmake/macros/ConfigInstall.cmake index 836ec610c802e6..090e3dba2ce44b 100644 --- a/src/cmake/macros/ConfigInstall.cmake +++ b/src/cmake/macros/ConfigInstall.cmake @@ -73,7 +73,7 @@ endfunction() # # Use it like: -# CopyModuleConfig("warhead.conf.dist") +# CopyModuleConfig("acore.conf.dist") # function(CopyModuleConfig configDir) diff --git a/src/cmake/macros/FindOpenSSL.cmake b/src/cmake/macros/FindOpenSSL.cmake index f40a591f9a72d3..fb1651e6d421bc 100644 --- a/src/cmake/macros/FindOpenSSL.cmake +++ b/src/cmake/macros/FindOpenSSL.cmake @@ -575,7 +575,7 @@ if(OPENSSL_FOUND) include(EnsureVersion) ENSURE_VERSION("${OPENSSL_EXPECTED_VERSION}" "${OPENSSL_VERSION}" OPENSSL_VERSION_OK) if(NOT OPENSSL_VERSION_OK) - message(FATAL_ERROR "TrinityCore needs OpenSSL version ${OPENSSL_EXPECTED_VERSION} but found too new version ${OPENSSL_VERSION}. TrinityCore needs OpenSSL 1.0.x or 1.1.x to work properly. If you still have problems please install OpenSSL 1.0.x if you still have problems search on forum for TCE00022") + message(FATAL_ERROR "AzerothCore needs OpenSSL version ${OPENSSL_EXPECTED_VERSION} but found too new version ${OPENSSL_VERSION}. AzerothCore needs OpenSSL 1.0.x or 1.1.x to work properly. If you still have problems please install OpenSSL 1.0.x if you still have problems search on forum for TCE00022") endif() if(NOT TARGET OpenSSL::Crypto AND diff --git a/src/common/Collision/Maps/MapDefines.h b/src/common/Collision/Maps/MapDefines.h index 94f926c8c184b2..6772a20c7021ec 100644 --- a/src/common/Collision/Maps/MapDefines.h +++ b/src/common/Collision/Maps/MapDefines.h @@ -1,6 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2008+ TrinityCore + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ #ifndef _MAPDEFINES_H diff --git a/src/common/Common.h b/src/common/Common.h index 01b65e68196b5a..c31397e737a0e8 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -41,13 +41,6 @@ #include #endif -#if AC_COMPILER == AC_COMPILER_MICROSOFT -#define atoll _atoi64 -#define llabs _abs64 -#else -#define stricmp strcasecmp -#endif - #define STRINGIZE(a) #a #define MAX_NETCLIENT_PACKET_SIZE (32767 - 1) // Client hardcap: int16 with trailing zero space otherwise crash on memory free diff --git a/src/common/Configuration/Config.cpp b/src/common/Configuration/Config.cpp index 7a51fc178df3da..742777b18611a8 100644 --- a/src/common/Configuration/Config.cpp +++ b/src/common/Configuration/Config.cpp @@ -32,6 +32,7 @@ namespace std::vector _additonalFiles; std::vector _args; std::unordered_map _configOptions; + std::unordered_map _envVarCache; std::mutex _configLock; // Check system configs like *server.conf* @@ -120,7 +121,7 @@ namespace auto const& itr = fileConfigs.find(confOption); if (itr != fileConfigs.end()) { - PrintError(file, "> Config::LoadFile: Dublicate key name '{}' in config file '{}'", confOption, file); + PrintError(file, "> Config::LoadFile: Duplicate key name '{}' in config file '{}'", confOption, file); return true; } @@ -283,9 +284,14 @@ namespace return result; } + std::string GetEnvVarName(std::string const& configName) + { + return "AC_" + IniKeyToEnvVarKey(configName); + } + Optional EnvVarForIniKey(std::string const& key) { - std::string envKey = "AC_" + IniKeyToEnvVarKey(key); + std::string envKey = GetEnvVarName(key); char* val = std::getenv(envKey.c_str()); if (!val) return std::nullopt; @@ -330,6 +336,29 @@ bool ConfigMgr::Reload() return true; } +// Check the _envVarCache if the env var is there +// if not, check the env for the value +Optional GetEnvFromCache(std::string const& configName, std::string const& envVarName) +{ + auto foundInCache = _envVarCache.find(envVarName); + Optional foundInEnv; + // If it's not in the cache + if (foundInCache == _envVarCache.end()) + { + // Check the env itself + foundInEnv = EnvVarForIniKey(configName); + if (foundInEnv) + { + // If it's found in the env, put it in the cache + _envVarCache.emplace(envVarName, *foundInEnv); + } + // Return the result of checking env + return foundInEnv; + } + + return foundInCache->second; +} + std::vector ConfigMgr::OverrideWithEnvVariablesIfAny() { std::lock_guard lock(_configLock); @@ -357,28 +386,30 @@ template T ConfigMgr::GetValueDefault(std::string const& name, T const& def, bool showLogs /*= true*/) const { std::string strValue; + auto const& itr = _configOptions.find(name); - if (itr == _configOptions.end()) + bool notFound = itr == _configOptions.end(); + auto envVarName = GetEnvVarName(name); + Optional envVar = GetEnvFromCache(name, envVarName); + if (envVar) { - Optional envVar = EnvVarForIniKey(name); - if (!envVar) + // If showLogs and this key/value pair wasn't found in the currently saved config + if (showLogs && (notFound || itr->second != envVar->c_str())) { - if (showLogs) - { - LOG_ERROR("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file.", - name, _filename, name, Acore::ToString(def)); - } - - return def; + LOG_INFO("server.loading", "> Config: Found config value '{}' from environment variable '{}'.", name, envVarName ); + AddKey(name, envVar->c_str(), "ENVIRONMENT", false, false); } + strValue = *envVar; + } + else if (notFound) + { if (showLogs) { - LOG_WARN("server.loading", "Missing property {} in config file {}, recovered with environment '{}' value.", - name, _filename, envVar->c_str()); + LOG_ERROR("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.", + name, _filename, name, Acore::ToString(def), envVarName); } - - strValue = *envVar; + return def; } else { @@ -404,24 +435,26 @@ template<> std::string ConfigMgr::GetValueDefault(std::string const& name, std::string const& def, bool showLogs /*= true*/) const { auto const& itr = _configOptions.find(name); - if (itr == _configOptions.end()) + bool notFound = itr == _configOptions.end(); + auto envVarName = GetEnvVarName(name); + Optional envVar = GetEnvFromCache(name, envVarName); + if (envVar) { - Optional envVar = EnvVarForIniKey(name); - if (envVar) + // If showLogs and this key/value pair wasn't found in the currently saved config + if (showLogs && (notFound || itr->second != envVar->c_str())) { - if (showLogs) - { - LOG_WARN("server.loading", "Missing property {} in config file {}, recovered with environment '{}' value.", - name, _filename, envVar->c_str()); - } - - return *envVar; + LOG_INFO("server.loading", "> Config: Found config value '{}' from environment variable '{}'.", name, envVarName); + AddKey(name, *envVar, "ENVIRONMENT", false, false); } + return *envVar; + } + else if (notFound) + { if (showLogs) { - LOG_ERROR("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file.", - name, _filename, name, def); + LOG_ERROR("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.", + name, _filename, name, def, envVarName); } return def; diff --git a/src/common/Cryptography/TOTP.h b/src/common/Cryptography/TOTP.h index 01b2a53bd76865..ddcaf75734d551 100644 --- a/src/common/Cryptography/TOTP.h +++ b/src/common/Cryptography/TOTP.h @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#ifndef WARHEAD_TOTP_H -#define WARHEAD_TOTP_H +#ifndef ACORE_TOTP_H +#define ACORE_TOTP_H #include "Define.h" #include diff --git a/src/common/Encoding/Base32.cpp b/src/common/Encoding/Base32.cpp index 1a663a46e5ca52..8906e0eaf7df8c 100644 --- a/src/common/Encoding/Base32.cpp +++ b/src/common/Encoding/Base32.cpp @@ -1,6 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2021+ WarheadCore + * 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 "Base32.h" diff --git a/src/common/Encoding/Base32.h b/src/common/Encoding/Base32.h index 68c8be46363594..1f15212c1364d6 100644 --- a/src/common/Encoding/Base32.h +++ b/src/common/Encoding/Base32.h @@ -1,10 +1,22 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2021+ WarheadCore + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ -#ifndef WARHEAD_BASE32_H -#define WARHEAD_BASE32_H +#ifndef ACORE_BASE32_H +#define ACORE_BASE32_H #include "Define.h" #include "Optional.h" diff --git a/src/common/Encoding/Base64.cpp b/src/common/Encoding/Base64.cpp index 1e5c1968ec6f3a..ee37be5303d92a 100644 --- a/src/common/Encoding/Base64.cpp +++ b/src/common/Encoding/Base64.cpp @@ -1,6 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2021+ WarheadCore + * 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 "Base64.h" diff --git a/src/common/Encoding/Base64.h b/src/common/Encoding/Base64.h index 8fe7cf0d5bb2c3..b1cb7b18fe8493 100644 --- a/src/common/Encoding/Base64.h +++ b/src/common/Encoding/Base64.h @@ -1,10 +1,22 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2021+ WarheadCore + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ -#ifndef WARHEAD_BASE64_H -#define WARHEAD_BASE64_H +#ifndef ACORE_BASE64_H +#define ACORE_BASE64_H #include "Define.h" #include "Optional.h" diff --git a/src/common/Encoding/BaseEncoding.h b/src/common/Encoding/BaseEncoding.h index 8ae0673d3b5cb8..ed1ea96ec6a8a9 100644 --- a/src/common/Encoding/BaseEncoding.h +++ b/src/common/Encoding/BaseEncoding.h @@ -1,10 +1,22 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2021+ WarheadCore + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ -#ifndef WARHEAD_BASE_ENCODING_HPP -#define WARHEAD_BASE_ENCODING_HPP +#ifndef ACORE_BASE_ENCODING_HPP +#define ACORE_BASE_ENCODING_HPP #include "Define.h" #include "Optional.h" diff --git a/src/common/GitRevision.cpp b/src/common/GitRevision.cpp index 9510a0f0dfc03f..4bfdffe7ccc607 100644 --- a/src/common/GitRevision.cpp +++ b/src/common/GitRevision.cpp @@ -1,7 +1,19 @@ /* -* Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. -* Copyright (C) 2008-2016 TrinityCore -*/ + * 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 "GitRevision.h" #include "revision.h" diff --git a/src/common/GitRevision.h b/src/common/GitRevision.h index ececc723ab31b4..34d0d99223126d 100644 --- a/src/common/GitRevision.h +++ b/src/common/GitRevision.h @@ -1,7 +1,19 @@ /* -* Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. -* Copyright (C) 2008-2018 TrinityCore -*/ + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ #ifndef __GITREVISION_H__ #define __GITREVISION_H__ diff --git a/src/common/Logging/Log.cpp b/src/common/Logging/Log.cpp index 38a8ccbbdc11ee..6fd65216cacd10 100644 --- a/src/common/Logging/Log.cpp +++ b/src/common/Logging/Log.cpp @@ -398,6 +398,4 @@ void Log::LoadFromConfig() ReadAppendersFromConfig(); ReadLoggersFromConfig(); - - _debugLogMask = DebugLogFilters(sConfigMgr->GetOption("DebugLogMask", LOG_FILTER_NONE, false)); } diff --git a/src/common/Logging/Log.h b/src/common/Logging/Log.h index bf349227b8fdbe..e2ec45cd5b5bae 100644 --- a/src/common/Logging/Log.h +++ b/src/common/Logging/Log.h @@ -121,8 +121,6 @@ typedef std::unordered_map LoggerMap; Acore::Asio::IoContext* _ioContext; Acore::Asio::Strand* _strand; - // Deprecated debug filter logs - DebugLogFilters _debugLogMask; }; #define sLog Log::instance() diff --git a/src/common/Logging/LogCommon.h b/src/common/Logging/LogCommon.h index 56b6dc58c1e4cc..ba53ba6dfcfe91 100644 --- a/src/common/Logging/LogCommon.h +++ b/src/common/Logging/LogCommon.h @@ -46,6 +46,7 @@ enum AppenderType : uint8 APPENDER_INVALID = 0xFF // SKIP }; +// EnumUtils: DESCRIBE THIS enum AppenderFlags : uint8 { APPENDER_FLAGS_NONE = 0x00, @@ -56,37 +57,4 @@ enum AppenderFlags : uint8 APPENDER_FLAGS_MAKE_FILE_BACKUP = 0x10 }; -// Dprecated debug log filters need delte later -enum DebugLogFilters -{ - LOG_FILTER_NONE = 0x00000000, - LOG_FILTER_UNITS = 0x00000001, // Anything related to units that doesn't fit in other categories. ie. creature formations - LOG_FILTER_PETS = 0x00000002, - LOG_FILTER_VEHICLES = 0x00000004, - LOG_FILTER_TSCR = 0x00000008, // C++ AI, instance scripts, etc. - LOG_FILTER_DATABASE_AI = 0x00000010, // SmartAI, EventAI, CreatureAI - LOG_FILTER_MAPSCRIPTS = 0x00000020, - LOG_FILTER_NETWORKIO = 0x00000040, // Anything packet/netcode related - LOG_FILTER_SPELLS_AURAS = 0x00000080, - LOG_FILTER_ACHIEVEMENTSYS = 0x00000100, - LOG_FILTER_CONDITIONSYS = 0x00000200, - LOG_FILTER_POOLSYS = 0x00000400, - LOG_FILTER_AUCTIONHOUSE = 0x00000800, - LOG_FILTER_BATTLEGROUND = 0x00001000, // Anything related to arena's and battlegrounds - LOG_FILTER_OUTDOORPVP = 0x00002000, - LOG_FILTER_CHATSYS = 0x00004000, - LOG_FILTER_LFG = 0x00008000, - LOG_FILTER_MAPS = 0x00010000, // Maps, instances, grids, cells, visibility - LOG_FILTER_PLAYER_LOADING = 0x00020000, // Debug output from Player::_Load functions - LOG_FILTER_PLAYER_ITEMS = 0x00040000, // Anything item related - LOG_FILTER_PLAYER_SKILLS = 0x00080000, // Skills related - LOG_FILTER_LOOT = 0x00100000, // Loot related - LOG_FILTER_GUILD = 0x00200000, // Guild related - LOG_FILTER_TRANSPORTS = 0x00400000, // Transport related - LOG_FILTER_WARDEN = 0x00800000, // Warden related - LOG_FILTER_BATTLEFIELD = 0x01000000, // Battlefield related - LOG_FILTER_MODULES = 0x02000000, // Modules debug - LOG_FILTER_CLOSE_SOCKET = 0x04000000, // Whenever KickPlayer() or CloseSocket() are called -}; - #endif // LogCommon_h__ diff --git a/src/common/Logging/enuminfo_LogCommon.cpp b/src/common/Logging/enuminfo_LogCommon.cpp index da8cbc44933a8b..2e4265563571c7 100644 --- a/src/common/Logging/enuminfo_LogCommon.cpp +++ b/src/common/Logging/enuminfo_LogCommon.cpp @@ -121,4 +121,55 @@ AC_API_EXPORT size_t EnumUtils::ToIndex(AppenderType value) default: throw std::out_of_range("value"); } } + +/*****************************************************************\ +|* data for enum 'AppenderFlags' in 'LogCommon.h' auto-generated *| +\*****************************************************************/ +template <> +AC_API_EXPORT EnumText EnumUtils::ToString(AppenderFlags value) +{ + switch (value) + { + case APPENDER_FLAGS_NONE: return { "APPENDER_FLAGS_NONE", "APPENDER_FLAGS_NONE", "" }; + case APPENDER_FLAGS_PREFIX_TIMESTAMP: return { "APPENDER_FLAGS_PREFIX_TIMESTAMP", "APPENDER_FLAGS_PREFIX_TIMESTAMP", "" }; + case APPENDER_FLAGS_PREFIX_LOGLEVEL: return { "APPENDER_FLAGS_PREFIX_LOGLEVEL", "APPENDER_FLAGS_PREFIX_LOGLEVEL", "" }; + case APPENDER_FLAGS_PREFIX_LOGFILTERTYPE: return { "APPENDER_FLAGS_PREFIX_LOGFILTERTYPE", "APPENDER_FLAGS_PREFIX_LOGFILTERTYPE", "" }; + case APPENDER_FLAGS_USE_TIMESTAMP: return { "APPENDER_FLAGS_USE_TIMESTAMP", "APPENDER_FLAGS_USE_TIMESTAMP", "" }; + case APPENDER_FLAGS_MAKE_FILE_BACKUP: return { "APPENDER_FLAGS_MAKE_FILE_BACKUP", "APPENDER_FLAGS_MAKE_FILE_BACKUP", "" }; + default: throw std::out_of_range("value"); + } +} + +template <> +AC_API_EXPORT size_t EnumUtils::Count() { return 6; } + +template <> +AC_API_EXPORT AppenderFlags EnumUtils::FromIndex(size_t index) +{ + switch (index) + { + case 0: return APPENDER_FLAGS_NONE; + case 1: return APPENDER_FLAGS_PREFIX_TIMESTAMP; + case 2: return APPENDER_FLAGS_PREFIX_LOGLEVEL; + case 3: return APPENDER_FLAGS_PREFIX_LOGFILTERTYPE; + case 4: return APPENDER_FLAGS_USE_TIMESTAMP; + case 5: return APPENDER_FLAGS_MAKE_FILE_BACKUP; + default: throw std::out_of_range("index"); + } +} + +template <> +AC_API_EXPORT size_t EnumUtils::ToIndex(AppenderFlags value) +{ + switch (value) + { + case APPENDER_FLAGS_NONE: return 0; + case APPENDER_FLAGS_PREFIX_TIMESTAMP: return 1; + case APPENDER_FLAGS_PREFIX_LOGLEVEL: return 2; + case APPENDER_FLAGS_PREFIX_LOGFILTERTYPE: return 3; + case APPENDER_FLAGS_USE_TIMESTAMP: return 4; + case APPENDER_FLAGS_MAKE_FILE_BACKUP: return 5; + default: throw std::out_of_range("value"); + } +} } diff --git a/src/common/Utilities/EnumFlag.h b/src/common/Utilities/EnumFlag.h index b9fc9168e5f4f5..d02232cfceb972 100644 --- a/src/common/Utilities/EnumFlag.h +++ b/src/common/Utilities/EnumFlag.h @@ -1,6 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. - * Copyright (C) 2008-2021 TrinityCore + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ #ifndef EnumFlag_h__ diff --git a/src/common/Utilities/SmartEnum.h b/src/common/Utilities/SmartEnum.h index 880f72c51822ad..e6e0be2572056e 100644 --- a/src/common/Utilities/SmartEnum.h +++ b/src/common/Utilities/SmartEnum.h @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#ifndef TRINITY_SMARTENUM_H -#define TRINITY_SMARTENUM_H +#ifndef AC_SMARTENUM_H +#define AC_SMARTENUM_H #include "IteratorPair.h" #include @@ -130,4 +130,4 @@ class EnumUtils static char const* ToDescription(Enum value) { return ToString(value).Description; } }; -#endif +#endif // AC_SMART_ENUM_H diff --git a/src/common/Utilities/TaskScheduler.cpp b/src/common/Utilities/TaskScheduler.cpp index b1c1cbd418874b..1d0bf89e6e355b 100644 --- a/src/common/Utilities/TaskScheduler.cpp +++ b/src/common/Utilities/TaskScheduler.cpp @@ -1,6 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2008+ TrinityCore + * 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 "TaskScheduler.h" diff --git a/src/common/Utilities/TaskScheduler.h b/src/common/Utilities/TaskScheduler.h index c8b7b584d05e0a..a256be6801e6aa 100644 --- a/src/common/Utilities/TaskScheduler.h +++ b/src/common/Utilities/TaskScheduler.h @@ -1,6 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2008+ TrinityCore + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ #ifndef _TASK_SCHEDULER_H_ @@ -432,11 +444,11 @@ class TaskContext : _task(right._task), _owner(right._owner), _consumed(right._consumed) { } // Move construct - TaskContext(TaskContext&& right) + TaskContext(TaskContext&& right) noexcept : _task(std::move(right._task)), _owner(std::move(right._owner)), _consumed(std::move(right._consumed)) { } // Copy assign - TaskContext& operator= (TaskContext const& right) + TaskContext& operator= (TaskContext const& right) noexcept { _task = right._task; _owner = right._owner; @@ -445,7 +457,7 @@ class TaskContext } // Move assign - TaskContext& operator= (TaskContext&& right) + TaskContext& operator= (TaskContext&& right) noexcept { _task = std::move(right._task); _owner = std::move(right._owner); diff --git a/src/server/apps/authserver/Main.cpp b/src/server/apps/authserver/Main.cpp index bc40f2f10bf9e0..4c110db7aaaf49 100644 --- a/src/server/apps/authserver/Main.cpp +++ b/src/server/apps/authserver/Main.cpp @@ -85,8 +85,6 @@ int main(int argc, char** argv) if (!sConfigMgr->LoadAppConfigs()) return 1; - std::vector overriddenKeys = sConfigMgr->OverrideWithEnvVariablesIfAny(); - // Init logging sLog->RegisterAppender(); sLog->Initialize(nullptr); @@ -103,9 +101,6 @@ int main(int argc, char** argv) LOG_INFO("server.authserver", "> Using Boost version: {}.{}.{}", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); }); - for (std::string const& key : overriddenKeys) - LOG_INFO("server.authserver", "Configuration field {} was overridden with environment variable.", key); - OpenSSLCrypto::threadsSetup(); std::shared_ptr opensslHandle(nullptr, [](void*) { OpenSSLCrypto::threadsCleanup(); }); diff --git a/src/server/apps/authserver/Server/AuthSession.h b/src/server/apps/authserver/Server/AuthSession.h index 4a333c8168c89a..fe19cf80927ffb 100644 --- a/src/server/apps/authserver/Server/AuthSession.h +++ b/src/server/apps/authserver/Server/AuthSession.h @@ -45,6 +45,7 @@ enum AuthStatus STATUS_CLOSED }; +// cppcheck-suppress ctuOneDefinitionRuleViolation struct AccountInfo { void LoadResult(Field* fields); diff --git a/src/server/apps/worldserver/Main.cpp b/src/server/apps/worldserver/Main.cpp index fa91207a72d673..f8f98ac6a215c5 100644 --- a/src/server/apps/worldserver/Main.cpp +++ b/src/server/apps/worldserver/Main.cpp @@ -184,8 +184,6 @@ int main(int argc, char** argv) if (!sConfigMgr->LoadAppConfigs()) return 1; - std::vector overriddenKeys = sConfigMgr->OverrideWithEnvVariablesIfAny(); - std::shared_ptr ioContext = std::make_shared(); // Init all logs @@ -205,9 +203,6 @@ int main(int argc, char** argv) LOG_INFO("server.worldserver", "> Using Boost version: {}.{}.{}", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); }); - for (std::string const& key : overriddenKeys) - LOG_INFO("server.worldserver", "Configuration field {} was overridden with environment variable.", key); - OpenSSLCrypto::threadsSetup(); std::shared_ptr opensslHandle(nullptr, [](void*) { OpenSSLCrypto::threadsCleanup(); }); @@ -436,7 +431,7 @@ int main(int argc, char** argv) // 0 - normal shutdown // 1 - shutdown at error - // 2 - restart command used, this code can be used by restarter for restart Warheadd + // 2 - restart command used, this code can be used by restarter for restart AzerothCore return World::GetExitCode(); } diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 0a5372c5c25ffb..9770e459e6a571 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -6,54 +6,78 @@ ################################################################################################### # SECTION INDEX # -# EXAMPLE CONFIG -# CONNECTIONS AND DIRECTORIES -# PERFORMANCE SETTINGS -# SERVER LOGGING -# SERVER SETTINGS +# SERVER SYSTEM SETTINGS +# DATABASE & CONNECTIONS +# DIRECTORIES +# CONSOLE +# AUTOUPDATER +# NETWORK +# REMOTE ACCESS # CRYPTOGRAPHY -# WARDEN SETTINGS -# PLAYER INTERACTION -# CREATURE SETTINGS -# CHAT SETTINGS -# GAME MASTER SETTINGS -# VISIBILITY AND DISTANCES -# SERVER RATES -# STATS LIMITS -# AUTO BROADCAST -# BATTLEGROUND CONFIG -# BATTLEFIELD CONFIG -# ARENA CONFIG -# NETWORK CONFIG -# CONSOLE AND REMOTE ACCESS -# CHARACTER DELETE OPTIONS -# ITEM DELETE OPTIONS -# CUSTOM SERVER OPTIONS -# UPDATE SETTINGS -# LOGGING SYSTEM SETTINGS +# PERFORMANCE +# LOGGING +# METRIC +# SERVER # PACKET SPOOF PROTECTION SETTINGS +# WARDEN +# AUTO BROADCAST +# VISIBILITY AND DISTANCES +# MAPS +# WEATHER +# TICKETS +# COMMAND +# +# GAME SETTINGS +# GAME MASTER +# CHEAT +# CHARACTER DATABASE +# CHARACTER DELETE +# CHARACTER CREATION +# CHARACTER +# SKILL +# STATS +# REPUTATION +# EXPERIENCE +# CURRENCY +# DURABILITY +# DEATH +# PET +# ITEM DELETE +# ITEM +# QUEST +# CREATURE +# VENDOR +# GROUP +# INSTANCE +# DUNGEON AND BATTLEGROUND FINDER +# CHARTER +# GUILD +# FFAPVP +# WINTERGRASP +# BATTLEGROUND +# ARENA +# MAIL +# TRANSPORT +# CHAT CHANNEL +# FACTION INTERACTION +# RECRUIT A FRIEND +# CALENDAR +# GAME EVENT +# AUCTION HOUSE +# PLAYER DUMP +# CUSTOM # DEBUG -# METRIC SETTINGS # ################################################################################################### ################################################################################################### -# EXAMPLE CONFIG -# -# Variable -# Description: Brief description what the variable is doing. -# Important: Annotation for important things about this variable. -# Example: "Example, i.e. if the value is a string" -# Default: 10 - (Enabled|Comment|Variable name in case of grouped config options) -# 0 - (Disabled|Comment|Variable name in case of grouped config options) -# -# Note to developers: -# - Copy this example to keep the formatting. -# - Line breaks should be at column 100. +# # +# SERVER SYSTEM SETTINGS BEGIN # +# # ################################################################################################### ################################################################################################### -# CONNECTIONS AND DIRECTORIES +# DATABASE & CONNECTIONS # # RealmID # Description: ID of the Realm using this config. @@ -63,33 +87,18 @@ RealmID = 1 # -# DataDir -# Description: Data directory setting. -# Important: DataDir needs to be quoted, as the string might contain space characters. -# Example: "@prefix@\home\youruser\azerothcore\data" -# Default: "." - -DataDir = "." - -# -# LogsDir -# Description: Logs directory setting. -# Important: LogsDir needs to be quoted, as the string might contain space characters. -# Logs directory must exists, or log file creation will be disabled. -# Example: "/home/youruser/azerothcore/logs" -# Default: "" - (Log files will be stored in the current path) +# WorldServerPort +# Description: TCP port to reach the world server. +# Default: 8085 -LogsDir = "" +WorldServerPort = 8085 # -# TempDir -# Description: Temp directory setting. -# Important: TempDir needs to be quoted, as the string might contain space characters. -# TempDir directory must exists, or the server can't work properly -# Example: "/home/youruser/azerothcore/temp" -# Default: "" - (Temp files will be stored in the current path) +# BindIP +# Description: Bind world server to IP/hostname +# Default: "0.0.0.0" - (Bind to all IPs on the system) -TempDir = "" +BindIP = "0.0.0.0" # # LoginDatabaseInfo @@ -110,18 +119,6 @@ LoginDatabaseInfo = "127.0.0.1;3306;acore;acore;acore_auth" WorldDatabaseInfo = "127.0.0.1;3306;acore;acore;acore_world" CharacterDatabaseInfo = "127.0.0.1;3306;acore;acore;acore_characters" -# -# Database.Reconnect.Seconds -# Database.Reconnect.Attempts -# -# Description: How many seconds between every reconnection attempt -# and how many attempts will be performed in total -# Default: 20 attempts every 15 seconds -# - -Database.Reconnect.Seconds = 15 -Database.Reconnect.Attempts = 20 - # # LoginDatabase.WorkerThreads # WorldDatabase.WorkerThreads @@ -158,18 +155,50 @@ CharacterDatabase.SynchThreads = 2 MaxPingTime = 30 # -# WorldServerPort -# Description: TCP port to reach the world server. -# Default: 8085 +# Database.Reconnect.Seconds +# Database.Reconnect.Attempts +# +# Description: How many seconds between every reconnection attempt +# and how many attempts will be performed in total +# Default: 20 attempts every 15 seconds +# -WorldServerPort = 8085 +Database.Reconnect.Seconds = 15 +Database.Reconnect.Attempts = 20 # -# BindIP -# Description: Bind world server to IP/hostname -# Default: "0.0.0.0" - (Bind to all IPs on the system) +################################################################################################### -BindIP = "0.0.0.0" +################################################################################################### +# DIRECTORIES +# +# DataDir +# Description: Data directory setting. +# Important: DataDir needs to be quoted, as the string might contain space characters. +# Example: "@prefix@\home\youruser\azerothcore\data" +# Default: "." + +DataDir = "." + +# +# LogsDir +# Description: Logs directory setting. +# Important: LogsDir needs to be quoted, as the string might contain space characters. +# Logs directory must exists, or log file creation will be disabled. +# Example: "/home/youruser/azerothcore/logs" +# Default: "" - (Log files will be stored in the current path) + +LogsDir = "" + +# +# TempDir +# Description: Temp directory setting. +# Important: TempDir needs to be quoted, as the string might contain space characters. +# TempDir directory must exists, or the server can't work properly +# Example: "/home/youruser/azerothcore/temp" +# Default: "" - (Temp files will be stored in the current path) + +TempDir = "" # # CMakeCommand @@ -194,7 +223,7 @@ BuildDirectory = "" # SourceDirectory # Description: The path to your AzerothCore source directory. # If the path is left empty, the built-in CMAKE_SOURCE_DIR is used. -# Example: "../AzerothCore" +# Example: "../azerothcore-wotlk" # Default: "" SourceDirectory = "" @@ -211,248 +240,280 @@ SourceDirectory = "" MySQLExecutable = "" # -# ThreadPool -# Description: Number of threads to be used for the global thread pool -# The thread pool is currently used for: -# - Signal handling -# - Remote access -# - Database keep-alive ping -# - Core freeze check -# - World socket networking -# Default: 2 +# PidFile +# Description: World daemon PID file. +# Example: "./world.pid" - (Enabled) +# Default: "" - (Disabled) -ThreadPool = 2 +PidFile = "" # -# IPLocationFile -# Description: The path to your IP2Location database CSV file. -# Example: "C:/acore/IP2LOCATION-LITE-DB1.CSV" -# "/home/acore/IP2LOCATION-LITE-DB1.CSV" -# Default: "" - (Disabled) +################################################################################################### + +################################################################################################### +# CONSOLE # +# Console.Enable +# Description: Enable console. +# Default: 1 - (Enabled) +# 0 - (Disabled) -IPLocationFile = "" +Console.Enable = 1 # -# AllowLoggingIPAddressesInDatabase -# Description: Specifies if IP addresses can be logged to the database +# BeepAtStart +# Description: Beep when the world server finished starting (Unix/Linux systems). # Default: 1 - (Enabled) # 0 - (Disabled) + +BeepAtStart = 1 + # +# FlashAtStart +# Description: Flashes in taskbar when the world server finished starting. (Works on Windows only) +# Default: 1 - (Enabled) +# 0 - (Disabled) -AllowLoggingIPAddressesInDatabase = 1 +FlashAtStart = 1 # ################################################################################################### ################################################################################################### -# PERFORMANCE SETTINGS +# AUTOUPDATER # -# UseProcessors -# Description: Processors mask for Windows and Linux based multi-processor systems. -# Example: For a computer with 3 CPUs: -# 1 - 1st CPU only -# 2 - 2nd CPU only -# 4 - 3rd CPU only -# 6 - 2nd + 3rd CPUs, because "2 | 4" -> 6 -# Default: 0 - (Selected by OS) -# 1+ - (Bit mask value of selected processors) - -UseProcessors = 0 - +# Updates.EnableDatabases +# Description: A mask that describes which databases should be updated. # -# ProcessPriority -# Description: Process priority setting for Windows based systems. -# Default: 1 - (High) -# 0 - (Normal) +# Following flags are available +# DATABASE_LOGIN = 1, // Auth database +# DATABASE_CHARACTER = 2, // Character database +# DATABASE_WORLD = 4, // World database +# +# Default: 7 - (All enabled) +# 4 - (Enable world only) +# 0 - (All disabled) -ProcessPriority = 1 +Updates.EnableDatabases = 7 # -# Compression -# Description: Compression level for client update packages -# Range: 1-9 -# Default: 1 - (Speed) -# 9 - (Best compression) +# Updates.AutoSetup +# Description: Auto populate empty databases. +# Default: 1 - (Enabled) +# 0 - (Disabled) -Compression = 1 +Updates.AutoSetup = 1 # -# PlayerLimit -# Description: Maximum number of players in the world. Excluding Mods, GMs and Admins. -# Important: If you want to block players and only allow Mods, GMs or Admins to join the -# server, use the DB field "auth.realmlist.allowedSecurityLevel". -# Default: 1000 - (Enabled) -# 1+ - (Enabled) -# 0 - (Disabled, No limit) +# Updates.Redundancy +# Description: Perform data redundancy checks through hashing +# to detect changes on sql updates and reapply it. +# Default: 1 - (Enabled) +# 0 - (Disabled) -PlayerLimit = 1000 +Updates.Redundancy = 1 # -# SaveRespawnTimeImmediately -# Description: Save respawn time for creatures at death and gameobjects at use/open. -# Default: 1 - (Enabled, Save respawn time immediately) -# 0 - (Disabled, Save respawn time at grid unloading) +# Updates.ArchivedRedundancy +# Description: Check hashes of archived updates (slows down startup). +# Default: 0 - (Disabled) +# 1 - (Enabled) -SaveRespawnTimeImmediately = 1 +Updates.ArchivedRedundancy = 0 # -# MaxOverspeedPings -# Description: Maximum overspeed ping count before character is disconnected. -# Default: 2 - (Enabled, Minimum value) -# 3+ - (Enabled, More checks before kick) -# 0 - (Disabled) +# Updates.AllowRehash +# Description: Inserts the current file hash in the database if it is left empty. +# Useful if you want to mark a file as applied but you don't know its hash. +# Default: 1 - (Enabled) +# 0 - (Disabled) -MaxOverspeedPings = 2 +Updates.AllowRehash = 1 # -# CloseIdleConnections -# Description: Automatically close idle connections. -# SocketTimeOutTime and SocketTimeOutTimeActive determine when a connection is considered as idle. -# Default: 1 - (enable, Automatically close idle connections) -# 0 - (disable, Do not close idle connections) +# Updates.CleanDeadRefMaxCount +# Description: Cleans dead/ orphaned references that occur if an update was removed or renamed and edited in one step. +# It only starts the clean up if the count of the missing updates is below or equal the Updates.CleanDeadRefMaxCount value. +# This way prevents erasing of the update history due to wrong source directory state (maybe wrong branch or bad revision). +# Disable this if you want to know if the database is in a possible "dirty state". +# Default: 3 - (Enabled) +# 0 - (Disabled) +# -1 - (Enabled - unlimited) -CloseIdleConnections = 1 +Updates.CleanDeadRefMaxCount = 3 # -# SocketTimeOutTime -# Description: Time (in milliseconds) after which a connection being idle on the character -# selection screen is disconnected. -# Default: 900000 - (15 minutes) - -SocketTimeOutTime = 900000 +################################################################################################### +################################################################################################### +# NETWORK # -# SocketTimeOutTimeActive -# Description: Time (in milliseconds) after which an idle connection is dropped while -# logged into the world. -# The client sends keepalive packets every 30 seconds. Values <= 30s are not recommended. -# Default: 60000 - (1 minute) +# Network.Threads +# Description: Number of threads for network. +# Default: 1 - (Recommended 1 thread per 1000 connections) -SocketTimeOutTimeActive = 60000 +Network.Threads = 1 # -# SessionAddDelay -# Description: Time (in microseconds) that a network thread will sleep after authentication -# protocol handling before adding a connection to the world session map. -# Default: 10000 - (10 milliseconds, 0.01 second) +# Network.OutKBuff +# Description: Amount of memory (in bytes) used for the output kernel buffer (see SO_SNDBUF +# socket option, TCP manual). +# Default: -1 - (Use system default setting) -SessionAddDelay = 10000 +Network.OutKBuff = -1 # -# MinWorldUpdateTime -# Description: Minimum time (milliseconds) between world update ticks (for mostly idle servers). -# Default: 1 - (0.001 second) +# Network.OutUBuff +# Description: Amount of memory (in bytes) reserved in the user space per connection for +# output buffering. +# Default: 65536 -MinWorldUpdateTime = 1 +Network.OutUBuff = 65536 # -# MapUpdateInterval -# Description: Time (milliseconds) for map update interval. -# Default: 10 - (0.01 second) +# Network.TcpNoDelay: +# Description: TCP Nagle algorithm setting. +# Default: 0 - (Enabled, Less traffic, More latency) +# 1 - (Disabled, More traffic, Less latency, TCP_NO_DELAY) -MapUpdateInterval = 10 +Network.TcpNodelay = 1 # -# ChangeWeatherInterval -# Description: Time (in milliseconds) for weather update interval. -# Default: 600000 - (10 min) +################################################################################################### -ChangeWeatherInterval = 600000 +################################################################################################### +# REMOTE ACCESS +# +# Ra.Enable +# Description: Enable remote console (telnet). +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Ra.Enable = 0 # -# PlayerSaveInterval -# Description: Time (in milliseconds) for player save interval. -# Default: 900000 - (15 min) +# Ra.IP +# Description: Bind remote access to IP/hostname. +# Default: "0.0.0.0" - (Bind to all IPs on the system) -PlayerSaveInterval = 900000 +Ra.IP = "0.0.0.0" # -# PlayerSave.Stats.MinLevel -# Description: Minimum level for saving character stats in the database for external usage. -# Default: 0 - (Disabled, Do not save character stats) -# 1+ - (Enabled, Level beyond which character stats are saved) +# Ra.Port +# Description: TCP port to reach the remote console. +# Default: 3443 -PlayerSave.Stats.MinLevel = 0 +Ra.Port = 3443 # -# PlayerSave.Stats.SaveOnlyOnLogout -# Description: Save player stats only on logout. -# Default: 1 - (Enabled, Only save on logout) -# 0 - (Disabled, Save on every player save) +# Ra.MinLevel +# Description: Required security level to use the remote console. +# Default: 3 -PlayerSave.Stats.SaveOnlyOnLogout = 1 +Ra.MinLevel = 3 # -# vmap.enableLOS -# vmap.enableHeight -# Description: VMmap support for line of sight and height calculation. -# Default: 1 - (Enabled, vmap.enableLOS) -# 1 - (Enabled, vmap.enableHeight) -# 0 - (Disabled) +# SOAP.Enable +# Description: Enable soap service +# Default: 0 - (Disabled) +# 1 - (Enabled) -vmap.enableLOS = 1 -vmap.enableHeight = 1 +SOAP.Enabled = 0 # -# vmap.petLOS -# Description: Check line of sight for pets, to avoid them attacking through walls. -# Default: 1 - (Enabled, each pet attack will be checked for line of sight) -# 0 - (Disabled, somewhat less CPU usage) +# SOAP.IP +# Description: Bind SOAP service to IP/hostname +# Default: "127.0.0.1" - (Bind to localhost) -vmap.petLOS = 1 +SOAP.IP = "127.0.0.1" -# vmap.BlizzlikePvPLOS -# Description: Check line of sight for battleground and arena gameobjects and other doodads (such as WSG treestumps). -# Default: 1 - (Enabled, players will be able to fire spells through treestumps and other objects). -# 0 - (Disabled, players will NOT be able to fire spells through treestumps and other objects). +# +# SOAP.Port +# Description: TCP port to reach the SOAP service. +# Default: 7878 -vmap.BlizzlikePvPLOS = 1 +SOAP.Port = 7878 # -# vmap.enableIndoorCheck -# Description: VMap based indoor check to remove outdoor-only auras (mounts etc.). -# Default: 1 - (Enabled) -# 0 - (Disabled, somewhat less CPU usage) +################################################################################################### -vmap.enableIndoorCheck = 1 +################################################################################################### +# CRYPTOGRAPHY +# +# TOTPMasterSecret +# Description: The key used by authserver to decrypt TOTP secrets from database storage. +# You only need to set this here if you plan to use the in-game 2FA +# management commands (.account 2fa), otherwise this can be left blank. +# +# The server will auto-detect if this does not match your authserver setting, +# in which case any commands reliant on the secret will be disabled. +# +# Default: +# + +TOTPMasterSecret = # -# DetectPosCollision -# Description: Check final move position, summon position, etc for visible collision with -# other objects or walls (walls only if vmaps are enabled). -# Default: 1 - (Enabled) -# 0 - (Disabled, Less position precision but less CPU usage) +################################################################################################### -DetectPosCollision = 1 +################################################################################################### +# PERFORMANCE +# +# ThreadPool +# Description: Number of threads to be used for the global thread pool +# The thread pool is currently used for: +# - Signal handling +# - Remote access +# - Database keep-alive ping +# - Core freeze check +# - World socket networking +# Default: 2 + +ThreadPool = 2 # -# CheckGameObjectLoS -# Description: Include dynamic game objects (doors, chests etc.) in line of sight checks. -# This increases CPU usage somewhat. -# Default: 1 - (Enabled) -# 0 - (Disabled, may break some boss encounters) +# UseProcessors +# Description: Processors mask for Windows and Linux based multi-processor systems. +# Example: For a computer with 3 CPUs: +# 1 - 1st CPU only +# 2 - 2nd CPU only +# 4 - 3rd CPU only +# 6 - 2nd + 3rd CPUs, because "2 | 4" -> 6 +# Default: 0 - (Selected by OS) +# 1+ - (Bit mask value of selected processors) -CheckGameObjectLoS = 1 +UseProcessors = 0 # -# TargetPosRecalculateRange -# Description: Max distance from movement target point (+moving unit size) and targeted -# object (+size) after that new target movement point calculated. -# Range: 0.5-5.0 -# Default: 1.5 -# 0.5 - (Minimum, Contact Range, More sensitive reaction to target movement) -# 5.0 - (Maximum, Melee attack range, Less CPU usage) +# ProcessPriority +# Description: Process priority setting for Windows based systems. +# Default: 1 - (High) +# 0 - (Normal) -TargetPosRecalculateRange = 1.5 +ProcessPriority = 1 # -# UpdateUptimeInterval -# Description: Update realm uptime period (in minutes). -# Default: 10 - (10 minutes) -# 1+ +# Compression +# Description: Compression level for client update packages +# Range: 1-9 +# Default: 1 - (Speed) +# 9 - (Best compression) -UpdateUptimeInterval = 1 +Compression = 1 + +# +################################################################################################### + +################################################################################################### +# LOGGING +# +# PacketLogFile +# Description: Binary packet logging file for the world server. +# Filename extension must be .pkt to be parsable with WowPacketParser. +# Example: "World.pkt" - (Enabled) +# Default: "" - (Disabled) + +PacketLogFile = "" # # LogDB.Opt.ClearInterval @@ -472,1881 +533,1784 @@ LogDB.Opt.ClearInterval = 10 LogDB.Opt.ClearTime = 1209600 # -# MaxCoreStuckTime -# Description: Time (in seconds) before the server is forced to crash if it is frozen. -# FreezeDetector -# Default: 0 - (Disabled) -# 10+ - (Enabled, Recommended 30+) -# Note: If enabled and the setting is too low, it can cause unexpected crash. +# RecordUpdateTimeDiffInterval +# Description: Time (in milliseconds) update time diff is written to the log file. +# Update diff can be used as a performance indicator. Diff < 300: good +# performance. Diff > 600 bad performance, may be caused by high CPU usage. +# Default: 300000 - (Enabled, 5 minutes) +# 0 - (Disabled) -MaxCoreStuckTime = 0 +RecordUpdateTimeDiffInterval = 300000 # -# AddonChannel -# Description: Configure the use of the addon channel through the server (some client side -# addons will not work correctly with disabled addon channel) -# Default: 1 - (Enabled) -# 0 - (Disabled) +# MinRecordUpdateTimeDiff +# Description: Only record update time diff which is greater than this value. +# Default: 100 -AddonChannel = 1 +MinRecordUpdateTimeDiff = 100 # -# MapUpdate.Threads -# Description: Number of threads to update maps. -# Default: 1 - -MapUpdate.Threads = 1 - +# IPLocationFile +# Description: The path to your IP2Location database CSV file. +# Example: "C:/acore/IP2LOCATION-LITE-DB1.CSV" +# "/home/acore/IP2LOCATION-LITE-DB1.CSV" +# Default: "" - (Disabled) # -# CleanCharacterDB -# Description: Clean out deprecated achievements, skills, spells and talents from the db. -# Default: 0 - (Disabled) -# 1 - (Enable) -CleanCharacterDB = 0 +IPLocationFile = "" # -# PersistentCharacterCleanFlags -# Description: Determines the character clean flags that remain set after cleanups. -# This is a bitmask value, you can use one of the following values: -# -# CLEANING_FLAG_ACHIEVEMENT_PROGRESS = 0x1 -# CLEANING_FLAG_SKILLS = 0x2 -# CLEANING_FLAG_SPELLS = 0x4 -# CLEANING_FLAG_TALENTS = 0x8 -# CLEANING_FLAG_QUESTSTATUS = 0x10 -# -# Before use this feature, make a backup of your database. +# AllowLoggingIPAddressesInDatabase +# Description: Specifies if IP addresses can be logged to the database +# Default: 1 - (Enabled) +# 0 - (Disabled) # -# Example: 14 - (CLEANING_FLAG_SKILLS + CLEANING_FLAG_SPELLS + CLEANING_FLAG_TALENTS -# 2+4+8 => 14. This will clean up skills, talents and spells will -# remain enabled after the next cleanup) -# Default: 0 - (All cleanup methods will be disabled after the next cleanup) -PersistentCharacterCleanFlags = 0 +AllowLoggingIPAddressesInDatabase = 1 # -# PreloadAllNonInstancedMapGrids -# Description: Preload all grids on all non-instanced maps. This will take a great amount -# of additional RAM (ca. 9 GB) and causes the server to take longer to start, -# but can increase performance if used on a server with a high amount of players. -# It will also activate all creatures which are set active (e.g. the Fel Reavers -# in Hellfire Peninsula) on server start. +# Allow.IP.Based.Action.Logging +# Description: Logs actions, e.g. account login and logout to name a few, based on IP of current session. # Default: 0 - (Disabled) # 1 - (Enabled) +# -PreloadAllNonInstancedMapGrids = 0 +Allow.IP.Based.Action.Logging = 0 # -# SetAllCreaturesWithWaypointMovementActive -# Description: Set all creatures with waypoint movement active. This means that they will start -# movement once they are loaded (which happens on grid load) and keep moving even -# when no player is near. This will increase CPU usage significantly and can be -# used with enabled "PreloadAllNonInstancedMapGrids" to start waypoint movement on -# server startup. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -SetAllCreaturesWithWaypointMovementActive = 0 - -# -################################################################################################### - -################################################################################################### -# SERVER LOGGING -# -# PidFile -# Description: World daemon PID file. -# Example: "./world.pid" - (Enabled) -# Default: "" - (Disabled) - -PidFile = "" - +# Appender config values: Given an appender "name" +# Appender.name +# Description: Defines 'where to log'. +# Format: Type,LogLevel,Flags,optional1,optional2,optional3 # -# PacketLogFile -# Description: Binary packet logging file for the world server. -# Filename extension must be .pkt to be parsable with WowPacketParser. -# Example: "World.pkt" - (Enabled) -# Default: "" - (Disabled) - -PacketLogFile = "" - -# Extended Logging system configuration moved to end of file (on purpose) +# Type +# 0 - (None) +# 1 - (Console) +# 2 - (File) +# 3 - (DB) # -################################################################################################### - -################################################################################################### -# SERVER SETTINGS +# LogLevel +# 0 - (Disabled) +# 1 - (Fatal) +# 2 - (Error) +# 3 - (Warning) +# 4 - (Info) +# 5 - (Debug) +# 6 - (Trace) # -# GameType -# Description: Server realm type. -# Default: 0 - (NORMAL) -# 1 - (PVP) -# 4 - (NORMAL) -# 6 - (RP) -# 8 - (RPPVP) -# 16 - (FFA_PVP, Free for all PvP mode like arena PvP in all zones except rest -# activated places and sanctuaries) - -GameType = 0 - +# Flags: +# 0 - None +# 1 - Prefix Timestamp to the text +# 2 - Prefix Log Level to the text +# 4 - Prefix Log Filter type to the text +# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS +# (Only used with Type = 2) +# 16 - Make a backup of existing file before overwrite +# (Only used with Mode = w) # -# RealmZone -# Description: Server realm zone. Set allowed alphabet in character, etc. names. -# Default 1 - (Development - any language) -# 2 - (United States - extended-Latin) -# 3 - (Oceanic - extended-Latin) -# 4 - (Latin America - extended-Latin) -# 5 - (Tournament - basic-Latin at create, any at login) -# 6 - (Korea - East-Asian) -# 7 - (Tournament - basic-Latin at create, any at login) -# 8 - (English - extended-Latin) -# 9 - (German - extended-Latin) -# 10 - (French - extended-Latin) -# 11 - (Spanish - extended-Latin) -# 12 - (Russian - Cyrillic) -# 13 - (Tournament - basic-Latin at create, any at login) -# 14 - (Taiwan - East-Asian) -# 15 - (Tournament - basic-Latin at create, any at login) -# 16 - (China - East-Asian) -# 17 - (CN1 - basic-Latin at create, any at login) -# 18 - (CN2 - basic-Latin at create, any at login) -# 19 - (CN3 - basic-Latin at create, any at login) -# 20 - (CN4 - basic-Latin at create, any at login) -# 21 - (CN5 - basic-Latin at create, any at login) -# 22 - (CN6 - basic-Latin at create, any at login) -# 23 - (CN7 - basic-Latin at create, any at login) -# 24 - (CN8 - basic-Latin at create, any at login) -# 25 - (Tournament - basic-Latin at create, any at login) -# 26 - (Test Server - any language) -# 27 - (Tournament - basic-Latin at create, any at login) -# 28 - (QA Server - any language) -# 29 - (CN9 - basic-Latin at create, any at login) - -RealmZone = 1 - +# Colors (read as optional1 if Type = Console) +# Format: "fatal error warn info debug trace" +# 0 - BLACK +# 1 - RED +# 2 - GREEN +# 3 - BROWN +# 4 - BLUE +# 5 - MAGENTA +# 6 - CYAN +# 7 - GREY +# 8 - YELLOW +# 9 - LRED +# 10 - LGREEN +# 11 - LBLUE +# 12 - LMAGENTA +# 13 - LCYAN +# 14 - WHITE +# Example: "1 9 3 6 5 8" # -# World.RealmAvailability -# Description: If enabled, players will enter the realm normally. -# Character creation will still be possible even when realm is disabled. -# Default: 1 - (Enabled) -# 0 - (Disabled) - -World.RealmAvailability = 1 - +# File: Name of the file (read as optional1 if Type = File) +# Allows to use one "%s" to create dynamic files # -# StrictNames.Reserved -# Description: Use the Reserved Filter from DBC. -# Prevents Player, Pet & Charter names from containing reserved names. -# Default: 1 - Enabled -# 0 - Disabled - -StrictNames.Reserved = 1 - +# Mode: Mode to open the file (read as optional2 if Type = File) +# a - (Append) +# w - (Overwrite) # -# StrictNames.Profanity -# Description: Use the Profanity Filter from DBC. -# Prevents Player, Pet & Charter names from containing profanity. -# Default: 1 - Enabled -# 0 - Disabled - -StrictNames.Profanity = 1 - +# MaxFileSize: Maximum file size of the log file before creating a new log file +# (read as optional3 if Type = File) +# Size is measured in bytes expressed in a 64-bit unsigned integer. +# Maximum value is 4294967295 (4 GB). Leave blank for no limit. +# NOTE: Does not work with dynamic filenames. +# Example: 536870912 (512 MB) # -# StrictPlayerNames -# Description: Limit player name to language specific symbol set. Prevents character -# creation and forces rename request if not allowed symbols are used -# Default: 0 - (Disable, Limited server timezone dependent client check) -# 1 - (Enabled, Strictly basic Latin characters) -# 2 - (Enabled, Strictly realm zone specific, See RealmZone setting, -# Note: Client needs to have the appropriate fonts installed which support -# the charset. For non-official localization, custom fonts need to be -# placed in clientdir/Fonts. -# 3 - (Enabled, Basic Latin characters + server timezone specific) -StrictPlayerNames = 0 +Appender.Console=1,4,0,"1 9 3 6 5 8" +Appender.Server=2,5,0,Server.log,w +# Appender.GM=2,5,15,gm_%s.log +Appender.Errors=2,5,0,Errors.log +# Appender.DB=3,5,0 +# Logger config values: Given a logger "name" +# Logger.name +# Description: Defines 'What to log' +# Format: LogLevel,AppenderList # -# StrictCharterNames -# Description: Limit guild/arena team charter names to language specific symbol set. -# Prevents charter creation if not allowed symbols are used. -# Default: 0 - (Disable, Limited server timezone dependent client check) -# 1 - (Enabled, Strictly basic Latin characters) -# 2 - (Enabled, Strictly realm zone specific, See RealmZone setting, -# Note: Client needs to have the appropriate fonts installed which support -# the charset. For non-official localization, custom fonts need to be -# placed in clientdir/Fonts. -# 3 - (Enabled, Basic Latin characters + server timezone specific) - -StrictCharterNames = 0 - +# LogLevel +# 0 - (Disabled) +# 1 - (Fatal) +# 2 - (Error) +# 3 - (Warning) +# 4 - (Info) +# 5 - (Debug) +# 6 - (Trace) # -# StrictPetNames -# Description: Limit pet names to language specific symbol set. -# Prevents pet naming if not allowed symbols are used. -# Default: 0 - (Disable, Limited server timezone dependent client check) -# 1 - (Enabled, Strictly basic Latin characters) -# 2 - (Enabled, Strictly realm zone specific, See RealmZone setting, -# Note: Client needs to have the appropriate fonts installed which support -# the charset. For non-official localization, custom fonts need to be -# placed in clientdir/Fonts. -# 3 - (Enabled, Basic Latin characters + server timezone specific) - -StrictPetNames = 0 - +# AppenderList: List of appenders linked to logger +# (Using spaces as separator). # -# DBC.Locale -# Description: DBC language settings. -# Default: 255 - (Auto Detect) -# 0 - (English) -# 1 - (Korean) -# 2 - (French) -# 3 - (German) -# 4 - (Chinese) -# 5 - (Taiwanese) -# 6 - (Spanish) -# 7 - (Spanish Mexico) -# 8 - (Russian) -DBC.Locale = 255 +Logger.root=2,Console Server +Logger.commands.gm=4,Console GM +Logger.diff=3,Console Server +Logger.mmaps=4,Server +Logger.scripts.hotswap=4,Console Server +Logger.server=4,Console Server +Logger.sql.sql=2,Console Errors +Logger.sql=4,Console Server +Logger.time.update=4,Console Server +Logger.module=4,Console Server +Logger.spells.scripts=2,Console Errors +#Logger.achievement=4,Console Server +#Logger.addon=4,Console Server +#Logger.ahbot=4,Console Server +#Logger.auctionHouse=4,Console Server +#Logger.autobroadcast=4, Console Server +#Logger.bg.arena=4,Console Server +#Logger.bg.battlefield=4,Console Server +#Logger.bg.battleground=4,Console Server +#Logger.bg.reportpvpafk=4,Console Server +#Logger.calendar=4,Console Server +#Logger.chat.log=4,Console Server +#Logger.chat.log.addon=4,Console Server +#Logger.chat.system=4,Console Server +#Logger.cheat=4,Console Server +#Logger.commands.ra=4,Console Server +#Logger.condition=4,Console Server +#Logger.dbc=4,Console Server +#Logger.disable=4,Console Server +#Logger.entities.dyobject=4,Console Server +#Logger.entities.faction=4,Console Server +#Logger.entities.gameobject=4,Console Server +#Logger.entities.object=4,Console Server +#Logger.entities.pet=4,Console Server +#Logger.entities.player.character=4,Console Server +#Logger.entities.player.dump=4,Console Server +#Logger.entities.player.items=4,Console Server +#Logger.entities.player.loading=4,Console Server +#Logger.entities.player.skills=4,Console Server +#Logger.entities.player=4,Console Server +#Logger.entities.transport=4,Console Server +#Logger.entities.unit.ai=4,Console Server +#Logger.entities.unit=4,Console Server +#Logger.entities.vehicle=4,Console Server +#Logger.gameevent=4,Console Server +#Logger.group=4,Console Server +#Logger.guild=4,Console Server +#Logger.instance.save=4,Console Server +#Logger.instance.script=4,Console Server +#Logger.lfg=4,Console Server +#Logger.loot=4,Console Server +#Logger.mail=4,Console Server +#Logger.maps.script=4,Console Server +#Logger.maps=4,Console Server +#Logger.misc=4,Console Server +#Logger.mmaps.tiles=4,Console Server +#Logger.movement.flightpath=4,Console Server +#Logger.movement.motionmaster=4,Console Server +#Logger.movement.splinechain=4,Console Server +#Logger.movement=4,Console Server +#Logger.network.kick=4,Console Server +#Logger.network.opcode=4,Console Server +#Logger.network.soap=4,Console Server +#Logger.network=4,Console Server +#Logger.outdoorpvp=4,Console Server +#Logger.pool=4,Console Server +#Logger.rbac=4,Console Server +#Logger.reputation=4,Console Server +#Logger.scripts.ai.escortai=4,Console Server +#Logger.scripts.ai.followerai=4,Console Server +#Logger.scripts.ai.petai=4,Console Server +#Logger.scripts.ai.sai=4,Console Server +#Logger.scripts.ai=4,Console Server +#Logger.scripts.cos=4,Console Server +#Logger.scripts=4,Console Server +#Logger.server.authserver=4,Console Server +#Logger.spells.aura.effect.nospell=4,Console Server +#Logger.spells.aura.effect=4,Console Server +#Logger.spells.effect.nospell=4,Console Server +#Logger.spells.effect=4,Console Server +#Logger.spells.scripts=4,Console Server +#Logger.spells=4,Console Server +#Logger.sql.dev=4,Console Server +#Logger.sql.driver=4,Console Server +#Logger.vehicles=4,Console Server +#Logger.warden=4,Console Server +#Logger.weather=4,Console Server # -# DeclinedNames -# Description: Allow Russian clients to set and use declined names. -# Default: 0 - (Disabled, Except when the Russian RealmZone is set) +# Log.Async.Enable +# Description: Enables asynchronous message logging. +# Default: 0 - (Disabled) # 1 - (Enabled) -DeclinedNames = 0 - -# -# Expansion -# Description: Allow server to use content from expansions. Checks for expansion-related -# map files, client compatibility and class/race character creation. -# Default: 2 - (Expansion 2) -# 1 - (Expansion 1) -# 0 - (Disabled, Ignore and disable expansion content (maps, races, classes) - -Expansion = 2 +Log.Async.Enable = 0 # -# MinPlayerName -# Description: Minimal player name length. -# Range: 1-12 -# Default: 2 - -MinPlayerName = 2 +################################################################################################### +################################################################################################### +# METRIC # -# MinCharterName -# Description: Minimal charter name length. -# Range: 1-24 -# Default: 2 - -MinCharterName = 2 - +# These settings control the statistics sent to the metric database (currently InfluxDB) # -# MinPetName -# Description: Minimal pet name length. -# Range: 1-12 -# Default: 2 - -MinPetName = 2 - +# Metric.Enable +# Description: Enables statistics sent to the metric database. +# Default: 0 - (Disabled) +# 1 - (Enabled) # -# Guild.CharterCost -# ArenaTeam.CharterCost.2v2 -# ArenaTeam.CharterCost.3v3 -# ArenaTeam.CharterCost.5v5 -# Description: Amount of money (in Copper) the petitions costs. -# Default: 1000 - (10 Silver) -# 800000 - (80 Gold) -# 1200000 - (120 Gold) -# 2000000 - (200 Gold) -Guild.CharterCost = 1000 -ArenaTeam.CharterCost.2v2 = 800000 -ArenaTeam.CharterCost.3v3 = 1200000 -ArenaTeam.CharterCost.5v5 = 2000000 +Metric.Enable = 0 # -# MaxWhoListReturns -# Description: Set the max number of players returned in the /who list and interface. -# Default: 49 - (stable) +# Metric.Interval +# Description: Interval between every batch of data sent in seconds +# Default: 10 seconds +# -MaxWhoListReturns = 49 +Metric.Interval = 10 # -# CharacterCreating.Disabled -# Description: Disable character creation for players based on faction. -# Default: 0 - (Enabled, All factions are allowed) -# 1 - (Disabled, Alliance) -# 2 - (Disabled, Horde) -# 3 - (Disabled, Both factions) +# Metric.ConnectionInfo +# Description: Connection settings for metric database (currently InfluxDB). +# Example: "hostname;port;database" +# Default: "127.0.0.1;8086;worldserver" +# -CharacterCreating.Disabled = 0 +Metric.ConnectionInfo = "127.0.0.1;8086;worldserver" # -# CharacterCreating.Disabled.RaceMask -# Description: Mask of races which cannot be created by players. -# Example: 1536 - (1024 + 512, Blood Elf and Draenei races are disabled) -# Default: 0 - (Enabled, All races are allowed) -# 1 - (Disabled, Human) -# 2 - (Disabled, Orc) -# 4 - (Disabled, Dwarf) -# 8 - (Disabled, Night Elf) -# 16 - (Disabled, Undead) -# 32 - (Disabled, Tauren) -# 64 - (Disabled, Gnome) -# 128 - (Disabled, Troll) -# 512 - (Disabled, Blood Elf) -# 1024 - (Disabled, Draenei) +# Metric.OverallStatusInterval +# Description: Interval between every gathering of overall worldserver status data in seconds +# Default: 1 second +# -CharacterCreating.Disabled.RaceMask = 0 +Metric.OverallStatusInterval = 1 # -# CharacterCreating.Disabled.ClassMask -# Description: Mask of classes which cannot be created by players. -# Example: 288 - (32 + 256, Death Knight and Warlock classes are disabled) -# Default: 0 - (Enabled, All classes are allowed) -# 1 - (Disabled, Warrior) -# 2 - (Disabled, Paladin) -# 4 - (Disabled, Hunter) -# 8 - (Disabled, Rogue) -# 16 - (Disabled, Priest) -# 32 - (Disabled, Death Knight) -# 64 - (Disabled, Shaman) -# 128 - (Disabled, Mage) -# 256 - (Disabled, Warlock) -# 1024 - (Disabled, Druid) +# Metric threshold values: Given a metric "name" +# Metric.Threshold.name +# Description: Skips sending statistics with a value lower than the config value. +# If the threshold is commented out, the metric will be ignored. +# Only metrics logged with METRIC_DETAILED_TIMER in the sources are affected. +# Disabled by default. Requires WITH_DETAILED_METRICS CMake flag. +# +# Format: Value as integer +# -CharacterCreating.Disabled.ClassMask = 0 +#Metric.Threshold.world_update_sessions_time = 100 +#Metric.Threshold.worldsession_update_opcode_time = 50 # -# CharactersPerAccount -# Description: Limit number of characters per account on all realms on this realmlist. -# Important: Number must be >= CharactersPerRealm -# Default: 50 +################################################################################################### -CharactersPerAccount = 50 +################################################################################################### +# SERVER # -# CharactersPerRealm -# Description: Limit number of characters per account on this realm. -# Range: 1-10 -# Default: 10 - (Client limitation) +# BirthdayTime +# Description: Set to date of project's birth in UNIX time. By default Thu Oct 2, 2008 +# Default: 1222964635 -CharactersPerRealm = 10 +BirthdayTime = 1222964635 # -# HeroicCharactersPerRealm -# Description: Limit number of heroic class characters per account on this realm. -# Range: 1-10 -# Default: 1 +# PlayerLimit +# Description: Maximum number of players in the world. Excluding Mods, GMs and Admins. +# Important: If you want to block players and only allow Mods, GMs or Admins to join the +# server, use the DB field "auth.realmlist.allowedSecurityLevel". +# Default: 1000 - (Enabled) +# 1+ - (Enabled) +# 0 - (Disabled, No limit) -HeroicCharactersPerRealm = 1 +PlayerLimit = 1000 # -# CharacterCreating.MinLevelForHeroicCharacter -# Description: Limit creating heroic characters only for account with another -# character of specific level (ignored for GM accounts) -# Default: 55 - (Enabled, Requires at least another level 55 character) -# 0 - (Disabled) -# 1 - (Enabled, Requires at least another level 1 character) +# World.RealmAvailability +# Description: If enabled, players will enter the realm normally. +# Character creation will still be possible even when realm is disabled. +# Default: 1 - (Enabled) +# 0 - (Disabled) -CharacterCreating.MinLevelForHeroicCharacter = 55 +World.RealmAvailability = 1 # -# SkipCinematics -# Description: Disable cinematic intro at first login after character creation. -# Prevents buggy intros in case of custom start location coordinates. -# Default: 0 - (Show intro for each new character) -# 1 - (Show intro only for first character of selected race) -# 2 - (Disable intro for all classes) +# GameType +# Description: Server realm type. +# Default: 0 - (NORMAL) +# 1 - (PVP) +# 4 - (NORMAL) +# 6 - (RP) +# 8 - (RPPVP) +# 16 - (FFA_PVP, Free for all PvP mode like arena PvP in all zones except rest +# activated places and sanctuaries) -SkipCinematics = 0 +GameType = 0 # -# MaxPlayerLevel -# Description: Maximum level that can be reached by players. -# Important: Levels beyond 100 are not recommended at all. -# Range: 1-255 -# Default: 80 +# RealmZone +# Description: Server realm zone. Set allowed alphabet in character, etc. names. +# Default 1 - (Development - any language) +# 2 - (United States - extended-Latin) +# 3 - (Oceanic - extended-Latin) +# 4 - (Latin America - extended-Latin) +# 5 - (Tournament - basic-Latin at create, any at login) +# 6 - (Korea - East-Asian) +# 7 - (Tournament - basic-Latin at create, any at login) +# 8 - (English - extended-Latin) +# 9 - (German - extended-Latin) +# 10 - (French - extended-Latin) +# 11 - (Spanish - extended-Latin) +# 12 - (Russian - Cyrillic) +# 13 - (Tournament - basic-Latin at create, any at login) +# 14 - (Taiwan - East-Asian) +# 15 - (Tournament - basic-Latin at create, any at login) +# 16 - (China - East-Asian) +# 17 - (CN1 - basic-Latin at create, any at login) +# 18 - (CN2 - basic-Latin at create, any at login) +# 19 - (CN3 - basic-Latin at create, any at login) +# 20 - (CN4 - basic-Latin at create, any at login) +# 21 - (CN5 - basic-Latin at create, any at login) +# 22 - (CN6 - basic-Latin at create, any at login) +# 23 - (CN7 - basic-Latin at create, any at login) +# 24 - (CN8 - basic-Latin at create, any at login) +# 25 - (Tournament - basic-Latin at create, any at login) +# 26 - (Test Server - any language) +# 27 - (Tournament - basic-Latin at create, any at login) +# 28 - (QA Server - any language) +# 29 - (CN9 - basic-Latin at create, any at login) -MaxPlayerLevel = 80 +RealmZone = 1 # -# MinDualSpecLevel -# Description: Level requirement for Dual Talent Specialization -# Default: 40 +# DBC.Locale +# Description: DBC language settings. +# Default: 255 - (Auto Detect) +# 0 - (English) +# 1 - (Korean) +# 2 - (French) +# 3 - (German) +# 4 - (Chinese) +# 5 - (Taiwanese) +# 6 - (Spanish) +# 7 - (Spanish Mexico) +# 8 - (Russian) -MinDualSpecLevel = 40 +DBC.Locale = 255 # -# StartPlayerLevel -# Description: Starting level for characters after creation. -# Range: 1-MaxPlayerLevel -# Default: 1 +# Expansion +# Description: Allow server to use content from expansions. Checks for expansion-related +# map files, client compatibility and class/race character creation. +# Default: 2 - (Expansion 2) +# 1 - (Expansion 1) +# 0 - (Disabled, Ignore and disable expansion content (maps, races, classes) -StartPlayerLevel = 1 +Expansion = 2 # -# StartHeroicPlayerLevel -# Description: Staring level for heroic class characters after creation. -# Range: 1-MaxPlayerLevel -# Default: 55 +# ClientCacheVersion +# Description: Client cache version for client cache data reset. Use any value different +# from DB and not recently been used to trigger client side cache reset. +# Default: 0 - (Use DB value from world DB db_version.cache_id field) -StartHeroicPlayerLevel = 55 +ClientCacheVersion = 0 # -# StartPlayerMoney -# Description: Amount of money (in Copper) that a character has after creation. -# Default: 0 -# 100 - (1 Silver) +# SessionAddDelay +# Description: Time (in microseconds) that a network thread will sleep after authentication +# protocol handling before adding a connection to the world session map. +# Default: 10000 - (10 milliseconds, 0.01 second) -StartPlayerMoney = 0 +SessionAddDelay = 10000 # -# StartHeroicPlayerMoney -# Description: Amount of money (in Copper) that heroic class characters have after creation. -# Default: 2000 -# 2000 - (20 Silver) +# GridCleanUpDelay +# Description: Time (in milliseconds) grid clean up delay. +# Default: 300000 - (5 minutes) -StartHeroicPlayerMoney = 2000 +GridCleanUpDelay = 300000 # -# MaxHonorPoints -# Description: Maximum honor points a character can have. -# Default: 75000 +# CloseIdleConnections +# Description: Automatically close idle connections. +# SocketTimeOutTime and SocketTimeOutTimeActive determine when a connection is considered as idle. +# Default: 1 - (enable, Automatically close idle connections) +# 0 - (disable, Do not close idle connections) -MaxHonorPoints = 75000 +CloseIdleConnections = 1 # -# MaxHonorPointsMoneyPerPoint -# Description: Convert excess honor points into money if players got more points than allowed after changing the honor cap. -# Honor points will be converted into copper according to the value set in this config. -# Default: 0 - Disabled +# SocketTimeOutTime +# Description: Time (in milliseconds) after which a connection being idle on the character +# selection screen is disconnected. +# Default: 900000 - (15 minutes) -MaxHonorPointsMoneyPerPoint = 0 +SocketTimeOutTime = 900000 # -# StartHonorPoints -# Description: Amount of honor points that characters have after creation. -# Default: 0 +# SocketTimeOutTimeActive +# Description: Time (in milliseconds) after which an idle connection is dropped while +# logged into the world. +# The client sends keepalive packets every 30 seconds. Values <= 30s are not recommended. +# Default: 60000 - (1 minute) -StartHonorPoints = 0 +SocketTimeOutTimeActive = 60000 # -# MaxArenaPoints -# Description: Maximum arena points a character can have. -# Default: 10000 +# MaxOverspeedPings +# Description: Maximum overspeed ping count before character is disconnected. +# Default: 2 - (Enabled, Minimum value) +# 3+ - (Enabled, More checks before kick) +# 0 - (Disabled) -MaxArenaPoints = 10000 +MaxOverspeedPings = 2 # -# StartArenaPoints -# Description: Amount of arena points that characters has after creation. +# DisconnectToleranceInterval +# Description: Allows to skip queue after being disconnected for a given number of seconds. # Default: 0 -StartArenaPoints = 0 +DisconnectToleranceInterval = 0 # -# Arena.LegacyArenaPoints -# Description: Use arena point calculation from TBC for season 1 - 5 when rating is less or equal to 1500 -# Default: 1 - (Enabled) -# 0 - (Disabled) +# EnableLoginAfterDC +# Description: After not logging out properly (clicking Logout and waiting 20 seconds), +# characters stay in game world for a full minute, even if the client connection was closed. +# Such behaviour prevents for example exploiting boss encounters by alt+f4 +# and skipping crucial boss abilities, or escaping opponents in PvP. +# This setting is used to allow/disallow players to log back into characters that are left in world. +# Default: 1 - (by clicking "Enter World" player will log back into a character that is already in world) +# 0 - (by clicking "Enter World" player will get an error message when trying to log into a character +# that is left in world, and has to wait a minute for the character to be removed from world) -Arena.LegacyArenaPoints = 0 +EnableLoginAfterDC = 1 # -# RecruitAFriend.MaxLevel -# Description: Highest level up to which a character can benefit from the Recruit-A-Friend -# experience multiplier. -# Default: 60 +# MinWorldUpdateTime +# Description: Minimum time (milliseconds) between world update ticks (for mostly idle servers). +# Default: 1 - (0.001 second) -RecruitAFriend.MaxLevel = 60 +MinWorldUpdateTime = 1 # -# RecruitAFriend.MaxDifference -# Description: Highest level difference between linked Recruiter and Friend benefit from -# the Recruit-A-Friend experience multiplier. -# Default: 4 +# UpdateUptimeInterval +# Description: Update realm uptime period (in minutes). +# Default: 10 - (10 minutes) +# 1+ -RecruitAFriend.MaxDifference = 4 +UpdateUptimeInterval = 1 # -# InstantLogout -# Description: Required security level for instantly logging out everywhere. -# Does not work while in combat, dueling or falling. -# Default: 1 - (Enabled, Mods/GMs/Admins) -# 0 - (Enabled, Everyone) -# 2 - (Enabled, GMs/Admins) -# 3 - (Enabled, Admins) -# 4 - (Disabled) +# MaxCoreStuckTime +# Description: Time (in seconds) before the server is forced to crash if it is frozen. +# FreezeDetector +# Default: 0 - (Disabled) +# 10+ - (Enabled, Recommended 30+) +# Note: If enabled and the setting is too low, it can cause unexpected crash. -InstantLogout = 1 +MaxCoreStuckTime = 0 # -# PreventAFKLogout -# Description: Prevent players AFK from being logged out -# Default: 0 - (Disabled) -# 1 - (Enabled, prevent players AFK from being logged out in Sanctuary zones) -# 2 - (Enabled, prevent players AFK from being logged out in all zones) +# SaveRespawnTimeImmediately +# Description: Save respawn time for creatures at death and gameobjects at use/open. +# Default: 1 - (Enabled, Save respawn time immediately) +# 0 - (Disabled, Save respawn time at grid unloading) -PreventAFKLogout = 0 +SaveRespawnTimeImmediately = 1 # -# DisableWaterBreath -# Description: Required security level for water breathing. -# Default: 4 - (Disabled) -# 0 - (Enabled, Everyone) -# 1 - (Enabled, Mods/GMs/Admins) -# 2 - (Enabled, GMs/Admins) -# 3 - (Enabled, Admins) +# Server.LoginInfo +# Description: Display core version (.server info) on login. +# Default: 0 - (Disabled) +# 1 - (Enabled) -DisableWaterBreath = 4 +Server.LoginInfo = 0 # -# AllFlightPaths -# Description: Character knows all flight paths (of both factions) after creation. +# ShowKickInWorld +# Description: Determines whether a message is broadcast to the entire server when a +# player gets kicked # Default: 0 - (Disabled) # 1 - (Enabled) -AllFlightPaths = 0 +ShowKickInWorld = 0 # -# InstantFlightPaths -# Description: Flight paths will take players to their destination instantly instead -# of making them wait while flying. +# ShowMuteInWorld +# Description: Determines whether a message is broadcast to the entire server when a +# player gets muted. # Default: 0 - (Disabled) # 1 - (Enabled) -# 2 - (Enabled, but the player can toggle instant flight off or on at each flight master) -InstantFlightPaths = 0 +ShowMuteInWorld = 0 # -# AlwaysMaxSkillForLevel -# Description: Players will automatically gain max skill level when logging in or leveling -# up. +# ShowBanInWorld +# Description: Determines whether a message is broadcast to the entire server when a +# player gets banned. # Default: 0 - (Disabled) # 1 - (Enabled) -AlwaysMaxSkillForLevel = 0 +ShowBanInWorld = 0 # -# ActivateWeather -# Description: Activate the weather system. -# Default: 1 - (Enabled) -# 0 - (Disabled) +# MaxWhoListReturns +# Description: Set the max number of players returned in the /who list and interface. +# Default: 49 - (stable) -ActivateWeather = 1 +MaxWhoListReturns = 49 # -# CastUnstuck -# Description: Allow casting the Unstuck spell using .start or unstuck button in client -# help options. -# Default: 1 - (Enabled) -# 0 - (Disabled) +# PreventAFKLogout +# Description: Prevent players AFK from being logged out +# Default: 0 - (Disabled) +# 1 - (Enabled, prevent players AFK from being logged out in Sanctuary zones) +# 2 - (Enabled, prevent players AFK from being logged out in all zones) -CastUnstuck = 1 +PreventAFKLogout = 0 # -# Instance.IgnoreLevel -# Description: Ignore level requirement when entering instances. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -Instance.IgnoreLevel = 0 +################################################################################################### +################################################################################################### +# PACKET SPOOF PROTECTION SETTINGS # -# Instance.IgnoreRaid -# Description: Ignore raid group requirement when entering instances. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -Instance.IgnoreRaid = 0 - +# These settings determine which action to take when harmful packet spoofing is detected. # -# Instance.GMSummonPlayer -# Description: Allow GM to summon players or only other GM accounts inside instances. -# Default: 0 - (Disabled, Only GM accounts can be summoned by GM) -# 1 - (Enabled, GM and Player accounts can be summoned by GM) +# PacketSpoof.Policy +# Description: Determines the course of action when packet spoofing is detected. +# Values: 0 - Log only +# 1 - Log + kick +# 2 - Log + kick + ban -Instance.GMSummonPlayer = 0 +PacketSpoof.Policy = 1 # -# Instance.ResetTimeHour -# Description: Hour of the day when the global instance reset occurs. -# Range: 0-23 -# Default: 4 - (04:00 AM) +# PacketSpoof.BanMode +# Description: If PacketSpoof.Policy equals 2, this will determine the ban mode. +# Values: 0 - Ban Account +# 1 - Ban IP +# Note: Banning by character not supported for logical reasons. +# -Instance.ResetTimeHour = 4 +PacketSpoof.BanMode = 0 # -# Instance.UnloadDelay -# Description: Time (in milliseconds) before instance maps are unloaded from memory if no -# characters are inside. -# Default: 1800000 - (Enabled, 30 minutes) -# 0 - (Disabled, Instance maps are kept in memory until the instance -# resets) +# PacketSpoof.BanDuration +# Description: Duration of the ban in seconds. Only valid if PacketSpoof.Policy is set to 2. +# Set to 0 for permanent ban. +# Default: 86400 seconds (1 day) +# -Instance.UnloadDelay = 1800000 +PacketSpoof.BanDuration = 86400 # -# Quests.EnableQuestTracker -# Description: Store data in the database about quest completion and abandonment to help finding bugged quests. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -Quests.EnableQuestTracker = 0 +################################################################################################### +################################################################################################### +# WARDEN SETTINGS # -# Quests.LowLevelHideDiff -# Description: Level difference between player and quest level at which quests are -# considered low-level and are not shown via exclamation mark (!) at quest -# givers. -# Default: 4 - (Enabled, Hide quests that have 4 levels less than the character) -# -1 - (Disabled, Show all available quest marks) +# Warden.Enabled +# Description: Enable Warden anti-cheat system. +# Default: 1 - (Enabled) +# 0 - (Disabled) -Quests.LowLevelHideDiff = 4 +Warden.Enabled = 1 # -# Quests.HighLevelHideDiff -# Description: Level difference between player and quest level at which quests are -# considered high-level and are not shown via exclamation mark (!) at quest -# givers. -# Default: 7 - (Enabled, Hide quests that have 7 levels more than the character) -# -1 - (Disabled, Show all available quest marks) +# Warden.NumMemChecks +# Description: Number of Warden memory checks that are sent to the client each cycle. +# Default: 3 - (Enabled) +# 0 - (Disabled) -Quests.HighLevelHideDiff = 7 +Warden.NumMemChecks = 3 # -# Quests.IgnoreRaid -# Description: Allow non-raid quests to be completed while in a raid group. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Warden.NumLuaChecks +# Description: Number of Warden LUA checks that are sent to the client each cycle. +# Default: 1 - (Enabled) +# 0 - (Disabled) -Quests.IgnoreRaid = 0 +Warden.NumLuaChecks = 1 # -# Quests.IgnoreAutoAccept -# Description: Ignore auto accept flag. Clients will have to manually accept all quests. -# Default: 0 - (Disabled, DB values determine if quest is marked auto accept or not.) -# 1 - (Enabled, clients will not be told to automatically accept any quest.) +# Warden.NumOtherChecks +# Description: Number of Warden checks other than memory checks that are added to request +# each checking cycle. +# Default: 7 - (Enabled) +# 0 - (Disabled) -Quests.IgnoreAutoAccept = 0 +Warden.NumOtherChecks = 7 # -# Quests.IgnoreAutoComplete -# Description: Ignore auto complete flag. Clients will have to manually complete all quests. -# Default: 0 - (Disabled, DB values determine if quest is marked auto complete or not.) -# 1 - (Enabled, clients will not be told to automatically complete any quest.) +# Warden.ClientResponseDelay +# Description: Time (in seconds) before client is getting disconnecting for not responding. +# Default: 600 - (10 Minutes) +# 0 - (Disabled, client won't be kicked) -Quests.IgnoreAutoComplete = 0 +Warden.ClientResponseDelay = 600 # -# Calendar.DeleteOldEventsHour -# Description: Hour of the day when the daily deletion of old calendar events occurs. -# Range: 0-23 -# Default: 6 - (06:00 AM) +# Warden.ClientCheckHoldOff +# Description: Time (in seconds) to wait before sending the next check request to the client. +# A low number increases traffic and load on client and server side. +# Default: 30 - (30 Seconds) +# 0 - (Send check as soon as possible) -Calendar.DeleteOldEventsHour = 6 +Warden.ClientCheckHoldOff = 30 # -# Guild.EventLogRecordsCount -# Description: Number of log entries for guild events that are stored per guild. Old entries -# will be overwritten if the number of log entries exceed the configured value. -# High numbers prevent this behavior but may have performance impacts. -# Default: 100 +# Warden.ClientCheckFailAction +# Description: Default action being taken if a client check failed. Actions can be +# overwritten for each single check via warden_action table in characters +# database. +# Default: 0 - (Disabled, Logging only) +# 1 - (Kick) +# 2 - (Ban) -Guild.EventLogRecordsCount = 100 +Warden.ClientCheckFailAction = 0 # -# Guild.ResetHour -# Description: Hour of the day when the daily cap resets occur. -# Range: 0-23 -# Default: 6 - (06:00 AM) +# Warden.BanDuration +# Description: Time (in seconds) an account will be banned if ClientCheckFailAction is set +# to ban. +# Default: 86400 - (24 hours) +# 0 - (Permanent ban) -Guild.ResetHour = 6 +Warden.BanDuration = 259200 # -# Guild.BankEventLogRecordsCount -# Description: Number of log entries for guild bank events that are stored per guild. Old -# entries will be overwritten if the number of log entries exceed the -# configured value. High numbers prevent this behavior but may have performance -# impacts. -# Default: 25 - (Minimum) - -Guild.BankEventLogRecordsCount = 25 +################################################################################################### +################################################################################################### +# AUTO BROADCAST # -# MaxPrimaryTradeSkill -# Description: Maximum number of primary professions a character can learn. -# Range: 0-11 -# Default: 2 +# AutoBroadcast.On +# Description: Enable auto broadcast. +# Default: 0 - (Disabled) +# 1 - (Enabled) -MaxPrimaryTradeSkill = 2 +AutoBroadcast.On = 0 # -# MinPetitionSigns -# Description: Number of required signatures on charters to create a guild. -# Range: 0-9 -# Default: 9 +# AutoBroadcast.Center +# Description: Auto broadcasting display method. +# Default: 0 - (Announce) +# 1 - (Notify) +# 2 - (Both) -MinPetitionSigns = 9 +AutoBroadcast.Center = 0 # -# MaxGroupXPDistance -# Description: Max distance to creature for group member to get experience at creature -# death. -# Default: 74 +# AutoBroadcast.Timer +# Description: Timer (in milliseconds) for auto broadcasts. +# Default: 60000 - (60 seconds) -MaxGroupXPDistance = 74 +AutoBroadcast.Timer = 60000 # -# MaxRecruitAFriendBonusDistance -# Description: Max distance between character and and group to gain the Recruit-A-Friend -# XP multiplier. -# Default: 100 +# AutoBroadcast.MinDisableLevel +# Description: Minimum level required to disable autobroadcast announcements if EnablePlayerSettings option is enabled. +# Default: 0 - (Not allowed to disable it) -MaxRecruitAFriendBonusDistance = 100 +AutoBroadcast.MinDisableLevel = 0 # -# MailDeliveryDelay -# Description: Time (in seconds) mail delivery is delayed when sending items. -# Default: 3600 - (1 hour) - -MailDeliveryDelay = 3600 +################################################################################################### +################################################################################################### +# VISIBILITY AND DISTANCES # -# SkillChance.Prospecting -# Description: Allow skill increase from prospecting. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Visibility.GroupMode +# Description: Group visibility modes. Defines which groups can aways detect invisible +# characters of the same raid, group or faction. +# Default: 1 - (Raid) +# 0 - (Party) +# 2 - (Faction) -SkillChance.Prospecting = 0 +Visibility.GroupMode = 1 # -# SkillChance.Milling -# Description: Allow skill increase from milling. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Visibility.Distance.Continents +# Visibility.Distance.Instances +# Visibility.Distance.BGArenas +# Description: Visibility distance to see other players or gameobjects. +# Visibility on continents on retail ~100 yards. In BG/Arenas ~533. +# For instances default ~170. +# Max limited by grid size: 533.33333 +# Min limit is max aggro radius (45) * Rate.Creature.Aggro +# Default: 100 - (Visibility.Distance.Continents) +# 170 - (Visibility.Distance.Instances) +# 533 - (Visibility.Distance.BGArenas) -SkillChance.Milling = 0 +Visibility.Distance.Continents = 100 +Visibility.Distance.Instances = 170 +Visibility.Distance.BGArenas = 533 # -# OffhandCheckAtSpellUnlearn -# Description: Unlearning certain spells can change offhand weapon restrictions -# for equip slots. -# Default: 1 - (Recheck offhand slot weapon at unlearning a spell) -# 0 - (Recheck offhand slot weapon only at zone update) +# 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) -OffhandCheckAtSpellUnlearn = 1 +Visibility.Notify.Period.OnContinents = 1000 +Visibility.Notify.Period.InInstances = 1000 +Visibility.Notify.Period.InBGArenas = 1000 # -# ClientCacheVersion -# Description: Client cache version for client cache data reset. Use any value different -# from DB and not recently been used to trigger client side cache reset. -# Default: 0 - (Use DB value from world DB db_version.cache_id field) +# Visibility.ObjectSparkles +# Description: Whether or not to display sparkles on gameobjects related to active quests. +# Default: 1 - (Show Sparkles) +# 0 - (Hide Sparkles) -ClientCacheVersion = 0 +Visibility.ObjectSparkles = 1 # -# Event.Announce -# Description: Announce events. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Visibility.ObjectQuestMarkers +# Description: Show quest icons above game objects in the same way as creature quest givers. +# Default: 1 - (Show quest markers, post patch 2.3 behavior) +# 0 - (Hide quest markers, pre patch 2.3 behavior) -Event.Announce = 0 +Visibility.ObjectQuestMarkers = 1 # -# BeepAtStart -# Description: Beep when the world server finished starting (Unix/Linux systems). -# Default: 1 - (Enabled) -# 0 - (Disabled) +################################################################################################### -BeepAtStart = 1 +################################################################################################### +# MAPS +# +# MapUpdateInterval +# Description: Time (milliseconds) for map update interval. +# Default: 10 - (0.01 second) + +MapUpdateInterval = 10 # -# FlashAtStart -# Description: Flashes in taskbar when the world server finished starting. (Works on Windows only) -# Default: 1 - (Enabled) -# 0 - (Disabled) +# MapUpdate.Threads +# Description: Number of threads to update maps. +# Default: 1 -FlashAtStart = 1 +MapUpdate.Threads = 1 # -# Server.LoginInfo -# Description: Display core version (.server info) on login. +# MoveMaps.Enable +# Description: Enable/Disable pathfinding using mmaps - recommended. # Default: 0 - (Disabled) # 1 - (Enabled) -Server.LoginInfo = 0 +MoveMaps.Enable = 1 # -# Command.LookupMaxResults -# Description: Number of results being displayed using a .lookup command. -# Default: 0 - (Unlimited) +# vmap.enableLOS +# vmap.enableHeight +# Description: VMmap support for line of sight and height calculation. +# Default: 1 - (Enabled, vmap.enableLOS) +# 1 - (Enabled, vmap.enableHeight) +# 0 - (Disabled) -Command.LookupMaxResults = 0 +vmap.enableLOS = 1 +vmap.enableHeight = 1 # -# AllowTickets -# Description: Allow/disallow sending new tickets. -# Default: 1 - (Enabled) -# 0 - (Disabled) +# vmap.petLOS +# Description: Check line of sight for pets, to avoid them attacking through walls. +# Default: 1 - (Enabled, each pet attack will be checked for line of sight) +# 0 - (Disabled, somewhat less CPU usage) -AllowTickets = 1 +vmap.petLOS = 1 -# DeletedCharacterTicketTrace -# Description: Keep trace of tickets opened by deleted characters -# gm_ticket.playerGuid will be 0, old GUID and character name -# will be included in gm_ticket.comment -# Default: 0 - (Disabled) -# 1 - (Enabled) +# vmap.BlizzlikePvPLOS +# Description: Check line of sight for battleground and arena gameobjects and other doodads (such as WSG treestumps). +# Default: 1 - (Enabled, players will be able to fire spells through treestumps and other objects). +# 0 - (Disabled, players will NOT be able to fire spells through treestumps and other objects). -DeletedCharacterTicketTrace = 0 +vmap.BlizzlikePvPLOS = 1 # -# DBC.EnforceItemAttributes -# Disallow overriding item attributes stored in DBC files with values from the database -# Default: 0 - Off, Use DB values -# 1 - On, Enforce DBC Values (default) +# vmap.enableIndoorCheck +# Description: VMap based indoor check to remove outdoor-only auras (mounts etc.). +# Default: 1 - (Enabled) +# 0 - (Disabled, somewhat less CPU usage) -DBC.EnforceItemAttributes = 1 +vmap.enableIndoorCheck = 1 # -# AccountInstancesPerHour -# Description: Controls the max amount of different instances player can enter within hour -# Default: 5 +# DetectPosCollision +# Description: Check final move position, summon position, etc for visible collision with +# other objects or walls (walls only if vmaps are enabled). +# Default: 1 - (Enabled) +# 0 - (Disabled, Less position precision but less CPU usage) -AccountInstancesPerHour = 5 +DetectPosCollision = 1 # -# BirthdayTime -# Description: Set to date of project's birth in UNIX time. By default Thu Oct 2, 2008 -# Default: 1222964635 -# +# CheckGameObjectLoS +# Description: Include dynamic game objects (doors, chests etc.) in line of sight checks. +# This increases CPU usage somewhat. +# Default: 1 - (Enabled) +# 0 - (Disabled, may break some boss encounters) + +CheckGameObjectLoS = 1 + # +# TargetPosRecalculateRange +# Description: Max distance from movement target point (+moving unit size) and targeted +# object (+size) after that new target movement point calculated. +# Range: 0.5-5.0 +# Default: 1.5 +# 0.5 - (Minimum, Contact Range, More sensitive reaction to target movement) +# 5.0 - (Maximum, Melee attack range, Less CPU usage) -BirthdayTime = 1222964635 +TargetPosRecalculateRange = 1.5 # -# IsContinentTransport.Enabled -# Description: Controls the continent transport (ships, zeppelins etc..) -# Default: 1 - (Enabled) -# -# +# PreloadAllNonInstancedMapGrids +# Description: Preload all grids on all non-instanced maps. This will take a great amount +# of additional RAM (ca. 9 GB) and causes the server to take longer to start, +# but can increase performance if used on a server with a high amount of players. +# It will also activate all creatures which are set active (e.g. the Fel Reavers +# in Hellfire Peninsula) on server start. +# Default: 0 - (Disabled) +# 1 - (Enabled) -IsContinentTransport.Enabled = 1 +PreloadAllNonInstancedMapGrids = 0 # -# IsPreloadedContinentTransport.Enabled -# Description: Should we preload the transport? -# (Not recommended on low-end servers as it consumes 100% more ram) -# and it's not really necessary to be enabled. -# +# SetAllCreaturesWithWaypointMovementActive +# Description: Set all creatures with waypoint movement active. This means that they will start +# movement once they are loaded (which happens on grid load) and keep moving even +# when no player is near. This will increase CPU usage significantly and can be +# used with enabled "PreloadAllNonInstancedMapGrids" to start waypoint movement on +# server startup. # Default: 0 - (Disabled) +# 1 - (Enabled) + +SetAllCreaturesWithWaypointMovementActive = 0 + # -# +# DontCacheRandomMovementPaths +# Description: Random movement paths (calculated using MoveMaps) can be cached to save cpu time, +# but this may use up considerable amount of memory and can be prevented by setting this option to 1. +# Recommended setting for populated servers is having enough RAM and setting this to 0. +# Default: 0 - (cache paths, uses more memory) +# 1 - (don't cache, uses more cpu) -IsPreloadedContinentTransport.Enabled = 0 +DontCacheRandomMovementPaths = 0 # ################################################################################################### ################################################################################################### -# CRYPTOGRAPHY -# -# TOTPMasterSecret -# Description: The key used by authserver to decrypt TOTP secrets from database storage. -# You only need to set this here if you plan to use the in-game 2FA -# management commands (.account 2fa), otherwise this can be left blank. -# -# The server will auto-detect if this does not match your authserver setting, -# in which case any commands reliant on the secret will be disabled. +# WEATHER # -# Default: +# ActivateWeather +# Description: Activate the weather system. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +ActivateWeather = 1 + # +# ChangeWeatherInterval +# Description: Time (in milliseconds) for weather update interval. +# Default: 600000 - (10 min) -TOTPMasterSecret = +ChangeWeatherInterval = 600000 # ################################################################################################### ################################################################################################### -# UPDATE SETTINGS -# -# Updates.EnableDatabases -# Description: A mask that describes which databases shall be updated. -# -# Following flags are available -# DATABASE_LOGIN = 1, // Auth database -# DATABASE_CHARACTER = 2, // Character database -# DATABASE_WORLD = 4, // World database -# -# Default: 7 - (All enabled) -# 4 - (Enable world only) -# 0 - (All disabled) - -Updates.EnableDatabases = 7 - +# TICKETS # -# Updates.AutoSetup -# Description: Auto populate empty databases. +# AllowTickets +# Description: Allow/disallow sending new tickets. # Default: 1 - (Enabled) # 0 - (Disabled) -Updates.AutoSetup = 1 +AllowTickets = 1 # -# Updates.Redundancy -# Description: Perform data redundancy checks through hashing -# to detect changes on sql updates and reapply it. -# Default: 1 - (Enabled) -# 0 - (Disabled) +# LevelReq.Ticket +# Description: Level requirement for characters to be able to write tickets. +# Default: 1 -Updates.Redundancy = 1 +LevelReq.Ticket = 1 -# -# Updates.ArchivedRedundancy -# Description: Check hashes of archived updates (slows down startup). +# DeletedCharacterTicketTrace +# Description: Keep trace of tickets opened by deleted characters +# gm_ticket.playerGuid will be 0, old GUID and character name +# will be included in gm_ticket.comment # Default: 0 - (Disabled) # 1 - (Enabled) -Updates.ArchivedRedundancy = 0 +DeletedCharacterTicketTrace = 0 # -# Updates.AllowRehash -# Description: Inserts the current file hash in the database if it is left empty. -# Useful if you want to mark a file as applied but you don't know its hash. -# Default: 1 - (Enabled) -# 0 - (Disabled) - -Updates.AllowRehash = 1 +################################################################################################### +################################################################################################### +# COMMAND # -# Updates.CleanDeadRefMaxCount -# Description: Cleans dead/ orphaned references that occur if an update was removed or renamed and edited in one step. -# It only starts the clean up if the count of the missing updates is below or equal the Updates.CleanDeadRefMaxCount value. -# This way prevents erasing of the update history due to wrong source directory state (maybe wrong branch or bad revision). -# Disable this if you want to know if the database is in a possible "dirty state". -# Default: 3 - (Enabled) +# AllowPlayerCommands +# Description: Allow players to use commands. +# Default: 1 - (Enabled) # 0 - (Disabled) -# -1 - (Enabled - unlimited) -Updates.CleanDeadRefMaxCount = 3 +AllowPlayerCommands = 1 # -################################################################################################### +# Command.LookupMaxResults +# Description: Number of results being displayed using a .lookup command. +# Default: 0 - (Unlimited) + +Command.LookupMaxResults = 0 -################################################################################################### -# WARDEN SETTINGS # -# Warden.Enabled -# Description: Enable Warden anti-cheat system. +# Die.Command.Mode +# Description: Do not trigger things like loot from .die command. # Default: 1 - (Enabled) # 0 - (Disabled) -Warden.Enabled = 1 +Die.Command.Mode = 1 # -# Warden.NumMemChecks -# Description: Number of Warden memory checks that are sent to the client each cycle. -# Default: 3 - (Enabled) -# 0 - (Disabled) +################################################################################################### -Warden.NumMemChecks = 3 +################################################################################################### +# # +# SERVER SYSTEM SETTINGS END # +# # +################################################################################################### +################################################################################################### +# # +# GAME SETTINGS BEGIN # +# # +################################################################################################### + +################################################################################################### +# GAME MASTER # -# Warden.NumLuaChecks -# Description: Number of Warden LUA checks that are sent to the client each cycle. -# Default: 1 - (Enabled) -# 0 - (Disabled) +# GM.LoginState +# Description: GM mode at login. +# Default: 2 - (Last save state) +# 0 - (Disable) +# 1 - (Enable) -Warden.NumLuaChecks = 1 +GM.LoginState = 2 # -# Warden.NumOtherChecks -# Description: Number of Warden checks other than memory checks that are added to request -# each checking cycle. -# Default: 7 - (Enabled) -# 0 - (Disabled) +# GM.Visible +# Description: GM visibility at login. +# Default: 2 - (Last save state) +# 0 - (Invisible) +# 1 - (Visible) -Warden.NumOtherChecks = 7 +GM.Visible = 2 # -# Warden.ClientResponseDelay -# Description: Time (in seconds) before client is getting disconnecting for not responding. -# Default: 600 - (10 Minutes) -# 0 - (Disabled, client won't be kicked) +# GM.Chat +# Description: GM chat mode at login. +# Default: 2 - (Last save state) +# 0 - (Disable) +# 1 - (Enable) -Warden.ClientResponseDelay = 600 +GM.Chat = 2 # -# Warden.ClientCheckHoldOff -# Description: Time (in seconds) to wait before sending the next check request to the client. -# A low number increases traffic and load on client and server side. -# Default: 30 - (30 Seconds) -# 0 - (Send check as soon as possible) +# GM.WhisperingTo +# Description: Is GM accepting whispers from player by default or not. +# Default: 2 - (Last save state) +# 0 - (Disable) +# 1 - (Enable) -Warden.ClientCheckHoldOff = 30 +GM.WhisperingTo = 2 # -# Warden.ClientCheckFailAction -# Description: Default action being taken if a client check failed. Actions can be -# overwritten for each single check via warden_action table in characters -# database. -# Default: 0 - (Disabled, Logging only) -# 1 - (Kick) -# 2 - (Ban) +# GM.InGMList.Level +# Description: Maximum GM level shown in GM list (if enabled) in non-GM state (.gm off). +# Default: 3 - (Anyone) +# 0 - (Only players) +# 1 - (Only moderators) +# 2 - (Only gamemasters) -Warden.ClientCheckFailAction = 0 +GM.InGMList.Level = 3 # -# Warden.BanDuration -# Description: Time (in seconds) an account will be banned if ClientCheckFailAction is set -# to ban. -# Default: 86400 - (24 hours) -# 0 - (Permanent ban) +# GM.InWhoList.Level +# Description: Max GM level showed in who list (if visible). +# Default: 3 - (Anyone) +# 0 - (Only players) +# 1 - (Only moderators) +# 2 - (Only gamemasters) -Warden.BanDuration = 259200 +GM.InWhoList.Level = 3 # -################################################################################################### +# GM.StartLevel +# Description: GM character starting level. +# Default: 1 + +GM.StartLevel = 1 -################################################################################################### -# PLAYER INTERACTION # -# AllowTwoSide.Accounts -# Description: Allow creating characters of both factions on the same account. -# Default: 1 - (Enabled) -# 0 - (Disabled) +# GM.AllowInvite +# Description: Allow players to invite GM characters. +# Default: 0 - (Disabled) +# 1 - (Enabled) -AllowTwoSide.Accounts = 1 +GM.AllowInvite = 0 # -# AllowTwoSide.Interaction.Calendar -# Description: Allow calendar invites between factions. +# GM.AllowFriend +# Description: Allow players to add GM characters to their friends list. # Default: 0 - (Disabled) # 1 - (Enabled) -AllowTwoSide.Interaction.Calendar = 0 +GM.AllowFriend = 0 # -# AllowTwoSide.Interaction.Chat -# Description: Allow say chat between factions. +# GM.LowerSecurity +# Description: Allow lower security levels to use commands on higher security level +# characters. # Default: 0 - (Disabled) # 1 - (Enabled) -AllowTwoSide.Interaction.Chat = 0 +GM.LowerSecurity = 0 + +# +# GM.TicketSystem.ChanceOfGMSurvey +# Description: Chance of sending a GM survey after ticket completion. +# Default: 50 - (Enabled) +# 0 - (Disabled) + +GM.TicketSystem.ChanceOfGMSurvey = 50 # -# AllowTwoSide.Interaction.Emote -# Description: Allow emote messages between factions (e.g. "/e looks into the sky") -# Default: 0 - (Disabled) -# 1 - (Enabled) - -AllowTwoSide.Interaction.Emote = 0 +################################################################################################### +################################################################################################### +# CHEAT # -# AllowTwoSide.Interaction.Channel -# Description: Allow channel chat between factions. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# DisableWaterBreath +# Description: Required security level for water breathing. +# Default: 4 - (Disabled) +# 0 - (Enabled, Everyone) +# 1 - (Enabled, Mods/GMs/Admins) +# 2 - (Enabled, GMs/Admins) +# 3 - (Enabled, Admins) -AllowTwoSide.Interaction.Channel = 0 +DisableWaterBreath = 4 # -# AllowTwoSide.Interaction.Group -# Description: Allow group joining between factions. +# AllFlightPaths +# Description: Character knows all flight paths (of both factions) after creation. # Default: 0 - (Disabled) # 1 - (Enabled) -AllowTwoSide.Interaction.Group = 0 +AllFlightPaths = 0 # -# AllowTwoSide.Interaction.Guild -# Description: Allow guild joining between factions. +# InstantFlightPaths +# Description: Flight paths will take players to their destination instantly instead +# of making them wait while flying. # Default: 0 - (Disabled) # 1 - (Enabled) +# 2 - (Enabled, but the player can toggle instant flight off or on at each flight master) -AllowTwoSide.Interaction.Guild = 0 +InstantFlightPaths = 0 # -# AllowTwoSide.Interaction.Arena -# Description: Allow joining arena teams between factions. +# AlwaysMaxSkillForLevel +# Description: Players will automatically gain max skill level when logging in or leveling +# up. # Default: 0 - (Disabled) # 1 - (Enabled) -AllowTwoSide.Interaction.Arena = 0 +AlwaysMaxSkillForLevel = 0 # -# AllowTwoSide.Interaction.Auction -# Description: Allow auctions between factions. +# AlwaysMaxWeaponSkill +# Description: Players will automatically gain max weapon/defense skill when logging in, +# or leveling. # Default: 0 - (Disabled) # 1 - (Enabled) -AllowTwoSide.Interaction.Auction = 0 +AlwaysMaxWeaponSkill = 0 # -# AllowTwoSide.Interaction.Mail -# Description: Allow sending mails between factions. +# PlayerStart.AllReputation +# Description: Players will start with most of the high level reputations that are needed +# for items, mounts etc. # Default: 0 - (Disabled) # 1 - (Enabled) -AllowTwoSide.Interaction.Mail = 0 +PlayerStart.AllReputation = 0 # -# AllowTwoSide.WhoList -# Description: Show characters from both factions in the /who list. +# PlayerStart.CustomSpells +# Description: If enabled, players will start with custom spells defined in +# playercreateinfo_spell_custom table. # Default: 0 - (Disabled) # 1 - (Enabled) -AllowTwoSide.WhoList = 0 +PlayerStart.CustomSpells = 0 # -# AllowTwoSide.AddFriend -# Description: Allow adding friends from other faction the friends list. +# PlayerStart.MapsExplored +# Description: Characters start with all maps explored. # Default: 0 - (Disabled) # 1 - (Enabled) -AllowTwoSide.AddFriend = 0 +PlayerStart.MapsExplored = 0 # -# AllowTwoSide.Trade -# Description: Allow trading between factions. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# InstantLogout +# Description: Required security level for instantly logging out everywhere. +# Does not work while in combat, dueling or falling. +# Default: 1 - (Enabled, Mods/GMs/Admins) +# 0 - (Enabled, Everyone) +# 2 - (Enabled, GMs/Admins) +# 3 - (Enabled, Admins) +# 4 - (Disabled) -AllowTwoSide.Trade = 0 +InstantLogout = 1 # -# TalentsInspecting -# Description: Allow inspecting characters from the opposing faction. -# Doesn't affect characters in gamemaster mode. +# CastUnstuck +# Description: Allow casting the Unstuck spell using .start or unstuck button in client +# help options. # Default: 1 - (Enabled) # 0 - (Disabled) -TalentsInspecting = 1 +CastUnstuck = 1 # ################################################################################################### ################################################################################################### -# CREATURE SETTINGS -# -# ThreatRadius -# Description: Distance for creatures to evade after being pulled away from the combat -# starting point. If ThreatRadius is less than creature aggro radius then aggro -# radius will be used. -# Default: 60 - -ThreatRadius = 60 - -# -# Rate.Creature.Aggro -# Description: Aggro radius percentage. -# Default: 1 - (Enabled, 100%) -# 1.5 - (Enabled, 150%) -# 0 - (Disabled, 0%) - -Rate.Creature.Aggro = 1 - -# -# CreatureFamilyFleeAssistanceRadius -# Description: Distance for fleeing creatures seeking assistance from other creatures. -# Default: 30 - (Enabled) -# 0 - (Disabled) - -CreatureFamilyFleeAssistanceRadius = 30 - -# -# CreatureFamilyAssistanceRadius -# Description: Distance for creatures calling for assistance from other creatures without -# moving. -# Default: 10 - (Enabled) -# 0 - (Disabled) - -CreatureFamilyAssistanceRadius = 10 - +# CHARACTER DATABASE # -# CreatureFamilyAssistanceDelay -# Description: Time (in milliseconds) before creature assistance call. -# Default: 2000 - (2 Seconds) +# PlayerSaveInterval +# Description: Time (in milliseconds) for player save interval. +# Default: 900000 - (15 min) -CreatureFamilyAssistanceDelay = 2000 +PlayerSaveInterval = 900000 # -# CreatureFamilyAssistancePeriod -# Description: Time (in milliseconds) before next creature assistance call. -# Default: 3000 - (3 Seconds) -# 0 - (Disabled) +# PlayerSave.Stats.MinLevel +# Description: Minimum level for saving character stats in the database for external usage. +# Default: 0 - (Disabled, Do not save character stats) +# 1+ - (Enabled, Level beyond which character stats are saved) -CreatureFamilyAssistancePeriod = 3000 +PlayerSave.Stats.MinLevel = 0 # -# CreatureFamilyFleeDelay -# Description: Time (in milliseconds) during which creature can flee if no assistance was -# found. -# Default: 7000 (7 Seconds) +# PlayerSave.Stats.SaveOnlyOnLogout +# Description: Save player stats only on logout. +# Default: 1 - (Enabled, Only save on logout) +# 0 - (Disabled, Save on every player save) -CreatureFamilyFleeDelay = 7000 +PlayerSave.Stats.SaveOnlyOnLogout = 1 # -# WorldBossLevelDiff -# Description: World boss level difference. -# Default: 3 +# CleanCharacterDB +# Description: Clean out deprecated achievements, skills, spells and talents from the db. +# Default: 0 - (Disabled) +# 1 - (Enable) -WorldBossLevelDiff = 3 +CleanCharacterDB = 0 # -# Corpse.Decay.NORMAL -# Corpse.Decay.RARE -# Corpse.Decay.ELITE -# Corpse.Decay.RAREELITE -# Corpse.Decay.WORLDBOSS -# Description: Time (in seconds) until creature corpse will decay if not looted or skinned. -# Default: 60 - (1 Minute, Corpse.Decay.NORMAL) -# 300 - (5 Minutes, Corpse.Decay.RARE) -# 300 - (5 Minutes, Corpse.Decay.ELITE) -# 300 - (5 Minutes, Corpse.Decay.RAREELITE) -# 3600 - (1 Hour, Corpse.Decay.WORLDBOSS) - -Corpse.Decay.NORMAL = 60 -Corpse.Decay.RARE = 300 -Corpse.Decay.ELITE = 300 -Corpse.Decay.RAREELITE = 300 -Corpse.Decay.WORLDBOSS = 3600 - +# PersistentCharacterCleanFlags +# Description: Determines the character clean flags that remain set after cleanups. +# This is a bitmask value, you can use one of the following values: # -# Rate.Corpse.Decay.Looted -# Description: Multiplier for Corpse.Decay.* to configure how long creature corpses stay -# after they have been looted. -# Default: 0.5 - -Rate.Corpse.Decay.Looted = 0.5 - +# CLEANING_FLAG_ACHIEVEMENT_PROGRESS = 0x1 +# CLEANING_FLAG_SKILLS = 0x2 +# CLEANING_FLAG_SPELLS = 0x4 +# CLEANING_FLAG_TALENTS = 0x8 +# CLEANING_FLAG_QUESTSTATUS = 0x10 # -# Rate.Creature.Normal.Damage -# Rate.Creature.Elite.Elite.Damage -# Rate.Creature.Elite.RARE.Damage -# Rate.Creature.Elite.RAREELITE.Damage -# Rate.Creature.Elite.WORLDBOSS.Damage -# Description: Multiplier for creature melee damage. -# Default: 1 - (Rate.Creature.Normal.Damage) -# 1 - (Rate.Creature.Elite.Elite.Damage) -# 1 - (Rate.Creature.Elite.RARE.Damage) -# 1 - (Rate.Creature.Elite.RAREELITE.Damage) -# 1 - (Rate.Creature.Elite.WORLDBOSS.Damage) +# Before use this feature, make a backup of your database. # +# Example: 14 - (CLEANING_FLAG_SKILLS + CLEANING_FLAG_SPELLS + CLEANING_FLAG_TALENTS +# 2+4+8 => 14. This will clean up skills, talents and spells will +# remain enabled after the next cleanup) +# Default: 0 - (All cleanup methods will be disabled after the next cleanup) -Rate.Creature.Normal.Damage = 1 -Rate.Creature.Elite.Elite.Damage = 1 -Rate.Creature.Elite.RARE.Damage = 1 -Rate.Creature.Elite.RAREELITE.Damage = 1 -Rate.Creature.Elite.WORLDBOSS.Damage = 1 +PersistentCharacterCleanFlags = 0 # -# Rate.Creature.Normal.SpellDamage -# Rate.Creature.Elite.Elite.SpellDamage -# Rate.Creature.Elite.RARE.SpellDamage -# Rate.Creature.Elite.RAREELITE.SpellDamage -# Rate.Creature.Elite.WORLDBOSS.SpellDamage -# Description: Multiplier for creature spell damage. -# Default: 1 - (Rate.Creature.Normal.SpellDamage) -# 1 - (Rate.Creature.Elite.Elite.SpellDamage) -# 1 - (Rate.Creature.Elite.RARE.SpellDamage) -# 1 - (Rate.Creature.Elite.RAREELITE.SpellDamage) -# 1 - (Rate.Creature.Elite.WORLDBOSS.SpellDamage) - -Rate.Creature.Normal.SpellDamage = 1 -Rate.Creature.Elite.Elite.SpellDamage = 1 -Rate.Creature.Elite.RARE.SpellDamage = 1 -Rate.Creature.Elite.RAREELITE.SpellDamage = 1 -Rate.Creature.Elite.WORLDBOSS.SpellDamage = 1 +################################################################################################### +################################################################################################### +# CHARACTER DELETE # -# Rate.Creature.Normal.HP -# Rate.Creature.Elite.Elite.HP -# Rate.Creature.Elite.RARE.HP -# Rate.Creature.Elite.RAREELITE.HP -# Rate.Creature.Elite.WORLDBOSS.HP -# Description: Multiplier for creature health. -# Default: 1 - (Rate.Creature.Normal.HP) -# 1 - (Rate.Creature.Elite.Elite.HP) -# 1 - (Rate.Creature.Elite.RARE.HP) -# 1 - (Rate.Creature.Elite.RAREELITE.HP) -# 1 - (Rate.Creature.Elite.WORLDBOSS.HP) +# CharDelete.Method +# Description: Character deletion behavior. +# Default: 0 - (Completely remove character from the database) +# 1 - (Unlink the character from account and free up the name, Appears as +# deleted ingame) -Rate.Creature.Normal.HP = 1 -Rate.Creature.Elite.Elite.HP = 1 -Rate.Creature.Elite.RARE.HP = 1 -Rate.Creature.Elite.RAREELITE.HP = 1 -Rate.Creature.Elite.WORLDBOSS.HP = 1 +CharDelete.Method = 0 # -# ListenRange.Say -# Description: Distance in which players can read say messages from creatures or -# gameobjects. -# Default: 40 +# CharDelete.MinLevel +# Description: Required level to use the unlinking method if enabled. +# Default: 0 - (Same method for every level) +# 1+ - (Only characters with the specified level will use the unlinking method) -ListenRange.Say = 40 +CharDelete.MinLevel = 0 # -# ListenRange.TextEmote -# Description: Distance in which players can read emotes from creatures or gameobjects. -# Default: 40 +# CharDelete.KeepDays +# Description: Time (in days) before unlinked characters will be removed from the database. +# Default: 30 - (Enabled) +# 0 - (Disabled, Don't delete any characters) -ListenRange.TextEmote = 40 +CharDelete.KeepDays = 30 # -# ListenRange.Yell -# Description: Distance in which players can read yell messages from creatures or -# gameobjects. -# Default: 300 - -ListenRange.Yell = 300 +################################################################################################### +################################################################################################### +# CHARACTER CREATION # -# Creature.MovingStopTimeForPlayer -# Description: Time (in milliseconds) during which creature will not move after -# interaction with player. -# Default: 180000 +# MinPlayerName +# Description: Minimal player name length. +# Range: 1-12 +# Default: 2 -Creature.MovingStopTimeForPlayer = 180000 +MinPlayerName = 2 -# WaypointMovementStopTimeForPlayer -# Description: Specifies the time (in seconds) that a creature with waypoint -# movement will wait after a player interacts with it. -# default: 120 +# +# MinPetName +# Description: Minimal pet name length. +# Range: 1-12 +# Default: 2 -WaypointMovementStopTimeForPlayer = 120 +MinPetName = 2 -# NpcEvadeIfTargetIsUnreachable -# Description: Specifies the time (in seconds) that a creature whom target -# is unreachable to end up in evade mode. -# Default: 5 +# +# DeclinedNames +# Description: Allow Russian clients to set and use declined names. +# Default: 0 - (Disabled, Except when the Russian RealmZone is set) +# 1 - (Enabled) -NpcEvadeIfTargetIsUnreachable = 5 +DeclinedNames = 0 -# NpcRegenHPIfTargetIsUnreachable -# Description: Regenerates HP for Creatures in Raids if they cannot reach the target. -# Keep disabled if you are experiencing mmaps/pathing issues. # -# Default: 1 - (Enabled) -# 0 - (Disabled) +# StrictNames.Reserved +# Description: Use the Reserved Filter from DBC. +# Prevents Player, Pet & Charter names from containing reserved names. +# Default: 1 - Enabled +# 0 - Disabled -NpcRegenHPIfTargetIsUnreachable = 1 +StrictNames.Reserved = 1 -# NpcRegenHPTimeIfTargetIsUnreachable -# Description: Specifies the time (in seconds) that a creature whom target -# is unreachable in raid to end up regenerate health. -# Default: 10 +# +# StrictNames.Profanity +# Description: Use the Profanity Filter from DBC. +# Prevents Player, Pet & Charter names from containing profanity. +# Default: 1 - Enabled +# 0 - Disabled -NpcRegenHPTimeIfTargetIsUnreachable = 10 +StrictNames.Profanity = 1 -# Creatures.CustomIDs -# Description: The list of custom creatures with gossip dialogues hardcoded in core, -# divided by "," without spaces. -# It is implied that you do not use for these NPC dialogs data from "gossip_menu" table. -# Server will skip these IDs during the definitions validation process. -# Example: Creatures.CustomIDs = "190010,55005,999991,25462,98888,601014" - Npcs for Transmog, Guild-zone, 1v1-arena, Skip Dk, -# Racial Trait Swap, NPC - All Mounts Modules -# Default: "" +# +# StrictPlayerNames +# Description: Limit player name to language specific symbol set. Prevents character +# creation and forces rename request if not allowed symbols are used +# Default: 0 - (Disable, Limited server timezone dependent client check) +# 1 - (Enabled, Strictly basic Latin characters) +# 2 - (Enabled, Strictly realm zone specific, See RealmZone setting, +# Note: Client needs to have the appropriate fonts installed which support +# the charset. For non-official localization, custom fonts need to be +# placed in clientdir/Fonts.) +# 3 - (Enabled, Basic Latin characters + server timezone specific) -Creatures.CustomIDs = "190010,55005,999991,25462,98888,601014,34567,34568" +StrictPlayerNames = 0 # -################################################################################################### +# StrictPetNames +# Description: Limit pet names to language specific symbol set. +# Prevents pet naming if not allowed symbols are used. +# Default: 0 - (Disable, Limited server timezone dependent client check) +# 1 - (Enabled, Strictly basic Latin characters) +# 2 - (Enabled, Strictly realm zone specific, See RealmZone setting, +# Note: Client needs to have the appropriate fonts installed which support +# the charset. For non-official localization, custom fonts need to be +# placed in clientdir/Fonts.) +# 3 - (Enabled, Basic Latin characters + server timezone specific) + +StrictPetNames = 0 -################################################################################################### -# CHAT SETTINGS -# -# ChatFakeMessagePreventing -# Description: Additional protection from creating fake chat messages using spaces. -# Collapses multiple subsequent whitespaces into a single whitespace. -# Not applied to the addon language, but may break old addons that use -# "normal" chat messages for sending data to other clients. -# Default: 1 - (Enabled, Blizzlike) -# 0 - (Disabled) # +# CharacterCreating.Disabled +# Description: Disable character creation for players based on faction. +# Default: 0 - (Enabled, All factions are allowed) +# 1 - (Disabled, Alliance) +# 2 - (Disabled, Horde) +# 3 - (Disabled, Both factions) -ChatFakeMessagePreventing = 1 +CharacterCreating.Disabled = 0 # -# ChatStrictLinkChecking.Severity -# Description: Check chat messages for in-game links to spells, items, quests, etc. -# -1 - (Only verify validity of link data, but permit use of custom colors) -# Default: 0 - (Only verify that link data and color are valid without checking text) -# 1 - (Additionally verifies that the link text matches the provided data) +# CharacterCreating.Disabled.RaceMask +# Description: Mask of races which cannot be created by players. +# Example: 1536 - (1024 + 512, Blood Elf and Draenei races are disabled) +# Default: 0 - (Enabled, All races are allowed) +# 1 - (Disabled, Human) +# 2 - (Disabled, Orc) +# 4 - (Disabled, Dwarf) +# 8 - (Disabled, Night Elf) +# 16 - (Disabled, Undead) +# 32 - (Disabled, Tauren) +# 64 - (Disabled, Gnome) +# 128 - (Disabled, Troll) +# 512 - (Disabled, Blood Elf) +# 1024 - (Disabled, Draenei) + +CharacterCreating.Disabled.RaceMask = 0 + # -# Note: If this is set to '1', you must additionally provide .dbc files for all -# client locales that are in use on your server. -# If any files are missing, messages with links from clients using those -# locales will likely be blocked by the server. +# CharacterCreating.Disabled.ClassMask +# Description: Mask of classes which cannot be created by players. +# Example: 288 - (32 + 256, Death Knight and Warlock classes are disabled) +# Default: 0 - (Enabled, All classes are allowed) +# 1 - (Disabled, Warrior) +# 2 - (Disabled, Paladin) +# 4 - (Disabled, Hunter) +# 8 - (Disabled, Rogue) +# 16 - (Disabled, Priest) +# 32 - (Disabled, Death Knight) +# 64 - (Disabled, Shaman) +# 128 - (Disabled, Mage) +# 256 - (Disabled, Warlock) +# 1024 - (Disabled, Druid) + +CharacterCreating.Disabled.ClassMask = 0 + # +# CharactersPerAccount +# Description: Limit number of characters per account on all realms on this realmlist. +# Important: Number must be >= CharactersPerRealm +# Default: 50 -ChatStrictLinkChecking.Severity = 0 +CharactersPerAccount = 50 # -# ChatStrictLinkChecking.Kick -# Description: Defines what should be done if a message containing invalid control characters -# is received. -# Default: 0 - (Silently ignore message) -# 1 - (Ignore message and kick player) +# CharactersPerRealm +# Description: Limit number of characters per account on this realm. +# Range: 1-10 +# Default: 10 - (Client limitation) + +CharactersPerRealm = 10 + # +# HeroicCharactersPerRealm +# Description: Limit number of heroic class characters per account on this realm. +# Range: 1-10 +# Default: 1 -ChatStrictLinkChecking.Kick = 0 +HeroicCharactersPerRealm = 1 # -# ChatFlood.MessageCount -# Description: Chat flood protection, number of messages before player gets muted. -# Default: 10 - (Enabled) +# CharacterCreating.MinLevelForHeroicCharacter +# Description: Limit creating heroic characters only for account with another +# character of specific level (ignored for GM accounts) +# Default: 55 - (Enabled, Requires at least another level 55 character) # 0 - (Disabled) +# 1 - (Enabled, Requires at least another level 1 character) -ChatFlood.MessageCount = 10 +CharacterCreating.MinLevelForHeroicCharacter = 55 # -# ChatFlood.MessageDelay -# Description: Time (in seconds) between messages to be counted into ChatFlood.MessageCount. +# StartPlayerLevel +# Description: Starting level for characters after creation. +# Range: 1-MaxPlayerLevel # Default: 1 -ChatFlood.MessageDelay = 1 +StartPlayerLevel = 1 # -# ChatFlood.AddonMessageCount -# Description: Chat flood protection, number of addon messages before player gets muted. -# Default: 100 - (Enabled) -# 0 - (Disabled) +# StartHeroicPlayerLevel +# Description: Staring level for heroic class characters after creation. +# Range: 1-MaxPlayerLevel +# Default: 55 -ChatFlood.AddonMessageCount = 100 +StartHeroicPlayerLevel = 55 # -# ChatFlood.AddonMessageDelay -# Description: Time (in seconds) between addon messages to be counted into ChatFlood.AddonMessageCount. -# Default: 1 +# SkipCinematics +# Description: Disable cinematic intro at first login after character creation. +# Prevents buggy intros in case of custom start location coordinates. +# Default: 0 - (Show intro for each new character) +# 1 - (Show intro only for first character of selected race) +# 2 - (Disable intro for all classes) + +SkipCinematics = 0 + +# +# StartPlayerMoney +# Description: Amount of money (in Copper) that a character has after creation. +# Default: 0 +# 100 - (1 Silver) + +StartPlayerMoney = 0 + +# +# StartHeroicPlayerMoney +# Description: Amount of money (in Copper) that heroic class characters have after creation. +# Default: 2000 +# 2000 - (20 Silver) -ChatFlood.AddonMessageDelay = 1 +StartHeroicPlayerMoney = 2000 # -# ChatFlood.MuteTime -# Description: Time (in seconds) characters get muted for violating ChatFlood.MessageCount / ChatFlood.AddonMessageCount. -# Default: 10 +# PlayerStart.String +# Description: String to be displayed at first login of newly created characters. +# Default: "" - (Disabled) -ChatFlood.MuteTime = 10 +PlayerStart.String = "" # -# Chat.MuteFirstLogin -# Description: Speaking is allowed after playing for Chat.MuteTimeFirstLogin minutes. You may use party and guild chat. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -Chat.MuteFirstLogin = 0 +################################################################################################### +################################################################################################### +# CHARACTER # -# Chat.MuteTimeFirstLogin -# Description: The time after which the player will be able to speak. -# Default: 120 - (Minutes) +# EnablePlayerSettings +# Description: Enables the usage of character specific settings. +# Default: 0 - Disabled +# 1 - Enabled -Chat.MuteTimeFirstLogin = 120 +EnablePlayerSettings = 0 # -# Channel.RestrictedLfg -# Description: Restrict LookupForGroup channel to characters registered in the LFG tool. -# Default: 1 - (Enabled, Allow join to channel only if registered in LFG) -# 0 - (Disabled, Allow join to channel in any time) +# MaxPlayerLevel +# Description: Maximum level that can be reached by players. +# Important: Levels beyond 100 are not recommended at all. +# Range: 1-255 +# Default: 80 -Channel.RestrictedLfg = 1 +MaxPlayerLevel = 80 # -# Channel.SilentlyGMJoin -# Description: Silently join GM characters to channels. If set to 1, channel kick and ban -# commands issued by a GM will not be broadcasted. -# Default: 0 - (Disabled, Join with announcement) -# 1 - (Enabled, Join without announcement) +# MinDualSpecLevel +# Description: Level requirement for Dual Talent Specialization +# Default: 40 -Channel.SilentlyGMJoin = 0 +MinDualSpecLevel = 40 -# Channel.ModerationGMLevel -# Min GM account security level required for executing moderator in-game commands in the channels -# This also bypasses password prompts on joining channels which require password -# 0 (in-game channel moderator privileges only) -# Default: 1 (enabled for moderators and above) +# +# WaterBreath.Timer +# Description: The timer for player's breath underwater in milliseconds +# Default: 180000 (3 minutes) +# -Channel.ModerationGMLevel = 1 +WaterBreath.Timer = 180000 # -# ChatLevelReq.Channel -# Description: Level requirement for characters to be able to write in chat channels. -# Default: 1 +# EnableLowLevelRegenBoost +# Description: Greatly increase Health and Mana regen rates for players under level 15 (Added in patch 3.3) +# Default: 1 - Enabled +# 0 - Disabled +# -ChatLevelReq.Channel = 1 +EnableLowLevelRegenBoost = 1 # -# ChatLevelReq.Whisper -# Description: Level requirement for characters to be able to whisper other characters. +# Rate.MoveSpeed +# Description: Movement speed rate. # Default: 1 -ChatLevelReq.Whisper = 1 +Rate.MoveSpeed = 1 # -# ChatLevelReq.Say -# Description: Level requirement for characters to be able to use say/yell/emote. +# Rate.Damage.Fall +# Description: Damage after fall rate. # Default: 1 -ChatLevelReq.Say = 1 +Rate.Damage.Fall = 1 # -# PartyLevelReq -# Description: Minimum level at which players can invite to group, even if they aren't on -# the invite friends list. (Players who are on that friend list can always -# invite despite having lower level) +# Rate.Talent +# Description: Talent point rate. # Default: 1 -PartyLevelReq = 1 +Rate.Talent = 1 # -# AllowPlayerCommands -# Description: Allow players to use commands. -# Default: 1 - (Enabled) -# 0 - (Disabled) +# Rate.Health +# Rate.Mana +# Rate.Rage.Income +# Rate.Rage.Loss +# Rate.RunicPower.Income +# 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) +# 1 - (Rate.Mana) +# 1 - (Rate.Rage.Income) +# 1 - (Rate.Rage.Loss) +# 1 - (Rate.RunicPower.Income) +# 1 - (Rate.RunicPower.Loss) +# 1 - (Rate.Focus) +# 1 - (Rate.Energy) +# 1 - (Rate.Loyalty) -AllowPlayerCommands = 1 +Rate.Health = 1 +Rate.Mana = 1 +Rate.Rage.Income = 1 +Rate.Rage.Loss = 1 +Rate.RunicPower.Income = 1 +Rate.RunicPower.Loss = 1 +Rate.Focus = 1 +Rate.Energy = 1 +Rate.Loyalty = 1 # -# PreserveCustomChannels -# Description: Store custom chat channel settings like password, automatic ownership handout -# or ban list in the database. Needs to be enabled to save custom -# world/trade/etc. channels that have automatic ownership handout disabled. -# (.channel set ownership $channel off) -# Default: 0 - (Disabled, Blizzlike, Channel settings are lost if last person left) -# 1 - (Enabled) +# Rate.Rest.InGame +# Rate.Rest.Offline.InTavernOrCity +# Rate.Rest.Offline.InWilderness +# Description: Resting points grow rates. +# Default: 1 - (Rate.Rest.InGame) +# 1 - (Rate.Rest.Offline.InTavernOrCity) +# 1 - (Rate.Rest.Offline.InWilderness) -PreserveCustomChannels = 1 +Rate.Rest.InGame = 1 +Rate.Rest.Offline.InTavernOrCity = 1 +Rate.Rest.Offline.InWilderness = 1 # -# PreserveCustomChannelDuration -# Description: Time (in days) that needs to pass before the customs chat channels get -# cleaned up from the database. Only channels with ownership handout enabled -# (default behavior) will be cleaned. -# Default: 14 - (Enabled, Clean channels that haven't been used for 14 days) -# 0 - (Disabled, Infinite channel storage) - -PreserveCustomChannelDuration = 14 - +# Rate.MissChanceMultiplier.Creature +# Rate.MissChanceMultiplier.Player +# Rate.MissChanceMultiplier.OnlyAffectsPlayer # -################################################################################################### - -################################################################################################### -# GAME MASTER SETTINGS +# Description: When the target is 3 or more level higher than the player, +# the chance to hit is determined by the formula: 94 - (levelDiff - 2) * Rate.MissChanceMultiplier +# The higher the Rate.MissChanceMultiplier constant, the higher is the chance to miss. # -# GM.LoginState -# Description: GM mode at login. -# Default: 2 - (Last save state) -# 0 - (Disable) -# 1 - (Enable) - -GM.LoginState = 2 - +# Note: this does not affect when the player is less than 3 levels different than the target, +# where this (linear) formula is used instead to calculate the hit chance: 96 - levelDiff. +# You can set Rate.MissChanceMultiplier.OnlyAffectsPlayer to 1 if you only want to affect the MissChance +# for player casters only. This way you won't be affecting creature missing chance. # -# GM.Visible -# Description: GM visibility at login. -# Default: 2 - (Last save state) -# 0 - (Invisible) -# 1 - (Visible) - -GM.Visible = 2 - +# Example: if you want the chance to keep growing linearly, use 1. # -# GM.Chat -# Description: GM chat mode at login. -# Default: 2 - (Last save state) -# 0 - (Disable) -# 1 - (Enable) - -GM.Chat = 2 - +# Default: Rate.MissChanceMultiplier.TargetCreature = 11 +# Rate.MissChanceMultiplier.TargetPlayer = 7 +# Rate.MissChanceMultiplier.OnlyAffectsPlayer = 0 # -# GM.WhisperingTo -# Description: Is GM accepting whispers from player by default or not. -# Default: 2 - (Last save state) -# 0 - (Disable) -# 1 - (Enable) -GM.WhisperingTo = 2 +Rate.MissChanceMultiplier.TargetCreature = 11 +Rate.MissChanceMultiplier.TargetPlayer = 7 +Rate.MissChanceMultiplier.OnlyAffectsPlayer = 0 # -# GM.InGMList.Level -# Description: Maximum GM level shown in GM list (if enabled) in non-GM state (.gm off). -# Default: 3 - (Anyone) -# 0 - (Only players) -# 1 - (Only moderators) -# 2 - (Only gamemasters) +# LevelReq.Trade +# Description: Level requirement for characters to be able to trade. +# Default: 1 -GM.InGMList.Level = 3 +LevelReq.Trade = 1 # -# GM.InWhoList.Level -# Description: Max GM level showed in who list (if visible). -# Default: 3 - (Anyone) -# 0 - (Only players) -# 1 - (Only moderators) -# 2 - (Only gamemasters) +# NoResetTalentsCost +# Description: Resetting talents doesn't cost anything. +# Default: 0 - (Disabled) +# 1 - (Enabled) -GM.InWhoList.Level = 3 +NoResetTalentsCost = 0 # -# GM.StartLevel -# Description: GM character starting level. -# Default: 1 +# ToggleXP.Cost +# Description: Cost of locking/unlocking XP +# Default: 100000 - (10 Gold) +# -GM.StartLevel = 1 +ToggleXP.Cost = 100000 # -# GM.AllowInvite -# Description: Allow players to invite GM characters. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -GM.AllowInvite = 0 +################################################################################################### +################################################################################################### +# SKILL # -# GM.AllowFriend -# Description: Allow players to add GM characters to their friends list. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# MaxPrimaryTradeSkill +# Description: Maximum number of primary professions a character can learn. +# Range: 0-11 +# Default: 2 -GM.AllowFriend = 0 +MaxPrimaryTradeSkill = 2 # -# GM.LowerSecurity -# Description: Allow lower security levels to use commands on higher security level -# characters. +# SkillChance.Prospecting +# Description: Allow skill increase from prospecting. # Default: 0 - (Disabled) # 1 - (Enabled) -GM.LowerSecurity = 0 +SkillChance.Prospecting = 0 # -# GM.TicketSystem.ChanceOfGMSurvey -# Description: Chance of sending a GM survey after ticket completion. -# Default: 50 - (Enabled) -# 0 - (Disabled) - -GM.TicketSystem.ChanceOfGMSurvey = 50 +# SkillChance.Milling +# Description: Allow skill increase from milling. +# Default: 0 - (Disabled) +# 1 - (Enabled) -# -################################################################################################### +SkillChance.Milling = 0 -################################################################################################### -# VISIBILITY AND DISTANCES # -# Visibility.GroupMode -# Description: Group visibility modes. Defines which groups can aways detect invisible -# characters of the same raid, group or faction. -# Default: 1 - (Raid) -# 0 - (Party) -# 2 - (Faction) +# Rate.Skill.Discovery +# Description: Multiplier for skill discovery. +# Default: 1 -Visibility.GroupMode = 1 +Rate.Skill.Discovery = 1 # -# Visibility.Distance.Continents -# Visibility.Distance.Instances -# Visibility.Distance.BGArenas -# Description: Visibility distance to see other players or gameobjects. -# Visibility on continents on retail ~90 yards. In BG/Arenas ~180. -# For instances default ~120. -# Max limited by active player zone: ~ 333 -# Min limit is max aggro radius (45) * Rate.Creature.Aggro -# Default: 90 - (Visibility.Distance.Continents) -# 120 - (Visibility.Distance.Instances) -# 180 - (Visibility.Distance.BGArenas) +# SkillGain.Crafting +# SkillGain.Defense +# SkillGain.Gathering +# SkillGain.Weapon +# Description: Crafting/defense/gathering/weapon skills gain rate. +# Default: 1 - (SkillGain.Crafting) +# 1 - (SkillGain.Defense) +# 1 - (SkillGain.Gathering) +# 1 - (SkillGain.Weapon) -Visibility.Distance.Continents = 90 -Visibility.Distance.Instances = 120 -Visibility.Distance.BGArenas = 180 +SkillGain.Crafting = 1 +SkillGain.Defense = 1 +SkillGain.Gathering = 1 +SkillGain.Weapon = 1 # -# 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) +# SkillChance.Orange +# SkillChance.Yellow +# SkillChance.Green +# SkillChance.Grey +# Description: Chance to increase skill based on recipe color. +# Default: 100 - (SkillChance.Orange) +# 75 - (SkillChance.Yellow) +# 25 - (SkillChance.Green) +# 0 - (SkillChance.Grey) -Visibility.Notify.Period.OnContinents = 1000 -Visibility.Notify.Period.InInstances = 1000 -Visibility.Notify.Period.InBGArenas = 1000 +SkillChance.Orange = 100 +SkillChance.Yellow = 75 +SkillChance.Green = 25 +SkillChance.Grey = 0 # -# Visibility.ObjectSparkles -# Description: Whether or not to display sparkles on gameobjects related to active quests. -# Default: 1 - (Show Sparkles) -# 0 - (Hide Sparkles) +# SkillChance.MiningSteps +# SkillChance.SkinningSteps +# Description: Skinning and Mining chance decreases with skill level. +# Default: 0 - (Disabled) +# 75 - (In 2 times each 75 skill points) -Visibility.ObjectSparkles = 1 +SkillChance.MiningSteps = 0 +SkillChance.SkinningSteps = 0 # -# Visibility.ObjectQuestMarkers -# Description: Show quest icons above game objects in the same way as creature quest givers. -# Default: 1 - (Show quest markers, post patch 2.3 behavior) -# 0 - (Hide quest markers, pre patch 2.3 behavior) +# OffhandCheckAtSpellUnlearn +# Description: Unlearning certain spells can change offhand weapon restrictions +# for equip slots. +# Default: 1 - (Recheck offhand slot weapon at unlearning a spell) +# 0 - (Recheck offhand slot weapon only at zone update) -Visibility.ObjectQuestMarkers = 1 +OffhandCheckAtSpellUnlearn = 1 # ################################################################################################### ################################################################################################### -# SERVER RATES +# STATS # -# Rate.Health -# Rate.Mana -# Rate.Rage.Income -# Rate.Rage.Loss -# Rate.RunicPower.Income -# 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) -# 1 - (Rate.Mana) -# 1 - (Rate.Rage.Income) -# 1 - (Rate.Rage.Loss) -# 1 - (Rate.RunicPower.Income) -# 1 - (Rate.RunicPower.Loss) -# 1 - (Rate.Focus) -# 1 - (Rate.Energy) -# 1 - (Rate.Loyalty) +# Stats.Limits.Enable +# Description: Enable or disable stats system limitations +# Default: 0 - Disabled +# 1 - Enabled -Rate.Health = 1 -Rate.Mana = 1 -Rate.Rage.Income = 1 -Rate.Rage.Loss = 1 -Rate.RunicPower.Income = 1 -Rate.RunicPower.Loss = 1 -Rate.Focus = 1 -Rate.Energy = 1 -Rate.Loyalty = 1 +Stats.Limits.Enable = 0 # -# Rate.Skill.Discovery -# Description: Multiplier for skill discovery. -# Default: 1 +# Stats.Limit.[STAT] +# Description: Set percentage limit for dodge, parry, block and crit rating +# Default: 95.0 (95%) -Rate.Skill.Discovery = 1 +Stats.Limits.Dodge = 95.0 +Stats.Limits.Parry = 95.0 +Stats.Limits.Block = 95.0 +Stats.Limits.Crit = 95.0 # -# Rate.Drop.Item.Poor -# Rate.Drop.Item.Normal -# Rate.Drop.Item.Uncommon -# Rate.Drop.Item.Rare -# Rate.Drop.Item.Epic -# Rate.Drop.Item.Legendary -# Rate.Drop.Item.Artifact -# Rate.Drop.Item.Referenced -# Rate.Drop.Money -# Description: Drop rates for money and items based on quality. -# Default: 1 - (Rate.Drop.Item.Poor) -# 1 - (Rate.Drop.Item.Normal) -# 1 - (Rate.Drop.Item.Uncommon) -# 1 - (Rate.Drop.Item.Rare) -# 1 - (Rate.Drop.Item.Epic) -# 1 - (Rate.Drop.Item.Legendary) -# 1 - (Rate.Drop.Item.Artifact) -# 1 - (Rate.Drop.Item.Referenced) -# 1 - (Rate.Drop.Money) - -Rate.Drop.Item.Poor = 1 -Rate.Drop.Item.Normal = 1 -Rate.Drop.Item.Uncommon = 1 -Rate.Drop.Item.Rare = 1 -Rate.Drop.Item.Epic = 1 -Rate.Drop.Item.Legendary = 1 -Rate.Drop.Item.Artifact = 1 -Rate.Drop.Item.Referenced = 1 -Rate.Drop.Money = 1 +################################################################################################### -# Rate.Drop.Item.ReferencedAmount -# Description: Multiplier for referenced loot amount. Makes many raid bosses (and others) drop additional loot. +################################################################################################### +# REPUTATION +# +# Rate.Reputation.Gain +# Description: Reputation gain rate. # Default: 1 -Rate.Drop.Item.ReferencedAmount = 1 +Rate.Reputation.Gain = 1 # -# Rate.Drop.Item.GroupAmount -# Description: Multiplier for grouped items. Makes many dungeon bosses (and others) drop additional loot. +# Rate.Reputation.LowLevel.Kill +# Description: Reputation gain from killing low level (grey) creatures. # Default: 1 -Rate.Drop.Item.GroupAmount = 1 +Rate.Reputation.LowLevel.Kill = 1 -# Rate.RewardBonusMoney -# Description: Allows to further tweak the amount of extra money rewarded by quests when the player -# is at MaxPlayerLevel (this amount is specified in quest_template.RewardBonusMoney). -# NOTE: the final amount will also affected by Rate.Drop.Money +# +# Rate.Reputation.LowLevel.Quest +# Description: Reputation gain rate. # Default: 1 -Rate.RewardBonusMoney = 1 +Rate.Reputation.LowLevel.Quest = 1 # -# Rate.SellValue.Item.Poor -# Rate.SellValue.Item.Normal -# Rate.SellValue.Item.Uncommon -# Rate.SellValue.Item.Rare -# Rate.SellValue.Item.Epic -# Rate.SellValue.Item.Legendary -# Rate.SellValue.Item.Artifact -# Rate.SellValue.Item.Heirloom -# Description: Item Sale Value rates based on quality. -# Default: 1 - (Rate.SellValue.Item.Poor) -# 1 - (Rate.SellValue.Item.Normal) -# 1 - (Rate.SellValue.Item.Uncommon) -# 1 - (Rate.SellValue.Item.Rare) -# 1 - (Rate.SellValue.Item.Epic) -# 1 - (Rate.SellValue.Item.Legendary) -# 1 - (Rate.SellValue.Item.Artifact) -# 1 - (Rate.SellValue.Item.Heirloom) +# Rate.Reputation.RecruitAFriendBonus +# Description: Reputation bonus rate for recruit-a-friend. +# Default: 0.1 -Rate.SellValue.Item.Poor = 1 -Rate.SellValue.Item.Normal = 1 -Rate.SellValue.Item.Uncommon = 1 -Rate.SellValue.Item.Rare = 1 -Rate.SellValue.Item.Epic = 1 -Rate.SellValue.Item.Legendary = 1 -Rate.SellValue.Item.Artifact = 1 -Rate.SellValue.Item.Heirloom = 1 +Rate.Reputation.RecruitAFriendBonus = 0.1 # -# Rate.BuyValue.Item.Poor -# Rate.BuyValue.Item.Normal -# Rate.BuyValue.Item.Uncommon -# Rate.BuyValue.Item.Rare -# Rate.BuyValue.Item.Epic -# Rate.BuyValue.Item.Legendary -# Rate.BuyValue.Item.Artifact -# Rate.BuyValue.Item.Heirloom -# Description: Item Sale Value rates based on quality. -# Default: 1 - (Rate.BuyValue.Item.Poor) -# 1 - (Rate.BuyValue.Item.Normal) -# 1 - (Rate.BuyValue.Item.Uncommon) -# 1 - (Rate.BuyValue.Item.Rare) -# 1 - (Rate.BuyValue.Item.Epic) -# 1 - (Rate.BuyValue.Item.Legendary) -# 1 - (Rate.BuyValue.Item.Artifact) -# 1 - (Rate.BuyValue.Item.Heirloom) +################################################################################################### -Rate.BuyValue.Item.Poor = 1 -Rate.BuyValue.Item.Normal = 1 -Rate.BuyValue.Item.Uncommon = 1 -Rate.BuyValue.Item.Rare = 1 -Rate.BuyValue.Item.Epic = 1 -Rate.BuyValue.Item.Legendary = 1 -Rate.BuyValue.Item.Artifact = 1 -Rate.BuyValue.Item.Heirloom = 1 +################################################################################################### +# EXPERIENCE +# +# MaxGroupXPDistance +# Description: Max distance to creature for group member to get experience at creature +# death. +# Default: 74 + +MaxGroupXPDistance = 74 # # Rate.XP.Kill @@ -2380,1154 +2344,1492 @@ Rate.XP.BattlegroundKillSOTA = 1 Rate.XP.BattlegroundKillIC = 1 # -# Rate.RepairCost -# Description: Repair cost rate. +# Rate.Pet.LevelXP +# Description: Modifies the amount of experience required to level up a pet. +# The lower the rate the less experience is required. +# Default: 0.05 +# + +Rate.Pet.LevelXP = 0.05 + +# +################################################################################################### + +################################################################################################### +# CURRENCY +# +# MaxHonorPoints +# Description: Maximum honor points a character can have. +# Default: 75000 + +MaxHonorPoints = 75000 + +# +# MaxHonorPointsMoneyPerPoint +# Description: Convert excess honor points into money if players got more points than allowed after changing the honor cap. +# Honor points will be converted into copper according to the value set in this config. +# Default: 0 - Disabled + +MaxHonorPointsMoneyPerPoint = 0 + +# +# StartHonorPoints +# Description: Amount of honor points that characters have after creation. +# Default: 0 + +StartHonorPoints = 0 + +# +# HonorPointsAfterDuel +# Description: Amount of honor points the duel winner will get after a duel. +# Default: 0 - (Disabled) +# 1+ - (Enabled) + +HonorPointsAfterDuel = 0 + +# +# Rate.Honor +# Description: Honor gain rate. # Default: 1 -Rate.RepairCost = 1 +Rate.Honor = 1 # -# Rate.Rest.InGame -# Rate.Rest.Offline.InTavernOrCity -# Rate.Rest.Offline.InWilderness -# Description: Resting points grow rates. -# Default: 1 - (Rate.Rest.InGame) -# 1 - (Rate.Rest.Offline.InTavernOrCity) -# 1 - (Rate.Rest.Offline.InWilderness) +# MaxArenaPoints +# Description: Maximum arena points a character can have. +# Default: 10000 + +MaxArenaPoints = 10000 + +# +# StartArenaPoints +# Description: Amount of arena points that characters has after creation. +# Default: 0 + +StartArenaPoints = 0 + +# +# Arena.LegacyArenaPoints +# Description: Use arena point calculation from TBC for season 1 - 5 when rating is less or equal to 1500 +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Arena.LegacyArenaPoints = 0 + +# +# Rate.ArenaPoints +# Description: Arena points gain rate. +# Default: 1 + +Rate.ArenaPoints = 1 + +# +# PvPToken.Enable +# Description: Character will receive a token after defeating another character that yields +# honor. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +PvPToken.Enable = 0 + +# +# PvPToken.MapAllowType +# Description: Define where characters can receive tokens. +# Default: 4 - (All maps) +# 3 - (Battlegrounds) +# 2 - (FFA areas only like Gurubashi arena) +# 1 - (Battlegrounds and FFA areas) + +PvPToken.MapAllowType = 4 + +# +# PvPToken.ItemID +# Description: Item characters will receive after defeating another character if PvP Token +# system is enabled. +# Default: 29434 - (Badge of justice) + +PvPToken.ItemID = 29434 + +# +# PvPToken.ItemCount +# Description: Number of tokens a character will receive. +# Default: 1 + +PvPToken.ItemCount = 1 + +# +################################################################################################### + +################################################################################################### +# DURABILITY +# +# DurabilityLoss.InPvP +# Description: Durability loss on death during PvP. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +DurabilityLoss.InPvP = 0 + +# +# DurabilityLoss.OnDeath +# Description: Durability loss percentage on death. +# Note: On 3.3.5 client always shows log message "Your items have lost 10% durability" +# Default: 10 + +DurabilityLoss.OnDeath = 10 + +# +# DurabilityLossChance.Damage +# Description: Chance to lose durability on one equipped item from damage. +# Default: 0.5 - (100/0.5 = 200, Each 200 damage one equipped item will use durability) + +DurabilityLossChance.Damage = 0.5 + +# +# DurabilityLossChance.Absorb +# Description: Chance to lose durability on one equipped armor item when absorbing damage. +# Default: 0.5 - (100/0.5 = 200, Each 200 absorbed damage one equipped item will lose +# durability) + +DurabilityLossChance.Absorb = 0.5 + +# +# DurabilityLossChance.Parry +# Description: Chance to lose durability on main weapon when parrying attacks. +# Default: 0.05 - (100/0.05 = 2000, Each 2000 parried damage the main weapon will lose +# durability) + +DurabilityLossChance.Parry = 0.05 + +# +# DurabilityLossChance.Block +# Description: Chance to lose durability on shield when blocking attacks. +# Default: 0.05 - (100/0.05 = 2000, Each 2000 blocked damage the shield will lose +# durability) + +DurabilityLossChance.Block = 0.05 + +# +################################################################################################### + +################################################################################################### +# DEATH +# +# Death.SicknessLevel +# Description: Starting level for resurrection sickness. +# Example: 11 - (Level 1-10 characters will not be affected, +# Level 11-19 characters will be affected for 1 minute, +# Level 20-MaxPlayerLevel characters will be affected for 10 minutes) +# Default: 11 - (Enabled, See Example) +# MaxPlayerLevel+1 - (Disabled) +# -10 - (Enabled, Level 1+ characters have 10 minute duration) + +Death.SicknessLevel = 11 + +# +# Death.CorpseReclaimDelay.PvP +# Death.CorpseReclaimDelay.PvE +# Description: Increase corpse reclaim delay at PvP/PvE deaths. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Death.CorpseReclaimDelay.PvP = 1 +Death.CorpseReclaimDelay.PvE = 0 + +# +# Death.Bones.World +# Death.Bones.BattlegroundOrArena +# Description: Create bones instead of corpses at resurrection in normal zones, instances, +# battleground or arenas. +# Default: 1 - (Enabled, Death.Bones.World) +# 1 - (Enabled, Death.Bones.BattlegroundOrArena) +# 0 - (Disabled) + +Death.Bones.World = 1 +Death.Bones.BattlegroundOrArena = 1 + +# +################################################################################################### + +################################################################################################### +# PET +# +# Pet.RankMod.Health +# Description: Allows pet health to be modified by rank health rates (set in config) +# Default: 1 - Enabled +# 0 - Disabled + +Pet.RankMod.Health = 1 + +# +################################################################################################### + +################################################################################################### +# ITEM DELETE +# +# ItemDelete.Method +# Description: Item deletion behavior. +# Default: 0 - (Completely remove item from the database) +# 1 - (Save Item to database) + +ItemDelete.Method = 0 + +# +# ItemDelete.Vendor +# Description: Saving items into database when the player sells items to vendor +# Default: 0 (disabled) +# 1 (enabled) +# + +ItemDelete.Vendor = 0 + +# +# ItemDelete.Quality +# Description: Saving items into database that have quality greater or equal to ItemDelete.Quality +# +# ID | Color | Quality +# 0 | Grey | Poor +# 1 | White | Common +# 2 | Green | Uncommon +# 3 | Blue | Rare +# 4 | Purple| Epic +# 5 | Orange| Legendary +# 6 | Red | Artifact +# 7 | Gold | Bind to Account +# +# Default: 3 +# -Rate.Rest.InGame = 1 -Rate.Rest.Offline.InTavernOrCity = 1 -Rate.Rest.Offline.InWilderness = 1 +ItemDelete.Quality = 3 # -# Rate.Damage.Fall -# Description: Damage after fall rate. -# Default: 1 +# ItemDelete.ItemLevel +# Description: Saving items into database that are Item Levels greater or equal to ItemDelete.ItemLevel +# Default: 80 +# -Rate.Damage.Fall = 1 +ItemDelete.ItemLevel = 80 # -# Rate.Auction.Time -# Rate.Auction.Deposit -# Rate.Auction.Cut -# Description: Auction rates (auction time, deposit get at auction start, -# auction cut from price at auction end) -# Default: 1 - (Rate.Auction.Time) -# 1 - (Rate.Auction.Deposit) -# 1 - (Rate.Auction.Cut) - -Rate.Auction.Time = 1 -Rate.Auction.Deposit = 1 -Rate.Auction.Cut = 1 +################################################################################################### +################################################################################################### +# ITEM # -# Rate.Honor -# Description: Honor gain rate. -# Default: 1 +# DBC.EnforceItemAttributes +# Disallow overriding item attributes stored in DBC files with values from the database +# Default: 0 - Off, Use DB values +# 1 - On, Enforce DBC Values (default) -Rate.Honor = 1 +DBC.EnforceItemAttributes = 1 # -# Rate.ArenaPoints -# Description: Arena points gain rate. -# Default: 1 +# Rate.Drop.Item.Poor +# Rate.Drop.Item.Normal +# Rate.Drop.Item.Uncommon +# Rate.Drop.Item.Rare +# Rate.Drop.Item.Epic +# Rate.Drop.Item.Legendary +# Rate.Drop.Item.Artifact +# Rate.Drop.Item.Referenced +# Rate.Drop.Money +# Description: Drop rates for money and items based on quality. +# Default: 1 - (Rate.Drop.Item.Poor) +# 1 - (Rate.Drop.Item.Normal) +# 1 - (Rate.Drop.Item.Uncommon) +# 1 - (Rate.Drop.Item.Rare) +# 1 - (Rate.Drop.Item.Epic) +# 1 - (Rate.Drop.Item.Legendary) +# 1 - (Rate.Drop.Item.Artifact) +# 1 - (Rate.Drop.Item.Referenced) +# 1 - (Rate.Drop.Money) -Rate.ArenaPoints = 1 +Rate.Drop.Item.Poor = 1 +Rate.Drop.Item.Normal = 1 +Rate.Drop.Item.Uncommon = 1 +Rate.Drop.Item.Rare = 1 +Rate.Drop.Item.Epic = 1 +Rate.Drop.Item.Legendary = 1 +Rate.Drop.Item.Artifact = 1 +Rate.Drop.Item.Referenced = 1 +Rate.Drop.Money = 1 -# -# Rate.Talent -# Description: Talent point rate. +# Rate.Drop.Item.ReferencedAmount +# Description: Multiplier for referenced loot amount. Makes many raid bosses (and others) drop additional loot. # Default: 1 -Rate.Talent = 1 +Rate.Drop.Item.ReferencedAmount = 1 # -# Rate.Reputation.Gain -# Description: Reputation gain rate. +# Rate.Drop.Item.GroupAmount +# Description: Multiplier for grouped items. Makes many dungeon bosses (and others) drop additional loot. # Default: 1 -Rate.Reputation.Gain = 1 +Rate.Drop.Item.GroupAmount = 1 # -# Rate.Reputation.LowLevel.Kill -# Description: Reputation gain from killing low level (grey) creatures. -# Default: 1 +# LootNeedBeforeGreedILvlRestriction +# Description: Specify level restriction for items below player's subclass in Need Before Greed loot mode in DF groups +# Default: 70 +# 0 - Disabled -Rate.Reputation.LowLevel.Kill = 1 +LootNeedBeforeGreedILvlRestriction = 70 # -# Rate.Reputation.LowLevel.Quest -# Description: Reputation gain rate. -# Default: 1 +# Item.SetItemTradeable +# Description: Enabled/Disabled trading BoP items among raid members. +# Default: 1 - (Set BoP items tradeable timer to 2 hours) +# 0 - (Disable trading BoP items among raid members) -Rate.Reputation.LowLevel.Quest = 1 +Item.SetItemTradeable = 1 # -# Rate.Reputation.RecruitAFriendBonus -# Description: Reputation bonus rate for recruit-a-friend. -# Default: 0.1 - -Rate.Reputation.RecruitAFriendBonus = 0.1 +################################################################################################### +################################################################################################### +# QUEST # -# Rate.MoveSpeed -# Description: Movement speed rate. -# Default: 1 +# Quests.EnableQuestTracker +# Description: Store data in the database about quest completion and abandonment to help finding bugged quests. +# Default: 0 - (Disabled) +# 1 - (Enabled) -Rate.MoveSpeed = 1 +Quests.EnableQuestTracker = 0 # -# Rate.InstanceResetTime -# Description: Multiplier for the rate between global raid/heroic instance resets -# (dbc value). Higher value increases the time between resets, -# lower value lowers the time, you need clean instance_reset in -# characters db in order to let new values work. -# Default: 1 +# QuestPOI.Enabled +# Description: Show points of interest on the map +# Default: 1 - Enabled +# 0 - Disabled -Rate.InstanceResetTime = 1 +QuestPOI.Enabled = 1 # -# Rate.Pet.LevelXP -# Description: Modifies the amount of experience required to level up a pet. -# The lower the rate the less experience is required. -# Default: 0.05 -# +# Quests.LowLevelHideDiff +# Description: Level difference between player and quest level at which quests are +# considered low-level and are not shown via exclamation mark (!) at quest +# givers. +# Default: 4 - (Enabled, Hide quests that have 4 levels less than the character) +# -1 - (Disabled, Show all available quest marks) -Rate.Pet.LevelXP = 0.05 +Quests.LowLevelHideDiff = 4 # -# WaterBreath.Timer -# Description: The timer for player's breath underwater in milliseconds -# Default: 180000 (3 minutes) -# +# Quests.HighLevelHideDiff +# Description: Level difference between player and quest level at which quests are +# considered high-level and are not shown via exclamation mark (!) at quest +# givers. +# Default: 7 - (Enabled, Hide quests that have 7 levels more than the character) +# -1 - (Disabled, Show all available quest marks) -WaterBreath.Timer = 180000 +Quests.HighLevelHideDiff = 7 # -# EnableLowLevelRegenBoost -# Description: Greatly increase Health and Mana regen rates for players under level 15 (Added in patch 3.3) -# Default: 1 - Enabled -# 0 - Disabled -# +# Quests.IgnoreRaid +# Description: Allow non-raid quests to be completed while in a raid group. +# Default: 0 - (Disabled) +# 1 - (Enabled) -EnableLowLevelRegenBoost = 1 +Quests.IgnoreRaid = 0 # -# SkillGain.Crafting -# SkillGain.Defense -# SkillGain.Gathering -# SkillGain.Weapon -# Description: Crafting/defense/gathering/weapon skills gain rate. -# Default: 1 - (SkillGain.Crafting) -# 1 - (SkillGain.Defense) -# 1 - (SkillGain.Gathering) -# 1 - (SkillGain.Weapon) +# Quests.IgnoreAutoAccept +# Description: Ignore auto accept flag. Clients will have to manually accept all quests. +# Default: 0 - (Disabled, DB values determine if quest is marked auto accept or not.) +# 1 - (Enabled, clients will not be told to automatically accept any quest.) -SkillGain.Crafting = 1 -SkillGain.Defense = 1 -SkillGain.Gathering = 1 -SkillGain.Weapon = 1 +Quests.IgnoreAutoAccept = 0 # -# SkillChance.Orange -# SkillChance.Yellow -# SkillChance.Green -# SkillChance.Grey -# Description: Chance to increase skill based on recipe color. -# Default: 100 - (SkillChance.Orange) -# 75 - (SkillChance.Yellow) -# 25 - (SkillChance.Green) -# 0 - (SkillChance.Grey) +# Quests.IgnoreAutoComplete +# Description: Ignore auto complete flag. Clients will have to manually complete all quests. +# Default: 0 - (Disabled, DB values determine if quest is marked auto complete or not.) +# 1 - (Enabled, clients will not be told to automatically complete any quest.) -SkillChance.Orange = 100 -SkillChance.Yellow = 75 -SkillChance.Green = 25 -SkillChance.Grey = 0 +Quests.IgnoreAutoComplete = 0 # -# SkillChance.MiningSteps -# SkillChance.SkinningSteps -# Description: Skinning and Mining chance decreases with skill level. -# Default: 0 - (Disabled) -# 75 - (In 2 times each 75 skill points) +# Rate.RewardBonusMoney +# Description: Allows to further tweak the amount of extra money rewarded by quests when the player +# is at MaxPlayerLevel (this amount is specified in quest_template.RewardBonusMoney). +# NOTE: the final amount will also affected by Rate.Drop.Money +# Default: 1 -SkillChance.MiningSteps = 0 -SkillChance.SkinningSteps = 0 +Rate.RewardBonusMoney = 1 # -# DurabilityLoss.InPvP -# Description: Durability loss on death during PvP. -# Default: 0 - (Disabled) -# 1 - (Enabled) +################################################################################################### -DurabilityLoss.InPvP = 0 +################################################################################################### +# CREATURE +# +# MonsterSight +# Description: The maximum distance in yards that a "monster" creature can see +# regardless of level difference (through CreatureAI::IsVisible). +# Increases CONFIG_SIGHT_MONSTER to 50 yards. Used to be 20 yards. +# Default: 50.000000 + +MonsterSight = 50.000000 # -# DurabilityLoss.OnDeath -# Description: Durability loss percentage on death. -# Note: On 3.3.5 client always shows log message "Your items have lost 10% durability" -# Default: 10 +# ThreatRadius +# Description: Distance for creatures to evade after being pulled away from the combat +# starting point. If ThreatRadius is less than creature aggro radius then aggro +# radius will be used. +# Default: 60 -DurabilityLoss.OnDeath = 10 +ThreatRadius = 60 # -# DurabilityLossChance.Damage -# Description: Chance to lose durability on one equipped item from damage. -# Default: 0.5 - (100/0.5 = 200, Each 200 damage one equipped item will use durability) +# Rate.Creature.Aggro +# Description: Aggro radius percentage. +# Default: 1 - (Enabled, 100%) +# 1.5 - (Enabled, 150%) +# 0 - (Disabled, 0%) -DurabilityLossChance.Damage = 0.5 +Rate.Creature.Aggro = 1 # -# DurabilityLossChance.Absorb -# Description: Chance to lose durability on one equipped armor item when absorbing damage. -# Default: 0.5 - (100/0.5 = 200, Each 200 absorbed damage one equipped item will lose -# durability) +# CreatureFamilyFleeAssistanceRadius +# Description: Distance for fleeing creatures seeking assistance from other creatures. +# Default: 30 - (Enabled) +# 0 - (Disabled) -DurabilityLossChance.Absorb = 0.5 +CreatureFamilyFleeAssistanceRadius = 30 # -# DurabilityLossChance.Parry -# Description: Chance to lose durability on main weapon when parrying attacks. -# Default: 0.05 - (100/0.05 = 2000, Each 2000 parried damage the main weapon will lose -# durability) +# CreatureFamilyAssistanceRadius +# Description: Distance for creatures calling for assistance from other creatures without +# moving. +# Default: 10 - (Enabled) +# 0 - (Disabled) -DurabilityLossChance.Parry = 0.05 +CreatureFamilyAssistanceRadius = 10 # -# DurabilityLossChance.Block -# Description: Chance to lose durability on shield when blocking attacks. -# Default: 0.05 - (100/0.05 = 2000, Each 2000 blocked damage the shield will lose -# durability) +# CreatureFamilyAssistanceDelay +# Description: Time (in milliseconds) before creature assistance call. +# Default: 2000 - (2 Seconds) -DurabilityLossChance.Block = 0.05 +CreatureFamilyAssistanceDelay = 2000 # -# Death.SicknessLevel -# Description: Starting level for resurrection sickness. -# Example: 11 - (Level 1-10 characters will not be affected, -# Level 11-19 characters will be affected for 1 minute, -# Level 20-MaxPlayerLevel characters will be affected for 10 minutes) -# Default: 11 - (Enabled, See Example) -# MaxPlayerLevel+1 - (Disabled) -# -10 - (Enabled, Level 1+ characters have 10 minute duration) +# CreatureFamilyAssistancePeriod +# Description: Time (in milliseconds) before next creature assistance call. +# Default: 3000 - (3 Seconds) +# 0 - (Disabled) -Death.SicknessLevel = 11 +CreatureFamilyAssistancePeriod = 3000 # -# Death.CorpseReclaimDelay.PvP -# Death.CorpseReclaimDelay.PvE -# Description: Increase corpse reclaim delay at PvP/PvE deaths. -# Default: 1 - (Enabled) -# 0 - (Disabled) +# CreatureFamilyFleeDelay +# Description: Time (in milliseconds) during which creature can flee if no assistance was +# found. +# Default: 7000 (7 Seconds) -Death.CorpseReclaimDelay.PvP = 1 -Death.CorpseReclaimDelay.PvE = 0 +CreatureFamilyFleeDelay = 7000 # -# Death.Bones.World -# Death.Bones.BattlegroundOrArena -# Description: Create bones instead of corpses at resurrection in normal zones, instances, -# battleground or arenas. -# Default: 1 - (Enabled, Death.Bones.World) -# 1 - (Enabled, Death.Bones.BattlegroundOrArena) -# 0 - (Disabled) +# WorldBossLevelDiff +# Description: World boss level difference. +# Default: 3 -Death.Bones.World = 1 -Death.Bones.BattlegroundOrArena = 1 +WorldBossLevelDiff = 3 # -# Die.Command.Mode -# Description: Do not trigger things like loot from .die command. -# Default: 1 - (Enabled) -# 0 - (Disabled) +# Corpse.Decay.NORMAL +# Corpse.Decay.RARE +# Corpse.Decay.ELITE +# Corpse.Decay.RAREELITE +# Corpse.Decay.WORLDBOSS +# Description: Time (in seconds) until creature corpse will decay if not looted or skinned. +# Default: 60 - (1 Minute, Corpse.Decay.NORMAL) +# 300 - (5 Minutes, Corpse.Decay.RARE) +# 300 - (5 Minutes, Corpse.Decay.ELITE) +# 300 - (5 Minutes, Corpse.Decay.RAREELITE) +# 3600 - (1 Hour, Corpse.Decay.WORLDBOSS) -Die.Command.Mode = 1 +Corpse.Decay.NORMAL = 60 +Corpse.Decay.RARE = 300 +Corpse.Decay.ELITE = 300 +Corpse.Decay.RAREELITE = 300 +Corpse.Decay.WORLDBOSS = 3600 -# Rate.MissChanceMultiplier.Creature -# Rate.MissChanceMultiplier.Player -# Rate.MissChanceMultiplier.OnlyAffectsPlayer -# -# Description: When the target is 3 or more level higher than the player, -# the chance to hit is determined by the formula: 94 - (levelDiff - 2) * Rate.MissChanceMultiplier -# The higher the Rate.MissChanceMultiplier constant, the higher is the chance to miss. -# -# Note: this does not affect when the player is less than 3 levels different than the target, -# where this (linear) formula is used instead to calculate the hit chance: 96 - levelDiff. -# You can set Rate.MissChanceMultiplier.OnlyAffectsPlayer to 1 if you only want to affect the MissChance -# for player casters only. This way you won't be affecting creature missing chance. -# -# Example: if you want the chance to keep growing linearly, use 1. -# -# Default: Rate.MissChanceMultiplier.TargetCreature = 11 -# Rate.MissChanceMultiplier.TargetPlayer = 7 -# Rate.MissChanceMultiplier.OnlyAffectsPlayer = 0 # +# Rate.Corpse.Decay.Looted +# Description: Multiplier for Corpse.Decay.* to configure how long creature corpses stay +# after they have been looted. +# Default: 0.5 -Rate.MissChanceMultiplier.TargetCreature = 11 -Rate.MissChanceMultiplier.TargetPlayer = 7 -Rate.MissChanceMultiplier.OnlyAffectsPlayer = 0 +Rate.Corpse.Decay.Looted = 0.5 # -################################################################################################### - -################################################################################################### -# STATS LIMITS +# Rate.Creature.Normal.Damage +# Rate.Creature.Elite.Elite.Damage +# Rate.Creature.Elite.RARE.Damage +# Rate.Creature.Elite.RAREELITE.Damage +# Rate.Creature.Elite.WORLDBOSS.Damage +# Description: Multiplier for creature melee damage. +# Default: 1 - (Rate.Creature.Normal.Damage) +# 1 - (Rate.Creature.Elite.Elite.Damage) +# 1 - (Rate.Creature.Elite.RARE.Damage) +# 1 - (Rate.Creature.Elite.RAREELITE.Damage) +# 1 - (Rate.Creature.Elite.WORLDBOSS.Damage) # -# Stats.Limits.Enable -# Description: Enable or disable stats system limitations -# Default: 0 - Disabled -# 1 - Enabled -Stats.Limits.Enable = 0 +Rate.Creature.Normal.Damage = 1 +Rate.Creature.Elite.Elite.Damage = 1 +Rate.Creature.Elite.RARE.Damage = 1 +Rate.Creature.Elite.RAREELITE.Damage = 1 +Rate.Creature.Elite.WORLDBOSS.Damage = 1 # -# Stats.Limit.[STAT] -# Description: Set percentage limit for dodge, parry, block and crit rating -# Default: 95.0 (95%) +# Rate.Creature.Normal.SpellDamage +# Rate.Creature.Elite.Elite.SpellDamage +# Rate.Creature.Elite.RARE.SpellDamage +# Rate.Creature.Elite.RAREELITE.SpellDamage +# Rate.Creature.Elite.WORLDBOSS.SpellDamage +# Description: Multiplier for creature spell damage. +# Default: 1 - (Rate.Creature.Normal.SpellDamage) +# 1 - (Rate.Creature.Elite.Elite.SpellDamage) +# 1 - (Rate.Creature.Elite.RARE.SpellDamage) +# 1 - (Rate.Creature.Elite.RAREELITE.SpellDamage) +# 1 - (Rate.Creature.Elite.WORLDBOSS.SpellDamage) -Stats.Limits.Dodge = 95.0 -Stats.Limits.Parry = 95.0 -Stats.Limits.Block = 95.0 -Stats.Limits.Crit = 95.0 +Rate.Creature.Normal.SpellDamage = 1 +Rate.Creature.Elite.Elite.SpellDamage = 1 +Rate.Creature.Elite.RARE.SpellDamage = 1 +Rate.Creature.Elite.RAREELITE.SpellDamage = 1 +Rate.Creature.Elite.WORLDBOSS.SpellDamage = 1 # -################################################################################################### +# Rate.Creature.Normal.HP +# Rate.Creature.Elite.Elite.HP +# Rate.Creature.Elite.RARE.HP +# Rate.Creature.Elite.RAREELITE.HP +# Rate.Creature.Elite.WORLDBOSS.HP +# Description: Multiplier for creature health. +# Default: 1 - (Rate.Creature.Normal.HP) +# 1 - (Rate.Creature.Elite.Elite.HP) +# 1 - (Rate.Creature.Elite.RARE.HP) +# 1 - (Rate.Creature.Elite.RAREELITE.HP) +# 1 - (Rate.Creature.Elite.WORLDBOSS.HP) + +Rate.Creature.Normal.HP = 1 +Rate.Creature.Elite.Elite.HP = 1 +Rate.Creature.Elite.RARE.HP = 1 +Rate.Creature.Elite.RAREELITE.HP = 1 +Rate.Creature.Elite.WORLDBOSS.HP = 1 -################################################################################################### -# AUTO BROADCAST # -# AutoBroadcast.On -# Description: Enable auto broadcast. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# ListenRange.Say +# Description: Distance in which players can read say messages from creatures or +# gameobjects. +# Default: 40 -AutoBroadcast.On = 0 +ListenRange.Say = 40 # -# AutoBroadcast.Center -# Description: Auto broadcasting display method. -# Default: 0 - (Announce) -# 1 - (Notify) -# 2 - (Both) +# ListenRange.TextEmote +# Description: Distance in which players can read emotes from creatures or gameobjects. +# Default: 40 -AutoBroadcast.Center = 0 +ListenRange.TextEmote = 40 # -# AutoBroadcast.Timer -# Description: Timer (in milliseconds) for auto broadcasts. -# Default: 60000 - (60 seconds) +# ListenRange.Yell +# Description: Distance in which players can read yell messages from creatures or +# gameobjects. +# Default: 300 -AutoBroadcast.Timer = 60000 +ListenRange.Yell = 300 # -# AutoBroadcast.MinDisableLevel -# Description: Minimum level required to disable autobroadcast announcements if EnablePlayerSettings option is enabled. -# Default: 0 - (Not allowed to disable it) +# Creature.MovingStopTimeForPlayer +# Description: Time (in milliseconds) during which creature will not move after +# interaction with player. +# Default: 180000 -AutoBroadcast.MinDisableLevel = 0 +Creature.MovingStopTimeForPlayer = 180000 -# -################################################################################################### +# WaypointMovementStopTimeForPlayer +# Description: Specifies the time (in seconds) that a creature with waypoint +# movement will wait after a player interacts with it. +# default: 120 -################################################################################################### -# BATTLEGROUND CONFIG +WaypointMovementStopTimeForPlayer = 120 + +# NpcEvadeIfTargetIsUnreachable +# Description: Specifies the time (in seconds) that a creature whom target +# is unreachable to end up in evade mode. +# Default: 5 + +NpcEvadeIfTargetIsUnreachable = 5 + +# NpcRegenHPIfTargetIsUnreachable +# Description: Regenerates HP for Creatures in Raids if they cannot reach the target. +# Keep disabled if you are experiencing mmaps/pathing issues. # -# Battleground.CastDeserter -# Description: Cast Deserter spell at players who leave battlegrounds in progress. # Default: 1 - (Enabled) # 0 - (Disabled) -Battleground.CastDeserter = 1 +NpcRegenHPIfTargetIsUnreachable = 1 -# -# Battleground.QueueAnnouncer.Enable -# Description: Announce battleground queue status to chat. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# NpcRegenHPTimeIfTargetIsUnreachable +# Description: Specifies the time (in seconds) that a creature whom target +# is unreachable in raid to end up regenerate health. +# Default: 10 + +NpcRegenHPTimeIfTargetIsUnreachable = 10 + +# Creatures.CustomIDs +# Description: The list of custom creatures with gossip dialogues hardcoded in core, +# divided by "," without spaces. +# It is implied that you do not use for these NPC dialogs data from "gossip_menu" table. +# Server will skip these IDs during the definitions validation process. +# Example: Creatures.CustomIDs = "190010,55005,999991,25462,98888,601014" - Npcs for Transmog, Guild-zone, 1v1-arena, Skip Dk, +# Racial Trait Swap, NPC - All Mounts Modules +# Default: "" -Battleground.QueueAnnouncer.Enable = 0 +Creatures.CustomIDs = "190010,55005,999991,25462,98888,601014,34567,34568" # -# Battleground.QueueAnnouncer.Limit.MinLevel -# Description: Limit the QueueAnnouncer starting from a certain level. -# When limited, it announces only if there are at least MinPlayers queued (see below) -# At 80 it only limits RBG, at lower level only limits Warsong Gulch. -# Default: 0 - (Disabled, no limits) -# 10 - (Enabled for all, because BGs start at 10) -# 20 - (Enabled for 20 and higher) -# 80 - (Enabled only for 80) - -Battleground.QueueAnnouncer.Limit.MinLevel = 0 +################################################################################################### +################################################################################################### +# VENDOR # -# Battleground.QueueAnnouncer.Limit.MinPlayers -# Description: When the Battleground.QueueAnnouncer.Limit.MinLevel limit is enabled (not 0) -# only show when at least MinPlayers are queued. -# Default: 3 - (Show only when 3 or more players are queued) +# Rate.SellValue.Item.Poor +# Rate.SellValue.Item.Normal +# Rate.SellValue.Item.Uncommon +# Rate.SellValue.Item.Rare +# Rate.SellValue.Item.Epic +# Rate.SellValue.Item.Legendary +# Rate.SellValue.Item.Artifact +# Rate.SellValue.Item.Heirloom +# Description: Item Sale Value rates based on quality. +# Default: 1 - (Rate.SellValue.Item.Poor) +# 1 - (Rate.SellValue.Item.Normal) +# 1 - (Rate.SellValue.Item.Uncommon) +# 1 - (Rate.SellValue.Item.Rare) +# 1 - (Rate.SellValue.Item.Epic) +# 1 - (Rate.SellValue.Item.Legendary) +# 1 - (Rate.SellValue.Item.Artifact) +# 1 - (Rate.SellValue.Item.Heirloom) -Battleground.QueueAnnouncer.Limit.MinPlayers = 3 +Rate.SellValue.Item.Poor = 1 +Rate.SellValue.Item.Normal = 1 +Rate.SellValue.Item.Uncommon = 1 +Rate.SellValue.Item.Rare = 1 +Rate.SellValue.Item.Epic = 1 +Rate.SellValue.Item.Legendary = 1 +Rate.SellValue.Item.Artifact = 1 +Rate.SellValue.Item.Heirloom = 1 # -# Battleground.QueueAnnouncer.SpamProtection.Delay -# Description: Show announce if player rejoined in queue after sec -# Default: 30 -# +# Rate.BuyValue.Item.Poor +# Rate.BuyValue.Item.Normal +# Rate.BuyValue.Item.Uncommon +# Rate.BuyValue.Item.Rare +# Rate.BuyValue.Item.Epic +# Rate.BuyValue.Item.Legendary +# Rate.BuyValue.Item.Artifact +# Rate.BuyValue.Item.Heirloom +# Description: Item Sale Value rates based on quality. +# Default: 1 - (Rate.BuyValue.Item.Poor) +# 1 - (Rate.BuyValue.Item.Normal) +# 1 - (Rate.BuyValue.Item.Uncommon) +# 1 - (Rate.BuyValue.Item.Rare) +# 1 - (Rate.BuyValue.Item.Epic) +# 1 - (Rate.BuyValue.Item.Legendary) +# 1 - (Rate.BuyValue.Item.Artifact) +# 1 - (Rate.BuyValue.Item.Heirloom) -Battleground.QueueAnnouncer.SpamProtection.Delay = 30 +Rate.BuyValue.Item.Poor = 1 +Rate.BuyValue.Item.Normal = 1 +Rate.BuyValue.Item.Uncommon = 1 +Rate.BuyValue.Item.Rare = 1 +Rate.BuyValue.Item.Epic = 1 +Rate.BuyValue.Item.Legendary = 1 +Rate.BuyValue.Item.Artifact = 1 +Rate.BuyValue.Item.Heirloom = 1 # -# Battleground.QueueAnnouncer.PlayerOnly -# Description: Battleground queue announcement type. -# Default: 0 - (System message, Anyone can see it) -# 1 - (Private, Only queued players can see it) +# Rate.RepairCost +# Description: Repair cost rate. +# Default: 1 -Battleground.QueueAnnouncer.PlayerOnly = 0 +Rate.RepairCost = 1 # -# Battleground.QueueAnnouncer.Timed -# Description: Enabled battleground queue announcements based on timer -# Default: 0 - (Disabled) -# 1 - (Enabled - Set Arena.QueueAnnouncer.Timer) -# - -Battleground.QueueAnnouncer.Timed = 0 +################################################################################################### +################################################################################################### +# GROUP # -# Battleground.QueueAnnouncer.Timer -# Description: Set timer for queue announcements -# Default: 30000 (30 sec) +# LeaveGroupOnLogout.Enabled +# Description: Should the player leave their group when they log out? +# (It does not affect raids or dungeon finder groups) # +# Default: 1 - (Enabled) -Battleground.QueueAnnouncer.Timer = 30000 +LeaveGroupOnLogout.Enabled = 1 # -# Battleground.PrematureFinishTimer -# Description: Time (in milliseconds) before battleground will end prematurely if there are -# not enough players on one team. (Values defined in battleground template) -# Default: 300000 - (Enabled, 5 minutes) -# 0 - (Disabled, Not recommended) - -Battleground.PrematureFinishTimer = 300000 - +# Group.Raid.LevelRestriction +# +# The Group members need to the same, or higher level than the specified value. +# Minimum level is 10. +# Default: 10 # -# Battleground.PremadeGroupWaitForMatch -# Description: Time (in milliseconds) a pre-made group has to wait for matching group of the -# other faction. -# Default: 1800000 - (Enabled, 30 minutes) -# 0 - (Disabled, Not recommended) -Battleground.PremadeGroupWaitForMatch = 1800000 +Group.Raid.LevelRestriction = 10 # -# Battleground.GiveXPForKills -# Description: Give experience for honorable kills in battlegrounds. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -Battleground.GiveXPForKills = 0 +################################################################################################### +################################################################################################### +# INSTANCE # -# Battleground.Random.ResetHour -# Description: Hour of the day when the global instance resets occur. -# Range: 0-23 -# Default: 6 - (06:00 AM) +# Instance.GMSummonPlayer +# Description: Allow GM to summon players or only other GM accounts inside instances. +# Default: 0 - (Disabled, Only GM accounts can be summoned by GM) +# 1 - (Enabled, GM and Player accounts can be summoned by GM) -Battleground.Random.ResetHour = 6 +Instance.GMSummonPlayer = 0 -# Battleground.StoreStatistics.Enable -# Description: Store Battleground scores in the database. +# +# Instance.IgnoreLevel +# Description: Ignore level requirement when entering instances. # Default: 0 - (Disabled) # 1 - (Enabled) -Battleground.StoreStatistics.Enable = 1 +Instance.IgnoreLevel = 0 -# Battleground.TrackDeserters.Enable -# Description: Track deserters of Battlegrounds. +# +# Instance.IgnoreRaid +# Description: Ignore raid group requirement when entering instances. # Default: 0 - (Disabled) # 1 - (Enabled) -Battleground.TrackDeserters.Enable = 1 +Instance.IgnoreRaid = 0 # -# Battleground.InvitationType -# Description: Set Battleground invitation type. -# Default: 0 - (Normal, Invite as much players to battlegrounds as queued, -# Don't bother with balance) -# 1 - (Experimental, Don't allow to invite much more players -# of one faction) -# 2 - (Experimental, Try to have even teams) +# Instance.ResetTimeHour +# Description: Hour of the day when the global instance reset occurs. +# Range: 0-23 +# Default: 4 - (04:00 AM) -Battleground.InvitationType = 0 +Instance.ResetTimeHour = 4 # -# Battleground.ReportAFK.Timer -# Description: After a few minutes that battle started you can report the player. -# Default: 4 +# Instance.ResetTimeRelativeTimestamp +# Description: Needed for displaying valid instance reset times in ingame calendar. +# This timestamp should be set to a date in the past (midnight) on which +# both 3-day and 7-day raids were reset. +# Default: 1135814400 - (Thu, 29 Dec 2005 00:00:00 GMT - meaning that 7-day raid reset falls on Thursdays, +# while 3-day reset falls on "Thu 29 Dec 2005", "Sun 01 Jan 2006", "Wed 04 Jan 2006", and so on) -Battleground.ReportAFK.Timer = 4 +Instance.ResetTimeRelativeTimestamp = 1135814400 # -# Battleground.ReportAFK -# Description: Number of reports needed to kick someone AFK from Battleground. -# Range: 1-9 -# Default: 3 +# Rate.InstanceResetTime +# Description: Multiplier for the rate between global raid/heroic instance resets +# (dbc value). Higher value increases the time between resets, +# lower value lowers the time, you need clean instance_reset in +# characters db in order to let new values work. +# Default: 1 -Battleground.ReportAFK = 3 +Rate.InstanceResetTime = 1 -# Battleground.DisableQuestShareInBG -# Description: Disables the ability to share quests while in a Battleground. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# +# Instance.UnloadDelay +# Description: Time (in milliseconds) before instance maps are unloaded from memory if no +# characters are inside. +# Default: 1800000 - (Enabled, 30 minutes) +# 0 - (Disabled, Instance maps are kept in memory until the instance +# resets) -Battleground.DisableQuestShareInBG = 0 +Instance.UnloadDelay = 1800000 # -# Battleground.DisableReadyCheckInBG -# Description: Disables the ability to send a Ready Check survey while in a Battleground. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# AccountInstancesPerHour +# Description: Controls the max amount of different instances player can enter within hour +# Default: 5 -Battleground.DisableReadyCheckInBG = 0 +AccountInstancesPerHour = 5 # -# Battleground.RewardWinnerHonorFirst -# Battleground.RewardWinnerArenaFirst -# Battleground.RewardWinnerHonorLast -# Battleground.RewardWinnerArenaLast -# Battleground.RewardLoserHonorFirst -# Battleground.RewardLoserHonorLast -# Description: Random Battlegrounds / call to the arms rewards -# Default: 30 - Battleground.RewardWinnerHonorFirst -# 25 - Battleground.RewardWinnerArenaFirst -# 15 - Battleground.RewardWinnerHonorLast -# 0 - Battleground.RewardWinnerArenaLast -# 5 - Battleground.RewardLoserHonorFirst -# 5 - Battleground.RewardLoserHonorLast +# Instance.SharedNormalHeroicId +# Description: Forces ICC and RS Normal and Heroic to share lockouts. ToC is uneffected and Normal and Heroic will be separate. +# Default: 1 - Enable +# 0 - Disable # -Battleground.RewardWinnerHonorFirst = 30 -Battleground.RewardWinnerArenaFirst = 25 -Battleground.RewardWinnerHonorLast = 15 -Battleground.RewardWinnerArenaLast = 0 -Battleground.RewardLoserHonorFirst = 5 -Battleground.RewardLoserHonorLast = 5 +Instance.SharedNormalHeroicId = 1 # -# Battleground.PlayerRespawn -# Description: Battleground player resurrection interval (in seconds). -# Default: 30 - -Battleground.PlayerRespawn = 30 - +# DungeonAccessRequirements.PrintMode +# +# Description: Select the preferred format to display information to the player who cannot enter a portal dungeon because when has not met the access requirements: +# Default: 1 - (Display only one requirement at a time (BlizzLike, like in the LFG interface)) +# 0 - (Display no extra information, only "Requirements not met") +# 2 - (Display detailed requirements, all at once, with clickable links) # -# Battleground.RestorationBuffRespawn -# Description: Battleground restoration buff respawn time (in seconds). -# Default: 20 (Recommended 10+) -Battleground.RestorationBuffRespawn = 20 +DungeonAccessRequirements.PrintMode = 1 # -# Battleground.BerserkingBuffRespawn -# Description: Battleground berserking buff respawn time (in seconds). -# Default: 120 (Recommended 10+) +# DungeonAccessRequirements.PortalAvgIlevelCheck +# +# Description: Enable average item level requirement when entering a dungeon/raid's portal (= deny the entry if player has too low average ilevel, like in LFG). +# Default: 0 - (Disabled -> Blizzlike) +# 1 - (Enabled) -Battleground.BerserkingBuffRespawn = 120 +DungeonAccessRequirements.PortalAvgIlevelCheck = 0 # -# Battleground.SpeedBuffRespawn -# Description: Battleground speed buff respawn time (in seconds). -# Default: 150 (Recommended 10+) +# DungeonAccessRequirements.OptionalStringID +# +# Description: Display an extra message from acore_strings in the chat after printing the dungeon access requirements. +# To enable it set the ID of your desired string from the table acore_strings +# Default: 0 - (Disabled) +# 1+ - (Enabled) -Battleground.SpeedBuffRespawn = 150 +DungeonAccessRequirements.OptionalStringID = 0 # ################################################################################################### ################################################################################################### -# BATTLEFIELD CONFIG +# DUNGEON AND BATTLEGROUND FINDER # -# Wintergrasp.Enable -# Description: Enable the Wintergrasp battlefield. -# Default: 1 - (Enabled, Experimental as of still being in development) -# 0 - (Battleground disabled, Wintergrasp world processing still occurs) -# 2 - (Disable all Wintergrasp processing) +# JoinBGAndLFG.Enable +# Description: Allow queueing for BG and LFG at the same time. +# Default: 0 - Disabled +# 1 - Enabled -Wintergrasp.Enable = 1 +JoinBGAndLFG.Enable = 0 # -# Wintergrasp.PlayerMax -# Description: Maximum number of players allowed in Wintergrasp. -# Default: 100 +# DungeonFinder.OptionsMask +# Description: Dungeon and raid finder system. +# Value is a bitmask consisting of: +# LFG_OPTION_ENABLE_DUNGEON_FINDER = 1, Enable the dungeon finder browser +# LFG_OPTION_ENABLE_RAID_BROWSER = 2, Enable the raid browser +# LFG_OPTION_ENABLE_SEASONAL_BOSSES = 4, Enable seasonal bosses +# Default: 5 -Wintergrasp.PlayerMax = 120 +DungeonFinder.OptionsMask = 5 # -# Wintergrasp.PlayerMin -# Description: Minimum number of players required for Wintergrasp. -# Default: 0 - -Wintergrasp.PlayerMin = 0 - +# LFG.Location.All # -# Wintergrasp.PlayerMinLvl -# Description: Required character level for the Wintergrasp battle. -# Default: 77 - -Wintergrasp.PlayerMinLvl = 77 - +# Includes satellite to search for work elsewhere LFG +# Default: 0 - Disable +# 1 - Enable # -# Wintergrasp.BattleTimer -# Description: Time (in minutes) for the Wintergrasp battle to last. -# Default: 30 -Wintergrasp.BattleTimer = 30 +LFG.Location.All = 0 # -# Wintergrasp.NoBattleTimer -# Description: Time (in minutes) between Wintergrasp battles. -# Default: 150 +# LFG.MaxKickCount +# Description: Specify the maximum number of kicks allowed in LFG groups (max 3 kicks) +# Default: 2 +# 0 - Disabled (kicks are never allowed) -Wintergrasp.NoBattleTimer = 150 +LFG.MaxKickCount = 2 # -# Wintergrasp.CrashRestartTimer -# Description: Time (in minutes) to delay the restart of Wintergrasp if the world server -# crashed during a running battle. -# Default: 10 +# LFG.KickPreventionTimer +# Description: Specify for how long players are prevented from being kicked after just joining LFG groups +# Default: 900 secs (15 minutes) +# 0 - Disabled -Wintergrasp.CrashRestartTimer = 10 +LFG.KickPreventionTimer = 900 # -################################################################################################### - -################################################################################################### -# ARENA CONFIG +# DungeonAccessRequirements.LFGLevelDBCOverride # -# Arena.MaxRatingDifference -# Description: Maximum rating difference between two teams in rated matches. -# Default: 150 - (Enabled) -# 0 - (Disabled) +# Description: If enabled, use `min_level` and `max_level` values from table `dungeon_access_requirements` to list or to hide a dungeon from the LFG window. +# Default: 0 - (Disabled) +# 1 - (Enabled) -Arena.MaxRatingDifference = 150 +DungeonAccessRequirements.LFGLevelDBCOverride = 0 # -# Arena.RatingDiscardTimer -# Description: Time (in milliseconds) after which rating differences are ignored when -# setting up matches. -# Default: 600000 - (Enabled, 10 minutes) -# 0 - (Disabled) - -Arena.RatingDiscardTimer = 600000 +################################################################################################### +################################################################################################### +# CHARTER # -# Arena.PreviousOpponentsDiscardTimer -# Description: Time (in milliseconds) after which the previous opponents will be ignored. -# Default: 120000 - (Enabled, 2 minutes - Blizzlike) -# 0 - (Disabled) +# MinCharterName +# Description: Minimal charter name length. +# Range: 1-24 +# Default: 2 -Arena.PreviousOpponentsDiscardTimer = 120000 +MinCharterName = 2 # -# Arena.AutoDistributePoints -# Description: Automatically distribute arena points. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# StrictCharterNames +# Description: Limit guild/arena team charter names to language specific symbol set. +# Prevents charter creation if not allowed symbols are used. +# Default: 0 - (Disable, Limited server timezone dependent client check) +# 1 - (Enabled, Strictly basic Latin characters) +# 2 - (Enabled, Strictly realm zone specific, See RealmZone setting, +# Note: Client needs to have the appropriate fonts installed which support +# the charset. For non-official localization, custom fonts need to be +# placed in clientdir/Fonts. +# 3 - (Enabled, Basic Latin characters + server timezone specific) -Arena.AutoDistributePoints = 0 +StrictCharterNames = 0 # -# Arena.AutoDistributeInterval -# Description: Time (in days) how often arena points should be distributed if automatic -# distribution is enabled. -# Default: 7 - (Weekly) - -Arena.AutoDistributeInterval = 7 +################################################################################################### +################################################################################################### +# GUILD # -# Arena.GamesRequired -# Description: Number of arena matches teams must participate in to be eligible for arena point distribution. -# Default: 10 +# Guild.EventLogRecordsCount +# Description: Number of log entries for guild events that are stored per guild. Old entries +# will be overwritten if the number of log entries exceed the configured value. +# High numbers prevent this behavior but may have performance impacts. +# Default: 100 -Arena.GamesRequired = 10 +Guild.EventLogRecordsCount = 100 # -# Arena.QueueAnnouncer.Enable -# Description: Announce arena queue status to chat. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Guild.ResetHour +# Description: Hour of the day when the daily cap resets occur. +# Range: 0-23 +# Default: 6 - (06:00 AM) -Arena.QueueAnnouncer.Enable = 0 +Guild.ResetHour = 6 # -# Arena.QueueAnnouncer.PlayerOnly -# Description: Arena queue announcement type. -# Default: 0 - (System message, Anyone can see it) -# 1 - (Private, Only queued players can see it) -# +# Guild.BankEventLogRecordsCount +# Description: Number of log entries for guild bank events that are stored per guild. Old +# entries will be overwritten if the number of log entries exceed the +# configured value. High numbers prevent this behavior but may have performance +# impacts. +# Default: 25 - (Minimum) -Arena.QueueAnnouncer.PlayerOnly = 0 +Guild.BankEventLogRecordsCount = 25 # -# Arena.QueueAnnouncer.Detail -# Description: The amount of detail to announce on teams queued for arenas. -# Default: 3 - (Announce the team's name and rating) -# 2 - (Announce only the team's name) -# 1 - (Announce only the team's rating) -# 0 - (Do not announce any information about the teams) -# +# MinPetitionSigns +# Description: Number of required signatures on charters to create a guild. +# Range: 0-9 +# Default: 9 -Arena.QueueAnnouncer.Detail = 3 +MinPetitionSigns = 9 # -# Arena.ArenaSeason.ID -# Description: Current arena season id shown in clients. -# Default: 8 +# Guild.CharterCost +# Description: Amount of money (in Copper) the petitions costs. +# Default: 1000 - (10 Silver) -Arena.ArenaSeason.ID = 8 +Guild.CharterCost = 1000 # -# Arena.ArenaSeason.InProgress -# Description: State of current arena season. -# Default: 1 - (Active) -# 0 - (Finished) +# Guild.AllowMultipleGuildMaster +# Description: Allow more than one guild master. Additional Guild Masters must be set using +# the ".guild rank" command. +# Default: 0 - (Disabled) +# 1 - (Enabled) -Arena.ArenaSeason.InProgress = 1 +Guild.AllowMultipleGuildMaster = 0 # -# Arena.ArenaStartRating -# Description: Start rating for new arena teams. -# Default: 0 +# Guild.BankInitialTabs +# Description: Changes the amounts of available tabs of the guild bank on guild creation +# Default: 0 (no tabs given for free) +# 1-6 (amount of tabs of the guild bank at guild creation) -Arena.ArenaStartRating = 0 +Guild.BankInitialTabs = 0 # -# Arena.ArenaStartPersonalRating -# Description: Start personal rating when joining a team. -# Default: 0 +# Guild.BankTabCost0-5 +# Description: Changes the price of the guild tabs. Note that the client will still show the default values. +# Default: 1000000 - (100 Gold) +# 2500000 - (250 Gold) +# 5000000 - (500 Gold) +# 10000000 - (1000 Gold) +# 25000000 - (2500 Gold) +# 50000000 - (5000 Gold) -Arena.ArenaStartPersonalRating = 0 +Guild.BankTabCost0 = 1000000 +Guild.BankTabCost1 = 2500000 +Guild.BankTabCost2 = 5000000 +Guild.BankTabCost3 = 10000000 +Guild.BankTabCost4 = 25000000 +Guild.BankTabCost5 = 50000000# # -# Arena.ArenaStartMatchmakerRating -# Description: Start matchmaker rating for players. -# Default: 1500 - -Arena.ArenaStartMatchmakerRating = 1500 +################################################################################################### +################################################################################################### +# FFAPVP # -# Arena.ArenaWinRatingModifier1 -# Description: Modifier of rating addition when winner team rating is less than 1300 -# be aware that from 1000 to 1300 it gradually decreases automatically down to the half of it -# (increasing this value will give more rating) -# Default: 48 +# FFAPvPTimer +# Description: Specify time offset when player unset FFAPvP flag when leaving FFAPvP area. (e.g. Gurubashi Arena) +# Default: 30 sec -Arena.ArenaWinRatingModifier1 = 48 +FFAPvPTimer = 30 # -# Arena.ArenaWinRatingModifier2 -# Description: Modifier of rating addition when winner team rating is equal or more than 1300 -# (increasing this value will give more rating) -# Default: 24 - -Arena.ArenaWinRatingModifier2 = 24 +################################################################################################### +################################################################################################### +# WINTERGRASP # -# Arena.ArenaLoseRatingModifier -# Description: Modifier of rating subtraction for loser team -# (increasing this value will subtract more rating) -# Default: 24 +# Wintergrasp.Enable +# Description: Enable the Wintergrasp battlefield. +# Default: 1 - (Enabled, Experimental as of still being in development) +# 0 - (Battleground disabled, Wintergrasp world processing still occurs) +# 2 - (Disable all Wintergrasp processing) -Arena.ArenaLoseRatingModifier = 24 +Wintergrasp.Enable = 1 # -# Arena.ArenaMatchmakerRatingModifier -# Description: Modifier of matchmaker rating -# Default: 24 +# Wintergrasp.PlayerMax +# Description: Maximum number of players allowed in Wintergrasp. +# Default: 100 -Arena.ArenaMatchmakerRatingModifier = 24 +Wintergrasp.PlayerMax = 120 # -################################################################################################### +# Wintergrasp.PlayerMin +# Description: Minimum number of players required for Wintergrasp. +# Default: 0 + +Wintergrasp.PlayerMin = 0 -################################################################################################### -# NETWORK CONFIG # -# Network.Threads -# Description: Number of threads for network. -# Default: 1 - (Recommended 1 thread per 1000 connections) +# Wintergrasp.PlayerMinLvl +# Description: Required character level for the Wintergrasp battle. +# Default: 77 -Network.Threads = 1 +Wintergrasp.PlayerMinLvl = 77 # -# Network.OutKBuff -# Description: Amount of memory (in bytes) used for the output kernel buffer (see SO_SNDBUF -# socket option, TCP manual). -# Default: -1 - (Use system default setting) +# Wintergrasp.BattleTimer +# Description: Time (in minutes) for the Wintergrasp battle to last. +# Default: 30 -Network.OutKBuff = -1 +Wintergrasp.BattleTimer = 30 # -# Network.OutUBuff -# Description: Amount of memory (in bytes) reserved in the user space per connection for -# output buffering. -# Default: 65536 +# Wintergrasp.NoBattleTimer +# Description: Time (in minutes) between Wintergrasp battles. +# Default: 150 -Network.OutUBuff = 65536 +Wintergrasp.NoBattleTimer = 150 # -# Network.TcpNoDelay: -# Description: TCP Nagle algorithm setting. -# Default: 0 - (Enabled, Less traffic, More latency) -# 1 - (Disabled, More traffic, Less latency, TCP_NO_DELAY) +# Wintergrasp.CrashRestartTimer +# Description: Time (in minutes) to delay the restart of Wintergrasp if the world server +# crashed during a running battle. +# Default: 10 -Network.TcpNodelay = 1 +Wintergrasp.CrashRestartTimer = 10 # ################################################################################################### ################################################################################################### -# CONSOLE AND REMOTE ACCESS +# BATTLEGROUND # -# Console.Enable -# Description: Enable console. +# Battleground.CastDeserter +# Description: Cast Deserter spell at players who leave battlegrounds in progress. # Default: 1 - (Enabled) # 0 - (Disabled) -Console.Enable = 1 +Battleground.CastDeserter = 1 # -# Ra.Enable -# Description: Enable remote console (telnet). +# Battleground.QueueAnnouncer.Enable +# Description: Announce battleground queue status to chat. # Default: 0 - (Disabled) # 1 - (Enabled) -Ra.Enable = 0 +Battleground.QueueAnnouncer.Enable = 0 # -# Ra.IP -# Description: Bind remote access to IP/hostname. -# Default: "0.0.0.0" - (Bind to all IPs on the system) +# Battleground.QueueAnnouncer.Limit.MinLevel +# Description: Limit the QueueAnnouncer starting from a certain level. +# When limited, it announces only if there are at least MinPlayers queued (see below) +# At 80 it only limits RBG, at lower level only limits Warsong Gulch. +# Default: 0 - (Disabled, no limits) +# 10 - (Enabled for all, because BGs start at 10) +# 20 - (Enabled for 20 and higher) +# 80 - (Enabled only for 80) -Ra.IP = "0.0.0.0" +Battleground.QueueAnnouncer.Limit.MinLevel = 0 # -# Ra.Port -# Description: TCP port to reach the remote console. -# Default: 3443 +# Battleground.QueueAnnouncer.Limit.MinPlayers +# Description: When the Battleground.QueueAnnouncer.Limit.MinLevel limit is enabled (not 0) +# only show when at least MinPlayers are queued. +# Default: 3 - (Show only when 3 or more players are queued) -Ra.Port = 3443 +Battleground.QueueAnnouncer.Limit.MinPlayers = 3 # -# Ra.MinLevel -# Description: Required security level to use the remote console. -# Default: 3 +# Battleground.QueueAnnouncer.SpamProtection.Delay +# Description: Show announce if player rejoined in queue after sec +# Default: 30 +# -Ra.MinLevel = 3 +Battleground.QueueAnnouncer.SpamProtection.Delay = 30 # -# SOAP.Enable -# Description: Enable soap service -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Battleground.QueueAnnouncer.PlayerOnly +# Description: Battleground queue announcement type. +# Default: 0 - (System message, Anyone can see it) +# 1 - (Private, Only queued players can see it) -SOAP.Enabled = 0 +Battleground.QueueAnnouncer.PlayerOnly = 0 # -# SOAP.IP -# Description: Bind SOAP service to IP/hostname -# Default: "127.0.0.1" - (Bind to localhost) +# Battleground.QueueAnnouncer.Timed +# Description: Enabled battleground queue announcements based on timer +# Default: 0 - (Disabled) +# 1 - (Enabled - Set Arena.QueueAnnouncer.Timer) +# -SOAP.IP = "127.0.0.1" +Battleground.QueueAnnouncer.Timed = 0 # -# SOAP.Port -# Description: TCP port to reach the SOAP service. -# Default: 7878 +# Battleground.QueueAnnouncer.Timer +# Description: Set timer for queue announcements +# Default: 30000 (30 sec) +# -SOAP.Port = 7878 +Battleground.QueueAnnouncer.Timer = 30000 # -################################################################################################### +# Battleground.PrematureFinishTimer +# Description: Time (in milliseconds) before battleground will end prematurely if there are +# not enough players on one team. (Values defined in battleground template) +# Default: 300000 - (Enabled, 5 minutes) +# 0 - (Disabled, Not recommended) + +Battleground.PrematureFinishTimer = 300000 -################################################################################################### -# CHARACTER DELETE OPTIONS # -# CharDelete.Method -# Description: Character deletion behavior. -# Default: 0 - (Completely remove character from the database) -# 1 - (Unlink the character from account and free up the name, Appears as -# deleted ingame) +# Battleground.PremadeGroupWaitForMatch +# Description: Time (in milliseconds) a pre-made group has to wait for matching group of the +# other faction. +# Default: 1800000 - (Enabled, 30 minutes) +# 0 - (Disabled, Not recommended) -CharDelete.Method = 0 +Battleground.PremadeGroupWaitForMatch = 1800000 # -# CharDelete.MinLevel -# Description: Required level to use the unlinking method if enabled. -# Default: 0 - (Same method for every level) -# 1+ - (Only characters with the specified level will use the unlinking method) +# Battleground.GiveXPForKills +# Description: Give experience for honorable kills in battlegrounds. +# Default: 0 - (Disabled) +# 1 - (Enabled) -CharDelete.MinLevel = 0 +Battleground.GiveXPForKills = 0 # -# CharDelete.KeepDays -# Description: Time (in days) before unlinked characters will be removed from the database. -# Default: 30 - (Enabled) -# 0 - (Disabled, Don't delete any characters) +# Battleground.Random.ResetHour +# Description: Hour of the day when the global instance resets occur. +# Range: 0-23 +# Default: 6 - (06:00 AM) -CharDelete.KeepDays = 30 +Battleground.Random.ResetHour = 6 -# -################################################################################################### +# Battleground.StoreStatistics.Enable +# Description: Store Battleground scores in the database. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Battleground.StoreStatistics.Enable = 1 + +# Battleground.TrackDeserters.Enable +# Description: Track deserters of Battlegrounds. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Battleground.TrackDeserters.Enable = 1 -################################################################################################### -# ITEM DELETE OPTIONS # -# ItemDelete.Method -# Description: Item deletion behavior. -# Default: 0 - (Completely remove item from the database) -# 1 - (Save Item to database) +# Battleground.InvitationType +# Description: Set Battleground invitation type. +# Default: 0 - (Normal, Invite as much players to battlegrounds as queued, +# Don't bother with balance) +# 1 - (Experimental, Don't allow to invite much more players +# of one faction) +# 2 - (Experimental, Try to have even teams) -ItemDelete.Method = 0 +Battleground.InvitationType = 0 # -# ItemDelete.Vendor -# Description: Saving items into database when the player sells items to vendor -# Default: 0 (disabled) -# 1 (enabled) +# Battleground.ReportAFK.Timer +# Description: After a few minutes that battle started you can report the player. +# Default: 4 + +Battleground.ReportAFK.Timer = 4 + # +# Battleground.ReportAFK +# Description: Number of reports needed to kick someone AFK from Battleground. +# Range: 1-9 +# Default: 3 -ItemDelete.Vendor = 0 +Battleground.ReportAFK = 3 + +# Battleground.DisableQuestShareInBG +# Description: Disables the ability to share quests while in a Battleground. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Battleground.DisableQuestShareInBG = 0 # -# ItemDelete.Quality -# Description: Saving items into database that have quality greater or equal to ItemDelete.Quality +# Battleground.DisableReadyCheckInBG +# Description: Disables the ability to send a Ready Check survey while in a Battleground. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Battleground.DisableReadyCheckInBG = 0 + # -# ID | Color | Quality -# 0 | Grey | Poor -# 1 | White | Common -# 2 | Green | Uncommon -# 3 | Blue | Rare -# 4 | Purple| Epic -# 5 | Orange| Legendary -# 6 | Red | Artifact -# 7 | Gold | Bind to Account +# Battleground.RewardWinnerHonorFirst +# Battleground.RewardWinnerArenaFirst +# Battleground.RewardWinnerHonorLast +# Battleground.RewardWinnerArenaLast +# Battleground.RewardLoserHonorFirst +# Battleground.RewardLoserHonorLast +# Description: Random Battlegrounds / call to the arms rewards +# Default: 30 - Battleground.RewardWinnerHonorFirst +# 25 - Battleground.RewardWinnerArenaFirst +# 15 - Battleground.RewardWinnerHonorLast +# 0 - Battleground.RewardWinnerArenaLast +# 5 - Battleground.RewardLoserHonorFirst +# 5 - Battleground.RewardLoserHonorLast # -# Default: 3 + +Battleground.RewardWinnerHonorFirst = 30 +Battleground.RewardWinnerArenaFirst = 25 +Battleground.RewardWinnerHonorLast = 15 +Battleground.RewardWinnerArenaLast = 0 +Battleground.RewardLoserHonorFirst = 5 +Battleground.RewardLoserHonorLast = 5 + # +# Battleground.PlayerRespawn +# Description: Battleground player resurrection interval (in seconds). +# Default: 30 -ItemDelete.Quality = 3 +Battleground.PlayerRespawn = 30 # -# ItemDelete.ItemLevel -# Description: Saving items into database that are Item Levels greater or equal to ItemDelete.ItemLevel -# Default: 80 -# +# Battleground.RestorationBuffRespawn +# Description: Battleground restoration buff respawn time (in seconds). +# Default: 20 (Recommended 10+) -ItemDelete.ItemLevel = 80 +Battleground.RestorationBuffRespawn = 20 # -################################################################################################### +# Battleground.BerserkingBuffRespawn +# Description: Battleground berserking buff respawn time (in seconds). +# Default: 120 (Recommended 10+) + +Battleground.BerserkingBuffRespawn = 120 -################################################################################################### -# CUSTOM SERVER OPTIONS # -# PlayerStart.AllReputation -# Description: Players will start with most of the high level reputations that are needed -# for items, mounts etc. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Battleground.SpeedBuffRespawn +# Description: Battleground speed buff respawn time (in seconds). +# Default: 150 (Recommended 10+) -PlayerStart.AllReputation = 0 +Battleground.SpeedBuffRespawn = 150 # -# PlayerStart.CustomSpells -# Description: If enabled, players will start with custom spells defined in -# playercreateinfo_spell_custom table. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -PlayerStart.CustomSpells = 0 +################################################################################################### +################################################################################################### +# ARENA # -# PlayerStart.MapsExplored -# Description: Characters start with all maps explored. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Arena.MaxRatingDifference +# Description: Maximum rating difference between two teams in rated matches. +# Default: 150 - (Enabled) +# 0 - (Disabled) -PlayerStart.MapsExplored = 0 +Arena.MaxRatingDifference = 150 # -# HonorPointsAfterDuel -# Description: Amount of honor points the duel winner will get after a duel. -# Default: 0 - (Disabled) -# 1+ - (Enabled) +# Arena.RatingDiscardTimer +# Description: Time (in milliseconds) after which rating differences are ignored when +# setting up matches. +# Default: 600000 - (Enabled, 10 minutes) +# 0 - (Disabled) -HonorPointsAfterDuel = 0 +Arena.RatingDiscardTimer = 600000 # -# AlwaysMaxWeaponSkill -# Description: Players will automatically gain max weapon/defense skill when logging in, -# or leveling. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Arena.PreviousOpponentsDiscardTimer +# Description: Time (in milliseconds) after which the previous opponents will be ignored. +# Default: 120000 - (Enabled, 2 minutes - Blizzlike) +# 0 - (Disabled) -AlwaysMaxWeaponSkill = 0 +Arena.PreviousOpponentsDiscardTimer = 120000 # -# PvPToken.Enable -# Description: Character will receive a token after defeating another character that yields -# honor. +# Arena.AutoDistributePoints +# Description: Automatically distribute arena points. # Default: 0 - (Disabled) # 1 - (Enabled) -PvPToken.Enable = 0 +Arena.AutoDistributePoints = 0 # -# PvPToken.MapAllowType -# Description: Define where characters can receive tokens. -# Default: 4 - (All maps) -# 3 - (Battlegrounds) -# 2 - (FFA areas only like Gurubashi arena) -# 1 - (Battlegrounds and FFA areas) +# Arena.AutoDistributeInterval +# Description: Time (in days) how often arena points should be distributed if automatic +# distribution is enabled. +# Default: 7 - (Weekly) -PvPToken.MapAllowType = 4 +Arena.AutoDistributeInterval = 7 # -# PvPToken.ItemID -# Description: Item characters will receive after defeating another character if PvP Token -# system is enabled. -# Default: 29434 - (Badge of justice) +# Arena.GamesRequired +# Description: Number of arena matches teams must participate in to be eligible for arena point distribution. +# Default: 10 -PvPToken.ItemID = 29434 +Arena.GamesRequired = 10 # -# PvPToken.ItemCount -# Description: Number of tokens a character will receive. -# Default: 1 +# Arena.QueueAnnouncer.Enable +# Description: Announce arena queue status to chat. +# Default: 0 - (Disabled) +# 1 - (Enabled) -PvPToken.ItemCount = 1 +Arena.QueueAnnouncer.Enable = 0 # -# NoResetTalentsCost -# Description: Resetting talents doesn't cost anything. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Arena.QueueAnnouncer.PlayerOnly +# Description: Arena queue announcement type. +# Default: 0 - (System message, Anyone can see it) +# 1 - (Private, Only queued players can see it) +# -NoResetTalentsCost = 0 +Arena.QueueAnnouncer.PlayerOnly = 0 # -# ToggleXP.Cost -# Description: Cost of locking/unlocking XP -# Default: 100000 - (10 Gold) +# Arena.QueueAnnouncer.Detail +# Description: The amount of detail to announce on teams queued for arenas. +# Default: 3 - (Announce the team's name and rating) +# 2 - (Announce only the team's name) +# 1 - (Announce only the team's rating) +# 0 - (Do not announce any information about the teams) # -ToggleXP.Cost = 100000 +Arena.QueueAnnouncer.Detail = 3 # -# Guild.AllowMultipleGuildMaster -# Description: Allow more than one guild master. Additional Guild Masters must be set using -# the ".guild rank" command. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Arena.ArenaSeason.ID +# Description: Current arena season id shown in clients. +# Default: 8 -Guild.AllowMultipleGuildMaster = 0 +Arena.ArenaSeason.ID = 8 # -# Guild.BankInitialTabs -# Description: Changes the amounts of available tabs of the guild bank on guild creation -# Default: 0 (no tabs given for free) -# 1-6 (amount of tabs of the guild bank at guild creation) +# Arena.ArenaSeason.InProgress +# Description: State of current arena season. +# Default: 1 - (Active) +# 0 - (Finished) -Guild.BankInitialTabs = 0 +Arena.ArenaSeason.InProgress = 1 # -# Guild.BankTabCost0-5 -# Description: Changes the price of the guild tabs. Note that the client will still show the default values. -# Default: 1000000 - (100 Gold) -# 2500000 - (250 Gold) -# 5000000 - (500 Gold) -# 10000000 - (1000 Gold) -# 25000000 - (2500 Gold) -# 50000000 - (5000 Gold) +# Arena.ArenaStartRating +# Description: Start rating for new arena teams. +# Default: 0 -Guild.BankTabCost0 = 1000000 -Guild.BankTabCost1 = 2500000 -Guild.BankTabCost2 = 5000000 -Guild.BankTabCost3 = 10000000 -Guild.BankTabCost4 = 25000000 -Guild.BankTabCost5 = 50000000 +Arena.ArenaStartRating = 0 # -# ShowKickInWorld -# Description: Determines whether a message is broadcast to the entire server when a -# player gets kicked -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Arena.ArenaStartPersonalRating +# Description: Start personal rating when joining a team. +# Default: 0 -ShowKickInWorld = 0 +Arena.ArenaStartPersonalRating = 0 # -# ShowMuteInWorld -# Description: Determines whether a message is broadcast to the entire server when a -# player gets muted. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Arena.ArenaStartMatchmakerRating +# Description: Start matchmaker rating for players. +# Default: 1500 -ShowMuteInWorld = 0 +Arena.ArenaStartMatchmakerRating = 1500 # -# ShowBanInWorld -# Description: Determines whether a message is broadcast to the entire server when a -# player gets banned. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Arena.ArenaWinRatingModifier1 +# Description: Modifier of rating addition when winner team rating is less than 1300 +# be aware that from 1000 to 1300 it gradually decreases automatically down to the half of it +# (increasing this value will give more rating) +# Default: 48 -ShowBanInWorld = 0 +Arena.ArenaWinRatingModifier1 = 48 # -# RecordUpdateTimeDiffInterval -# Description: Time (in milliseconds) update time diff is written to the log file. -# Update diff can be used as a performance indicator. Diff < 300: good -# performance. Diff > 600 bad performance, may be caused by high CPU usage. -# Default: 300000 - (Enabled, 5 minutes) -# 0 - (Disabled) +# Arena.ArenaWinRatingModifier2 +# Description: Modifier of rating addition when winner team rating is equal or more than 1300 +# (increasing this value will give more rating) +# Default: 24 -RecordUpdateTimeDiffInterval = 300000 +Arena.ArenaWinRatingModifier2 = 24 # -# MinRecordUpdateTimeDiff -# Description: Only record update time diff which is greater than this value. -# Default: 100 +# Arena.ArenaLoseRatingModifier +# Description: Modifier of rating subtraction for loser team +# (increasing this value will subtract more rating) +# Default: 24 -MinRecordUpdateTimeDiff = 100 +Arena.ArenaLoseRatingModifier = 24 # -# PlayerStart.String -# Description: String to be displayed at first login of newly created characters. -# Default: "" - (Disabled) +# Arena.ArenaMatchmakerRatingModifier +# Description: Modifier of matchmaker rating +# Default: 24 -PlayerStart.String = "" +Arena.ArenaMatchmakerRatingModifier = 24 # -# LevelReq.Trade -# Description: Level requirement for characters to be able to trade. -# Default: 1 +# ArenaTeam.CharterCost.2v2 +# ArenaTeam.CharterCost.3v3 +# ArenaTeam.CharterCost.5v5 +# Description: Amount of money (in Copper) the petitions costs. +# Default: 800000 - (80 Gold) +# 1200000 - (120 Gold) +# 2000000 - (200 Gold) -LevelReq.Trade = 1 +ArenaTeam.CharterCost.2v2 = 800000 +ArenaTeam.CharterCost.3v3 = 1200000 +ArenaTeam.CharterCost.5v5 = 2000000 # -# LevelReq.Ticket -# Description: Level requirement for characters to be able to write tickets. -# Default: 1 +# MaxAllowedMMRDrop +# Description: Some players continuously lose arena matches to lower their MMR and then fight with weaker opponents. +# This setting prevents lowering MMR too much from max achieved MMR. +# Eg. if max achieved MMR for a character was 2400, with default setting (MaxAllowedMMRDrop = 500) the character can't get below 1900 MMR no matter what. +# Default: 500 -LevelReq.Ticket = 1 +MaxAllowedMMRDrop = 500 + +# +################################################################################################### +################################################################################################### +# MAIL # -# LevelReq.Auction -# Description: Level requirement for characters to be able to use the auction house. -# Default: 1 +# MailDeliveryDelay +# Description: Time (in seconds) mail delivery is delayed when sending items. +# Default: 3600 - (1 hour) -LevelReq.Auction = 1 +MailDeliveryDelay = 3600 # # LevelReq.Mail @@ -3537,35 +3839,36 @@ LevelReq.Auction = 1 LevelReq.Mail = 1 # -# PlayerDump.DisallowPaths -# Description: Disallow using paths in PlayerDump output files -# Default: 1 - -PlayerDump.DisallowPaths = 1 +################################################################################################### +################################################################################################### +# TRANSPORT +# +# IsContinentTransport.Enabled +# Description: Controls the continent transport (ships, zeppelins etc..) +# Default: 1 - (Enabled) +# # -# PlayerDump.DisallowOverwrite -# Description: Disallow overwriting existing files with PlayerDump -# Default: 1 -PlayerDump.DisallowOverwrite = 1 +IsContinentTransport.Enabled = 1 # -# DisconnectToleranceInterval -# Description: Allows to skip queue after being disconnected for a given number of seconds. -# Default: 0 +# IsPreloadedContinentTransport.Enabled +# Description: Should we preload the transport? +# (Not recommended on low-end servers as it consumes 100% more ram) +# and it's not really necessary to be enabled. +# +# Default: 0 - (Disabled) +# +# -DisconnectToleranceInterval = 0 +IsPreloadedContinentTransport.Enabled = 0 # -# MonsterSight -# Description: The maximum distance in yards that a "monster" creature can see -# regardless of level difference (through CreatureAI::IsVisible). -# Increases CONFIG_SIGHT_MONSTER to 50 yards. Used to be 20 yards. -# Default: 50.000000 - -MonsterSight = 50.000000 +################################################################################################### +################################################################################################### +# CHAT CHANNEL # # StrictChannelNames # Description: Limit channel names to language specific symbol set. @@ -3581,277 +3884,296 @@ MonsterSight = 50.000000 StrictChannelNames = 0 # -# Instance.SharedNormalHeroicId -# Description: Forces ICC and RS Normal and Heroic to share lockouts. ToC is uneffected and Normal and Heroic will be separate. -# Default: 1 - Enable -# 0 - Disable -# +# AddonChannel +# Description: Configure the use of the addon channel through the server (some client side +# addons will not work correctly with disabled addon channel) +# Default: 1 - (Enabled) +# 0 - (Disabled) -Instance.SharedNormalHeroicId = 1 +AddonChannel = 1 # -# Instance.ResetTimeRelativeTimestamp -# Description: Needed for displaying valid instance reset times in ingame calendar. -# This timestamp should be set to a date in the past (midnight) on which -# both 3-day and 7-day raids were reset. -# Default: 1135814400 - (Thu, 29 Dec 2005 00:00:00 GMT - meaning that 7-day raid reset falls on Thursdays, -# while 3-day reset falls on "Thu 29 Dec 2005", "Sun 01 Jan 2006", "Wed 04 Jan 2006", and so on) +# ChatFakeMessagePreventing +# Description: Additional protection from creating fake chat messages using spaces. +# Collapses multiple subsequent whitespaces into a single whitespace. +# Not applied to the addon language, but may break old addons that use +# "normal" chat messages for sending data to other clients. +# Default: 1 - (Enabled, Blizzlike) +# 0 - (Disabled) +# -Instance.ResetTimeRelativeTimestamp = 1135814400 +ChatFakeMessagePreventing = 1 # -# TeleportTimeoutNear -# Description: No description -# Default: 25 +# ChatStrictLinkChecking.Severity +# Description: Check chat messages for in-game links to spells, items, quests, etc. +# -1 - (Only verify validity of link data, but permit use of custom colors) +# Default: 0 - (Only verify that link data and color are valid without checking text) +# 1 - (Additionally verifies that the link text matches the provided data) +# +# Note: If this is set to '1', you must additionally provide .dbc files for all +# client locales that are in use on your server. +# If any files are missing, messages with links from clients using those +# locales will likely be blocked by the server. # -TeleportTimeoutNear = 25 +ChatStrictLinkChecking.Severity = 0 # -# TeleportTimeoutFar -# Description: No description -# Default: 45 +# ChatStrictLinkChecking.Kick +# Description: Defines what should be done if a message containing invalid control characters +# is received. +# Default: 0 - (Silently ignore message) +# 1 - (Ignore message and kick player) # -TeleportTimeoutFar = 45 +ChatStrictLinkChecking.Kick = 0 # -# MaxAllowedMMRDrop -# Description: Some players continuously lose arena matches to lower their MMR and then fight with weaker opponents. -# This setting prevents lowering MMR too much from max achieved MMR. -# Eg. if max achieved MMR for a character was 2400, with default setting (MaxAllowedMMRDrop = 500) the character can't get below 1900 MMR no matter what. -# Default: 500 +# ChatFlood.MessageCount +# Description: Chat flood protection, number of messages before player gets muted. +# Default: 10 - (Enabled) +# 0 - (Disabled) -MaxAllowedMMRDrop = 500 +ChatFlood.MessageCount = 10 # -# EnableLoginAfterDC -# Description: After not logging out properly (clicking Logout and waiting 20 seconds), -# characters stay in game world for a full minute, even if the client connection was closed. -# Such behaviour prevents for example exploiting boss encounters by alt+f4 -# and skipping crucial boss abilities, or escaping opponents in PvP. -# This setting is used to allow/disallow players to log back into characters that are left in world. -# Default: 1 - (by clicking "Enter World" player will log back into a character that is already in world) -# 0 - (by clicking "Enter World" player will get an error message when trying to log into a character -# that is left in world, and has to wait a minute for the character to be removed from world) +# ChatFlood.MessageDelay +# Description: Time (in seconds) between messages to be counted into ChatFlood.MessageCount. +# Default: 1 -EnableLoginAfterDC = 1 +ChatFlood.MessageDelay = 1 # -# DontCacheRandomMovementPaths -# Description: Random movement paths (calculated using MoveMaps) can be cached to save cpu time, -# but this may use up considerable amount of memory and can be prevented by setting this option to 1. -# Recommended setting for populated servers is having enough RAM and setting this to 0. -# Default: 0 - (cache paths, uses more memory) -# 1 - (don't cache, uses more cpu) +# ChatFlood.AddonMessageCount +# Description: Chat flood protection, number of addon messages before player gets muted. +# Default: 100 - (Enabled) +# 0 - (Disabled) -DontCacheRandomMovementPaths = 0 +ChatFlood.AddonMessageCount = 100 # -# MoveMaps.Enable -# Description: Enable/Disable pathfinding using mmaps - recommended. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# ChatFlood.AddonMessageDelay +# Description: Time (in seconds) between addon messages to be counted into ChatFlood.AddonMessageCount. +# Default: 1 -MoveMaps.Enable = 1 +ChatFlood.AddonMessageDelay = 1 # -# Minigob.Manabonk.Enable -# Description: Enable/ Disable Minigob Manabonk -# Default: 1 +# ChatFlood.MuteTime +# Description: Time (in seconds) characters get muted for violating ChatFlood.MessageCount / ChatFlood.AddonMessageCount. +# Default: 10 -Minigob.Manabonk.Enable = 1 +ChatFlood.MuteTime = 10 # -# Allow.IP.Based.Action.Logging -# Description: Logs actions, e.g. account login and logout to name a few, based on IP of current session. +# Chat.MuteFirstLogin +# Description: Speaking is allowed after playing for Chat.MuteTimeFirstLogin minutes. You may use party and guild chat. # Default: 0 - (Disabled) # 1 - (Enabled) -# -Allow.IP.Based.Action.Logging = 0 +Chat.MuteFirstLogin = 0 # -# Calculate.Creature.Zone.Area.Data -# Description: Calculate at loading creature zoneId / areaId and save in creature table (WARNING: SLOW WORLD SERVER STARTUP) -# Default: 0 - (Do not show) -# +# Chat.MuteTimeFirstLogin +# Description: The time after which the player will be able to speak. +# Default: 120 - (Minutes) -Calculate.Creature.Zone.Area.Data = 0 +Chat.MuteTimeFirstLogin = 120 # -# Calculate.Gameoject.Zone.Area.Data -# Description: Calculate at loading gameobject zoneId / areaId and save in gameobject table (WARNING: SLOW WORLD SERVER STARTUP) -# Default: 0 - (Do not show) -# +# Channel.RestrictedLfg +# Description: Restrict LookupForGroup channel to characters registered in the LFG tool. +# Default: 1 - (Enabled, Allow join to channel only if registered in LFG) +# 0 - (Disabled, Allow join to channel in any time) -Calculate.Gameoject.Zone.Area.Data = 0 +Channel.RestrictedLfg = 1 # -# Group.Raid.LevelRestriction -# -# The Group members need to the same, or higher level than the specified value. -# Minimum level is 10. -# Default: 10 +# Channel.SilentlyGMJoin +# Description: Silently join GM characters to channels. If set to 1, channel kick and ban +# commands issued by a GM will not be broadcasted. +# Default: 0 - (Disabled, Join with announcement) +# 1 - (Enabled, Join without announcement) + +Channel.SilentlyGMJoin = 0 + +# Channel.ModerationGMLevel +# Min GM account security level required for executing moderator in-game commands in the channels +# This also bypasses password prompts on joining channels which require password +# 0 (in-game channel moderator privileges only) +# Default: 1 (enabled for moderators and above) + +Channel.ModerationGMLevel = 1 + # +# ChatLevelReq.Channel +# Description: Level requirement for characters to be able to write in chat channels. +# Default: 1 -Group.Raid.LevelRestriction = 10 +ChatLevelReq.Channel = 1 # -# DungeonFinder.OptionsMask -# Description: Dungeon and raid finder system. -# Value is a bitmask consisting of: -# LFG_OPTION_ENABLE_DUNGEON_FINDER = 1, Enable the dungeon finder browser -# LFG_OPTION_ENABLE_RAID_BROWSER = 2, Enable the raid browser -# LFG_OPTION_ENABLE_SEASONAL_BOSSES = 4, Enable seasonal bosses -# Default: 5 +# ChatLevelReq.Whisper +# Description: Level requirement for characters to be able to whisper other characters. +# Default: 1 -DungeonFinder.OptionsMask = 5 +ChatLevelReq.Whisper = 1 # -# LFG.Location.All +# ChatLevelReq.Say +# Description: Level requirement for characters to be able to use say/yell/emote. +# Default: 1 + +ChatLevelReq.Say = 1 + # -# Includes satellite to search for work elsewhere LFG -# Default: 0 - Disable -# 1 - Enable +# PartyLevelReq +# Description: Minimum level at which players can invite to group, even if they aren't on +# the invite friends list. (Players who are on that friend list can always +# invite despite having lower level) +# Default: 1 + +PartyLevelReq = 1 + # +# PreserveCustomChannels +# Description: Store custom chat channel settings like password, automatic ownership handout +# or ban list in the database. Needs to be enabled to save custom +# world/trade/etc. channels that have automatic ownership handout disabled. +# (.channel set ownership $channel off) +# Default: 0 - (Disabled, Blizzlike, Channel settings are lost if last person left) +# 1 - (Enabled) -LFG.Location.All = 0 +PreserveCustomChannels = 1 # -# DungeonAccessRequirements.PrintMode +# PreserveCustomChannelDuration +# Description: Time (in days) that needs to pass before the customs chat channels get +# cleaned up from the database. Only channels with ownership handout enabled +# (default behavior) will be cleaned. +# Default: 14 - (Enabled, Clean channels that haven't been used for 14 days) +# 0 - (Disabled, Infinite channel storage) + +PreserveCustomChannelDuration = 14 + # -# Description: Select the preferred format to display information to the player who cannot enter a portal dungeon because when has not met the access requirements: -# Default: 1 - (Display only one requirement at a time (BlizzLike, like in the LFG interface)) -# 0 - (Display no extra information, only "Requirements not met") -# 2 - (Display detailed requirements, all at once, with clickable links) +################################################################################################### + +################################################################################################### +# FACTION INTERACTION # +# AllowTwoSide.Accounts +# Description: Allow creating characters of both factions on the same account. +# Default: 1 - (Enabled) +# 0 - (Disabled) -DungeonAccessRequirements.PrintMode = 1 +AllowTwoSide.Accounts = 1 # -# DungeonAccessRequirements.PortalAvgIlevelCheck -# -# Description: Enable average item level requirement when entering a dungeon/raid's portal (= deny the entry if player has too low average ilevel, like in LFG). -# Default: 0 - (Disabled -> Blizzlike) +# AllowTwoSide.Interaction.Calendar +# Description: Allow calendar invites between factions. +# Default: 0 - (Disabled) # 1 - (Enabled) -DungeonAccessRequirements.PortalAvgIlevelCheck = 0 +AllowTwoSide.Interaction.Calendar = 0 # -# DungeonAccessRequirements.LFGLevelDBCOverride -# -# Description: If enabled, use `min_level` and `max_level` values from table `dungeon_access_requirements` to list or to hide a dungeon from the LFG window. +# AllowTwoSide.Interaction.Chat +# Description: Allow say chat between factions. # Default: 0 - (Disabled) # 1 - (Enabled) -DungeonAccessRequirements.LFGLevelDBCOverride = 0 +AllowTwoSide.Interaction.Chat = 0 # -# DungeonAccessRequirements.OptionalStringID -# -# Description: Display an extra message from acore_strings in the chat after printing the dungeon access requirements. -# To enable it set the ID of your desired string from the table acore_strings +# AllowTwoSide.Interaction.Emote +# Description: Allow emote messages between factions (e.g. "/e looks into the sky") # Default: 0 - (Disabled) -# 1+ - (Enabled) +# 1 - (Enabled) -DungeonAccessRequirements.OptionalStringID = 0 +AllowTwoSide.Interaction.Emote = 0 # -# ICC Buff -# Description: Specify ICC buff -# (It is necessary to restart the server after changing the values!) -# Default: ICC.Buff.Horde = 73822 -# ICC.Buff.Alliance = 73828 -# -# Spell IDs for the auras: -# 73816 - 5% buff Horde -# 73818 - 10% buff Horde -# 73819 - 15% buff Horde -# 73820 - 20% buff Horde -# 73821 - 25% buff Horde -# 73822 - 30% buff Horde -# 73762 - 5% buff Alliance -# 73824 - 10% buff Alliance -# 73825 - 15% buff Alliance -# 73826 - 20% buff Alliance -# 73827 - 25% buff Alliance -# 73828 - 30% buff Alliance +# AllowTwoSide.Interaction.Channel +# Description: Allow channel chat between factions. +# Default: 0 - (Disabled) +# 1 - (Enabled) -ICC.Buff.Horde = 73822 -ICC.Buff.Alliance = 73828 +AllowTwoSide.Interaction.Channel = 0 # -# Item.SetItemTradeable -# Description: Enabled/Disabled trading BoP items among raid members. -# Default: 1 - (Set BoP items tradeable timer to 2 hours) -# 0 - (Disable trading BoP items among raid members) +# AllowTwoSide.Interaction.Group +# Description: Allow group joining between factions. +# Default: 0 - (Disabled) +# 1 - (Enabled) -Item.SetItemTradeable = 1 +AllowTwoSide.Interaction.Group = 0 # -# FFAPvPTimer -# Description: Specify time offset when player unset FFAPvP flag when leaving FFAPvP area. (e.g. Gurubashi Arena) -# Default: 30 sec +# AllowTwoSide.Interaction.Guild +# Description: Allow guild joining between factions. +# Default: 0 - (Disabled) +# 1 - (Enabled) -FFAPvPTimer = 30 +AllowTwoSide.Interaction.Guild = 0 # -# LootNeedBeforeGreedILvlRestriction -# Description: Specify level restriction for items below player's subclass in Need Before Greed loot mode in DF groups -# Default: 70 -# 0 - Disabled +# AllowTwoSide.Interaction.Arena +# Description: Allow joining arena teams between factions. +# Default: 0 - (Disabled) +# 1 - (Enabled) -LootNeedBeforeGreedILvlRestriction = 70 +AllowTwoSide.Interaction.Arena = 0 # -# LFG.MaxKickCount -# Description: Specify the maximum number of kicks allowed in LFG groups (max 3 kicks) -# Default: 2 -# 0 - Disabled (kicks are never allowed) +# AllowTwoSide.Interaction.Auction +# Description: Allow auctions between factions. +# Default: 0 - (Disabled) +# 1 - (Enabled) -LFG.MaxKickCount = 2 +AllowTwoSide.Interaction.Auction = 0 # -# LFG.KickPreventionTimer -# Description: Specify for how long players are prevented from being kicked after just joining LFG groups -# Default: 900 secs (15 minutes) -# 0 - Disabled +# AllowTwoSide.Interaction.Mail +# Description: Allow sending mails between factions. +# Default: 0 - (Disabled) +# 1 - (Enabled) -LFG.KickPreventionTimer = 900 +AllowTwoSide.Interaction.Mail = 0 # -# EnablePlayerSettings -# Description: Enables the usage of character specific settings. -# Default: 0 - Disabled -# 1 - Enabled +# AllowTwoSide.WhoList +# Description: Show characters from both factions in the /who list. +# Default: 0 - (Disabled) +# 1 - (Enabled) -EnablePlayerSettings = 0 +AllowTwoSide.WhoList = 0 # -# JoinBGAndLFG.Enable -# Description: Allow queueing for BG and LFG at the same time. -# Default: 0 - Disabled -# 1 - Enabled +# AllowTwoSide.AddFriend +# Description: Allow adding friends from other faction the friends list. +# Default: 0 - (Disabled) +# 1 - (Enabled) -JoinBGAndLFG.Enable = 0 +AllowTwoSide.AddFriend = 0 # -# LeaveGroupOnLogout.Enabled -# Description: Should the player leave their group when they log out? -# (It does not affect raids or dungeon finder groups) -# -# Default: 1 - (Enabled) +# AllowTwoSide.Trade +# Description: Allow trading between factions. +# Default: 0 - (Disabled) +# 1 - (Enabled) -LeaveGroupOnLogout.Enabled = 1 +AllowTwoSide.Trade = 0 # -# QuestPOI.Enabled -# Description: Show points of interest on the map -# Default: 1 - Enabled -# 0 - Disabled +# TalentsInspecting +# Description: Allow inspecting characters from the opposing faction. +# Doesn't affect characters in gamemaster mode. +# Default: 1 - (Enabled) +# 0 - (Disabled) -QuestPOI.Enabled = 1 +TalentsInspecting = 1 # # ChangeFaction.MaxMoney @@ -3862,322 +4184,205 @@ QuestPOI.Enabled = 1 ChangeFaction.MaxMoney = 0 -# -# Pet.RankMod.Health -# Description: Allows pet health to be modified by rank health rates (set in config) -# Default: 1 - Enabled -# 0 - Disabled - -Pet.RankMod.Health = 1 - -# -# AuctionHouse.SearchTimeout -# Description: Time (in milliseconds) after which an auction house search is discarded. -# Default: 1000 - (1 second) - -AuctionHouse.SearchTimeout = 1000 - # ################################################################################################### ################################################################################################### -# LOGGING SYSTEM SETTINGS -# -# Appender config values: Given an appender "name" -# Appender.name -# Description: Defines 'where to log'. -# Format: Type,LogLevel,Flags,optional1,optional2,optional3 -# -# Type -# 0 - (None) -# 1 - (Console) -# 2 - (File) -# 3 - (DB) -# -# LogLevel -# 0 - (Disabled) -# 1 - (Fatal) -# 2 - (Error) -# 3 - (Warning) -# 4 - (Info) -# 5 - (Debug) -# 6 - (Trace) -# -# Flags: -# 0 - None -# 1 - Prefix Timestamp to the text -# 2 - Prefix Log Level to the text -# 4 - Prefix Log Filter type to the text -# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS -# (Only used with Type = 2) -# 16 - Make a backup of existing file before overwrite -# (Only used with Mode = w) -# -# Colors (read as optional1 if Type = Console) -# Format: "fatal error warn info debug trace" -# 0 - BLACK -# 1 - RED -# 2 - GREEN -# 3 - BROWN -# 4 - BLUE -# 5 - MAGENTA -# 6 - CYAN -# 7 - GREY -# 8 - YELLOW -# 9 - LRED -# 10 - LGREEN -# 11 - LBLUE -# 12 - LMAGENTA -# 13 - LCYAN -# 14 - WHITE -# Example: "1 9 3 6 5 8" -# -# File: Name of the file (read as optional1 if Type = File) -# Allows to use one "%s" to create dynamic files -# -# Mode: Mode to open the file (read as optional2 if Type = File) -# a - (Append) -# w - (Overwrite) +# RECRUIT A FRIEND # -# MaxFileSize: Maximum file size of the log file before creating a new log file -# (read as optional3 if Type = File) -# Size is measured in bytes expressed in a 64-bit unsigned integer. -# Maximum value is 4294967295 (4 GB). Leave blank for no limit. -# NOTE: Does not work with dynamic filenames. -# Example: 536870912 (512 MB) +# RecruitAFriend.MaxLevel +# Description: Highest level up to which a character can benefit from the Recruit-A-Friend +# experience multiplier. +# Default: 60 + +RecruitAFriend.MaxLevel = 60 + # +# RecruitAFriend.MaxDifference +# Description: Highest level difference between linked Recruiter and Friend benefit from +# the Recruit-A-Friend experience multiplier. +# Default: 4 -Appender.Console=1,4,0,"1 9 3 6 5 8" -Appender.Server=2,5,0,Server.log,w -# Appender.GM=2,5,15,gm_%s.log -Appender.Errors=2,5,0,Errors.log -# Appender.DB=3,5,0 +RecruitAFriend.MaxDifference = 4 -# Logger config values: Given a logger "name" -# Logger.name -# Description: Defines 'What to log' -# Format: LogLevel,AppenderList # -# LogLevel -# 0 - (Disabled) -# 1 - (Fatal) -# 2 - (Error) -# 3 - (Warning) -# 4 - (Info) -# 5 - (Debug) -# 6 - (Trace) +# MaxRecruitAFriendBonusDistance +# Description: Max distance between character and and group to gain the Recruit-A-Friend +# XP multiplier. +# Default: 100 + +MaxRecruitAFriendBonusDistance = 100 + # -# AppenderList: List of appenders linked to logger -# (Using spaces as separator). +################################################################################################### + +################################################################################################### +# CALENDAR # +# Calendar.DeleteOldEventsHour +# Description: Hour of the day when the daily deletion of old calendar events occurs. +# Range: 0-23 +# Default: 6 - (06:00 AM) -Logger.root=2,Console Server -Logger.commands.gm=4,Console GM -Logger.diff=3,Console Server -Logger.mmaps=4,Server -Logger.scripts.hotswap=4,Console Server -Logger.server=4,Console Server -Logger.sql.sql=2,Console Errors -Logger.sql=4,Console Server -Logger.time.update=4,Console Server -Logger.module=4,Console Server -Logger.spells.scripts=2,Console Errors +Calendar.DeleteOldEventsHour = 6 -#Logger.achievement=4,Console Server -#Logger.addon=4,Console Server -#Logger.ahbot=4,Console Server -#Logger.auctionHouse=4,Console Server -#Logger.autobroadcast=4, Console Server -#Logger.bg.arena=4,Console Server -#Logger.bg.battlefield=4,Console Server -#Logger.bg.battleground=4,Console Server -#Logger.bg.reportpvpafk=4,Console Server -#Logger.calendar=4,Console Server -#Logger.chat.log=4,Console Server -#Logger.chat.log.addon=4,Console Server -#Logger.chat.system=4,Console Server -#Logger.cheat=4,Console Server -#Logger.commands.ra=4,Console Server -#Logger.condition=4,Console Server -#Logger.dbc=4,Console Server -#Logger.disable=4,Console Server -#Logger.entities.dyobject=4,Console Server -#Logger.entities.faction=4,Console Server -#Logger.entities.gameobject=4,Console Server -#Logger.entities.object=4,Console Server -#Logger.entities.pet=4,Console Server -#Logger.entities.player.character=4,Console Server -#Logger.entities.player.dump=4,Console Server -#Logger.entities.player.items=4,Console Server -#Logger.entities.player.loading=4,Console Server -#Logger.entities.player.skills=4,Console Server -#Logger.entities.player=4,Console Server -#Logger.entities.transport=4,Console Server -#Logger.entities.unit.ai=4,Console Server -#Logger.entities.unit=4,Console Server -#Logger.entities.vehicle=4,Console Server -#Logger.gameevent=4,Console Server -#Logger.group=4,Console Server -#Logger.guild=4,Console Server -#Logger.instance.save=4,Console Server -#Logger.instance.script=4,Console Server -#Logger.lfg=4,Console Server -#Logger.loot=4,Console Server -#Logger.mail=4,Console Server -#Logger.maps.script=4,Console Server -#Logger.maps=4,Console Server -#Logger.misc=4,Console Server -#Logger.mmaps.tiles=4,Console Server -#Logger.movement.flightpath=4,Console Server -#Logger.movement.motionmaster=4,Console Server -#Logger.movement.splinechain=4,Console Server -#Logger.movement=4,Console Server -#Logger.network.kick=4,Console Server -#Logger.network.opcode=4,Console Server -#Logger.network.soap=4,Console Server -#Logger.network=4,Console Server -#Logger.outdoorpvp=4,Console Server -#Logger.pool=4,Console Server -#Logger.rbac=4,Console Server -#Logger.reputation=4,Console Server -#Logger.scripts.ai.escortai=4,Console Server -#Logger.scripts.ai.followerai=4,Console Server -#Logger.scripts.ai.petai=4,Console Server -#Logger.scripts.ai.sai=4,Console Server -#Logger.scripts.ai=4,Console Server -#Logger.scripts.cos=4,Console Server -#Logger.scripts=4,Console Server -#Logger.server.authserver=4,Console Server -#Logger.spells.aura.effect.nospell=4,Console Server -#Logger.spells.aura.effect=4,Console Server -#Logger.spells.effect.nospell=4,Console Server -#Logger.spells.effect=4,Console Server -#Logger.spells.scripts=4,Console Server -#Logger.spells=4,Console Server -#Logger.sql.dev=4,Console Server -#Logger.sql.driver=4,Console Server -#Logger.vehicles=4,Console Server -#Logger.warden=4,Console Server -#Logger.weather=4,Console Server +# +################################################################################################### +################################################################################################### +# GAME EVENT # -# Log.Async.Enable -# Description: Enables asynchronous message logging. +# Event.Announce +# Description: Announce events. # Default: 0 - (Disabled) # 1 - (Enabled) -Log.Async.Enable = 0 +Event.Announce = 0 # ################################################################################################### ################################################################################################### -# PACKET SPOOF PROTECTION SETTINGS +# AUCTION HOUSE # -# These settings determine which action to take when harmful packet spoofing is detected. -# -# PacketSpoof.Policy -# Description: Determines the course of action when packet spoofing is detected. -# Values: 0 - Log only -# 1 - Log + kick -# 2 - Log + kick + ban +# AuctionHouse.SearchTimeout +# Description: Time (in milliseconds) after which an auction house search is discarded. +# Default: 1000 - (1 second) -PacketSpoof.Policy = 1 +AuctionHouse.SearchTimeout = 1000 # -# PacketSpoof.BanMode -# Description: If PacketSpoof.Policy equals 2, this will determine the ban mode. -# Values: 0 - Ban Account -# 1 - Ban IP -# Note: Banning by character not supported for logical reasons. -# +# LevelReq.Auction +# Description: Level requirement for characters to be able to use the auction house. +# Default: 1 -PacketSpoof.BanMode = 0 +LevelReq.Auction = 1 # -# PacketSpoof.BanDuration -# Description: Duration of the ban in seconds. Only valid if PacketSpoof.Policy is set to 2. -# Set to 0 for permanent ban. -# Default: 86400 seconds (1 day) -# +# Rate.Auction.Time +# Rate.Auction.Deposit +# Rate.Auction.Cut +# Description: Auction rates (auction time, deposit get at auction start, +# auction cut from price at auction end) +# Default: 1 - (Rate.Auction.Time) +# 1 - (Rate.Auction.Deposit) +# 1 - (Rate.Auction.Cut) -PacketSpoof.BanDuration = 86400 +Rate.Auction.Time = 1 +Rate.Auction.Deposit = 1 +Rate.Auction.Cut = 1 # ################################################################################################### ################################################################################################### -# DEBUG +# PLAYER DUMP # -# Debug.Battleground -# Description: Enable or disable Battleground 1v0 mode. (If enabled, the in-game command is disabled.) -# Default: 0 - (Disabled) -# 1 - (Enabled) +# PlayerDump.DisallowPaths +# Description: Disallow using paths in PlayerDump output files +# Default: 1 -Debug.Battleground = 0 +PlayerDump.DisallowPaths = 1 # -# Debug.Arena -# Description: Enable or disable Arena 1v1 mode. (If enabled, the in-game command is disabled.) -# Default: 0 - (Disabled) -# 1 - (Enabled) +# PlayerDump.DisallowOverwrite +# Description: Disallow overwriting existing files with PlayerDump +# Default: 1 -Debug.Arena = 0 +PlayerDump.DisallowOverwrite = 1 # ################################################################################################### ################################################################################################### -# METRIC SETTINGS +# CUSTOM # -# These settings control the statistics sent to the metric database (currently InfluxDB) +# ICC Buff +# Description: Specify ICC buff +# (It is necessary to restart the server after changing the values!) +# Default: ICC.Buff.Horde = 73822 +# ICC.Buff.Alliance = 73828 # -# Metric.Enable -# Description: Enables statistics sent to the metric database. -# Default: 0 - (Disabled) -# 1 - (Enabled) +# Spell IDs for the auras: +# 73816 - 5% buff Horde +# 73818 - 10% buff Horde +# 73819 - 15% buff Horde +# 73820 - 20% buff Horde +# 73821 - 25% buff Horde +# 73822 - 30% buff Horde +# 73762 - 5% buff Alliance +# 73824 - 10% buff Alliance +# 73825 - 15% buff Alliance +# 73826 - 20% buff Alliance +# 73827 - 25% buff Alliance +# 73828 - 30% buff Alliance + +ICC.Buff.Horde = 73822 +ICC.Buff.Alliance = 73828 + # +# Minigob.Manabonk.Enable +# Description: Enable/ Disable Minigob Manabonk +# Default: 1 -Metric.Enable = 0 +Minigob.Manabonk.Enable = 1 # -# Metric.Interval -# Description: Interval between every batch of data sent in seconds -# Default: 10 seconds +# Calculate.Creature.Zone.Area.Data +# Description: Calculate at loading creature zoneId / areaId and save in creature table (WARNING: SLOW WORLD SERVER STARTUP) +# Default: 0 - (Do not show) # -Metric.Interval = 10 +Calculate.Creature.Zone.Area.Data = 0 # -# Metric.ConnectionInfo -# Description: Connection settings for metric database (currently InfluxDB). -# Example: "hostname;port;database" -# Default: "127.0.0.1;8086;worldserver" +# Calculate.Gameoject.Zone.Area.Data +# Description: Calculate at loading gameobject zoneId / areaId and save in gameobject table (WARNING: SLOW WORLD SERVER STARTUP) +# Default: 0 - (Do not show) # -Metric.ConnectionInfo = "127.0.0.1;8086;worldserver" +Calculate.Gameoject.Zone.Area.Data = 0 # -# Metric.OverallStatusInterval -# Description: Interval between every gathering of overall worldserver status data in seconds -# Default: 1 second +# TeleportTimeoutNear +# Description: No description +# Default: 25 + +TeleportTimeoutNear = 25 + # +# TeleportTimeoutFar +# Description: No description +# Default: 45 -Metric.OverallStatusInterval = 1 +TeleportTimeoutFar = 45 # -# Metric threshold values: Given a metric "name" -# Metric.Threshold.name -# Description: Skips sending statistics with a value lower than the config value. -# If the threshold is commented out, the metric will be ignored. -# Only metrics logged with METRIC_DETAILED_TIMER in the sources are affected. -# Disabled by default. Requires WITH_DETAILED_METRICS CMake flag. +################################################################################################### + +################################################################################################### +# DEBUG # -# Format: Value as integer +# Debug.Battleground +# Description: Enable or disable Battleground 1v0 mode. (If enabled, the in-game command is disabled.) +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Debug.Battleground = 0 + # +# Debug.Arena +# Description: Enable or disable Arena 1v1 mode. (If enabled, the in-game command is disabled.) +# Default: 0 - (Disabled) +# 1 - (Enabled) -#Metric.Threshold.world_update_sessions_time = 100 -#Metric.Threshold.worldsession_update_opcode_time = 50 +Debug.Arena = 0 # ################################################################################################### + +################################################################################################### +# # +# GAME SETTINGS END # +# # +################################################################################################### diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 23914ba558086d..d3afd8b4f10aba 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -74,7 +74,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " "arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, " "health, power1, power2, power3, power4, power5, power6, power7, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, " - "knownTitles, actionBars, grantableLevels, innTriggerId, extraBonusTalentCount FROM characters WHERE guid = ?", CONNECTION_ASYNC); + "knownTitles, actionBars, grantableLevels, innTriggerId, extraBonusTalentCount, UNIX_TIMESTAMP(creation_date) FROM characters WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_AURAS, "SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, " "base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = ?", CONNECTION_ASYNC); diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 993da42e22f26e..f21ae8b83ba8a0 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -82,7 +82,7 @@ class CreatureAI : public UnitAI Creature* DoSummon(uint32 entry, WorldObject* obj, float radius = 5.0f, uint32 despawnTime = 30000, TempSummonType summonType = TEMPSUMMON_CORPSE_TIMED_DESPAWN); Creature* DoSummonFlyer(uint32 entry, WorldObject* obj, float flightZ, float radius = 5.0f, uint32 despawnTime = 30000, TempSummonType summonType = TEMPSUMMON_CORPSE_TIMED_DESPAWN); public: - // EnumUtils: DESCRIBE THIS + // EnumUtils: DESCRIBE THIS (in CreatureAI::) enum EvadeReason { EVADE_REASON_NO_HOSTILES, // the creature's threat list is empty diff --git a/src/server/game/AI/enuminfo_CreatureAI.cpp b/src/server/game/AI/enuminfo_CreatureAI.cpp new file mode 100644 index 00000000000000..3cb4c7e158ce5f --- /dev/null +++ b/src/server/game/AI/enuminfo_CreatureAI.cpp @@ -0,0 +1,70 @@ +/* + * 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 "CreatureAI.h" +#include "Define.h" +#include "SmartEnum.h" +#include + +namespace Acore::Impl::EnumUtilsImpl +{ + +/****************************************************************************\ +|* data for enum 'CreatureAI::EvadeReason' in 'CreatureAI.h' auto-generated *| +\****************************************************************************/ +template <> +AC_API_EXPORT EnumText EnumUtils::ToString(CreatureAI::EvadeReason value) +{ + switch (value) + { + case CreatureAI::EVADE_REASON_NO_HOSTILES: return { "EVADE_REASON_NO_HOSTILES", "EVADE_REASON_NO_HOSTILES", "the creature's threat list is empty" }; + case CreatureAI::EVADE_REASON_BOUNDARY: return { "EVADE_REASON_BOUNDARY", "EVADE_REASON_BOUNDARY", "the creature has moved outside its evade boundary" }; + case CreatureAI::EVADE_REASON_SEQUENCE_BREAK: return { "EVADE_REASON_SEQUENCE_BREAK", "EVADE_REASON_SEQUENCE_BREAK", "this is a boss and the pre-requisite encounters for engaging it are not defeated yet" }; + case CreatureAI::EVADE_REASON_NO_PATH: return { "EVADE_REASON_NO_PATH", "EVADE_REASON_NO_PATH", "the creature was unable to reach its target for over 5 seconds" }; + default: throw std::out_of_range("value"); + } +} + +template <> +AC_API_EXPORT size_t EnumUtils::Count() { return 4; } + +template <> +AC_API_EXPORT CreatureAI::EvadeReason EnumUtils::FromIndex(size_t index) +{ + switch (index) + { + case 0: return CreatureAI::EVADE_REASON_NO_HOSTILES; + case 1: return CreatureAI::EVADE_REASON_BOUNDARY; + case 2: return CreatureAI::EVADE_REASON_SEQUENCE_BREAK; + case 3: return CreatureAI::EVADE_REASON_NO_PATH; + default: throw std::out_of_range("index"); + } +} + +template <> +AC_API_EXPORT size_t EnumUtils::ToIndex(CreatureAI::EvadeReason value) +{ + switch (value) + { + case CreatureAI::EVADE_REASON_NO_HOSTILES: return 0; + case CreatureAI::EVADE_REASON_BOUNDARY: return 1; + case CreatureAI::EVADE_REASON_SEQUENCE_BREAK: return 2; + case CreatureAI::EVADE_REASON_NO_PATH: return 3; + default: throw std::out_of_range("value"); + } +} +} diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 4b1c92e728d573..f445136f0d5f01 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -758,7 +758,12 @@ void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, C data << uint32(timedCompleted ? 0 : 1); // 1 is for keeping the counter at 0 in client data.AppendPackedTime(progress->date); data << uint32(timeElapsed); // time elapsed in seconds - data << uint32(0); // unk + + if (sAchievementMgr->IsAverageCriteria(entry)) + data << uint32(GameTime::GetGameTime().count() - GetPlayer()->GetCreationTime().count()); // for average achievements + else + data << uint32(timeElapsed); // time elapsed in seconds + GetPlayer()->SendDirectMessage(&data); } @@ -882,6 +887,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS: /* FIXME: for online player only currently */ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT: case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED: case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN: case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS: @@ -1148,6 +1154,21 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; } + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: + { + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if (!miscValue1) + continue; + + Map const* map = GetPlayer()->IsInWorld() ? GetPlayer()->GetMap() : sMapMgr->FindMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceId()); + if (!map || !map->IsDungeon()) + continue; + + if (map->ToInstanceMap()->GetMaxPlayers() != achievementCriteria->complete_raid.groupSize) + continue; + SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + break; + } case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if (!miscValue1) @@ -1752,7 +1773,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING: break; // FIXME: not triggered in code as result, need to implement - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: case ACHIEVEMENT_CRITERIA_TYPE_TOTAL: break; // Not implemented yet :( } @@ -1924,6 +1944,7 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: case ACHIEVEMENT_CRITERIA_TYPE_DEATH: case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON: + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: @@ -1948,6 +1969,7 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR: @@ -2356,7 +2378,11 @@ void AchievementMgr::BuildAllDataPacket(WorldPacket* data) const *data << uint32(0); /// @todo: This should be 1 if it is a failed timed criteria data->AppendPackedTime(iter->second.date); *data << uint32(now - iter->second.date); - *data << uint32(now - iter->second.date); + + if (sAchievementMgr->IsAverageCriteria(sAchievementCriteriaStore.LookupEntry(iter->first))) + *data << uint32(now - GetPlayer()->GetCreationTime().count()); // for average achievements + else + *data << uint32(now - iter->second.date); } *data << int32(-1); @@ -2445,6 +2471,19 @@ bool AchievementGlobalMgr::IsStatisticAchievement(AchievementEntry const* achiev return false; } +bool AchievementGlobalMgr::IsAverageCriteria(AchievementCriteriaEntry const* criteria) const +{ + if ((sAchievementStore.LookupEntry(criteria->referredAchievement))->flags & ACHIEVEMENT_FLAG_AVERAGE) + return true; + + if (AchievementEntryList const* achRefList = GetAchievementByReferencedId(criteria->referredAchievement)) + for (AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr) + if ((*itr)->flags & ACHIEVEMENT_FLAG_AVERAGE) + return true; + + return false; +} + bool AchievementGlobalMgr::IsRealmCompleted(AchievementEntry const* achievement) const { auto itr = _allCompletedAchievements.find(achievement->ID); diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index 7b46c58ccf0266..c82cc6f4e8ae17 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -330,6 +330,7 @@ class AchievementGlobalMgr bool IsStatisticCriteria(AchievementCriteriaEntry const* achievementCriteria) const; bool IsStatisticAchievement(AchievementEntry const* achievement) const; + bool IsAverageCriteria(AchievementCriteriaEntry const* criteria) const; [[nodiscard]] AchievementCriteriaEntryList const* GetAchievementCriteriaByType(AchievementCriteriaTypes type) const { diff --git a/src/server/game/Battlegrounds/Arena.h b/src/server/game/Battlegrounds/Arena.h index 0be78b705d589e..fd7460080301e6 100644 --- a/src/server/game/Battlegrounds/Arena.h +++ b/src/server/game/Battlegrounds/Arena.h @@ -63,4 +63,4 @@ class AC_GAME_API Arena : public Battleground void EndBattleground(TeamId winnerTeamId) override; }; -#endif // WARHEAD_ARENA_H +#endif // ACORE_ARENA_H diff --git a/src/server/game/Battlegrounds/ArenaScore.h b/src/server/game/Battlegrounds/ArenaScore.h index b51dacf95b7734..d29c1487c78295 100644 --- a/src/server/game/Battlegrounds/ArenaScore.h +++ b/src/server/game/Battlegrounds/ArenaScore.h @@ -72,4 +72,4 @@ struct AC_GAME_API ArenaTeamScore std::string TeamName{}; }; -#endif // WARHEAD_ARENA_SCORE_H +#endif // ACORE_ARENA_SCORE_H diff --git a/src/server/game/Battlegrounds/BattlegroundScore.h b/src/server/game/Battlegrounds/BattlegroundScore.h index e07c41dd750f53..4ed344b7e780f3 100644 --- a/src/server/game/Battlegrounds/BattlegroundScore.h +++ b/src/server/game/Battlegrounds/BattlegroundScore.h @@ -122,4 +122,4 @@ struct AC_GAME_API BattlegroundScore uint32 HealingDone = 0; }; -#endif // TRINITY_BATTLEGROUND_SCORE_H +#endif // _BATTLEGROUND_SCORE_H diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index 4cc94a60dae84c..0360ea47b5ff00 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -551,6 +551,6 @@ void BattlegroundAB::ApplyPhaseMask() for (auto const& itr : bgPlayerMap) { itr.second->SetPhaseMask(phaseMask, false); - itr.second->UpdateObjectVisibility(true, false); + itr.second->UpdateObjectVisibility(true); } } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index faeacdf3f32dba..3b7cbff20e77e1 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -374,17 +374,15 @@ void Creature::RemoveCorpse(bool setSpawnTime, bool skipVisibility) m_respawnTime = GameTime::GetGameTime().count() + WEEK; } - float x, y, z, o; - GetRespawnPosition(x, y, z, &o); - SetHomePosition(x, y, z, o); - SetPosition(x, y, z, o); - - // xinef: relocate notifier - m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f); - // pussywizard: if corpse was removed during falling then the falling will continue after respawn, so stop falling is such case if (IsFalling()) StopMoving(); + + float x, y, z, o; + GetRespawnPosition(x, y, z, &o); + UpdateAllowedPositionZ(x, y, z); + SetHomePosition(x, y, z, o); + GetMap()->CreatureRelocation(this, x, y, z, o); } /** @@ -546,7 +544,7 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele SetMeleeDamageSchool(SpellSchools(cInfo->dmgschool)); CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(GetLevel(), cInfo->unit_class); - float armor = (float)stats->GenerateArmor(cInfo); /// @todo: Why is this treated as uint32 when it's a float? + float armor = stats->GenerateArmor(cInfo); SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, armor); SetModifierValue(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_HOLY])); SetModifierValue(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_FIRE])); @@ -589,13 +587,13 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); } - if (GetMovementTemplate().IsRooted()) - { - SetControlled(true, UNIT_STATE_ROOT); - } - SetDetectionDistance(cInfo->detection_range); + // Update movement + if (IsRooted()) + SetControlled(true, UNIT_STATE_ROOT); + UpdateMovementFlags(); + LoadSpellTemplateImmunity(); if (updateAI) @@ -1497,6 +1495,9 @@ void Creature::SelectLevel(bool changelevel) uint8 minlevel = std::min(cInfo->maxlevel, cInfo->minlevel); uint8 maxlevel = std::max(cInfo->maxlevel, cInfo->minlevel); uint8 level = minlevel == maxlevel ? minlevel : urand(minlevel, maxlevel); + + sScriptMgr->OnBeforeCreatureSelectLevel(cInfo, this, level); + if (changelevel) SetLevel(level); @@ -2094,9 +2095,7 @@ void Creature::Respawn(bool force) m_respawnedTime = GameTime::GetGameTime().count(); } m_respawnedTime = GameTime::GetGameTime().count(); - // xinef: relocate notifier, fixes npc appearing in corpse position after forced respawn (instead of spawn) - m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f); - UpdateObjectVisibility(false); + UpdateObjectVisibility(); } void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer) @@ -2769,6 +2768,14 @@ bool Creature::IsSpellProhibited(SpellSchoolMask idSchoolMask) const return false; } +void Creature::ClearProhibitedSpellTimers() +{ + for (uint8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) + { + m_ProhibitSchoolTime[i] = 0; + } +} + void Creature::_AddCreatureSpellCooldown(uint32 spell_id, uint16 categoryId, uint32 end_time) { CreatureSpellCooldown spellCooldown; @@ -3126,7 +3133,7 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly /*= false*/, bool return true; } - if (updateAnimationTier && IsAlive() && !HasUnitState(UNIT_STATE_ROOT) && !GetMovementTemplate().IsRooted()) + if (updateAnimationTier && IsAlive() && !HasUnitState(UNIT_STATE_ROOT) && !IsRooted()) { if (IsLevitating()) SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_FLY); @@ -3275,7 +3282,7 @@ bool Creature::SetHover(bool enable, bool packetOnly /*= false*/, bool updateAni if (!packetOnly && !Unit::SetHover(enable)) return false; - if (updateAnimationTier && IsAlive() && !HasUnitState(UNIT_STATE_ROOT) && !GetMovementTemplate().IsRooted()) + if (updateAnimationTier && IsAlive() && !HasUnitState(UNIT_STATE_ROOT) && !IsRooted()) { if (IsLevitating()) SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_FLY); @@ -3724,6 +3731,24 @@ uint32 Creature::GetPlayerDamageReq() const return _playerDamageReq; } +bool Creature::CanCastSpell(uint32 spellID) const +{ + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID); + int32 currentPower = GetPower(getPowerType()); + + if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED) || IsSpellProhibited(spellInfo->GetSchoolMask())) + { + return false; + } + + if (spellInfo && (currentPower < spellInfo->CalcPowerCost(this, spellInfo->GetSchoolMask()))) + { + return false; + } + + return true; +} + std::string Creature::GetDebugInfo() const { std::stringstream sstr; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index eb8fa2e6e2b114..a51483e1a5f439 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -82,6 +82,7 @@ class Creature : public Unit, public GridObject, public MovableMapObje [[nodiscard]] bool CanEnterWater() const override; [[nodiscard]] bool CanFly() const override { return GetMovementTemplate().IsFlightAllowed() || IsFlying(); } [[nodiscard]] bool CanHover() const { return GetMovementTemplate().Ground == CreatureGroundMovementType::Hover || IsHovering(); } + [[nodiscard]] bool IsRooted() const { return GetMovementTemplate().IsRooted(); } MovementGeneratorType GetDefaultMovementType() const override { return m_defaultMovementType; } void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; } @@ -165,6 +166,7 @@ class Creature : public Unit, public GridObject, public MovableMapObje [[nodiscard]] uint32 GetSpellCooldown(uint32 spell_id) const; void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) override; [[nodiscard]] bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const; + void ClearProhibitedSpellTimers(); [[nodiscard]] bool HasSpell(uint32 spellID) const override; @@ -369,6 +371,7 @@ class Creature : public Unit, public GridObject, public MovableMapObje // Handling caster facing during spellcast void SetTarget(ObjectGuid guid = ObjectGuid::Empty) override; + void ClearTarget() { SetTarget(); }; void FocusTarget(Spell const* focusSpell, WorldObject const* target); void ReleaseFocus(Spell const* focusSpell); [[nodiscard]] bool IsMovementPreventedByCasting() const override; @@ -401,6 +404,12 @@ class Creature : public Unit, public GridObject, public MovableMapObje * */ void ResumeChasingVictim() { GetMotionMaster()->MoveChase(GetVictim()); }; + /** + * @brief Returns true if the creature is able to cast the spell. + * + * */ + bool CanCastSpell(uint32 spellID) const; + std::string GetDebugInfo() const override; protected: diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h index 80e4b3c7b8fa26..2d33cb9d34d3cd 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -292,7 +292,7 @@ struct CreatureBaseStats { uint32 BaseHealth[MAX_EXPANSIONS]; uint32 BaseMana; - uint32 BaseArmor; + float BaseArmor; uint32 AttackPower; uint32 RangedAttackPower; float BaseDamage[MAX_EXPANSIONS]; @@ -313,9 +313,9 @@ struct CreatureBaseStats return uint32(std::ceil(BaseMana * info->ModMana)); } - uint32 GenerateArmor(CreatureTemplate const* info) const + float GenerateArmor(CreatureTemplate const* info) const { - return uint32(std::ceil(BaseArmor * info->ModArmor)); + return std::ceil(BaseArmor * info->ModArmor); } float GenerateBaseDamage(CreatureTemplate const* info) const diff --git a/src/server/game/Entities/Creature/enuminfo_CreatureData.cpp b/src/server/game/Entities/Creature/enuminfo_CreatureData.cpp index 85b665f4d35e0b..80a6de93abfb5f 100644 --- a/src/server/game/Entities/Creature/enuminfo_CreatureData.cpp +++ b/src/server/game/Entities/Creature/enuminfo_CreatureData.cpp @@ -42,7 +42,7 @@ AC_API_EXPORT EnumText EnumUtils::ToString(CreatureFlagsExtr case CREATURE_FLAG_EXTRA_NO_TAUNT: return { "CREATURE_FLAG_EXTRA_NO_TAUNT", "CREATURE_FLAG_EXTRA_NO_TAUNT", "creature is immune to taunt auras and 'attack me' effects" }; case CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE: return { "CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE", "CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE", "creature won't update movement flags" }; case CREATURE_FLAG_EXTRA_GHOST_VISIBILITY: return { "CREATURE_FLAG_EXTRA_GHOST_VISIBILITY", "CREATURE_FLAG_EXTRA_GHOST_VISIBILITY", "creature will only be visible to dead players" }; - case CREATURE_FLAG_EXTRA_UNUSED_12: return { "CREATURE_FLAG_EXTRA_UNUSED_12", "CREATURE_FLAG_EXTRA_UNUSED_12", "TODO: Implement CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK (creature will use offhand attacks)" }; + case CREATURE_FLAG_EXTRA_UNUSED_12: return { "CREATURE_FLAG_EXTRA_UNUSED_12", "CREATURE_FLAG_EXTRA_UNUSED_12", "/ @todo: Implement CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK (creature will use offhand attacks)" }; case CREATURE_FLAG_EXTRA_NO_SELL_VENDOR: return { "CREATURE_FLAG_EXTRA_NO_SELL_VENDOR", "CREATURE_FLAG_EXTRA_NO_SELL_VENDOR", "players can't sell items to this vendor" }; case CREATURE_FLAG_EXTRA_IGNORE_COMBAT: return { "CREATURE_FLAG_EXTRA_IGNORE_COMBAT", "CREATURE_FLAG_EXTRA_IGNORE_COMBAT", "" }; case CREATURE_FLAG_EXTRA_WORLDEVENT: return { "CREATURE_FLAG_EXTRA_WORLDEVENT", "CREATURE_FLAG_EXTRA_WORLDEVENT", "custom flag for world event creatures (left room for merging)" }; @@ -55,10 +55,10 @@ AC_API_EXPORT EnumText EnumUtils::ToString(CreatureFlagsExtr case CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ: return { "CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ", "CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ", "creature does not need to take player damage for kill credit" }; case CREATURE_FLAG_EXTRA_AVOID_AOE: return { "CREATURE_FLAG_EXTRA_AVOID_AOE", "CREATURE_FLAG_EXTRA_AVOID_AOE", "pussywizard: ignored by aoe attacks (for icc blood prince council npc - Dark Nucleus)" }; case CREATURE_FLAG_EXTRA_NO_DODGE: return { "CREATURE_FLAG_EXTRA_NO_DODGE", "CREATURE_FLAG_EXTRA_NO_DODGE", "xinef: target cannot dodge" }; - case CREATURE_FLAG_EXTRA_MODULE: return { "CREATURE_FLAG_EXTRA_MODULE", "CREATURE_FLAG_EXTRA_MODULE", "Used by module creatures to avoid blizzlike checks." }; - case CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE: return { "CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE", "Creature does not call for assistance on initial aggro", "" }; - case CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS: return { "CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS", "Prevents creature from responding to assistance calls", "" }; - case CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI: return { "CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI", "Creature entry SAI won't be overriden by GUID SAI", "" }; + case CREATURE_FLAG_EXTRA_MODULE: return { "CREATURE_FLAG_EXTRA_MODULE", "CREATURE_FLAG_EXTRA_MODULE", "" }; + case CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE: return { "CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE", "CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE", "Prevent creatures from calling for assistance on initial aggro" }; + case CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS: return { "CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS", "CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS", "Prevents creature from responding to assistance calls" }; + case CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI: return { "CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI", "CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI", "Load both ENTRY and GUID specific SAI" }; case CREATURE_FLAG_EXTRA_DUNGEON_BOSS: return { "CREATURE_FLAG_EXTRA_DUNGEON_BOSS", "CREATURE_FLAG_EXTRA_DUNGEON_BOSS", "creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB)" }; case CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING: return { "CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING", "CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING", "creature ignore pathfinding" }; case CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK: return { "CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK", "CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK", "creature is immune to knockback effects" }; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 1365834de96b75..aa164d4f75f94a 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1724,7 +1724,10 @@ void GameObject::Use(Unit* user) player->SendCinematicStart(info->camera.cinematicId); if (info->camera.eventID) + { GetMap()->ScriptsStart(sEventScripts, info->camera.eventID, player, this); + EventInform(info->camera.eventID); + } return; } @@ -2276,7 +2279,14 @@ void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= nullptr*/ if (!IsDestructibleBuilding()) return; - if (!m_goValue.Building.MaxHealth || !change) + // if this building doesn't have health, return + if (!m_goValue.Building.MaxHealth) + return; + + sScriptMgr->OnGameObjectModifyHealth(this, attackerOrHealer, change, sSpellMgr->GetSpellInfo(spellId)); + + // if the health isn't being changed, return + if (!change) return; if (!m_allowModifyDestructibleBuilding) diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index fef69d6ef3d544..c0584ef005a6e8 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -65,7 +65,7 @@ constexpr float VisibilityDistances[AsUnderlyingType(VisibilityDistanceType::Max VISIBILITY_DISTANCE_SMALL, VISIBILITY_DISTANCE_LARGE, VISIBILITY_DISTANCE_GIGANTIC, - VISIBILITY_DISTANCE_INFINITE + MAX_VISIBILITY_DISTANCE }; Object::Object() : m_PackGUID(sizeof(uint64) + 1) @@ -2922,7 +2922,7 @@ void WorldObject::DestroyForNearbyPlayers() } } -void WorldObject::UpdateObjectVisibility(bool /*forced*/, bool /*fromUpdate*/) +void WorldObject::UpdateObjectVisibility(bool /*forced*/) { //updates object's visibility for nearby players Acore::VisibleChangesNotifier notifier(*this); @@ -2931,28 +2931,7 @@ void WorldObject::UpdateObjectVisibility(bool /*forced*/, bool /*fromUpdate*/) void WorldObject::AddToNotify(uint16 f) { - if (!(m_notifyflags & f)) - if (Unit* u = ToUnit()) - { - if (f & NOTIFY_VISIBILITY_CHANGED) - { - uint32 EVENT_VISIBILITY_DELAY = u->FindMap() ? DynamicVisibilityMgr::GetVisibilityNotifyDelay(u->FindMap()->GetEntry()->map_type) : 1000; - - uint32 diff = getMSTimeDiff(u->m_last_notify_mstime, GameTime::GetGameTimeMS().count()); - if (diff >= EVENT_VISIBILITY_DELAY / 2) - EVENT_VISIBILITY_DELAY /= 2; - else - EVENT_VISIBILITY_DELAY -= diff; - u->m_delayed_unit_relocation_timer = EVENT_VISIBILITY_DELAY; - u->m_last_notify_mstime = GameTime::GetGameTimeMS().count() + EVENT_VISIBILITY_DELAY - 1; - } - else if (f & NOTIFY_AI_RELOCATION) - { - u->m_delayed_unit_ai_notify_timer = u->FindMap() ? DynamicVisibilityMgr::GetAINotifyDelay(u->FindMap()->GetEntry()->map_type) : 500; - } - - m_notifyflags |= f; - } + m_notifyflags |= f; } struct WorldObjectChangeAccumulator diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 8a75f3d87e88c9..adaf92899d8887 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -379,14 +379,23 @@ class MovableMapObject template friend class RandomMovementGenerator; protected: - MovableMapObject() = default; + MovableMapObject() : _moveState(MAP_OBJECT_CELL_MOVE_NONE) + { + _newPosition.Relocate(0.0f, 0.0f, 0.0f, 0.0f); + } private: + Cell _currentCell; [[nodiscard]] Cell const& GetCurrentCell() const { return _currentCell; } void SetCurrentCell(Cell const& cell) { _currentCell = cell; } - Cell _currentCell; - MapObjectCellMoveState _moveState{MAP_OBJECT_CELL_MOVE_NONE}; + MapObjectCellMoveState _moveState; + Position _newPosition; + void SetNewCellPosition(float x, float y, float z, float o) + { + _moveState = MAP_OBJECT_CELL_MOVE_ACTIVE; + _newPosition.Relocate(x, y, z, o); + } }; class WorldObject : public Object, public WorldLocation @@ -538,7 +547,7 @@ class WorldObject : public Object, public WorldLocation void GetDeadCreatureListInGrid(std::list& lList, float maxSearchRange, bool alive = false) const; void DestroyForNearbyPlayers(); - virtual void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false); + virtual void UpdateObjectVisibility(bool forced = true); void BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet& player_set) override; void GetCreaturesWithEntryInRange(std::list& creatureList, float radius, uint32 entry); diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h index 55c4826339ab93..5d809c05f58b58 100644 --- a/src/server/game/Entities/Object/ObjectDefines.h +++ b/src/server/game/Entities/Object/ObjectDefines.h @@ -28,16 +28,15 @@ #define VISIBILITY_INC_FOR_GOBJECTS 30.0f // pussywizard #define SPELL_SEARCHER_COMPENSATION 30.0f // increase searchers size in case we have large npc near cell border #define TRADE_DISTANCE 11.11f -#define MAX_VISIBILITY_DISTANCE 250.0f // max distance for visible objects, experimental +#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects, experimental #define SIGHT_RANGE_UNIT 50.0f #define MAX_SEARCHER_DISTANCE 150.0f // pussywizard: replace the use of MAX_VISIBILITY_DISTANCE in searchers, because MAX_VISIBILITY_DISTANCE is quite too big for this purpose -#define VISIBILITY_DISTANCE_INFINITE 533.0f #define VISIBILITY_DISTANCE_GIGANTIC 400.0f #define VISIBILITY_DISTANCE_LARGE 200.0f #define VISIBILITY_DISTANCE_NORMAL 100.0f #define VISIBILITY_DISTANCE_SMALL 50.0f #define VISIBILITY_DISTANCE_TINY 25.0f -#define DEFAULT_VISIBILITY_DISTANCE 100.0f // default visible distance, 100 yards on continents +#define DEFAULT_VISIBILITY_DISTANCE VISIBILITY_DISTANCE_NORMAL // default visible distance, 100 yards on continents #define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards #define VISIBILITY_DIST_WINTERGRASP 175.0f #define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards diff --git a/src/server/game/Entities/Object/Position.h b/src/server/game/Entities/Object/Position.h index 8b87368d15f135..e88e3ea2e6c1b9 100644 --- a/src/server/game/Entities/Object/Position.h +++ b/src/server/game/Entities/Object/Position.h @@ -196,10 +196,10 @@ struct Position float GetRelativeAngle(const Position* pos) const { - return GetAngle(pos) - m_orientation; + return NormalizeOrientation(GetAngle(pos) - m_orientation); } - [[nodiscard]] float GetRelativeAngle(float x, float y) const { return GetAngle(x, y) - m_orientation; } + [[nodiscard]] float GetRelativeAngle(float x, float y) const { return NormalizeOrientation(GetAngle(x, y) - m_orientation); } [[nodiscard]] float ToAbsoluteAngle(float relAngle) const { return NormalizeOrientation(relAngle + m_orientation); } void GetSinCos(float x, float y, float& vsin, float& vcos) const; diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index b3507a3ecc80d5..36a770ac10a1ee 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -1175,6 +1175,14 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, aurEff->GetAmount(), true); } + break; + } + case NPC_VOIDWALKER: + { + if (AuraEffect* aurEff = owner->GetAuraEffectDummy(SPELL_GLYPH_OF_VOIDWALKER)) + { + HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_PCT, aurEff->GetAmount(), true); + } break; } case NPC_WATER_ELEMENTAL_PERM: diff --git a/src/server/game/Entities/Pet/PetDefines.h b/src/server/game/Entities/Pet/PetDefines.h index 22849c217891c3..65de91faad676c 100644 --- a/src/server/game/Entities/Pet/PetDefines.h +++ b/src/server/game/Entities/Pet/PetDefines.h @@ -147,6 +147,7 @@ enum PetScalingSpells SPELL_WARLOCK_PET_SCALING_04 = 34958, SPELL_WARLOCK_PET_SCALING_05 = 61013, // Hit / Expertise SPELL_GLYPH_OF_FELGUARD = 56246, + SPELL_GLYPH_OF_VOIDWALKER = 56247, SPELL_INFERNAL_SCALING_01 = 36186, SPELL_INFERNAL_SCALING_02 = 36188, SPELL_INFERNAL_SCALING_03 = 36189, diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index dfdbf584a3bc94..c5517290ad87fc 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -389,6 +389,8 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this) _activeCheats = CHEAT_NONE; + m_creationTime = 0s; + _cinematicMgr = new CinematicMgr(this); m_achievementMgr = new AchievementMgr(this); @@ -1304,6 +1306,8 @@ uint8 Player::GetChatTag() const tag |= CHAT_TAG_DND; if (isAFK()) tag |= CHAT_TAG_AFK; + if (IsCommentator()) + tag |= CHAT_TAG_COM; if (IsDeveloper()) tag |= CHAT_TAG_DEV; @@ -14019,8 +14023,13 @@ uint32 Player::CalculateTalentsPoints() const return uint32(talentPointsForLevel * sWorld->getRate(RATE_TALENT)); } -bool Player::canFlyInZone(uint32 mapid, uint32 zone, SpellInfo const* bySpell) const +bool Player::canFlyInZone(uint32 mapid, uint32 zone, SpellInfo const* bySpell) { + if (!sScriptMgr->OnCanPlayerFlyInZone(this, mapid,zone,bySpell)) + { + return false; + } + // continent checked in SpellInfo::CheckLocation at cast and area update uint32 v_map = GetVirtualMapForMapAndZone(mapid, zone); if (v_map == 571 && !bySpell->HasAttribute(SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT)) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 3d21c5aba08c82..185ec1eaf71fad 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -870,7 +870,7 @@ enum PlayerChatTag CHAT_TAG_AFK = 0x01, CHAT_TAG_DND = 0x02, CHAT_TAG_GM = 0x04, - CHAT_TAG_COM = 0x08, // Commentator + CHAT_TAG_COM = 0x08, // Commentator tag. Do not exist in clean client CHAT_TAG_DEV = 0x10, }; @@ -1172,6 +1172,8 @@ class Player : public Unit, public GridObject void SendTaxiNodeStatusMultiple(); // mount_id can be used in scripting calls + [[nodiscard]] bool IsCommentator() const { return HasPlayerFlag(PLAYER_FLAGS_COMMENTATOR2); } + void SetCommentator(bool on) { ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_COMMENTATOR2, on); } [[nodiscard]] bool IsDeveloper() const { return HasPlayerFlag(PLAYER_FLAGS_DEVELOPER); } void SetDeveloper(bool on) { ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER, on); } [[nodiscard]] bool isAcceptWhispers() const { return m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS; } @@ -1600,6 +1602,7 @@ class Player : public Unit, public GridObject void SaveToDB(CharacterDatabaseTransaction trans, bool create, bool logout); void SaveInventoryAndGoldToDB(CharacterDatabaseTransaction trans); // fast save function for item/money cheating preventing void SaveGoldToDB(CharacterDatabaseTransaction trans); + void _SaveSkills(CharacterDatabaseTransaction trans); static void Customize(CharacterCustomizeInfo const* customizeInfo, CharacterDatabaseTransaction trans); static void SavePositionInDB(uint32 mapid, float x, float y, float z, float o, uint32 zone, ObjectGuid guid); @@ -2371,7 +2374,7 @@ class Player : public Unit, public GridObject } void HandleFall(MovementInfo const& movementInfo); - [[nodiscard]] bool canFlyInZone(uint32 mapid, uint32 zone, SpellInfo const* bySpell) const; + [[nodiscard]] bool canFlyInZone(uint32 mapid, uint32 zone, SpellInfo const* bySpell); void SetClientControl(Unit* target, bool allowMove, bool packetOnly = false); @@ -2421,7 +2424,7 @@ class Player : public Unit, public GridObject bool IsVisibleGloballyFor(Player const* player) const; void GetInitialVisiblePackets(Unit* target); - void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false) override; + void UpdateObjectVisibility(bool forced = true) override; void UpdateVisibilityForPlayer(bool mapChange = false); void UpdateVisibilityOf(WorldObject* target); void UpdateTriggerVisibility(); @@ -2571,6 +2574,9 @@ class Player : public Unit, public GridObject void CompletedAchievement(AchievementEntry const* entry); [[nodiscard]] AchievementMgr* GetAchievementMgr() const { return m_achievementMgr; } + void SetCreationTime(Seconds creationTime) { m_creationTime = creationTime; } + [[nodiscard]] Seconds GetCreationTime() const { return m_creationTime; } + [[nodiscard]] bool HasTitle(uint32 bitIndex) const; bool HasTitle(CharTitlesEntry const* title) const { return HasTitle(title->bit_index); } void SetTitle(CharTitlesEntry const* title, bool lost = false); @@ -2772,7 +2778,6 @@ class Player : public Unit, public GridObject void _SaveWeeklyQuestStatus(CharacterDatabaseTransaction trans); void _SaveMonthlyQuestStatus(CharacterDatabaseTransaction trans); void _SaveSeasonalQuestStatus(CharacterDatabaseTransaction trans); - void _SaveSkills(CharacterDatabaseTransaction trans); void _SaveSpells(CharacterDatabaseTransaction trans); void _SaveEquipmentSets(CharacterDatabaseTransaction trans); void _SaveEntryPoint(CharacterDatabaseTransaction trans); @@ -3032,6 +3037,8 @@ class Player : public Unit, public GridObject bool _wasOutdoor; PlayerSettingMap m_charSettingsMap; + + Seconds m_creationTime; }; void AddItemsSetItem(Player* player, Item* item); diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 39efde4d7e523e..978a31112cd6b2 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -4985,8 +4985,8 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons //"arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, " // 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 //"health, power1, power2, power3, power4, power5, power6, power7, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, knownTitles, - // 70 71 72 73 - //"actionBars, grantableLevels, innTriggerId, extraBonusTalentCount FROM characters WHERE guid = '{}'", guid); + // 70 71 72 73 74 + //"actionBars, grantableLevels, innTriggerId, extraBonusTalentCount, UNIX_TIMESTAMP(creation_date) FROM characters WHERE guid = '{}'", guid); PreparedQueryResult result = holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM); if (!result) @@ -5063,6 +5063,9 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons SetObjectScale(1.0f); SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); + // load character creation date, relevant for achievements of type average + SetCreationTime(fields[74].Get()); + // load achievements before anything else to prevent multiple gains for the same achievement/criteria on every loading (as loading does call UpdateAchievementCriteria) m_achievementMgr->LoadFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS)); diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 4e703b43392d63..17c1319f9a4090 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -412,14 +412,6 @@ void Player::Update(uint32 p_time) SetHasDelayedTeleport(false); TeleportTo(teleportStore_dest, teleportStore_options); } - - if (!IsBeingTeleported() && bRequestForcedVisibilityUpdate) - { - bRequestForcedVisibilityUpdate = false; - UpdateObjectVisibility(true, true); - m_delayed_unit_relocation_timer = 0; - RemoveFromNotify(NOTIFY_VISIBILITY_CHANGED); - } } void Player::UpdateMirrorTimers() @@ -1550,23 +1542,13 @@ void Player::UpdateVisibilityForPlayer(bool mapChange) m_seer = this; } - Acore::VisibleNotifier notifierNoLarge( - *this, mapChange, - false); // visit only objects which are not large; default distance - Cell::VisitAllObjects(m_seer, notifierNoLarge, - GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS); - notifierNoLarge.SendToSelf(); - - Acore::VisibleNotifier notifierLarge( - *this, mapChange, true); // visit only large objects; maximum distance - Cell::VisitAllObjects(m_seer, notifierLarge, GetSightRange()); - notifierLarge.SendToSelf(); - - if (mapChange) - m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f); + // updates visibility of all objects around point of view for current player + Acore::VisibleNotifier notifier(*this, mapChange); + Cell::VisitAllObjects(m_seer, notifier, GetSightRange()); + notifier.SendToSelf(); // send gathered data } -void Player::UpdateObjectVisibility(bool forced, bool fromUpdate) +void Player::UpdateObjectVisibility(bool forced) { // Prevent updating visibility if player is not in world (example: LoadFromDB sets drunkstate which updates invisibility while player is not in map) if (!IsInWorld()) @@ -1576,11 +1558,6 @@ void Player::UpdateObjectVisibility(bool forced, bool fromUpdate) AddToNotify(NOTIFY_VISIBILITY_CHANGED); else if (!isBeingLoaded()) { - if (!fromUpdate) // pussywizard: - { - bRequestForcedVisibilityUpdate = true; - return; - } Unit::UpdateObjectVisibility(true); UpdateVisibilityForPlayer(); } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8c25950de50343..3cb2246aa91e40 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -319,12 +319,6 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject), m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); - m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f); - m_last_notify_mstime = 0; - m_delayed_unit_relocation_timer = 0; - m_delayed_unit_ai_notify_timer = 0; - bRequestForcedVisibilityUpdate = false; - m_applyResilience = false; _instantCast = false; @@ -413,32 +407,6 @@ void Unit::Update(uint32 p_time) if (!IsInWorld()) return; - // pussywizard: - if (GetTypeId() != TYPEID_PLAYER || (!ToPlayer()->IsBeingTeleported() && !bRequestForcedVisibilityUpdate)) - { - if (m_delayed_unit_relocation_timer) - { - if (m_delayed_unit_relocation_timer <= p_time) - { - m_delayed_unit_relocation_timer = 0; - //ExecuteDelayedUnitRelocationEvent(); - FindMap()->i_objectsForDelayedVisibility.insert(this); - } - else - m_delayed_unit_relocation_timer -= p_time; - } - if (m_delayed_unit_ai_notify_timer) - { - if (m_delayed_unit_ai_notify_timer <= p_time) - { - m_delayed_unit_ai_notify_timer = 0; - ExecuteDelayedUnitAINotifyEvent(); - } - else - m_delayed_unit_ai_notify_timer -= p_time; - } - } - _UpdateSpells( p_time ); if (CanHaveThreatList() && GetThreatMgr().isNeedUpdateToClient(p_time)) @@ -8373,13 +8341,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere CastCustomSpell(this, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura, originalCaster); break; } - // Shaman T8 Elemental 4P Bonus - case 64928: - { - basepoints0 = CalculatePct(int32(damage), triggerAmount); - triggered_spell_id = 64930; // Electrified - break; - } // Shaman T9 Elemental 4P Bonus case 67228: { @@ -11440,12 +11401,12 @@ void Unit::SendEnergizeSpellLog(Unit* victim, uint32 spellID, uint32 damage, Pow void Unit::EnergizeBySpell(Unit* victim, uint32 spellID, uint32 damage, Powers powerType) { - victim->ModifyPower(powerType, damage, false); + int32 gainedPower = victim->ModifyPower(powerType, damage, false); - if (powerType != POWER_HAPPINESS) + if (powerType != POWER_HAPPINESS && gainedPower) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID); - victim->getHostileRefMgr().threatAssist(this, float(damage) * 0.5f, spellInfo); + victim->getHostileRefMgr().threatAssist(this, float(gainedPower) * 0.5f, spellInfo); } SendEnergizeSpellLog(victim, spellID, damage, powerType); @@ -14226,6 +14187,9 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo // additional checks - only PvP case if (playerAffectingAttacker && playerAffectingTarget) { + if (!IsPvP() && bySpell && bySpell->IsAffectingArea() && !bySpell->HasAttribute(SPELL_ATTR5_IGNORE_AREA_EFFECT_PVP_CHECK)) + return false; + if (target->IsPvP()) return true; @@ -17946,13 +17910,17 @@ void Unit::SetContestedPvP(Player* attackedPlayer, bool lookForNearContestedGuar player->AddUnitState(UNIT_STATE_ATTACK_PLAYER); player->SetPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP); // call MoveInLineOfSight for nearby contested guards - AddToNotify(NOTIFY_AI_RELOCATION); + Acore::AIRelocationNotifier notifier(*this); + Cell::VisitWorldObjects(this, notifier, GetVisibilityRange()); } - if (!HasUnitState(UNIT_STATE_ATTACK_PLAYER)) + for (Unit* unit : m_Controlled) { - AddUnitState(UNIT_STATE_ATTACK_PLAYER); - // call MoveInLineOfSight for nearby contested guards - AddToNotify(NOTIFY_AI_RELOCATION); + if (!unit->HasUnitState(UNIT_STATE_ATTACK_PLAYER)) + { + unit->AddUnitState(UNIT_STATE_ATTACK_PLAYER); + Acore::AIRelocationNotifier notifier(*unit); + Cell::VisitWorldObjects(this, notifier, GetVisibilityRange()); + } } } @@ -19799,7 +19767,7 @@ void Unit::SetPhaseMask(uint32 newPhaseMask, bool update) } } -void Unit::UpdateObjectVisibility(bool forced, bool /*fromUpdate*/) +void Unit::UpdateObjectVisibility(bool forced) { if (!forced) AddToNotify(NOTIFY_VISIBILITY_CHANGED); @@ -19807,8 +19775,7 @@ void Unit::UpdateObjectVisibility(bool forced, bool /*fromUpdate*/) { WorldObject::UpdateObjectVisibility(true); Acore::AIRelocationNotifier notifier(*this); - float radius = 60.0f; - Cell::VisitAllObjects(this, notifier, radius); + Cell::VisitAllObjects(this, notifier, GetVisibilityRange()); } } @@ -20646,7 +20613,7 @@ bool Unit::CanSwim() const // Mirror client behavior, if this method returns false then client will not use swimming animation and for players will apply gravity as if there was no water if (HasUnitFlag(UNIT_FLAG_CANNOT_SWIM)) return false; - if (HasUnitFlag(UNIT_FLAG_POSSESSED)) // is player + if (HasUnitFlag(UNIT_FLAG_POSSESSED) || HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED)) // is player return true; if (HasUnitFlag2(UNIT_FLAG2_UNUSED_6)) return false; @@ -21167,124 +21134,6 @@ bool ConflagrateAuraStateDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time return true; } -void Unit::ExecuteDelayedUnitRelocationEvent() -{ - this->RemoveFromNotify(NOTIFY_VISIBILITY_CHANGED); - if (!this->IsInWorld() || this->IsDuringRemoveFromWorld()) - return; - - if (this->HasSharedVision()) - for (SharedVisionList::const_iterator itr = this->GetSharedVisionList().begin(); itr != this->GetSharedVisionList().end(); ++itr) - if (Player* player = (*itr)) - { - if (player->IsOnVehicle(this) || !player->IsInWorld() || player->IsDuringRemoveFromWorld()) // players on vehicles have their own event executed (due to passenger relocation) - continue; - WorldObject* viewPoint = player; - if (player->m_seer && player->m_seer->IsInWorld()) - viewPoint = player->m_seer; - if (!viewPoint->IsPositionValid() || !player->IsPositionValid()) - continue; - - if (Unit* active = viewPoint->ToUnit()) - { - //if (active->IsVehicle()) // always check original unit here, last notify position is not relocated - // active = player; - - float dx = active->m_last_notify_position.GetPositionX() - active->GetPositionX(); - float dy = active->m_last_notify_position.GetPositionY() - active->GetPositionY(); - float dz = active->m_last_notify_position.GetPositionZ() - active->GetPositionZ(); - float distsq = dx * dx + dy * dy + dz * dz; - float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(active->FindMap()->GetEntry()->map_type); - if (distsq < mindistsq) - continue; - - // this will be relocated below sharedvision! - //active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ()); - } - - Acore::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance - Cell::VisitAllObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS); - relocateNoLarge.SendToSelf(); - Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance - Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE); - relocateLarge.SendToSelf(); - } - - if (Player* player = this->ToPlayer()) - { - WorldObject* viewPoint = player; - if (player->m_seer && player->m_seer->IsInWorld()) - viewPoint = player->m_seer; - - if (viewPoint->GetMapId() != player->GetMapId() || !viewPoint->IsPositionValid() || !player->IsPositionValid()) - return; - - if (Unit* active = viewPoint->ToUnit()) - { - if (active->IsVehicle()) - active = player; - - if (!player->GetFarSightDistance()) - { - float dx = active->m_last_notify_position.GetPositionX() - active->GetPositionX(); - float dy = active->m_last_notify_position.GetPositionY() - active->GetPositionY(); - float dz = active->m_last_notify_position.GetPositionZ() - active->GetPositionZ(); - float distsq = dx * dx + dy * dy + dz * dz; - - float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(active->FindMap()->GetEntry()->map_type); - if (distsq < mindistsq) - return; - - active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ()); - } - } - - Acore::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance - Cell::VisitAllObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS); - relocateNoLarge.SendToSelf(); - - if (!player->GetFarSightDistance()) - { - Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance - Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE); - relocateLarge.SendToSelf(); - } - - this->AddToNotify(NOTIFY_AI_RELOCATION); - } - else if (Creature* unit = this->ToCreature()) - { - if (!unit->IsPositionValid()) - return; - - float dx = unit->m_last_notify_position.GetPositionX() - unit->GetPositionX(); - float dy = unit->m_last_notify_position.GetPositionY() - unit->GetPositionY(); - float dz = unit->m_last_notify_position.GetPositionZ() - unit->GetPositionZ(); - float distsq = dx * dx + dy * dy + dz * dz; - float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(unit->FindMap()->GetEntry()->map_type); - if (distsq < mindistsq) - return; - - unit->m_last_notify_position.Relocate(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ()); - - Acore::CreatureRelocationNotifier relocate(*unit); - Cell::VisitAllObjects(unit, relocate, unit->GetVisibilityRange() + VISIBILITY_COMPENSATION); - - this->AddToNotify(NOTIFY_AI_RELOCATION); - } -} - -void Unit::ExecuteDelayedUnitAINotifyEvent() -{ - this->RemoveFromNotify(NOTIFY_AI_RELOCATION); - if (!this->IsInWorld() || this->IsDuringRemoveFromWorld()) - return; - - Acore::AIRelocationNotifier notifier(*this); - float radius = 60.0f; - Cell::VisitAllObjects(this, notifier, radius); -} - void Unit::SetInFront(WorldObject const* target) { if (!HasUnitState(UNIT_STATE_CANNOT_TURN)) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 89112c89f2e812..79dc341b957722 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2185,7 +2185,7 @@ class Unit : public WorldObject // common function for visibility checks for player/creatures with detection code [[nodiscard]] uint32 GetPhaseByAuras() const; void SetPhaseMask(uint32 newPhaseMask, bool update) override;// overwrite WorldObject::SetPhaseMask - void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false) override; + void UpdateObjectVisibility(bool forced = true) override; SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]; uint32 m_lastSanctuaryTime; @@ -2462,14 +2462,6 @@ class Unit : public WorldObject void AddPointedBy(SafeUnitPointer* sup) { SafeUnitPointerSet.insert(sup); } void RemovePointedBy(SafeUnitPointer* sup) { SafeUnitPointerSet.erase(sup); } static void HandleSafeUnitPointersOnDelete(Unit* thisUnit); - // Relocation Nofier optimization - Position m_last_notify_position; - uint32 m_last_notify_mstime; - uint16 m_delayed_unit_relocation_timer; - uint16 m_delayed_unit_ai_notify_timer; - bool bRequestForcedVisibilityUpdate; - void ExecuteDelayedUnitRelocationEvent(); - void ExecuteDelayedUnitAINotifyEvent(); // cooldowns [[nodiscard]] virtual bool HasSpellCooldown(uint32 /*spell_id*/) const { return false; } diff --git a/src/server/game/Entities/Unit/enuminfo_Unit.cpp b/src/server/game/Entities/Unit/enuminfo_Unit.cpp index 8444ba3d49a54e..a3c4938c6156af 100644 --- a/src/server/game/Entities/Unit/enuminfo_Unit.cpp +++ b/src/server/game/Entities/Unit/enuminfo_Unit.cpp @@ -31,6 +31,7 @@ AC_API_EXPORT EnumText EnumUtils::ToString(UnitFlags value) { switch (value) { + case UNIT_FLAG_NONE: return { "UNIT_FLAG_NONE", "UNIT_FLAG_NONE", "" }; case UNIT_FLAG_SERVER_CONTROLLED: return { "UNIT_FLAG_SERVER_CONTROLLED", "UNIT_FLAG_SERVER_CONTROLLED", "set only when unit movement is controlled by server - by SPLINE/MONSTER_MOVE packets, together with UNIT_FLAG_STUNNED; only set to units controlled by client; client function CGUnit_C::IsClientControlled returns false when set for owner" }; case UNIT_FLAG_NON_ATTACKABLE: return { "UNIT_FLAG_NON_ATTACKABLE", "UNIT_FLAG_NON_ATTACKABLE", "not attackable" }; case UNIT_FLAG_DISABLE_MOVE: return { "UNIT_FLAG_DISABLE_MOVE", "UNIT_FLAG_DISABLE_MOVE", "" }; @@ -68,45 +69,46 @@ AC_API_EXPORT EnumText EnumUtils::ToString(UnitFlags value) } template <> -AC_API_EXPORT size_t EnumUtils::Count() { return 32; } +AC_API_EXPORT size_t EnumUtils::Count() { return 33; } template <> AC_API_EXPORT UnitFlags EnumUtils::FromIndex(size_t index) { switch (index) { - case 0: return UNIT_FLAG_SERVER_CONTROLLED; - case 1: return UNIT_FLAG_NON_ATTACKABLE; - case 2: return UNIT_FLAG_DISABLE_MOVE; - case 3: return UNIT_FLAG_PLAYER_CONTROLLED; - case 4: return UNIT_FLAG_RENAME; - case 5: return UNIT_FLAG_PREPARATION; - case 6: return UNIT_FLAG_UNK_6; - case 7: return UNIT_FLAG_NOT_ATTACKABLE_1; - case 8: return UNIT_FLAG_IMMUNE_TO_PC; - case 9: return UNIT_FLAG_IMMUNE_TO_NPC; - case 10: return UNIT_FLAG_LOOTING; - case 11: return UNIT_FLAG_PET_IN_COMBAT; - case 12: return UNIT_FLAG_PVP; - case 13: return UNIT_FLAG_SILENCED; - case 14: return UNIT_FLAG_CANNOT_SWIM; - case 15: return UNIT_FLAG_SWIMMING; - case 16: return UNIT_FLAG_NON_ATTACKABLE_2; - case 17: return UNIT_FLAG_PACIFIED; - case 18: return UNIT_FLAG_STUNNED; - case 19: return UNIT_FLAG_IN_COMBAT; - case 20: return UNIT_FLAG_TAXI_FLIGHT; - case 21: return UNIT_FLAG_DISARMED; - case 22: return UNIT_FLAG_CONFUSED; - case 23: return UNIT_FLAG_FLEEING; - case 24: return UNIT_FLAG_POSSESSED; - case 25: return UNIT_FLAG_NOT_SELECTABLE; - case 26: return UNIT_FLAG_SKINNABLE; - case 27: return UNIT_FLAG_MOUNT; - case 28: return UNIT_FLAG_UNK_28; - case 29: return UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT; - case 30: return UNIT_FLAG_SHEATHE; - case 31: return UNIT_FLAG_IMMUNE; + case 0: return UNIT_FLAG_NONE; + case 1: return UNIT_FLAG_SERVER_CONTROLLED; + case 2: return UNIT_FLAG_NON_ATTACKABLE; + case 3: return UNIT_FLAG_DISABLE_MOVE; + case 4: return UNIT_FLAG_PLAYER_CONTROLLED; + case 5: return UNIT_FLAG_RENAME; + case 6: return UNIT_FLAG_PREPARATION; + case 7: return UNIT_FLAG_UNK_6; + case 8: return UNIT_FLAG_NOT_ATTACKABLE_1; + case 9: return UNIT_FLAG_IMMUNE_TO_PC; + case 10: return UNIT_FLAG_IMMUNE_TO_NPC; + case 11: return UNIT_FLAG_LOOTING; + case 12: return UNIT_FLAG_PET_IN_COMBAT; + case 13: return UNIT_FLAG_PVP; + case 14: return UNIT_FLAG_SILENCED; + case 15: return UNIT_FLAG_CANNOT_SWIM; + case 16: return UNIT_FLAG_SWIMMING; + case 17: return UNIT_FLAG_NON_ATTACKABLE_2; + case 18: return UNIT_FLAG_PACIFIED; + case 19: return UNIT_FLAG_STUNNED; + case 20: return UNIT_FLAG_IN_COMBAT; + case 21: return UNIT_FLAG_TAXI_FLIGHT; + case 22: return UNIT_FLAG_DISARMED; + case 23: return UNIT_FLAG_CONFUSED; + case 24: return UNIT_FLAG_FLEEING; + case 25: return UNIT_FLAG_POSSESSED; + case 26: return UNIT_FLAG_NOT_SELECTABLE; + case 27: return UNIT_FLAG_SKINNABLE; + case 28: return UNIT_FLAG_MOUNT; + case 29: return UNIT_FLAG_UNK_28; + case 30: return UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT; + case 31: return UNIT_FLAG_SHEATHE; + case 32: return UNIT_FLAG_IMMUNE; default: throw std::out_of_range("index"); } } @@ -116,38 +118,39 @@ AC_API_EXPORT size_t EnumUtils::ToIndex(UnitFlags value) { switch (value) { - case UNIT_FLAG_SERVER_CONTROLLED: return 0; - case UNIT_FLAG_NON_ATTACKABLE: return 1; - case UNIT_FLAG_DISABLE_MOVE: return 2; - case UNIT_FLAG_PLAYER_CONTROLLED: return 3; - case UNIT_FLAG_RENAME: return 4; - case UNIT_FLAG_PREPARATION: return 5; - case UNIT_FLAG_UNK_6: return 6; - case UNIT_FLAG_NOT_ATTACKABLE_1: return 7; - case UNIT_FLAG_IMMUNE_TO_PC: return 8; - case UNIT_FLAG_IMMUNE_TO_NPC: return 9; - case UNIT_FLAG_LOOTING: return 10; - case UNIT_FLAG_PET_IN_COMBAT: return 11; - case UNIT_FLAG_PVP: return 12; - case UNIT_FLAG_SILENCED: return 13; - case UNIT_FLAG_CANNOT_SWIM: return 14; - case UNIT_FLAG_SWIMMING: return 15; - case UNIT_FLAG_NON_ATTACKABLE_2: return 16; - case UNIT_FLAG_PACIFIED: return 17; - case UNIT_FLAG_STUNNED: return 18; - case UNIT_FLAG_IN_COMBAT: return 19; - case UNIT_FLAG_TAXI_FLIGHT: return 20; - case UNIT_FLAG_DISARMED: return 21; - case UNIT_FLAG_CONFUSED: return 22; - case UNIT_FLAG_FLEEING: return 23; - case UNIT_FLAG_POSSESSED: return 24; - case UNIT_FLAG_NOT_SELECTABLE: return 25; - case UNIT_FLAG_SKINNABLE: return 26; - case UNIT_FLAG_MOUNT: return 27; - case UNIT_FLAG_UNK_28: return 28; - case UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT: return 29; - case UNIT_FLAG_SHEATHE: return 30; - case UNIT_FLAG_IMMUNE: return 31; + case UNIT_FLAG_NONE: return 0; + case UNIT_FLAG_SERVER_CONTROLLED: return 1; + case UNIT_FLAG_NON_ATTACKABLE: return 2; + case UNIT_FLAG_DISABLE_MOVE: return 3; + case UNIT_FLAG_PLAYER_CONTROLLED: return 4; + case UNIT_FLAG_RENAME: return 5; + case UNIT_FLAG_PREPARATION: return 6; + case UNIT_FLAG_UNK_6: return 7; + case UNIT_FLAG_NOT_ATTACKABLE_1: return 8; + case UNIT_FLAG_IMMUNE_TO_PC: return 9; + case UNIT_FLAG_IMMUNE_TO_NPC: return 10; + case UNIT_FLAG_LOOTING: return 11; + case UNIT_FLAG_PET_IN_COMBAT: return 12; + case UNIT_FLAG_PVP: return 13; + case UNIT_FLAG_SILENCED: return 14; + case UNIT_FLAG_CANNOT_SWIM: return 15; + case UNIT_FLAG_SWIMMING: return 16; + case UNIT_FLAG_NON_ATTACKABLE_2: return 17; + case UNIT_FLAG_PACIFIED: return 18; + case UNIT_FLAG_STUNNED: return 19; + case UNIT_FLAG_IN_COMBAT: return 20; + case UNIT_FLAG_TAXI_FLIGHT: return 21; + case UNIT_FLAG_DISARMED: return 22; + case UNIT_FLAG_CONFUSED: return 23; + case UNIT_FLAG_FLEEING: return 24; + case UNIT_FLAG_POSSESSED: return 25; + case UNIT_FLAG_NOT_SELECTABLE: return 26; + case UNIT_FLAG_SKINNABLE: return 27; + case UNIT_FLAG_MOUNT: return 28; + case UNIT_FLAG_UNK_28: return 29; + case UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT: return 30; + case UNIT_FLAG_SHEATHE: return 31; + case UNIT_FLAG_IMMUNE: return 32; default: throw std::out_of_range("value"); } } @@ -187,12 +190,13 @@ AC_API_EXPORT EnumText EnumUtils::ToString(NPCFlags value) case UNIT_NPC_FLAG_SPELLCLICK: return { "UNIT_NPC_FLAG_SPELLCLICK", "has spell click enabled", "cause client to send 1015 opcode (spell click)" }; case UNIT_NPC_FLAG_PLAYER_VEHICLE: return { "UNIT_NPC_FLAG_PLAYER_VEHICLE", "is player vehicle", "players with mounts that have vehicle data should have it set" }; case UNIT_NPC_FLAG_MAILBOX: return { "UNIT_NPC_FLAG_MAILBOX", "is mailbox", "" }; + case UNIT_NPC_FLAG_VENDOR_MASK: return { "UNIT_NPC_FLAG_VENDOR_MASK", "UNIT_NPC_FLAG_VENDOR_MASK", "" }; default: throw std::out_of_range("value"); } } template <> -AC_API_EXPORT size_t EnumUtils::Count() { return 27; } +AC_API_EXPORT size_t EnumUtils::Count() { return 28; } template <> AC_API_EXPORT NPCFlags EnumUtils::FromIndex(size_t index) @@ -226,6 +230,7 @@ AC_API_EXPORT NPCFlags EnumUtils::FromIndex(size_t index) case 24: return UNIT_NPC_FLAG_SPELLCLICK; case 25: return UNIT_NPC_FLAG_PLAYER_VEHICLE; case 26: return UNIT_NPC_FLAG_MAILBOX; + case 27: return UNIT_NPC_FLAG_VENDOR_MASK; default: throw std::out_of_range("index"); } } @@ -262,6 +267,7 @@ AC_API_EXPORT size_t EnumUtils::ToIndex(NPCFlags value) case UNIT_NPC_FLAG_SPELLCLICK: return 24; case UNIT_NPC_FLAG_PLAYER_VEHICLE: return 25; case UNIT_NPC_FLAG_MAILBOX: return 26; + case UNIT_NPC_FLAG_VENDOR_MASK: return 27; default: throw std::out_of_range("value"); } } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 4c3f88cb980f9e..dfe1769da19d86 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2863,47 +2863,43 @@ void ObjectMgr::LoadItemTemplates() if (dbcitem) { - if (itemTemplate.Class != dbcitem->ClassID) + if (enforceDBCAttributes) { - LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({}), must be ({}).", entry, itemTemplate.Class, dbcitem->ClassID); - if (enforceDBCAttributes) + if (itemTemplate.Class != dbcitem->ClassID) + { + LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({}), must be ({}).", entry, itemTemplate.Class, dbcitem->ClassID); itemTemplate.Class = dbcitem->ClassID; - } - if (itemTemplate.SubClass != dbcitem->SubclassID) - { - LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Subclass value ({}) for class {}, must be ({}).", entry, itemTemplate.SubClass, itemTemplate.Class, dbcitem->SubclassID); - if (enforceDBCAttributes) + } + if (itemTemplate.SubClass != dbcitem->SubclassID) + { + LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Subclass value ({}) for class {}, must be ({}).", entry, itemTemplate.SubClass, itemTemplate.Class, dbcitem->SubclassID); itemTemplate.SubClass = dbcitem->SubclassID; - } - if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclassID) - { - LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct SoundOverrideSubclass ({}), must be {}.", entry, itemTemplate.SoundOverrideSubclass); - if (enforceDBCAttributes) + } + if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclassID) + { + LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct SoundOverrideSubclass ({}), must be {}.", entry, itemTemplate.SoundOverrideSubclass, dbcitem->SoundOverrideSubclassID); itemTemplate.SoundOverrideSubclass = dbcitem->SoundOverrideSubclassID; - } - if (itemTemplate.Material != dbcitem->Material) - { - LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material); - if (enforceDBCAttributes) + } + if (itemTemplate.Material != dbcitem->Material) + { + LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material); itemTemplate.Material = dbcitem->Material; - } - if (itemTemplate.InventoryType != dbcitem->InventoryType) - { - LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong InventoryType value ({}), must be {}.", entry, itemTemplate.InventoryType, dbcitem->InventoryType); - if (enforceDBCAttributes) + } + if (itemTemplate.InventoryType != dbcitem->InventoryType) + { + LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong InventoryType value ({}), must be {}.", entry, itemTemplate.InventoryType, dbcitem->InventoryType); itemTemplate.InventoryType = dbcitem->InventoryType; - } - if (itemTemplate.DisplayInfoID != dbcitem->DisplayInfoID) - { - LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID); - if (enforceDBCAttributes) + } + if (itemTemplate.DisplayInfoID != dbcitem->DisplayInfoID) + { + LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID); itemTemplate.DisplayInfoID = dbcitem->DisplayInfoID; - } - if (itemTemplate.Sheath != dbcitem->SheatheType) - { - LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Sheath ({}), must be {}.", entry, itemTemplate.Sheath, dbcitem->SheatheType); - if (enforceDBCAttributes) + } + if (itemTemplate.Sheath != dbcitem->SheatheType) + { + LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Sheath ({}), must be {}.", entry, itemTemplate.Sheath, dbcitem->SheatheType); itemTemplate.Sheath = dbcitem->SheatheType; + } } } else diff --git a/src/server/game/Grids/Grid.h b/src/server/game/Grids/Grid.h index b9cafdbe0cd487..d67b9ca3180b38 100644 --- a/src/server/game/Grids/Grid.h +++ b/src/server/game/Grids/Grid.h @@ -96,6 +96,12 @@ class Grid visitor.Visit(i_objects); } + template + uint32 GetWorldObjectCountInGrid() const + { + return i_objects.template Count(); + } + /** Inserts a container type object into the grid. */ template void AddGridObject(SPECIFIC_OBJECT* obj) diff --git a/src/server/game/Grids/GridStates.cpp b/src/server/game/Grids/GridStates.cpp new file mode 100644 index 00000000000000..eb0183b78383ec --- /dev/null +++ b/src/server/game/Grids/GridStates.cpp @@ -0,0 +1,65 @@ +/* + * 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 "GridStates.h" +#include "GridNotifiers.h" +#include "Log.h" +#include "Map.h" +#include "ObjectGridLoader.h" + +void InvalidState::Update(Map&, NGridType&, GridInfo&, uint32) const +{ +} + +void ActiveState::Update(Map& map, NGridType& grid, GridInfo& info, uint32 diff) const +{ + // Only check grid activity every (grid_expiry/10) ms, because it's really useless to do it every cycle + info.UpdateTimeTracker(diff); + if (info.getTimeTracker().Passed()) + { + if (!grid.GetWorldObjectCountInNGrid() && !map.ActiveObjectsNearGrid(grid)) + { + ObjectGridStoper worker; + TypeContainerVisitor visitor(worker); + grid.VisitAllGrids(visitor); + grid.SetGridState(GRID_STATE_IDLE); + LOG_DEBUG("maps", "Grid[{}, {}] on map {} moved to IDLE state", grid.getX(), grid.getY(), map.GetId()); + } + else + map.ResetGridExpiry(grid, 0.1f); + } +} + +void IdleState::Update(Map& map, NGridType& grid, GridInfo&, uint32) const +{ + map.ResetGridExpiry(grid); + grid.SetGridState(GRID_STATE_REMOVAL); + LOG_DEBUG("maps", "Grid[{}, {}] on map {} moved to REMOVAL state", grid.getX(), grid.getY(), map.GetId()); +} + +void RemovalState::Update(Map& map, NGridType& grid, GridInfo& info, uint32 diff) const +{ + if (!info.getUnloadLock()) + { + info.UpdateTimeTracker(diff); + if (info.getTimeTracker().Passed() && !map.UnloadGrid(grid, false)) + { + LOG_DEBUG("maps", "Grid[{}, {}] for map {} differed unloading due to players or active objects nearby", grid.getX(), grid.getY(), map.GetId()); + map.ResetGridExpiry(grid); + } + } +} diff --git a/src/server/game/Grids/GridStates.h b/src/server/game/Grids/GridStates.h new file mode 100644 index 00000000000000..5b0aec3d9e2f82 --- /dev/null +++ b/src/server/game/Grids/GridStates.h @@ -0,0 +1,56 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef ACORE_GRIDSTATES_H +#define ACORE_GRIDSTATES_H + +#include "GridDefines.h" +#include "NGrid.h" + +class Map; + +class AC_GAME_API GridState +{ + public: + virtual ~GridState() { }; + virtual void Update(Map &, NGridType&, GridInfo &, uint32 t_diff) const = 0; +}; + +class AC_GAME_API InvalidState : public GridState +{ + public: + void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; +}; + +class AC_GAME_API ActiveState : public GridState +{ + public: + void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; +}; + +class AC_GAME_API IdleState : public GridState +{ + public: + void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; +}; + +class AC_GAME_API RemovalState : public GridState +{ + public: + void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; +}; +#endif diff --git a/src/server/game/Grids/NGrid.cpp b/src/server/game/Grids/NGrid.cpp new file mode 100644 index 00000000000000..c20bf555824898 --- /dev/null +++ b/src/server/game/Grids/NGrid.cpp @@ -0,0 +1,29 @@ +/* + * 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 "NGrid.h" +#include "Random.h" + +GridInfo::GridInfo() : i_timer(0), vis_Update(0, irand(0, DEFAULT_VISIBILITY_NOTIFY_PERIOD)), +i_unloadActiveLockCount(0), i_unloadExplicitLock(false), i_unloadReferenceLock(false) +{ +} + +GridInfo::GridInfo(std::chrono::seconds expiry, bool unload /*= true */) : i_timer(expiry.count()), vis_Update(0, irand(0, DEFAULT_VISIBILITY_NOTIFY_PERIOD)), +i_unloadActiveLockCount(0), i_unloadExplicitLock(!unload), i_unloadReferenceLock(false) +{ +} diff --git a/src/server/game/Grids/NGrid.h b/src/server/game/Grids/NGrid.h index ff1f1ed813d020..a49a299194cd99 100644 --- a/src/server/game/Grids/NGrid.h +++ b/src/server/game/Grids/NGrid.h @@ -26,6 +26,42 @@ #include "Timer.h" #include "Util.h" +#define DEFAULT_VISIBILITY_NOTIFY_PERIOD 1000 + +class AC_GAME_API GridInfo +{ +public: + GridInfo(); + GridInfo(std::chrono::seconds expiry, bool unload = true); + TimeTracker const& getTimeTracker() const { return i_timer; } + bool getUnloadLock() const { return i_unloadActiveLockCount || i_unloadExplicitLock || i_unloadReferenceLock; } + void setUnloadExplicitLock(bool on) { i_unloadExplicitLock = on; } + void setUnloadReferenceLock(bool on) { i_unloadReferenceLock = on; } + void incUnloadActiveLock() { ++i_unloadActiveLockCount; } + void decUnloadActiveLock() { if (i_unloadActiveLockCount) --i_unloadActiveLockCount; } + + void setTimer(TimeTracker const& pTimer) { i_timer = pTimer; } + void ResetTimeTracker(time_t interval) { i_timer.Reset(interval); } + void UpdateTimeTracker(time_t diff) { i_timer.Update(diff); } + PeriodicTimer& getRelocationTimer() { return vis_Update; } +private: + TimeTracker i_timer; + PeriodicTimer vis_Update; + + uint16 i_unloadActiveLockCount : 16; // lock from active object spawn points (prevent clone loading) + bool i_unloadExplicitLock : 1; // explicit manual lock or config setting + bool i_unloadReferenceLock : 1; // lock from instance map copy +}; + +typedef enum +{ + GRID_STATE_INVALID = 0, + GRID_STATE_ACTIVE = 1, + GRID_STATE_IDLE = 2, + GRID_STATE_REMOVAL = 3, + MAX_GRID_STATE = 4 +} grid_state_t; + template < uint32 N, @@ -37,10 +73,10 @@ class NGrid { public: typedef Grid GridType; - NGrid(uint32 id, int32 x, int32 y) - : i_gridId(id), i_x(x), i_y(y), i_GridObjectDataLoaded(false) - { - } + NGrid(uint32 id, int32 x, int32 y, std::chrono::seconds expiry, bool unload = true) : + i_gridId(id), i_GridInfo(GridInfo(expiry, unload)), i_x(x), i_y(y), + i_cellstate(GRID_STATE_INVALID), i_GridObjectDataLoaded(false) + { } GridType& GetGridType(const uint32 x, const uint32 y) { @@ -55,6 +91,9 @@ class NGrid } [[nodiscard]] uint32 GetGridId() const { return i_gridId; } + void SetGridId(uint32 id) { i_gridId = id; } + [[nodiscard]] grid_state_t GetGridState() const { return i_cellstate; } + void SetGridState(grid_state_t s) { i_cellstate = s; } [[nodiscard]] int32 getX() const { return i_x; } [[nodiscard]] int32 getY() const { return i_y; } @@ -65,6 +104,16 @@ class NGrid [[nodiscard]] bool isGridObjectDataLoaded() const { return i_GridObjectDataLoaded; } void setGridObjectDataLoaded(bool pLoaded) { i_GridObjectDataLoaded = pLoaded; } + GridInfo* getGridInfoRef() { return &i_GridInfo; } + TimeTracker const& getTimeTracker() const { return i_GridInfo.getTimeTracker(); } + bool getUnloadLock() const { return i_GridInfo.getUnloadLock(); } + void setUnloadExplicitLock(bool on) { i_GridInfo.setUnloadExplicitLock(on); } + void setUnloadReferenceLock(bool on) { i_GridInfo.setUnloadReferenceLock(on); } + void incUnloadActiveLock() { i_GridInfo.incUnloadActiveLock(); } + void decUnloadActiveLock() { i_GridInfo.decUnloadActiveLock(); } + void ResetTimeTracker(std::chrono::seconds interval) { i_GridInfo.ResetTimeTracker(interval.count()); } + void UpdateTimeTracker(std::chrono::seconds diff) { i_GridInfo.UpdateTimeTracker(diff.count()); } + /* template void AddWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj) { @@ -103,11 +152,23 @@ class NGrid GetGridType(x, y).Visit(visitor); } + template + uint32 GetWorldObjectCountInNGrid() const + { + uint32 count = 0; + for (uint32 x = 0; x < N; ++x) + for (uint32 y = 0; y < N; ++y) + count += i_cells[x][y].template GetWorldObjectCountInGrid(); + return count; + } + private: uint32 i_gridId; + GridInfo i_GridInfo; GridReference > i_Reference; int32 i_x; int32 i_y; + grid_state_t i_cellstate; GridType i_cells[N][N]; bool i_GridObjectDataLoaded; }; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index 7b25ab1bdd5f22..c9e9bd73522f3c 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -16,6 +16,7 @@ */ #include "GridNotifiers.h" +#include "GridNotifiersImpl.h" #include "Map.h" #include "ObjectAccessor.h" #include "SpellInfo.h" @@ -23,22 +24,10 @@ #include "Transport.h" #include "UpdateData.h" #include "WorldPacket.h" +#include "CellImpl.h" using namespace Acore; -void VisibleNotifier::Visit(GameObjectMapType& m) -{ - for (GameObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter) - { - GameObject* go = iter->GetSource(); - if (i_largeOnly != go->IsVisibilityOverridden()) - continue; - - vis_guids.erase(go->GetGUID()); - i_player.UpdateVisibilityOf(go, i_data, i_visibleNow); - } -} - void VisibleNotifier::SendToSelf() { // at this moment i_clientGUIDs have guids that not iterate at grid level checks @@ -46,9 +35,6 @@ void VisibleNotifier::SendToSelf() if (Transport* transport = i_player.GetTransport()) for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr) { - if (i_largeOnly != (*itr)->IsVisibilityOverridden()) - continue; - if (vis_guids.find((*itr)->GetGUID()) != vis_guids.end()) { vis_guids.erase((*itr)->GetGUID()); @@ -65,6 +51,9 @@ void VisibleNotifier::SendToSelf() case TYPEID_UNIT: i_player.UpdateVisibilityOf((*itr)->ToCreature(), i_data, i_visibleNow); break; + case TYPEID_DYNAMICOBJECT: + i_player.UpdateVisibilityOf((*itr)->ToDynObject(), i_data, i_visibleNow); + break; default: break; } @@ -73,12 +62,6 @@ void VisibleNotifier::SendToSelf() for (GuidUnorderedSet::const_iterator it = vis_guids.begin(); it != vis_guids.end(); ++it) { - if (WorldObject* obj = ObjectAccessor::GetWorldObject(i_player, *it)) - { - if (i_largeOnly != obj->IsVisibilityOverridden()) - continue; - } - // pussywizard: static transports are removed only in RemovePlayerFromMap and here if can no longer detect (eg. phase changed) if ((*it).IsTransport()) if (GameObject* staticTrans = i_player.GetMap()->GetGameObject(*it)) @@ -105,9 +88,6 @@ void VisibleNotifier::SendToSelf() for (std::vector::const_iterator it = i_visibleNow.begin(); it != i_visibleNow.end(); ++it) { - if (i_largeOnly != (*it)->IsVisibilityOverridden()) - continue; - i_player.GetInitialVisiblePackets(*it); } } @@ -178,6 +158,23 @@ void PlayerRelocationNotifier::Visit(PlayerMapType& m) } } +void PlayerRelocationNotifier::Visit(CreatureMapType& m) +{ + bool relocated_for_ai = (&i_player == i_player.m_seer); + + for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + { + Creature* c = iter->GetSource(); + + vis_guids.erase(c->GetGUID()); + + i_player.UpdateVisibilityOf(c, i_data, i_visibleNow); + + if (relocated_for_ai && !c->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + CreatureUnitRelocationWorker(c, &i_player); + } +} + void CreatureRelocationNotifier::Visit(PlayerMapType& m) { for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) @@ -194,6 +191,58 @@ void CreatureRelocationNotifier::Visit(PlayerMapType& m) } } +void CreatureRelocationNotifier::Visit(CreatureMapType& m) +{ + if (!i_creature.IsAlive()) + return; + + for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + { + Creature* c = iter->GetSource(); + CreatureUnitRelocationWorker(&i_creature, c); + + if (!c->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + CreatureUnitRelocationWorker(c, &i_creature); + } +} + +void DelayedUnitRelocation::Visit(CreatureMapType& m) +{ + for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + { + Creature* unit = iter->GetSource(); + if (!unit->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + continue; + + CreatureRelocationNotifier relocate(*unit); + + TypeContainerVisitor c2world_relocation(relocate); + TypeContainerVisitor c2grid_relocation(relocate); + + cell.Visit(p, c2world_relocation, i_map, *unit, i_radius); + cell.Visit(p, c2grid_relocation, i_map, *unit, i_radius); + } +} + +void DelayedUnitRelocation::Visit(PlayerMapType& m) +{ + for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + { + Player* player = iter->GetSource(); + WorldObject const* viewPoint = player->m_seer; + + if (!viewPoint->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + continue; + + if (player != viewPoint && !viewPoint->IsPositionValid()) + continue; + + PlayerRelocationNotifier relocate(*player); + Cell::VisitAllObjects(viewPoint, relocate, i_radius, false); + relocate.SendToSelf(); + } +} + void AIRelocationNotifier::Visit(CreatureMapType& m) { bool self = isCreature && !((Creature*)(&i_unit))->IsMoveInLineOfSightStrictlyDisabled(); @@ -341,14 +390,9 @@ void MessageDistDelivererToHostile::Visit(DynamicObjectMapType& m) template void ObjectUpdater::Visit(GridRefMgr& m) { - T* obj; - for (typename GridRefMgr::iterator iter = m.begin(); iter != m.end(); ) - { - obj = iter->GetSource(); - ++iter; - if (obj->IsInWorld() && (i_largeOnly == obj->IsVisibilityOverridden())) - obj->Update(i_timeDiff); - } + for (typename GridRefMgr::iterator iter = m.begin(); iter != m.end(); ++iter) + if (iter->GetSource()->IsInWorld()) + iter->GetSource()->Update(i_timeDiff); } bool AnyDeadUnitObjectInRangeCheck::operator()(Player* u) diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index e06b9091f31690..c634fe9e35f3f6 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -44,16 +44,14 @@ namespace Acore GuidUnorderedSet vis_guids; std::vector& i_visibleNow; bool i_gobjOnly; - bool i_largeOnly; UpdateData i_data; - VisibleNotifier(Player& player, bool gobjOnly, bool largeOnly) : - i_player(player), vis_guids(player.m_clientGUIDs), i_visibleNow(player.m_newVisible), i_gobjOnly(gobjOnly), i_largeOnly(largeOnly) + VisibleNotifier(Player& player, bool gobjOnly) : + i_player(player), vis_guids(player.m_clientGUIDs), i_visibleNow(player.m_newVisible), i_gobjOnly(gobjOnly) { i_visibleNow.clear(); } - void Visit(GameObjectMapType&); template void Visit(GridRefMgr& m); void SendToSelf(void); }; @@ -71,9 +69,10 @@ namespace Acore struct PlayerRelocationNotifier : public VisibleNotifier { - PlayerRelocationNotifier(Player& player, bool largeOnly): VisibleNotifier(player, false, largeOnly) { } + PlayerRelocationNotifier(Player& player) : VisibleNotifier(player, false) { } template void Visit(GridRefMgr& m) { VisibleNotifier::Visit(m); } + void Visit(CreatureMapType&); void Visit(PlayerMapType&); }; @@ -82,6 +81,20 @@ namespace Acore Creature& i_creature; CreatureRelocationNotifier(Creature& c) : i_creature(c) {} template void Visit(GridRefMgr&) {} + void Visit(CreatureMapType&); + void Visit(PlayerMapType&); + }; + + struct DelayedUnitRelocation + { + Map& i_map; + Cell& cell; + CellCoord& p; + const float i_radius; + DelayedUnitRelocation(Cell& c, CellCoord& pair, Map& map, float radius) : + i_map(map), cell(c), p(pair), i_radius(radius) { } + template void Visit(GridRefMgr&) { } + void Visit(CreatureMapType&); void Visit(PlayerMapType&); }; @@ -94,6 +107,25 @@ namespace Acore void Visit(CreatureMapType&); }; + struct GridUpdater + { + GridType& i_grid; + uint32 i_timeDiff; + GridUpdater(GridType& grid, uint32 diff) : i_grid(grid), i_timeDiff(diff) { } + + template void updateObjects(GridRefMgr& m) + { + for (typename GridRefMgr::iterator iter = m.begin(); iter != m.end(); ++iter) + iter->GetSource()->Update(i_timeDiff); + } + + void Visit(PlayerMapType& m) { updateObjects(m); } + void Visit(CreatureMapType& m) { updateObjects(m); } + void Visit(GameObjectMapType& m) { updateObjects(m); } + void Visit(DynamicObjectMapType& m) { updateObjects(m); } + void Visit(CorpseMapType& m) { updateObjects(m); } + }; + struct MessageDistDeliverer { WorldObject const* i_source; @@ -154,8 +186,7 @@ namespace Acore struct ObjectUpdater { uint32 i_timeDiff; - bool i_largeOnly; - explicit ObjectUpdater(const uint32 diff, bool largeOnly) : i_timeDiff(diff), i_largeOnly(largeOnly) {} + explicit ObjectUpdater(const uint32 diff) : i_timeDiff(diff) {} template void Visit(GridRefMgr& m); void Visit(PlayerMapType&) {} void Visit(CorpseMapType&) {} diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h index 3cd1b77dcf3ad3..00d967880c94e0 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h +++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h @@ -38,9 +38,6 @@ inline void Acore::VisibleNotifier::Visit(GridRefMgr& m) for (typename GridRefMgr::iterator iter = m.begin(); iter != m.end(); ++iter) { - if (i_largeOnly != iter->GetSource()->IsVisibilityOverridden()) - continue; - vis_guids.erase(iter->GetSource()->GetGUID()); i_player.UpdateVisibilityOf(iter->GetSource(), i_data, i_visibleNow); } diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp index 628189ae4b43b0..c0d9e78c08e91d 100644 --- a/src/server/game/Grids/ObjectGridLoader.cpp +++ b/src/server/game/Grids/ObjectGridLoader.cpp @@ -26,6 +26,35 @@ #include "Transport.h" #include "Vehicle.h" +void ObjectGridEvacuator::Visit(CreatureMapType& m) +{ + // creature in unloading grid can have respawn point in another grid + // if it will be unloaded then it will not respawn in original grid until unload/load original grid + // move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn. + for (CreatureMapType::iterator iter = m.begin(); iter != m.end();) + { + Creature* c = iter->GetSource(); + ++iter; + + ASSERT(!c->IsPet() && "ObjectGridRespawnMover must not be called for pets"); + c->GetMap()->CreatureRespawnRelocation(c, true); + } +} + +void ObjectGridEvacuator::Visit(GameObjectMapType& m) +{ + // gameobject in unloading grid can have respawn point in another grid + // if it will be unloaded then it will not respawn in original grid until unload/load original grid + // move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn. + for (GameObjectMapType::iterator iter = m.begin(); iter != m.end();) + { + GameObject* go = iter->GetSource(); + ++iter; + + go->GetMap()->GameObjectRespawnRelocation(go, true); + } +} + // for loading world object at grid loading (Corpses) //TODO: to implement npc on transport, also need to load npcs at grid loading class ObjectWorldLoader @@ -229,6 +258,17 @@ void ObjectGridUnloader::Visit(GridRefMgr& m) } } +void ObjectGridStoper::Visit(CreatureMapType& m) +{ + // stop any fights at grid de-activation and remove dynobjects created at cast by creatures + for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + { + iter->GetSource()->RemoveAllDynObjects(); + if (iter->GetSource()->IsInCombat()) + iter->GetSource()->CombatStop(); + } +} + template void ObjectGridCleaner::Visit(GridRefMgr& m) { diff --git a/src/server/game/Grids/ObjectGridLoader.h b/src/server/game/Grids/ObjectGridLoader.h index 863e5f15f5f8a9..d16c3c5bc4fbd5 100644 --- a/src/server/game/Grids/ObjectGridLoader.h +++ b/src/server/game/Grids/ObjectGridLoader.h @@ -53,6 +53,23 @@ class ObjectGridLoader uint32 i_corpses; }; +//Stop the creatures before unloading the NGrid +class AC_GAME_API ObjectGridStoper +{ +public: + void Visit(CreatureMapType& m); + template void Visit(GridRefMgr&) { } +}; + +//Move the foreign creatures back to respawn positions before unloading the NGrid +class AC_GAME_API ObjectGridEvacuator +{ +public: + void Visit(CreatureMapType& m); + void Visit(GameObjectMapType& m); + template void Visit(GridRefMgr&) { } +}; + //Clean up and remove from world class ObjectGridCleaner { diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 14d750bf0e7916..694f5130b363c3 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -225,9 +225,9 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) break; } } - // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) + // Overwritten by SPELL_AURA_MOD_LANGUAGE auras (Affects only Say and Yell) Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE); - if (!ModLangAuras.empty()) + if (!ModLangAuras.empty() && (type == CHAT_MSG_SAY || type == CHAT_MSG_YELL)) lang = ModLangAuras.front()->GetMiscValue(); } diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 195257b2ac95a5..e239f610530897 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -536,6 +536,9 @@ void WorldSession::HandleLootRoll(WorldPacket& recvData) case ROLL_GREED: GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, 1); break; + case ROLL_DISENCHANT: + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT, 1); + break; } } diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index efc07e5a46160d..66927f642062dd 100644 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -20,6 +20,7 @@ #include "Config.h" #include "GameTime.h" #include "GridNotifiers.h" +#include "GridStates.h" #include "Group.h" #include "InstanceScript.h" #include "Log.h" @@ -675,6 +676,9 @@ InstancePlayerBind* InstanceSaveMgr::PlayerBindToInstance(ObjectGuid guid, Insta stmt->SetData(1, save->GetInstanceId()); stmt->SetData(2, permanent); CharacterDatabase.Execute(stmt); + + if (player) + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID, 1); } if (bind.save != save) diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index f161e9c2dcfc9b..95737baa7aef77 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -302,6 +302,11 @@ void InstanceScript::UpdateMinionState(Creature* minion, EncounterState state) } } +void InstanceScript::Update(uint32 diff) +{ + scheduler.Update(diff); +} + void InstanceScript::UpdateDoorState(GameObject* door) { DoorInfoMapBounds range = doors.equal_range(door->GetEntry()); diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 0efc7b08b0e0b5..802d2785f177f2 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -19,6 +19,8 @@ #define ACORE_INSTANCE_DATA_H #include "CreatureAI.h" +#include "ObjectMgr.h" +#include "TaskScheduler.h" #include "World.h" #include "ZoneScript.h" #include "ChallengeModeCriteria.h" @@ -169,7 +171,7 @@ class InstanceScript : public ZoneScript void SaveToDB(); - virtual void Update(uint32 /*diff*/) {} + virtual void Update(uint32 /*diff*/); //Used by the map's CanEnter function. //This is to prevent players from entering during boss encounters. @@ -328,6 +330,7 @@ class InstanceScript : public ZoneScript return _challengeModeCriteria; } + TaskScheduler scheduler; protected: void SetHeaders(std::string const& dataHeaders); void SetBossNumber(uint32 number) { bosses.resize(number); } diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 2af53f51972071..6bf7cd9b6f1e10 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -1738,7 +1738,9 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode, // Rate.Drop.Item.GroupAmount is only in effect for the top loot template level if (isTopLevel) { - group->Process(loot, player, store, lootMode, sWorld->getRate(RATE_DROP_ITEM_GROUP_AMOUNT)); + uint32 groupAmount = sWorld->getRate(RATE_DROP_ITEM_GROUP_AMOUNT); + sScriptMgr->OnAfterCalculateLootGroupAmount(player, loot, lootMode, groupAmount, store); + group->Process(loot, player, store, lootMode, groupAmount); } else { diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 535f265649f503..fcd8f667286133 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -24,6 +24,8 @@ #include "GameTime.h" #include "Geometry.h" #include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "GridStates.h" #include "Group.h" #include "InstanceScript.h" #include "LFGMgr.h" @@ -56,6 +58,8 @@ u_map_magic MapLiquidMagic = { {'M', 'L', 'I', 'Q'} }; static uint16 const holetab_h[4] = { 0x1111, 0x2222, 0x4444, 0x8888 }; static uint16 const holetab_v[4] = { 0x000F, 0x00F0, 0x0F00, 0xF000 }; +GridState* si_GridStates[MAX_GRID_STATE]; + ZoneDynamicInfo::ZoneDynamicInfo() : MusicId(0), WeatherId(WEATHER_STATE_FINE), WeatherGrade(0.0f), OverrideLightId(0), LightFadeInTime(0) { } @@ -188,6 +192,7 @@ void Map::LoadMap(int gx, int gy, bool reload) // load grid map for base map m_parentMap->EnsureGridCreated(GridCoord(63 - gx, 63 - gy)); + ((MapInstanced*)(m_parentMap))->AddGridMapReference(GridCoord(gx, gy)); GridMaps[gx][gy] = m_parentMap->GridMaps[gx][gy]; return; } @@ -232,11 +237,14 @@ void Map::LoadMapAndVMap(int gx, int gy) } } -Map::Map(uint32 id, uint32 InstanceId, uint8 SpawnMode, Map* _parent) : +Map::Map(uint32 id, std::chrono::seconds expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent) : + _creatureToMoveLock(false), _gameObjectsToMoveLock(false), _dynamicObjectsToMoveLock(false), i_mapEntry(sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId), - m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), - _instanceResetPeriod(0), m_activeNonPlayersIter(m_activeNonPlayers.end()), - _transportsUpdateIter(_transports.end()), i_scriptLock(false), _defaultLight(GetDefaultMapLight(id)) + m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), _instanceResetPeriod(0), + m_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD), + m_activeNonPlayersIter(m_activeNonPlayers.end()), _transportsUpdateIter(_transports.end()), + i_gridExpiry(expiry), + i_scriptLock(false), _defaultLight(GetDefaultMapLight(id)) { m_parentMap = (_parent ? _parent : this); for (unsigned int idx = 0; idx < MAX_NUMBER_OF_GRIDS; ++idx) @@ -259,6 +267,7 @@ void Map::InitVisibilityDistance() { //init visibility for continents m_VisibleDistance = World::GetMaxVisibleDistanceOnContinents(); + m_VisibilityNotifyPeriod = World::GetVisibilityNotifyPeriodOnContinents(); switch (GetId()) { @@ -431,8 +440,6 @@ void Map::DeleteFromWorld(Player* player) void Map::EnsureGridCreated(const GridCoord& p) { - if (getNGrid(p.x_coord, p.y_coord)) // pussywizard - return; std::lock_guard guard(GridLock); EnsureGridCreated_i(p); } @@ -443,11 +450,14 @@ void Map::EnsureGridCreated_i(const GridCoord& p) { if (!getNGrid(p.x_coord, p.y_coord)) { - // pussywizard: moved setNGrid to the end of the function - NGridType* ngt = new NGridType(p.x_coord * MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord); + LOG_DEBUG("maps", "Creating grid[{}, {}] for map {} instance {}", p.x_coord, p.y_coord, GetId(), i_InstanceId); + + setNGrid(new NGridType(p.x_coord * MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry), p.x_coord, p.y_coord); // build a linkage between this map and NGridType - buildNGridLinkage(ngt); // pussywizard: getNGrid(x, y) changed to: ngt + buildNGridLinkage(getNGrid(p.x_coord, p.y_coord)); + + getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE); //z coord int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord; @@ -457,9 +467,22 @@ void Map::EnsureGridCreated_i(const GridCoord& p) { LoadMapAndVMap(gx, gy); } + } +} - // pussywizard: moved here - setNGrid(ngt, p.x_coord, p.y_coord); +//Load NGrid and make it active +void Map::EnsureGridLoadedForActiveObject(const Cell& cell, WorldObject* object) +{ + EnsureGridLoaded(cell); + NGridType* grid = getNGrid(cell.GridX(), cell.GridY()); + ASSERT(grid != nullptr); + + // refresh grid state & timer + if (grid->GetGridState() != GRID_STATE_ACTIVE) + { + LOG_DEBUG("maps", "Active object {} triggers loading of grid [{}, {}] on map {}", object->GetGUID().ToString().c_str(), cell.GridX(), cell.GridY(), GetId()); + ResetGridExpiry(*grid, 0.1f); + grid->SetGridState(GRID_STATE_ACTIVE); } } @@ -489,6 +512,29 @@ bool Map::EnsureGridLoaded(const Cell& cell) return false; } +void Map::GridMarkNoUnload(uint32 x, uint32 y) +{ + // First make sure this grid is loaded + float gX = ((float(x) - 0.5f - CENTER_GRID_ID) * SIZE_OF_GRIDS) + (CENTER_GRID_OFFSET * 2); + float gY = ((float(y) - 0.5f - CENTER_GRID_ID) * SIZE_OF_GRIDS) + (CENTER_GRID_OFFSET * 2); + Cell cell = Cell(gX, gY); + EnsureGridLoaded(cell); + + // Mark as don't unload + NGridType* grid = getNGrid(x, y); + grid->setUnloadExplicitLock(true); +} + +void Map::GridUnmarkNoUnload(uint32 x, uint32 y) +{ + // If grid is loaded, clear unload lock + if (IsGridLoaded(GridCoord(x, y))) + { + NGridType* grid = getNGrid(x, y); + grid->setUnloadExplicitLock(false); + } +} + void Map::LoadGrid(float x, float y) { EnsureGridLoaded(Cell(x, y)); @@ -501,6 +547,22 @@ void Map::LoadAllCells() LoadGrid((cellX + 0.5f - CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL, (cellY + 0.5f - CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL); } +void Map::InitStateMachine() +{ + si_GridStates[GRID_STATE_INVALID] = new InvalidState(); + si_GridStates[GRID_STATE_ACTIVE] = new ActiveState(); + si_GridStates[GRID_STATE_IDLE] = new IdleState(); + si_GridStates[GRID_STATE_REMOVAL] = new RemovalState(); +} + +void Map::DeleteStateMachine() +{ + delete si_GridStates[GRID_STATE_INVALID]; + delete si_GridStates[GRID_STATE_ACTIVE]; + delete si_GridStates[GRID_STATE_IDLE]; + delete si_GridStates[GRID_STATE_REMOVAL]; +} + bool Map::AddPlayerToMap(Player* player) { CellCoord cellCoord = Acore::ComputeCellCoord(player->GetPositionX(), player->GetPositionY()); @@ -512,7 +574,7 @@ bool Map::AddPlayerToMap(Player* player) } Cell cell(cellCoord); - EnsureGridLoaded(cell); + EnsureGridLoadedForActiveObject(cell, player); AddToGrid(player, cell); // Check if we are adding to correct map @@ -540,15 +602,15 @@ void Map::InitializeObject(T* /*obj*/) } template<> -void Map::InitializeObject(Creature* /*obj*/) +void Map::InitializeObject(Creature* obj) { - //obj->_moveState = MAP_OBJECT_CELL_MOVE_NONE; + obj->_moveState = MAP_OBJECT_CELL_MOVE_NONE; } template<> -void Map::InitializeObject(GameObject* /*obj*/) +void Map::InitializeObject(GameObject* obj) { - //obj->_moveState = MAP_OBJECT_CELL_MOVE_NONE; + obj->_moveState = MAP_OBJECT_CELL_MOVE_NONE; } template @@ -576,7 +638,7 @@ bool Map::AddToMap(T* obj, bool checkTransport) Cell cell(cellCoord); if (obj->isActiveObject()) - EnsureGridLoaded(cell); + EnsureGridLoadedForActiveObject(cell, obj); else EnsureGridCreated(GridCoord(cell.GridX(), cell.GridY())); @@ -658,45 +720,8 @@ bool Map::IsGridLoaded(const GridCoord& p) const return (getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord)); } -void Map::VisitNearbyCellsOfPlayer(Player* player, TypeContainerVisitor& gridVisitor, - TypeContainerVisitor& worldVisitor, - TypeContainerVisitor& largeGridVisitor, - TypeContainerVisitor& largeWorldVisitor) -{ - // check for valid position - if (!player->IsPositionValid()) - return; - - // check normal grid activation range of the player - VisitNearbyCellsOf(player, gridVisitor, worldVisitor, largeGridVisitor, largeWorldVisitor); - - // check maximum visibility distance for large creatures - CellArea area = Cell::CalculateCellArea(player->GetPositionX(), player->GetPositionY(), MAX_VISIBILITY_DISTANCE); - - for (uint32 x = area.low_bound.x_coord; x <= area.high_bound.x_coord; ++x) - { - for (uint32 y = area.low_bound.y_coord; y <= area.high_bound.y_coord; ++y) - { - // marked cells are those that have been visited - // don't visit the same cell twice - uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x; - if (isCellMarkedLarge(cell_id)) - continue; - - markCellLarge(cell_id); - CellCoord pair(x, y); - Cell cell(pair); - - Visit(cell, largeGridVisitor); - Visit(cell, largeWorldVisitor); - } - } -} - void Map::VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor& gridVisitor, - TypeContainerVisitor& worldVisitor, - TypeContainerVisitor& largeGridVisitor, - TypeContainerVisitor& largeWorldVisitor) + TypeContainerVisitor& worldVisitor) { // Check for valid position if (!obj->IsPositionValid()) @@ -725,13 +750,6 @@ void Map::VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitorGetSource(); - - if (!player || !player->IsInWorld()) - continue; - - // update players at tick - player->Update(s_diff); - } - - HandleDelayedVisibility(); - return; - } - /// update active cells around players and active objects resetMarkedCells(); - resetMarkedCellsLarge(); - Acore::ObjectUpdater updater(t_diff, false); + Acore::ObjectUpdater updater(t_diff); // for creature TypeContainerVisitor grid_object_update(updater); // for pets TypeContainerVisitor world_object_update(updater); - // for large creatures - Acore::ObjectUpdater largeObjectUpdater(t_diff, true); - TypeContainerVisitor grid_large_object_update(largeObjectUpdater); - TypeContainerVisitor world_large_object_update(largeObjectUpdater); - // pussywizard: container for far creatures in combat with players std::vector updateList; updateList.reserve(10); @@ -800,7 +795,7 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) if (!obj || !obj->IsInWorld()) continue; - VisitNearbyCellsOf(obj, grid_object_update, world_object_update, grid_large_object_update, world_large_object_update); + VisitNearbyCellsOf(obj, grid_object_update, world_object_update); } // the player iterator is stored in the map object @@ -815,20 +810,11 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) // update players at tick player->Update(s_diff); - VisitNearbyCellsOfPlayer(player, grid_object_update, world_object_update, grid_large_object_update, world_large_object_update); + VisitNearbyCellsOf(player, grid_object_update, world_object_update); // If player is using far sight, visit that object too if (WorldObject* viewPoint = player->GetViewpoint()) - { - if (Creature* viewCreature = viewPoint->ToCreature()) - { - VisitNearbyCellsOf(viewCreature, grid_object_update, world_object_update, grid_large_object_update, world_large_object_update); - } - else if (DynamicObject* viewObject = viewPoint->ToDynObject()) - { - VisitNearbyCellsOf(viewObject, grid_object_update, world_object_update, grid_large_object_update, world_large_object_update); - } - } + VisitNearbyCellsOf(viewPoint, grid_object_update, world_object_update); // handle updates for creatures in combat with player and are more than X yards away if (player->IsInCombat()) @@ -846,7 +832,7 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) ref = ref->next(); } for (std::vector::const_iterator itr = updateList.begin(); itr != updateList.end(); ++itr) - VisitNearbyCellsOf(*itr, grid_object_update, world_object_update, grid_large_object_update, world_large_object_update); + VisitNearbyCellsOf(*itr, grid_object_update, world_object_update); } } @@ -875,7 +861,8 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) MoveAllGameObjectsInMoveList(); MoveAllDynamicObjectsInMoveList(); - HandleDelayedVisibility(); + if (!m_mapRefMgr.IsEmpty() || !m_activeNonPlayers.empty()) + ProcessRelocationNotifies(t_diff); sScriptMgr->OnMapUpdate(this, t_diff); @@ -888,15 +875,6 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) METRIC_TAG("map_instanceid", std::to_string(GetInstanceId()))); } -void Map::HandleDelayedVisibility() -{ - if (i_objectsForDelayedVisibility.empty()) - return; - for (std::unordered_set::iterator itr = i_objectsForDelayedVisibility.begin(); itr != i_objectsForDelayedVisibility.end(); ++itr) - (*itr)->ExecuteDelayedUnitRelocationEvent(); - i_objectsForDelayedVisibility.clear(); -} - struct ResetNotifier { templateinline void resetNotify(GridRefMgr& m) @@ -909,6 +887,83 @@ struct ResetNotifier void Visit(PlayerMapType& m) { resetNotify(m);} }; +void Map::ProcessRelocationNotifies(uint32 diff) +{ + for (GridRefMgr::iterator i = GridRefMgr::begin(); i != GridRefMgr::end(); ++i) + { + NGridType* grid = i->GetSource(); + + if (grid->GetGridState() != GRID_STATE_ACTIVE) + continue; + + grid->getGridInfoRef()->getRelocationTimer().TUpdate(diff); + if (!grid->getGridInfoRef()->getRelocationTimer().TPassed()) + continue; + + uint32 gx = grid->getX(), gy = grid->getY(); + + CellCoord cell_min(gx * MAX_NUMBER_OF_CELLS, gy * MAX_NUMBER_OF_CELLS); + CellCoord cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord + MAX_NUMBER_OF_CELLS); + + for (uint32 x = cell_min.x_coord; x < cell_max.x_coord; ++x) + { + for (uint32 y = cell_min.y_coord; y < cell_max.y_coord; ++y) + { + uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x; + if (!isCellMarked(cell_id)) + continue; + + CellCoord pair(x, y); + Cell cell(pair); + cell.SetNoCreate(); + + Acore::DelayedUnitRelocation cell_relocation(cell, pair, *this, MAX_VISIBILITY_DISTANCE); + TypeContainerVisitor grid_object_relocation(cell_relocation); + TypeContainerVisitor world_object_relocation(cell_relocation); + Visit(cell, grid_object_relocation); + Visit(cell, world_object_relocation); + } + } + } + + ResetNotifier reset; + TypeContainerVisitor grid_notifier(reset); + TypeContainerVisitor world_notifier(reset); + for (GridRefMgr::iterator i = GridRefMgr::begin(); i != GridRefMgr::end(); ++i) + { + NGridType* grid = i->GetSource(); + + if (grid->GetGridState() != GRID_STATE_ACTIVE) + continue; + + if (!grid->getGridInfoRef()->getRelocationTimer().TPassed()) + continue; + + grid->getGridInfoRef()->getRelocationTimer().TReset(diff, m_VisibilityNotifyPeriod); + + uint32 gx = grid->getX(), gy = grid->getY(); + + CellCoord cell_min(gx * MAX_NUMBER_OF_CELLS, gy * MAX_NUMBER_OF_CELLS); + CellCoord cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord + MAX_NUMBER_OF_CELLS); + + for (uint32 x = cell_min.x_coord; x < cell_max.x_coord; ++x) + { + for (uint32 y = cell_min.y_coord; y < cell_max.y_coord; ++y) + { + uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x; + if (!isCellMarked(cell_id)) + continue; + + CellCoord pair(x, y); + Cell cell(pair); + cell.SetNoCreate(); + Visit(cell, grid_notifier); + Visit(cell, world_notifier); + } + } + } +} + void Map::RemovePlayerFromMap(Player* player, bool remove) { player->getHostileRefMgr().deleteReferences(true); // pussywizard: multithreading crashfix @@ -1000,15 +1055,19 @@ void Map::RemoveFromMap(MotionTransport* obj, bool remove) void Map::PlayerRelocation(Player* player, float x, float y, float z, float o) { + ASSERT(player); + Cell old_cell(player->GetPositionX(), player->GetPositionY()); Cell new_cell(x, y); if (old_cell.DiffGrid(new_cell) || old_cell.DiffCell(new_cell)) { + LOG_DEBUG("maps", "Player {} relocation grid[{}, {}]cell[{}, {}]->grid[{}, {}]cell[{}, {}]", player->GetName().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + player->RemoveFromGrid(); if (old_cell.DiffGrid(new_cell)) - EnsureGridLoaded(new_cell); + EnsureGridLoadedForActiveObject(new_cell, player); AddToGrid(player, new_cell); } @@ -1030,10 +1089,15 @@ void Map::CreatureRelocation(Creature* creature, float x, float y, float z, floa if (old_cell.DiffGrid(new_cell)) EnsureGridLoaded(new_cell); - AddCreatureToMoveList(creature); + #ifdef ACORE_DEBUG + LOG_DEBUG("maps", "Creature {} added to moving list from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", creature->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + #endif + AddCreatureToMoveList(creature, x, y, z, o); } else + { RemoveCreatureFromMoveList(creature); + } creature->Relocate(x, y, z, o); if (creature->IsVehicle()) @@ -1052,10 +1116,15 @@ void Map::GameObjectRelocation(GameObject* go, float x, float y, float z, float if (old_cell.DiffGrid(new_cell)) EnsureGridLoaded(new_cell); - AddGameObjectToMoveList(go); + #ifdef ACORE_DEBUG + LOG_DEBUG("maps", "GameObject {} added to moving list from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + #endif + AddGameObjectToMoveList(go, x, y, z, o); } else + { RemoveGameObjectFromMoveList(go); + } go->Relocate(x, y, z, o); go->UpdateModelPosition(); @@ -1073,61 +1142,85 @@ void Map::DynamicObjectRelocation(DynamicObject* dynObj, float x, float y, float if (old_cell.DiffGrid(new_cell)) EnsureGridLoaded(new_cell); - AddDynamicObjectToMoveList(dynObj); + #ifdef ACORE_DEBUG + LOG_DEBUG("maps", "GameObject {} added to moving list from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", dynObj->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + #endif + AddDynamicObjectToMoveList(dynObj, x, y, z, o); } else + { RemoveDynamicObjectFromMoveList(dynObj); + } dynObj->Relocate(x, y, z, o); dynObj->SetPositionDataUpdate(); dynObj->UpdateObjectVisibility(false); } -void Map::AddCreatureToMoveList(Creature* c) +void Map::AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang) { + if (_creatureToMoveLock) //can this happen? + return; + if (c->_moveState == MAP_OBJECT_CELL_MOVE_NONE) _creaturesToMove.push_back(c); - c->_moveState = MAP_OBJECT_CELL_MOVE_ACTIVE; + c->SetNewCellPosition(x, y, z, ang); } void Map::RemoveCreatureFromMoveList(Creature* c) { + if (_creatureToMoveLock) //can this happen? + return; + if (c->_moveState == MAP_OBJECT_CELL_MOVE_ACTIVE) c->_moveState = MAP_OBJECT_CELL_MOVE_INACTIVE; } -void Map::AddGameObjectToMoveList(GameObject* go) +void Map::AddGameObjectToMoveList(GameObject* go, float x, float y, float z, float ang) { + if (_gameObjectsToMoveLock) //can this happen? + return; + if (go->_moveState == MAP_OBJECT_CELL_MOVE_NONE) _gameObjectsToMove.push_back(go); - go->_moveState = MAP_OBJECT_CELL_MOVE_ACTIVE; + go->SetNewCellPosition(x, y, z, ang); } void Map::RemoveGameObjectFromMoveList(GameObject* go) { + if (_gameObjectsToMoveLock) //can this happen? + return; + if (go->_moveState == MAP_OBJECT_CELL_MOVE_ACTIVE) go->_moveState = MAP_OBJECT_CELL_MOVE_INACTIVE; } -void Map::AddDynamicObjectToMoveList(DynamicObject* dynObj) +void Map::AddDynamicObjectToMoveList(DynamicObject* dynObj, float x, float y, float z, float ang) { + if (_dynamicObjectsToMoveLock) //can this happen? + return; + if (dynObj->_moveState == MAP_OBJECT_CELL_MOVE_NONE) _dynamicObjectsToMove.push_back(dynObj); - dynObj->_moveState = MAP_OBJECT_CELL_MOVE_ACTIVE; + dynObj->SetNewCellPosition(x, y, z, ang); } void Map::RemoveDynamicObjectFromMoveList(DynamicObject* dynObj) { + if (_dynamicObjectsToMoveLock) //can this happen? + return; + if (dynObj->_moveState == MAP_OBJECT_CELL_MOVE_ACTIVE) dynObj->_moveState = MAP_OBJECT_CELL_MOVE_INACTIVE; } void Map::MoveAllCreaturesInMoveList() { + _creatureToMoveLock = true; for (std::vector::iterator itr = _creaturesToMove.begin(); itr != _creaturesToMove.end(); ++itr) { Creature* c = *itr; - if (c->FindMap() != this) + if (c->FindMap() != this) //pet is teleported to another map continue; if (c->_moveState != MAP_OBJECT_CELL_MOVE_ACTIVE) @@ -1140,23 +1233,51 @@ void Map::MoveAllCreaturesInMoveList() if (!c->IsInWorld()) continue; - Cell const& old_cell = c->GetCurrentCell(); - Cell new_cell(c->GetPositionX(), c->GetPositionY()); - - c->RemoveFromGrid(); - if (old_cell.DiffGrid(new_cell)) - EnsureGridLoaded(new_cell); - AddToGrid(c, new_cell); + // do move or do move to respawn or remove creature if previous all fail + if (CreatureCellRelocation(c, Cell(c->_newPosition.m_positionX, c->_newPosition.m_positionY))) + { + // update pos + c->Relocate(c->_newPosition); + if (c->IsVehicle()) + c->GetVehicleKit()->RelocatePassengers(); + //CreatureRelocationNotify(c, new_cell, new_cell.cellCoord()); + c->UpdatePositionData(); + c->UpdateObjectVisibility(false); + } + else + { + // if creature can't be move in new cell/grid (not loaded) move it to repawn cell/grid + // creature coordinates will be updated and notifiers send + if (!CreatureRespawnRelocation(c, false)) + { + // ... or unload (if respawn grid also not loaded) +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "Creature {} cannot be move to unloaded respawn grid.", c->GetGUID().ToString().c_str()); +#endif + //AddObjectToRemoveList(Pet*) should only be called in Pet::Remove + //This may happen when a player just logs in and a pet moves to a nearby unloaded cell + //To avoid this, we can load nearby cells when player log in + //But this check is always needed to ensure safety + /// @todo pets will disappear if this is outside CreatureRespawnRelocation + //need to check why pet is frequently relocated to an unloaded cell + if (c->IsPet()) + ((Pet*)c)->Remove(PET_SAVE_NOT_IN_SLOT, true); + else + AddObjectToRemoveList(c); + } + } } _creaturesToMove.clear(); + _creatureToMoveLock = false; } void Map::MoveAllGameObjectsInMoveList() { + _gameObjectsToMoveLock = true; for (std::vector::iterator itr = _gameObjectsToMove.begin(); itr != _gameObjectsToMove.end(); ++itr) { GameObject* go = *itr; - if (go->FindMap() != this) + if (go->FindMap() != this) //transport is teleported to another map continue; if (go->_moveState != MAP_OBJECT_CELL_MOVE_ACTIVE) @@ -1169,23 +1290,40 @@ void Map::MoveAllGameObjectsInMoveList() if (!go->IsInWorld()) continue; - Cell const& old_cell = go->GetCurrentCell(); - Cell new_cell(go->GetPositionX(), go->GetPositionY()); - - go->RemoveFromGrid(); - if (old_cell.DiffGrid(new_cell)) - EnsureGridLoaded(new_cell); - AddToGrid(go, new_cell); + // do move or do move to respawn or remove creature if previous all fail + if (GameObjectCellRelocation(go, Cell(go->_newPosition.m_positionX, go->_newPosition.m_positionY))) + { + // update pos + go->Relocate(go->_newPosition); + go->UpdateModelPosition(); + go->UpdatePositionData(); + go->UpdateObjectVisibility(false); + } + else + { + // if GameObject can't be move in new cell/grid (not loaded) move it to repawn cell/grid + // GameObject coordinates will be updated and notifiers send + if (!GameObjectRespawnRelocation(go, false)) + { + // ... or unload (if respawn grid also not loaded) +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "GameObject {} cannot be move to unloaded respawn grid.", go->GetGUID().ToString().c_str()); +#endif + AddObjectToRemoveList(go); + } + } } _gameObjectsToMove.clear(); + _gameObjectsToMoveLock = false; } void Map::MoveAllDynamicObjectsInMoveList() { + _dynamicObjectsToMoveLock = true; for (std::vector::iterator itr = _dynamicObjectsToMove.begin(); itr != _dynamicObjectsToMove.end(); ++itr) { DynamicObject* dynObj = *itr; - if (dynObj->FindMap() != this) + if (dynObj->FindMap() != this) //transport is teleported to another map continue; if (dynObj->_moveState != MAP_OBJECT_CELL_MOVE_ACTIVE) @@ -1198,60 +1336,344 @@ void Map::MoveAllDynamicObjectsInMoveList() if (!dynObj->IsInWorld()) continue; - Cell const& old_cell = dynObj->GetCurrentCell(); - Cell new_cell(dynObj->GetPositionX(), dynObj->GetPositionY()); - - dynObj->RemoveFromGrid(); - if (old_cell.DiffGrid(new_cell)) - EnsureGridLoaded(new_cell); - AddToGrid(dynObj, new_cell); + // do move or do move to respawn or remove creature if previous all fail + if (DynamicObjectCellRelocation(dynObj, Cell(dynObj->_newPosition.m_positionX, dynObj->_newPosition.m_positionY))) + { + // update pos + dynObj->Relocate(dynObj->_newPosition); + dynObj->UpdatePositionData(); + dynObj->UpdateObjectVisibility(false); + } + else + { +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "DynamicObject {} cannot be moved to unloaded grid.", dynObj->GetGUID().ToString().c_str()); +#endif + } } + _dynamicObjectsToMove.clear(); + _dynamicObjectsToMoveLock = false; } -bool Map::UnloadGrid(NGridType& ngrid) +bool Map::CreatureCellRelocation(Creature* c, Cell new_cell) { - // pussywizard: UnloadGrid only done when whole map is unloaded, no need to worry about moving npcs between grids, etc. + Cell const& old_cell = c->GetCurrentCell(); + if (!old_cell.DiffGrid(new_cell)) // in same grid + { + // if in same cell then none do + if (old_cell.DiffCell(new_cell)) + { +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "Creature {} moved in grid[{}, {}] from cell[{}, {}] to cell[{}, {}].", c->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY()); +#endif - const uint32 x = ngrid.getX(); - const uint32 y = ngrid.getY(); + c->RemoveFromGrid(); + AddToGrid(c, new_cell); + } + else + { +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "Creature {} moved in same grid[{}, {}]cell[{}, {}].", c->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); +#endif + } + return true; + } + + // in diff. grids but active creature + if (c->isActiveObject()) { - ObjectGridCleaner worker; - TypeContainerVisitor visitor(worker); - ngrid.VisitAllGrids(visitor); + EnsureGridLoadedForActiveObject(new_cell, c); + +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "Active creature {} moved from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", c->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); +#endif + + c->RemoveFromGrid(); + AddToGrid(c, new_cell); + + return true; } - RemoveAllObjectsInRemoveList(); + if (c->GetCharmerOrOwnerGUID().IsPlayer()) + EnsureGridLoaded(new_cell); + // in diff. loaded grid normal creature + if (IsGridLoaded(GridCoord(new_cell.GridX(), new_cell.GridY()))) { - ObjectGridUnloader worker; - TypeContainerVisitor visitor(worker); - ngrid.VisitAllGrids(visitor); +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "Creature {} moved from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", c->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); +#endif + + c->RemoveFromGrid(); + EnsureGridCreated(GridCoord(new_cell.GridX(), new_cell.GridY())); + AddToGrid(c, new_cell); + + return true; } - ASSERT(i_objectsToRemove.empty()); + // fail to move: normal creature attempt move to unloaded grid +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "Creature {} attempted to move from grid[{}, {}]cell[{}, {}] to unloaded grid[{}, {}]cell[{}, {}].", c->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); +#endif + return false; +} - delete &ngrid; - setNGrid(nullptr, x, y); +bool Map::GameObjectCellRelocation(GameObject* go, Cell new_cell) +{ + Cell const& old_cell = go->GetCurrentCell(); + if (!old_cell.DiffGrid(new_cell)) // in same grid + { + // if in same cell then none do + if (old_cell.DiffCell(new_cell)) + { +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "GameObject {} moved in grid[{}, {}] from cell[{}, {}] to cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY()); +#endif - int gx = (MAX_NUMBER_OF_GRIDS - 1) - x; - int gy = (MAX_NUMBER_OF_GRIDS - 1) - y; + go->RemoveFromGrid(); + AddToGrid(go, new_cell); + } + else + { +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "GameObject {} moved in same grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); +#endif + } - if (i_InstanceId == 0) + return true; + } + + // in diff. grids but active GameObject + if (go->isActiveObject()) { - if (GridMaps[gx][gy]) + EnsureGridLoadedForActiveObject(new_cell, go); + +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "Active GameObject {} moved from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); +#endif + + go->RemoveFromGrid(); + AddToGrid(go, new_cell); + + return true; + } + + // in diff. loaded grid normal GameObject + if (IsGridLoaded(GridCoord(new_cell.GridX(), new_cell.GridY()))) + { +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "GameObject {} moved from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); +#endif + + go->RemoveFromGrid(); + EnsureGridCreated(GridCoord(new_cell.GridX(), new_cell.GridY())); + AddToGrid(go, new_cell); + + return true; + } + + // fail to move: normal GameObject attempt move to unloaded grid +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "GameObject {} attempted to move from grid[{}, {}]cell[{}, {}] to unloaded grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); +#endif + return false; +} + +bool Map::DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell) +{ + Cell const& old_cell = go->GetCurrentCell(); + if (!old_cell.DiffGrid(new_cell)) // in same grid + { + // if in same cell then none do + if (old_cell.DiffCell(new_cell)) + { +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "DynamicObject {} moved in grid[{}, {}] from cell[{}, {}] to cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY()); +#endif + + go->RemoveFromGrid(); + AddToGrid(go, new_cell); + } + else { - GridMaps[gx][gy]->unloadData(); - delete GridMaps[gx][gy]; +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "DynamicObject {} moved in same grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); +#endif } - // x and y are swapped - VMAP::VMapFactory::createOrGetVMapMgr()->unloadMap(GetId(), gx, gy); - MMAP::MMapFactory::createOrGetMMapMgr()->unloadMap(GetId(), gx, gy); + + return true; } - GridMaps[gx][gy] = nullptr; + // in diff. grids but active GameObject + if (go->isActiveObject()) + { + EnsureGridLoadedForActiveObject(new_cell, go); + +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "Active DynamicObject {} moved from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); +#endif + + go->RemoveFromGrid(); + AddToGrid(go, new_cell); + + return true; + } + + // in diff. loaded grid normal GameObject + if (IsGridLoaded(GridCoord(new_cell.GridX(), new_cell.GridY()))) + { +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "DynamicObject {} moved from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); +#endif + + go->RemoveFromGrid(); + EnsureGridCreated(GridCoord(new_cell.GridX(), new_cell.GridY())); + AddToGrid(go, new_cell); + + return true; + } + + // fail to move: normal GameObject attempt move to unloaded grid +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "DynamicObject {} attempted to move from grid[{}, {}]cell[{}, {}] to unloaded grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString().c_str(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); +#endif + return false; +} + +bool Map::CreatureRespawnRelocation(Creature* c, bool diffGridOnly) +{ + float resp_x, resp_y, resp_z, resp_o; + c->GetRespawnPosition(resp_x, resp_y, resp_z, &resp_o); + Cell resp_cell(resp_x, resp_y); + + //creature will be unloaded with grid + if (diffGridOnly && !c->GetCurrentCell().DiffGrid(resp_cell)) + return true; + + c->CombatStop(); + c->GetMotionMaster()->Clear(); + +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "Creature {} moved from grid[{}, {}]cell[{}, {}] to respawn grid[{}, {}]cell[{}, {}].", c->GetGUID().ToString().c_str(), c->GetCurrentCell().GridX(), c->GetCurrentCell().GridY(), c->GetCurrentCell().CellX(), c->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY()); +#endif + + // teleport it to respawn point (like normal respawn if player see) + if (CreatureCellRelocation(c, resp_cell)) + { + c->Relocate(resp_x, resp_y, resp_z, resp_o); + c->GetMotionMaster()->Initialize(); // prevent possible problems with default move generators + //CreatureRelocationNotify(c, resp_cell, resp_cell.GetCellCoord()); + c->UpdatePositionData(); + c->UpdateObjectVisibility(false); + return true; + } + return false; +} + +bool Map::GameObjectRespawnRelocation(GameObject* go, bool diffGridOnly) +{ + float resp_x, resp_y, resp_z, resp_o; + go->GetRespawnPosition(resp_x, resp_y, resp_z, &resp_o); + Cell resp_cell(resp_x, resp_y); + + //GameObject will be unloaded with grid + if (diffGridOnly && !go->GetCurrentCell().DiffGrid(resp_cell)) + return true; + +#ifdef ACORE_DEBUG + LOG_DEBUG("maps", "GameObject {} moved from grid[{}, {}]cell[{}, {}] to respawn grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString().c_str(), go->GetCurrentCell().GridX(), go->GetCurrentCell().GridY(), go->GetCurrentCell().CellX(), go->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY()); +#endif + + // teleport it to respawn point (like normal respawn if player see) + if (GameObjectCellRelocation(go, resp_cell)) + { + go->Relocate(resp_x, resp_y, resp_z, resp_o); + go->UpdatePositionData(); + go->UpdateObjectVisibility(false); + return true; + } + + return false; +} + +bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll) +{ + const uint32 x = ngrid.getX(); + const uint32 y = ngrid.getY(); + + { + if (!unloadAll) + { + //pets, possessed creatures (must be active), transport passengers + if (ngrid.GetWorldObjectCountInNGrid()) + return false; + + if (ActiveObjectsNearGrid(ngrid)) + return false; + } + + LOG_DEBUG("maps", "Unloading grid[{}, {}] for map {}", x, y, GetId()); + + if (!unloadAll) + { + // Finish creature moves, remove and delete all creatures with delayed remove before moving to respawn grids + // Must know real mob position before move + MoveAllCreaturesInMoveList(); + MoveAllGameObjectsInMoveList(); + + // move creatures to respawn grids if this is diff.grid or to remove list + ObjectGridEvacuator worker; + TypeContainerVisitor visitor(worker); + ngrid.VisitAllGrids(visitor); + + // Finish creature moves, remove and delete all creatures with delayed remove before unload + MoveAllCreaturesInMoveList(); + MoveAllGameObjectsInMoveList(); + } + + { + ObjectGridCleaner worker; + TypeContainerVisitor visitor(worker); + ngrid.VisitAllGrids(visitor); + } + + RemoveAllObjectsInRemoveList(); + + { + ObjectGridUnloader worker; + TypeContainerVisitor visitor(worker); + ngrid.VisitAllGrids(visitor); + } + + ASSERT(i_objectsToRemove.empty()); + + delete& ngrid; + setNGrid(nullptr, x, y); + } + int gx = (MAX_NUMBER_OF_GRIDS - 1) - x; + int gy = (MAX_NUMBER_OF_GRIDS - 1) - y; + + // delete grid map, but don't delete if it is from parent map (and thus only reference) + //+++if (GridMaps[gx][gy]) don't check for GridMaps[gx][gy], we might have to unload vmaps + { + if (i_InstanceId == 0) + { + if (GridMaps[gx][gy]) + { + GridMaps[gx][gy]->unloadData(); + delete GridMaps[gx][gy]; + } + VMAP::VMapFactory::createOrGetVMapMgr()->unloadMap(GetId(), gx, gy); + MMAP::MMapFactory::createOrGetMMapMgr()->unloadMap(GetId(), gx, gy); + } + else + ((MapInstanced*)m_parentMap)->RemoveGridMapReference(GridCoord(gx, gy)); + + GridMaps[gx][gy] = nullptr; + } LOG_DEBUG("maps", "Unloading grid[{}, {}] for map {} finished", x, y, GetId()); return true; } @@ -1283,7 +1705,7 @@ void Map::UnloadAll() { NGridType& grid(*i->GetSource()); ++i; - UnloadGrid(grid); // deletes the grid and removes it from the GridRefMgr + UnloadGrid(grid, true); // deletes the grid and removes it from the GridRefMgr } // pussywizard: crashfix, some npc can be left on transport (not a default passenger) @@ -2639,6 +3061,20 @@ void Map::DelayedUpdate(const uint32 t_diff) } RemoveAllObjectsInRemoveList(); + + // Don't unload grids if it's battleground, since we may have manually added GOs, creatures, those doesn't load from DB at grid re-load ! + // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended + if (!IsBattlegroundOrArena()) + { + for (GridRefMgr::iterator i = GridRefMgr::begin(); i != GridRefMgr::end();) + { + NGridType* grid = i->GetSource(); + GridInfo* info = i->GetSource()->getGridInfoRef(); + ++i; // The update might delete the map and we need the next map before the iterator gets invalid + ASSERT(grid->GetGridState() >= 0 && grid->GetGridState() < MAX_GRID_STATE); + si_GridStates[grid->GetGridState()]->Update(*this, *grid, *info, t_diff); + } + } } void Map::AddObjectToRemoveList(WorldObject* obj) @@ -2698,7 +3134,6 @@ void Map::RemoveAllObjectsInRemoveList() { std::unordered_set::iterator itr = i_objectsToRemove.begin(); WorldObject* obj = *itr; - i_objectsToRemove.erase(itr); switch (obj->GetTypeId()) { @@ -2730,6 +3165,8 @@ void Map::RemoveAllObjectsInRemoveList() LOG_ERROR("maps", "Non-grid object (TypeId: {}) is in grid object remove list, ignored.", obj->GetTypeId()); break; } + + i_objectsToRemove.erase(itr); } //LOG_DEBUG("maps", "Object remover 2 check."); @@ -2750,6 +3187,43 @@ void Map::SendToPlayers(WorldPacket const* data) const itr->GetSource()->GetSession()->SendPacket(data); } +bool Map::ActiveObjectsNearGrid(NGridType const& ngrid) const +{ + CellCoord cell_min(ngrid.getX() * MAX_NUMBER_OF_CELLS, ngrid.getY() * MAX_NUMBER_OF_CELLS); + CellCoord cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord + MAX_NUMBER_OF_CELLS); + + //we must find visible range in cells so we unload only non-visible cells... + float viewDist = GetVisibilityRange(); + int cell_range = (int)ceilf(viewDist / SIZE_OF_GRID_CELL) + 1; + + cell_min.dec_x(cell_range); + cell_min.dec_y(cell_range); + cell_max.inc_x(cell_range); + cell_max.inc_y(cell_range); + + for (MapRefMgr::const_iterator iter = m_mapRefMgr.begin(); iter != m_mapRefMgr.end(); ++iter) + { + Player* player = iter->GetSource(); + + CellCoord p = Acore::ComputeCellCoord(player->GetPositionX(), player->GetPositionY()); + if ((cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) && + (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord)) + return true; + } + + for (ActiveNonPlayers::const_iterator iter = m_activeNonPlayers.begin(); iter != m_activeNonPlayers.end(); ++iter) + { + WorldObject* obj = *iter; + + CellCoord p = Acore::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY()); + if ((cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) && + (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord)) + return true; + } + + return false; +} + template void Map::AddToActive(T* obj) { @@ -2760,6 +3234,22 @@ template <> void Map::AddToActive(Creature* c) { AddToActiveHelper(c); + + // also not allow unloading spawn grid to prevent creating creature clone at load + if (!c->IsPet() && c->GetSpawnId()) + { + float x, y, z; + c->GetRespawnPosition(x, y, z); + GridCoord p = Acore::ComputeGridCoord(x, y); + if (getNGrid(p.x_coord, p.y_coord)) + getNGrid(p.x_coord, p.y_coord)->incUnloadActiveLock(); + else + { + GridCoord p2 = Acore::ComputeGridCoord(c->GetPositionX(), c->GetPositionY()); + LOG_ERROR("maps", "Active creature {} added to grid[{}, {}] but spawn grid[{}, {}] was not loaded.", + c->GetGUID().ToString().c_str(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord); + } + } } template<> @@ -2784,6 +3274,22 @@ template <> void Map::RemoveFromActive(Creature* c) { RemoveFromActiveHelper(c); + + // also allow unloading spawn grid + if (!c->IsPet() && c->GetSpawnId()) + { + float x, y, z; + c->GetRespawnPosition(x, y, z); + GridCoord p = Acore::ComputeGridCoord(x, y); + if (getNGrid(p.x_coord, p.y_coord)) + getNGrid(p.x_coord, p.y_coord)->decUnloadActiveLock(); + else + { + GridCoord p2 = Acore::ComputeGridCoord(c->GetPositionX(), c->GetPositionY()); + LOG_ERROR("maps", "Active creature {} removed from grid[{}, {}] but spawn grid[{}, {}] was not loaded.", + c->GetGUID().ToString().c_str(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord); + } + } } template<> @@ -2810,8 +3316,8 @@ template void Map::RemoveFromMap(DynamicObject*, bool); /* ******* Dungeon Instance Maps ******* */ -InstanceMap::InstanceMap(uint32 id, uint32 InstanceId, uint8 SpawnMode, Map* _parent) - : Map(id, InstanceId, SpawnMode, _parent), +InstanceMap::InstanceMap(uint32 id, std::chrono::seconds expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent) + : Map(id, expiry, InstanceId, SpawnMode, _parent), m_resetAfterUnload(false), m_unloadWhenEmpty(false), instance_data(nullptr), i_script_id(0) { @@ -2840,6 +3346,7 @@ void InstanceMap::InitVisibilityDistance() { //init visibility distance for instances m_VisibleDistance = World::GetMaxVisibleDistanceInInstances(); + m_VisibilityNotifyPeriod = World::GetVisibilityNotifyPeriodInInstances(); // pussywizard: this CAN NOT exceed MAX_VISIBILITY_DISTANCE switch (GetId()) @@ -3224,8 +3731,8 @@ uint32 InstanceMap::GetMaxResetDelay() const /* ******* Battleground Instance Maps ******* */ -BattlegroundMap::BattlegroundMap(uint32 id, uint32 InstanceId, Map* _parent, uint8 spawnMode) - : Map(id, InstanceId, spawnMode, _parent), m_bg(nullptr) +BattlegroundMap::BattlegroundMap(uint32 id, std::chrono::seconds expiry, uint32 InstanceId, Map* _parent, uint8 spawnMode) + : Map(id, expiry, InstanceId, spawnMode, _parent), m_bg(nullptr) { //lets initialize visibility distance for BG/Arenas BattlegroundMap::InitVisibilityDistance(); @@ -3245,6 +3752,7 @@ void BattlegroundMap::InitVisibilityDistance() { //init visibility distance for BG/Arenas m_VisibleDistance = World::GetMaxVisibleDistanceInBGArenas(); + m_VisibilityNotifyPeriod = World::GetVisibilityNotifyPeriodInBGArenas(); if (IsBattleArena()) // pussywizard: start with 30yd visibility range on arenas to ensure players can't get informations about the opponents in any way m_VisibleDistance = 30.0f; diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 0bf6b9c184d71f..9b607a1afbc90f 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -71,7 +71,6 @@ namespace VMAP namespace Acore { struct ObjectUpdater; - struct LargeObjectUpdater; } struct ScriptAction @@ -312,7 +311,7 @@ class Map : public GridRefMgr { friend class MapReference; public: - Map(uint32 id, uint32 InstanceId, uint8 SpawnMode, Map* _parent = nullptr); + Map(uint32 id, std::chrono::seconds, uint32 InstanceId, uint8 SpawnMode, Map* _parent = nullptr); ~Map() override; [[nodiscard]] MapEntry const* GetEntry() const { return i_mapEntry; } @@ -337,13 +336,7 @@ class Map : public GridRefMgr template void RemoveFromMap(T*, bool); void VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor& gridVisitor, - TypeContainerVisitor& worldVisitor, - TypeContainerVisitor& largeGridVisitor, - TypeContainerVisitor& largeWorldVisitor); - void VisitNearbyCellsOfPlayer(Player* player, TypeContainerVisitor& gridVisitor, - TypeContainerVisitor& worldVisitor, - TypeContainerVisitor& largeGridVisitor, - TypeContainerVisitor& largeWorldVisitor); + TypeContainerVisitor& worldVisitor); virtual void Update(const uint32, const uint32, bool thread = true); @@ -362,7 +355,7 @@ class Map : public GridRefMgr [[nodiscard]] bool IsRemovalGrid(float x, float y) const { GridCoord p = Acore::ComputeGridCoord(x, y); - return !getNGrid(p.x_coord, p.y_coord); + return !getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL; } [[nodiscard]] bool IsGridLoaded(float x, float y) const @@ -370,13 +363,26 @@ class Map : public GridRefMgr return IsGridLoaded(Acore::ComputeGridCoord(x, y)); } + bool GetUnloadLock(GridCoord const& p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); } + void SetUnloadLock(GridCoord const& p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); } void LoadGrid(float x, float y); void LoadAllCells(); - bool UnloadGrid(NGridType& ngrid); + bool UnloadGrid(NGridType& ngrid, bool pForce); + void GridMarkNoUnload(uint32 x, uint32 y); + void GridUnmarkNoUnload(uint32 x, uint32 y); virtual void UnloadAll(); + void ResetGridExpiry(NGridType& grid, float factor = 1) const + { + grid.ResetTimeTracker(std::chrono::duration_cast(i_gridExpiry * factor)); + } + + [[nodiscard]] std::chrono::seconds GetGridExpiry(void) const { return i_gridExpiry; } [[nodiscard]] uint32 GetId() const { return i_mapEntry->MapID; } + static void InitStateMachine(); + static void DeleteStateMachine(); + static bool ExistMap(uint32 mapid, int gx, int gy); static bool ExistVMap(uint32 mapid, int gx, int gy); @@ -415,6 +421,10 @@ class Map : public GridRefMgr void RemoveAllObjectsInRemoveList(); virtual void RemoveAllPlayers(); + // used only in MoveAllCreaturesInMoveList and ObjectGridUnloader + bool CreatureRespawnRelocation(Creature* c, bool diffGridOnly); + bool GameObjectRespawnRelocation(GameObject* go, bool diffGridOnly); + [[nodiscard]] uint32 GetInstanceId() const { return i_InstanceId; } [[nodiscard]] uint8 GetSpawnMode() const { return (i_spawnMode); } @@ -468,12 +478,10 @@ class Map : public GridRefMgr void resetMarkedCells() { marked_cells.reset(); } bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); } void markCell(uint32 pCellId) { marked_cells.set(pCellId); } - void resetMarkedCellsLarge() { marked_cells_large.reset(); } - bool isCellMarkedLarge(uint32 pCellId) { return marked_cells_large.test(pCellId); } - void markCellLarge(uint32 pCellId) { marked_cells_large.set(pCellId); } [[nodiscard]] bool HavePlayers() const { return !m_mapRefMgr.IsEmpty(); } [[nodiscard]] uint32 GetPlayersCountExceptGMs() const; + [[nodiscard]] bool ActiveObjectsNearGrid(NGridType const& ngrid) const; void AddWorldObject(WorldObject* obj) { i_worldObjects.insert(obj); } void RemoveWorldObject(WorldObject* obj) { i_worldObjects.erase(obj); } @@ -660,20 +668,30 @@ class Map : public GridRefMgr // Load MMap Data void LoadMMap(int gx, int gy); + bool CreatureCellRelocation(Creature* creature, Cell new_cell); + bool GameObjectCellRelocation(GameObject* go, Cell new_cell); + bool DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell); + template void InitializeObject(T* obj); - void AddCreatureToMoveList(Creature* c); + void AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang); void RemoveCreatureFromMoveList(Creature* c); - void AddGameObjectToMoveList(GameObject* go); + void AddGameObjectToMoveList(GameObject* go, float x, float y, float z, float ang); void RemoveGameObjectFromMoveList(GameObject* go); - void AddDynamicObjectToMoveList(DynamicObject* go); + void AddDynamicObjectToMoveList(DynamicObject* go, float x, float y, float z, float ang); void RemoveDynamicObjectFromMoveList(DynamicObject* go); + bool _creatureToMoveLock; std::vector _creaturesToMove; + + bool _gameObjectsToMoveLock; std::vector _gameObjectsToMove; + + bool _dynamicObjectsToMoveLock; std::vector _dynamicObjectsToMove; [[nodiscard]] bool IsGridLoaded(const GridCoord&) const; void EnsureGridCreated_i(const GridCoord&); + void EnsureGridLoadedForActiveObject(Cell const&, WorldObject* object); void buildNGridLinkage(NGridType* pNGridType) { pNGridType->link(this); } @@ -695,6 +713,8 @@ class Map : public GridRefMgr void SendObjectUpdates(); protected: + void SetUnloadReferenceLock(GridCoord const& p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } + std::mutex Lock; std::mutex GridLock; std::shared_mutex MMapLock; @@ -710,6 +730,8 @@ class Map : public GridRefMgr MapRefMgr m_mapRefMgr; MapRefMgr::iterator m_mapRefIter; + int32 m_VisibilityNotifyPeriod; + typedef std::set ActiveNonPlayers; ActiveNonPlayers m_activeNonPlayers; ActiveNonPlayers::iterator m_activeNonPlayersIter; @@ -728,6 +750,8 @@ class Map : public GridRefMgr void _ScriptProcessDoor(Object* source, Object* target, const ScriptInfo* scriptInfo) const; GameObject* _FindGameObject(WorldObject* pWorldObject, ObjectGuid::LowType guid) const; + std::chrono::seconds i_gridExpiry; + //used for fast base_map (e.g. MapInstanced class object) search for //InstanceMaps and BattlegroundMaps... Map* m_parentMap; @@ -735,7 +759,10 @@ class Map : public GridRefMgr NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; GridMap* GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; std::bitset marked_cells; - std::bitset marked_cells_large; + + //these functions used to process player/mob aggro reactions and + //visibility calculations. Highly optimized for massive calculations + void ProcessRelocationNotifies(uint32 diff); bool i_scriptLock; std::unordered_set i_objectsToRemove; @@ -812,7 +839,7 @@ enum InstanceResetMethod class InstanceMap : public Map { public: - InstanceMap(uint32 id, uint32 InstanceId, uint8 SpawnMode, Map* _parent); + InstanceMap(uint32 id, std::chrono::seconds, uint32 InstanceId, uint8 SpawnMode, Map* _parent); ~InstanceMap() override; bool AddPlayerToMap(Player*) override; void RemovePlayerFromMap(Player*, bool) override; @@ -846,7 +873,7 @@ class InstanceMap : public Map class BattlegroundMap : public Map { public: - BattlegroundMap(uint32 id, uint32 InstanceId, Map* _parent, uint8 spawnMode); + BattlegroundMap(uint32 id, std::chrono::seconds, uint32 InstanceId, Map* _parent, uint8 spawnMode); ~BattlegroundMap() override; bool AddPlayerToMap(Player*) override; diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index 12c6acf6b5e660..2ce5bbfbc108e4 100644 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -26,10 +26,10 @@ #include "ScriptMgr.h" #include "VMapFactory.h" -MapInstanced::MapInstanced(uint32 id) : Map(id, 0, DUNGEON_DIFFICULTY_NORMAL) +MapInstanced::MapInstanced(uint32 id, std::chrono::seconds expiry) : Map(id, expiry, 0, DUNGEON_DIFFICULTY_NORMAL) { - // initialize instanced maps list - m_InstancedMaps.clear(); + // fill with zero + memset(&GridMapReference, 0, MAX_NUMBER_OF_GRIDS * MAX_NUMBER_OF_GRIDS * sizeof(uint16)); } void MapInstanced::InitVisibilityDistance() @@ -203,7 +203,7 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save, LOG_DEBUG("maps", "MapInstanced::CreateInstance: {} map instance {} for {} created with difficulty {}", save ? "" : "new ", InstanceId, GetId(), difficulty ? "heroic" : "normal"); - InstanceMap* map = new InstanceMap(GetId(), InstanceId, difficulty, this); + InstanceMap* map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty, this); ASSERT(map->IsDungeon()); map->LoadRespawnTimes(); @@ -237,7 +237,7 @@ BattlegroundMap* MapInstanced::CreateBattleground(uint32 InstanceId, Battlegroun else spawnMode = REGULAR_DIFFICULTY; - BattlegroundMap* map = new BattlegroundMap(GetId(), InstanceId, this, spawnMode); + BattlegroundMap* map = new BattlegroundMap(GetId(), GetGridExpiry(), InstanceId, this, spawnMode); ASSERT(map->IsBattlegroundOrArena()); map->SetBG(bg); bg->SetBgMap(map); diff --git a/src/server/game/Maps/MapInstanced.h b/src/server/game/Maps/MapInstanced.h index f08c5687acbd4e..fd86b8fa612973 100644 --- a/src/server/game/Maps/MapInstanced.h +++ b/src/server/game/Maps/MapInstanced.h @@ -28,7 +28,7 @@ class MapInstanced : public Map public: using InstancedMaps = std::unordered_map; - MapInstanced(uint32 id); + MapInstanced(uint32 id, std::chrono::seconds expiry); ~MapInstanced() override {} // functions overwrite Map versions @@ -46,6 +46,19 @@ class MapInstanced : public Map } bool DestroyInstance(InstancedMaps::iterator& itr); + void AddGridMapReference(GridCoord const& p) + { + ++GridMapReference[p.x_coord][p.y_coord]; + SetUnloadReferenceLock(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - p.x_coord, (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord), true); + } + + void RemoveGridMapReference(GridCoord const& p) + { + --GridMapReference[p.x_coord][p.y_coord]; + if (!GridMapReference[p.x_coord][p.y_coord]) + SetUnloadReferenceLock(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - p.x_coord, (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord), false); + } + InstancedMaps& GetInstancedMaps() { return m_InstancedMaps; } void InitVisibilityDistance() override; @@ -54,5 +67,7 @@ class MapInstanced : public Map BattlegroundMap* CreateBattleground(uint32 InstanceId, Battleground* bg); InstancedMaps m_InstancedMaps; + + uint16 GridMapReference[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; }; #endif diff --git a/src/server/game/Maps/MapMgr.cpp b/src/server/game/Maps/MapMgr.cpp index 9e89d64e219daa..980b7898fd9737 100644 --- a/src/server/game/Maps/MapMgr.cpp +++ b/src/server/game/Maps/MapMgr.cpp @@ -36,6 +36,7 @@ MapMgr::MapMgr() { + i_gridCleanUpDelay = sWorld->getIntConfig(CONFIG_INTERVAL_GRIDCLEAN); i_timer[3].SetInterval(sWorld->getIntConfig(CONFIG_INTERVAL_MAPUPDATE)); mapUpdateStep = 0; _nextInstanceId = 0; @@ -53,6 +54,8 @@ MapMgr* MapMgr::instance() void MapMgr::Initialize() { + Map::InitStateMachine(); + int num_threads(sWorld->getIntConfig(CONFIG_NUMTHREADS)); // Start mtmaps if needed @@ -81,10 +84,10 @@ Map* MapMgr::CreateBaseMap(uint32 id) ASSERT(entry); if (entry->Instanceable()) - map = new MapInstanced(id); + map = new MapInstanced(id, std::chrono::seconds(i_gridCleanUpDelay)); else { - map = new Map(id, 0, REGULAR_DIFFICULTY); + map = new Map(id, std::chrono::seconds(i_gridCleanUpDelay), 0, REGULAR_DIFFICULTY); map->LoadRespawnTimes(); map->LoadCorpseData(); } @@ -333,6 +336,8 @@ void MapMgr::UnloadAll() if (m_updater.activated()) m_updater.deactivate(); + + Map::DeleteStateMachine(); } void MapMgr::GetNumInstances(uint32& dungeons, uint32& battlegrounds, uint32& arenas) diff --git a/src/server/game/Maps/MapMgr.h b/src/server/game/Maps/MapMgr.h index 9ff22ce1aec068..3778be5a0daf10 100644 --- a/src/server/game/Maps/MapMgr.h +++ b/src/server/game/Maps/MapMgr.h @@ -24,6 +24,7 @@ #include "MapInstanced.h" #include "MapUpdater.h" #include "Object.h" +#include "GridStates.h" #include @@ -73,6 +74,14 @@ class MapMgr void Initialize(void); void Update(uint32); + void SetGridCleanUpDelay(uint32 t) + { + if (t < MIN_GRID_DELAY) + i_gridCleanUpDelay = MIN_GRID_DELAY; + else + i_gridCleanUpDelay = t; + } + void SetMapUpdateInterval(uint32 t) { if (t < MIN_MAP_UPDATE_DELAY) @@ -171,6 +180,8 @@ class MapMgr MapMgr& operator=(const MapMgr&); std::mutex Lock; + uint32 i_gridCleanUpDelay; + MapMapType i_maps; IntervalTimer i_timer[4]; // continents, bgs/arenas, instances, total from the beginning uint8 mapUpdateStep; diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 824810fdaa183e..4cbadd49d56780 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1058,7 +1058,7 @@ enum AcoreStrings LANG_COMMAND_TICKETLISTRESPONSE = 2029, LANG_COMMAND_TICKETCOMPLETED = 2030, - // Trinity strings 5000-9999 + // acore strings 5000-9999 LANG_COMMAND_FREEZE = 5000, LANG_COMMAND_FREEZE_ERROR = 5001, LANG_COMMAND_FREEZE_WRONG = 5002, diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h index d713ba9f31d36c..5ebe5f5aa566f4 100644 --- a/src/server/game/Movement/Spline/MoveSpline.h +++ b/src/server/game/Movement/Spline/MoveSpline.h @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#ifndef TRINITYSERVER_MOVEPLINE_H -#define TRINITYSERVER_MOVEPLINE_H +#ifndef AC_MOVEPLINE_H +#define AC_MOVEPLINE_H #include "MoveSplineInitArgs.h" #include "Spline.h" @@ -132,4 +132,4 @@ namespace Movement } }; } -#endif // TRINITYSERVER_MOVEPLINE_H +#endif // AC_MOVEPLINE_H diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h index 638a921a16b8ff..17e8128156a062 100644 --- a/src/server/game/Movement/Spline/MoveSplineFlag.h +++ b/src/server/game/Movement/Spline/MoveSplineFlag.h @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#ifndef TRINITYSERVER_MOVESPLINEFLAG_H -#define TRINITYSERVER_MOVESPLINEFLAG_H +#ifndef AC_MOVESPLINEFLAG_H +#define AC_MOVESPLINEFLAG_H #include "MovementTypedefs.h" #include @@ -145,4 +145,4 @@ namespace Movement #endif } -#endif // TRINITYSERVER_MOVESPLINEFLAG_H +#endif // AC_MOVESPLINEFLAG_H diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 5d969e9f06d6ac..a98da344650e54 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#ifndef TRINITYSERVER_MOVESPLINEINIT_H -#define TRINITYSERVER_MOVESPLINEINIT_H +#ifndef AC_MOVESPLINEINIT_H +#define AC_MOVESPLINEINIT_H #include "MoveSplineInitArgs.h" #include "PathGenerator.h" @@ -209,4 +209,4 @@ namespace Movement inline void MoveSplineInit::DisableTransportPathTransformations() { args.TransformForTransport = false; } } -#endif // TRINITYSERVER_MOVESPLINEINIT_H +#endif // AC_MOVESPLINEINIT_H diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h index e0789a4f14c95f..a0d26fd54f094f 100644 --- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h +++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#ifndef TRINITYSERVER_MOVESPLINEINIT_ARGS_H -#define TRINITYSERVER_MOVESPLINEINIT_ARGS_H +#ifndef AC_MOVESPLINEINIT_ARGS_H +#define AC_MOVESPLINEINIT_ARGS_H #include "MoveSplineFlag.h" #include @@ -68,4 +68,4 @@ namespace Movement }; } -#endif // TRINITYSERVER_MOVESPLINEINIT_ARGS_H +#endif // AC_MOVESPLINEINIT_ARGS_H diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.h b/src/server/game/Movement/Spline/MovementPacketBuilder.h index 6ec1af6a3304d8..711eccc33e888e 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.h +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.h @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#ifndef TRINITYSERVER_PACKET_BUILDER_H -#define TRINITYSERVER_PACKET_BUILDER_H +#ifndef AC_PACKET_BUILDER_H +#define AC_PACKET_BUILDER_H #include "Define.h" @@ -40,4 +40,4 @@ namespace Movement static void WriteCreate(const MoveSpline& mov, ByteBuffer& data); }; } -#endif // TRINITYSERVER_PACKET_BUILDER_H +#endif // AC_PACKET_BUILDER_H diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h index d0b879c05c7b2f..512bcc7dc16e56 100644 --- a/src/server/game/Movement/Spline/MovementTypedefs.h +++ b/src/server/game/Movement/Spline/MovementTypedefs.h @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#ifndef TRINITYSERVER_TYPEDEFS_H -#define TRINITYSERVER_TYPEDEFS_H +#ifndef AC_TYPEDEFS_H +#define AC_TYPEDEFS_H #include "Common.h" @@ -74,4 +74,4 @@ namespace Movement extern UInt32Counter splineIdGen; } -#endif // TRINITYSERVER_TYPEDEFS_H +#endif // AC_TYPEDEFS_H diff --git a/src/server/game/Movement/Spline/Spline.h b/src/server/game/Movement/Spline/Spline.h index 98896d931a183f..d9d255f0a2dc4a 100644 --- a/src/server/game/Movement/Spline/Spline.h +++ b/src/server/game/Movement/Spline/Spline.h @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#ifndef TRINITYSERVER_SPLINE_H -#define TRINITYSERVER_SPLINE_H +#ifndef AC_SPLINE_H +#define AC_SPLINE_H #include "Errors.h" #include "MovementTypedefs.h" @@ -210,4 +210,4 @@ namespace Movement #include "SplineImpl.h" -#endif // TRINITYSERVER_SPLINE_H +#endif // AC_SPLINE_H diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index d14ddb3c33d698..aba9f1509f1422 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -38,7 +38,7 @@ Quest::Quest(Field* questRecord) Type = questRecord[5].Get(); SuggestedPlayers = questRecord[6].Get(); TimeAllowed = questRecord[7].Get(); - AllowableRaces = questRecord[8].Get(); + AllowableRaces = questRecord[8].Get(); RequiredFactionId1 = questRecord[9].Get(); RequiredFactionId2 = questRecord[10].Get(); RequiredFactionValue1 = questRecord[11].Get(); diff --git a/src/server/game/Scripting/ScriptDefines/AllCreatureScript.cpp b/src/server/game/Scripting/ScriptDefines/AllCreatureScript.cpp index 89619124248fda..ab588dcdd82749 100644 --- a/src/server/game/Scripting/ScriptDefines/AllCreatureScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/AllCreatureScript.cpp @@ -48,6 +48,15 @@ void ScriptMgr::OnCreatureSaveToDB(Creature* creature) }); } +void ScriptMgr::OnBeforeCreatureSelectLevel(const CreatureTemplate* cinfo, Creature* creature, uint8& level) +{ + ExecuteScript([&](AllCreatureScript* script) + { + script->OnBeforeCreatureSelectLevel(cinfo, creature, level); + }); + +} + void ScriptMgr::Creature_SelectLevel(const CreatureTemplate* cinfo, Creature* creature) { ExecuteScript([&](AllCreatureScript* script) diff --git a/src/server/game/Scripting/ScriptDefines/GameObjectScript.cpp b/src/server/game/Scripting/ScriptDefines/GameObjectScript.cpp index 07b614f9c58a7b..54dc08228cfd19 100644 --- a/src/server/game/Scripting/ScriptDefines/GameObjectScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/GameObjectScript.cpp @@ -160,6 +160,21 @@ void ScriptMgr::OnGameObjectDamaged(GameObject* go, Player* player) } } +void ScriptMgr::OnGameObjectModifyHealth(GameObject* go, Unit* attackerOrHealer, int32& change, SpellInfo const* spellInfo) +{ + ASSERT(go); + + ExecuteScript([&](AllGameObjectScript* script) + { + script->OnGameObjectModifyHealth(go, attackerOrHealer, change, spellInfo); + }); + + if (auto tempScript = ScriptRegistry::GetScriptById(go->GetScriptId())) + { + tempScript->OnModifyHealth(go, attackerOrHealer, change, spellInfo); + } +} + void ScriptMgr::OnGameObjectLootStateChanged(GameObject* go, uint32 state, Unit* unit) { ASSERT(go); diff --git a/src/server/game/Scripting/ScriptDefines/GlobalScript.cpp b/src/server/game/Scripting/ScriptDefines/GlobalScript.cpp index 74b1ddbe4ca4d0..4206c0618eafce 100644 --- a/src/server/game/Scripting/ScriptDefines/GlobalScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/GlobalScript.cpp @@ -55,6 +55,14 @@ void ScriptMgr::OnAfterRefCount(Player const* player, Loot& loot, bool canRate, }); } +void ScriptMgr::OnAfterCalculateLootGroupAmount(Player const* player, Loot& loot, uint16 lootMode, uint32& groupAmount, LootStore const& store) +{ + ExecuteScript([&](GlobalScript* script) + { + script->OnAfterCalculateLootGroupAmount(player, loot, lootMode, groupAmount, store); + }); +} + void ScriptMgr::OnBeforeDropAddItem(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store) { ExecuteScript([&](GlobalScript* script) diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp index f7a24c84cbe351..b5aec25d9e5f24 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp @@ -74,6 +74,21 @@ void ScriptMgr::OnPlayerReleasedGhost(Player* player) }); } +bool ScriptMgr::OnCanPlayerFlyInZone(Player* player, uint32 mapId, uint32 zoneId, SpellInfo const* bySpell) +{ + auto ret = IsValidBoolScript([player, mapId, zoneId, bySpell](PlayerScript* script) + { + return !script->OnCanPlayerFlyInZone(player, mapId, zoneId, bySpell); + }); + + if (ret && *ret) + { + return false; + } + + return true; +} + void ScriptMgr::OnPVPKill(Player* killer, Player* killed) { ExecuteScript([&](PlayerScript* script) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 4b4eab29fe136a..7920fe55b4211d 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -555,6 +555,9 @@ class AllCreatureScript : public ScriptObject // Called from End of Creature Update. virtual void OnAllCreatureUpdate(Creature* /*creature*/, uint32 /*diff*/) { } + // Called just before the level of the creature is set. + virtual void OnBeforeCreatureSelectLevel(const CreatureTemplate* /*cinfo*/, Creature* /*creature*/, uint8& /*level*/) { } + // Called from End of Creature SelectLevel. virtual void Creature_SelectLevel(const CreatureTemplate* /*cinfo*/, Creature* /*creature*/) { } @@ -705,6 +708,9 @@ class AllGameObjectScript : public ScriptObject // Called when the game object is damaged (destructible buildings only). virtual void OnGameObjectDamaged(GameObject* /*go*/, Player* /*player*/) { } + // Called when the health of a game object is modified (destructible buildings only). + virtual void OnGameObjectModifyHealth(GameObject* /*go*/, Unit* /*attackerOrHealer*/, int32& /*change*/, SpellInfo const* /*spellInfo*/) { } + // Called when the game object loot state is changed. virtual void OnGameObjectLootStateChanged(GameObject* /*go*/, uint32 /*state*/, Unit* /*unit*/) { } @@ -787,6 +793,9 @@ class GameObjectScript : public ScriptObject, public UpdatableScript // Called when the game object is damaged (destructible buildings only). virtual void OnDamaged(GameObject* /*go*/, Player* /*player*/) { } + // Called when the health of a game object is modified (destructible buildings only). + virtual void OnModifyHealth(GameObject* /*go*/, Unit* /*attackerOrHealer*/, int32& /*change*/, SpellInfo const* /*spellInfo*/) { } + // Called when the game object loot state is changed. virtual void OnLootStateChanged(GameObject* /*go*/, uint32 /*state*/, Unit* /*unit*/) { } @@ -1488,6 +1497,16 @@ class PlayerScript : public ScriptObject */ virtual void OnQuestAbandon(Player* /*player*/, uint32 /*questId*/) { } + /** + * @brief This hook called before other CanFlyChecks are applied + * + * @param player Contains information about the Player + * @param mapId Contains information about the current map id + * @param zoneId Contains information about the current zone + * @param bySpell Contains information about the spell that invoked the check + */ + [[nodiscard]] virtual bool OnCanPlayerFlyInZone(Player* /*player*/, uint32 /*mapId*/, uint32 /*zoneId*/, SpellInfo const* /*bySpell*/) { return true; } + // Passive Anticheat System virtual void AnticheatSetSkipOnePacketForASH(Player* /*player*/, bool /*apply*/) { } virtual void AnticheatSetCanFlybyServer(Player* /*player*/, bool /*apply*/) { } @@ -1638,6 +1657,7 @@ class GlobalScript : public ScriptObject // loot virtual void OnAfterRefCount(Player const* /*player*/, LootStoreItem* /*LootStoreItem*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, uint32& /*maxcount*/, LootStore const& /*store*/) { } + virtual void OnAfterCalculateLootGroupAmount(Player const* /*player*/, Loot& /*loot*/, uint16 /*lootMode*/, uint32& /*groupAmount*/, LootStore const& /*store*/) { } virtual void OnBeforeDropAddItem(Player const* /*player*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, LootStoreItem* /*LootStoreItem*/, LootStore const& /*store*/) { } virtual bool OnItemRoll(Player const* /*player*/, LootStoreItem const* /*LootStoreItem*/, float& /*chance*/, Loot& /*loot*/, LootStore const& /*store*/) { return true; }; virtual bool OnBeforeLootEqualChanced(Player const* /*player*/, LootStoreItemList /*EqualChanced*/, Loot& /*loot*/, LootStore const& /*store*/) { return true; } @@ -2234,6 +2254,7 @@ class ScriptMgr uint32 GetDialogStatus(Player* player, GameObject* go); void OnGameObjectDestroyed(GameObject* go, Player* player); void OnGameObjectDamaged(GameObject* go, Player* player); + void OnGameObjectModifyHealth(GameObject* go, Unit* attackerOrHealer, int32& change, SpellInfo const* spellInfo); void OnGameObjectLootStateChanged(GameObject* go, uint32 state, Unit* unit); void OnGameObjectStateChanged(GameObject* go, uint32 state); void OnGameObjectUpdate(GameObject* go, uint32 diff); @@ -2459,6 +2480,7 @@ class ScriptMgr bool CanSendErrorAlreadyLooted(Player* player); void OnAfterCreatureLoot(Player* player); void OnAfterCreatureLootMoney(Player* player); + bool OnCanPlayerFlyInZone(Player* player, uint32 mapId, uint32 zoneId, SpellInfo const* bySpell); // Anti cheat void AnticheatSetSkipOnePacketForASH(Player* player, bool apply); @@ -2509,6 +2531,7 @@ class ScriptMgr void OnGlobalMirrorImageDisplayItem(Item const* item, uint32& display); void OnBeforeUpdateArenaPoints(ArenaTeam* at, std::map& ap); void OnAfterRefCount(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, uint32& maxcount, LootStore const& store); + void OnAfterCalculateLootGroupAmount(Player const* player, Loot& loot, uint16 lootMode, uint32& groupAmount, LootStore const& store); void OnBeforeDropAddItem(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store); bool OnItemRoll(Player const* player, LootStoreItem const* LootStoreItem, float& chance, Loot& loot, LootStore const& store); bool OnBeforeLootEqualChanced(Player const* player, LootStoreItemList EqualChanced, Loot& loot, LootStore const& store); @@ -2560,6 +2583,7 @@ class ScriptMgr public: /* AllCreatureScript */ //listener function (OnAllCreatureUpdate) is called by OnCreatureUpdate //void OnAllCreatureUpdate(Creature* creature, uint32 diff); + void OnBeforeCreatureSelectLevel(const CreatureTemplate* cinfo, Creature* creature, uint8& level); void Creature_SelectLevel(const CreatureTemplate* cinfo, Creature* creature); void OnCreatureSaveToDB(Creature* creature); diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index 7097596ada63a3..52c45ba63063de 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -57,6 +57,7 @@ namespace WorldPackets class AC_GAME_API PlayMusic final : public ServerPacket { public: + // cppcheck-suppress missingReturn PlayMusic() : ServerPacket(SMSG_PLAY_MUSIC, 4) { } PlayMusic(uint32 soundKitID) : ServerPacket(SMSG_PLAY_MUSIC, 4), SoundKitID(soundKitID) { } @@ -68,6 +69,7 @@ namespace WorldPackets class AC_GAME_API PlayObjectSound final : public ServerPacket { public: + // cppcheck-suppress missingReturn PlayObjectSound() : ServerPacket(SMSG_PLAY_OBJECT_SOUND, 4 + 8) { } PlayObjectSound(ObjectGuid const& sourceObjectGUID, uint32 soundKitID) : ServerPacket(SMSG_PLAY_OBJECT_SOUND, 4 + 8), SourceObjectGUID(sourceObjectGUID), SoundKitID(soundKitID) { } @@ -82,6 +84,7 @@ namespace WorldPackets class AC_GAME_API Playsound final : public ServerPacket { public: + // cppcheck-suppress missingReturn Playsound() : ServerPacket(SMSG_PLAY_SOUND, 4) { } Playsound(uint32 soundKitID) : ServerPacket(SMSG_PLAY_SOUND, 4), SoundKitID(soundKitID) { } diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index f2ce1d91b88796..f6317b5049f95a 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -564,7 +564,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr authSes //! Negative mutetime indicates amount of minutes to be muted effective on next login - which is now. if (account.MuteTime < 0) { - account.MuteTime = GameTime::GetGameTime().count() + llabs(account.MuteTime); + account.MuteTime = GameTime::GetGameTime().count() + std::llabs(account.MuteTime); auto* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME_LOGIN); stmt->SetData(0, account.MuteTime); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 37a0d2d4a6f19e..6a42846ade903b 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1625,8 +1625,8 @@ void AuraEffect::HandleModInvisibility(AuraApplication const* aurApp, uint8 mode target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); } - target->UpdateObjectVisibility(target->GetTypeId() == TYPEID_PLAYER || target->GetOwnerGUID().IsPlayer() || target->GetMap()->Instanceable(), true); - target->bRequestForcedVisibilityUpdate = false; + if (target->IsInWorld()) + target->UpdateObjectVisibility(); } void AuraEffect::HandleModStealthDetect(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -1699,8 +1699,8 @@ void AuraEffect::HandleModStealth(AuraApplication const* aurApp, uint8 mode, boo target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); } - target->UpdateObjectVisibility(target->GetTypeId() == TYPEID_PLAYER || target->GetOwnerGUID().IsPlayer() || target->GetMap()->Instanceable(), true); - target->bRequestForcedVisibilityUpdate = false; + if (target->IsInWorld()) + target->UpdateObjectVisibility(); } void AuraEffect::HandleModStealthLevel(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -1864,7 +1864,6 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app if (!target->GetMap()->Instanceable()) { target->UpdateObjectVisibility(false); - target->m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f); } else target->UpdateObjectVisibility(); @@ -6392,6 +6391,13 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const // ignore non positive values (can be result apply spellmods to aura damage uint32 damage = std::max(GetAmount(), 0); + // If the damage is percent-max-health based, calculate damage before the Modify hook + if (GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE_PERCENT) + { + // xinef: ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner + damage = uint32(std::ceil(CalculatePct(target->GetMaxHealth(), damage))); + } + // Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage, GetSpellInfo()); @@ -6422,8 +6428,6 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const // 5..8 ticks have normal tick damage } } - else // xinef: ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner - damage = uint32(std::ceil(CalculatePct(target->GetMaxHealth(), damage))); // calculate crit chance bool crit = false; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index a8314090bb2156..0f1c652cac0a83 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -6146,23 +6146,6 @@ SpellCastResult Spell::CheckCast(bool strict) // for effects of spells that have only one target switch (m_spellInfo->Effects[i].Effect) { - case SPELL_EFFECT_DUMMY: - { - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT) - { - // Raise Ally - if( m_spellInfo->Id == 61999 ) - { - Unit* target = m_targets.GetUnitTarget(); - if (!target) - return SPELL_FAILED_BAD_TARGETS; - - if (target->IsAlive()) // not discovered attributeEx5? - return SPELL_FAILED_TARGET_NOT_DEAD; - } - } - break; - } case SPELL_EFFECT_LEARN_SPELL: { if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -6712,8 +6695,8 @@ SpellCastResult Spell::CheckCast(bool strict) } case SPELL_AURA_MOUNTED: { - // Xinef: disallow casting in water for mounts not increasing water movement Speed - if (m_caster->IsInWater() && !m_spellInfo->HasAura(SPELL_AURA_MOD_INCREASE_SWIM_SPEED)) + // Disallow casting flying mounts in water + if (m_caster->IsInWater() && m_spellInfo->HasAura(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED)) return SPELL_FAILED_ONLY_ABOVEWATER; // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 3442fae8434b53..12f36a4f09c0a8 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1946,13 +1946,6 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) case 48542: // Revitalize damage = int32(CalculatePct(unitTarget->GetMaxPower(power), damage)); break; - case 67490: // Runic Mana Injector (mana gain increased by 25% for engineers - 3.2.0 patch change) - { - if (Player* player = m_caster->ToPlayer()) - if (player->HasSkill(SKILL_ENGINEERING)) - AddPct(damage, 25); - break; - } case 71132: // Glyph of Shadow Word: Pain damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc break; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index e3da2d0b265f55..76550b0d294335 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -214,8 +214,8 @@ std::array SpellImplic {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 1 TARGET_UNIT_CASTER {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 2 TARGET_UNIT_NEARBY_ENEMY - {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_PARTY, TARGET_DIR_NONE}, // 3 TARGET_UNIT_NEARBY_PARTY - {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_ALLY, TARGET_DIR_NONE}, // 4 TARGET_UNIT_NEARBY_ALLY + {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_ALLY, TARGET_DIR_NONE}, // 3 TARGET_UNIT_NEARBY_ALLY + {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_PARTY, TARGET_DIR_NONE}, // 4 TARGET_UNIT_NEARBY_PARTY {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 5 TARGET_UNIT_PET {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 6 TARGET_UNIT_TARGET_ENEMY {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ENTRY, TARGET_DIR_NONE}, // 7 TARGET_UNIT_SRC_AREA_ENTRY @@ -1504,7 +1504,7 @@ SpellCastResult SpellInfo::CheckShapeshift(uint32 form) const return SPELL_CAST_OK; } -SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player /*= nullptr*/, bool strict /*= true*/) const +SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player* player /*= nullptr*/, bool strict /*= true*/) const { // normal case if (AreaGroupId > 0) diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 7b6b277eaf29b9..e8c24db9adbb60 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -477,7 +477,7 @@ friend class SpellMgr; bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const* spellInfo) const; SpellCastResult CheckShapeshift(uint32 form) const; - SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player = nullptr, bool strict = true) const; + SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player* player = nullptr, bool strict = true) const; SpellCastResult CheckTarget(Unit const* caster, WorldObject const* target, bool implicit = true) const; SpellCastResult CheckExplicitTarget(Unit const* caster, WorldObject const* target, Item const* itemTarget = nullptr) const; bool CheckTargetCreatureType(Unit const* target) const; diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index 24019070a48f4a..ff52a96b66b6aa 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -1028,14 +1028,6 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(6); }); - // Glyph of Voidwalker - ApplySpellFix({ 56247 }, [](SpellInfo* spellInfo) - { - spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER; - spellInfo->Effects[EFFECT_0].MiscValue = SPELLMOD_EFFECT1; - spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x8000000, 0, 0); - }); - // Everlasting Affliction ApplySpellFix({ 47201, 47202, 47203, 47204, 47205 }, [](SpellInfo* spellInfo) { @@ -1530,8 +1522,8 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE; }); - // Debris - ApplySpellFix({ 36449 }, [](SpellInfo* spellInfo) + // Debris - Debris Visual + ApplySpellFix({ 36449, 30632 }, [](SpellInfo* spellInfo) { spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF; }); @@ -1542,12 +1534,6 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE; }); - // Debris Visual - ApplySpellFix({ 30632 }, [](SpellInfo* spellInfo) - { - spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DYNOBJ_ALLY); - }); - // Activate Sunblade Protecto ApplySpellFix({ 46475, 46476 }, [](SpellInfo* spellInfo) { @@ -3928,12 +3914,6 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->ExcludeCasterAuraSpell = 42299; }); - // Catch the Wild Wolpertinger! - ApplySpellFix({ 41621 }, [](SpellInfo* spellInfo) - { - spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_DUMMY; - }); - // Brewfest quests ApplySpellFix({ 47134, 51798 }, [](SpellInfo* spellInfo) { @@ -4586,6 +4566,18 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->ProcChance = 3; }); + // Summon Water Elementals + ApplySpellFix({ 29962, 37051, 37052, 37053 }, [](SpellInfo* spellInfo) + { + spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd + }); + + // Instill Lord Valthalak's Spirit DND + ApplySpellFix({ 27360 }, [](SpellInfo* spellInfo) + { + spellInfo->ChannelInterruptFlags |= AURA_INTERRUPT_FLAG_MOVE; + }); + for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i) { SpellInfo* spellInfo = mSpellInfoMap[i]; diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index f035470e1b12ee..addd4069f0c6ce 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -208,6 +208,7 @@ enum WorldFloatConfigs enum WorldIntConfigs { CONFIG_COMPRESSION = 0, + CONFIG_INTERVAL_GRIDCLEAN, CONFIG_INTERVAL_MAPUPDATE, CONFIG_INTERVAL_CHANGEWEATHER, CONFIG_INTERVAL_DISCONNECT_TOLERANCE, diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 03cc19f9156fc3..e9bc18788b2aff 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -111,6 +111,10 @@ float World::_maxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE; float World::_maxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE; float World::_maxVisibleDistanceInBGArenas = DEFAULT_VISIBILITY_BGARENAS; +int32 World::m_visibility_notify_periodOnContinents = DEFAULT_VISIBILITY_NOTIFY_PERIOD; +int32 World::m_visibility_notify_periodInInstances = DEFAULT_VISIBILITY_NOTIFY_PERIOD; +int32 World::m_visibility_notify_periodInBGArenas = DEFAULT_VISIBILITY_NOTIFY_PERIOD; + Realm realm; /// World constructor @@ -668,6 +672,14 @@ void World::LoadConfigSettings(bool reload) LOG_ERROR("server.loading", "PlayerSave.Stats.MinLevel ({}) must be in range 0..80. Using default, do not save character stats (0).", _int_configs[CONFIG_MIN_LEVEL_STAT_SAVE]); _int_configs[CONFIG_MIN_LEVEL_STAT_SAVE] = 0; } + _int_configs[CONFIG_INTERVAL_GRIDCLEAN] = sConfigMgr->GetOption("GridCleanUpDelay", 5 * MINUTE * IN_MILLISECONDS); + if (_int_configs[CONFIG_INTERVAL_GRIDCLEAN] < MIN_GRID_DELAY) + { + LOG_ERROR("server.loading", "GridCleanUpDelay ({}) must be greater {}. Use this minimal value.", _int_configs[CONFIG_INTERVAL_GRIDCLEAN], MIN_GRID_DELAY); + _int_configs[CONFIG_INTERVAL_GRIDCLEAN] = MIN_GRID_DELAY; + } + if (reload) + sMapMgr->SetGridCleanUpDelay(_int_configs[CONFIG_INTERVAL_GRIDCLEAN]); _int_configs[CONFIG_INTERVAL_MAPUPDATE] = sConfigMgr->GetOption("MapUpdateInterval", 10); if (_int_configs[CONFIG_INTERVAL_MAPUPDATE] < MIN_MAP_UPDATE_DELAY) @@ -1262,6 +1274,10 @@ void World::LoadConfigSettings(bool reload) _maxVisibleDistanceInBGArenas = MAX_VISIBILITY_DISTANCE; } + m_visibility_notify_periodOnContinents = sConfigMgr->GetOption("Visibility.Notify.Period.OnContinents", DEFAULT_VISIBILITY_NOTIFY_PERIOD); + m_visibility_notify_periodInInstances = sConfigMgr->GetOption("Visibility.Notify.Period.InInstances", DEFAULT_VISIBILITY_NOTIFY_PERIOD); + m_visibility_notify_periodInBGArenas = sConfigMgr->GetOption("Visibility.Notify.Period.InBGArenas", DEFAULT_VISIBILITY_NOTIFY_PERIOD); + ///- Load the CharDelete related config options _int_configs[CONFIG_CHARDELETE_METHOD] = sConfigMgr->GetOption("CharDelete.Method", 0); _int_configs[CONFIG_CHARDELETE_MIN_LEVEL] = sConfigMgr->GetOption("CharDelete.MinLevel", 0); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index de373358a63d3f..68a349969db9f9 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -322,6 +322,10 @@ class World: public IWorld static float GetMaxVisibleDistanceInInstances() { return _maxVisibleDistanceInInstances; } static float GetMaxVisibleDistanceInBGArenas() { return _maxVisibleDistanceInBGArenas; } + static int32 GetVisibilityNotifyPeriodOnContinents() { return m_visibility_notify_periodOnContinents; } + static int32 GetVisibilityNotifyPeriodInInstances() { return m_visibility_notify_periodInInstances; } + static int32 GetVisibilityNotifyPeriodInBGArenas() { return m_visibility_notify_periodInBGArenas; } + // our: needed for arena spectator subscriptions uint32 GetNextWhoListUpdateDelaySecs() override; @@ -409,6 +413,10 @@ class World: public IWorld static float _maxVisibleDistanceInInstances; static float _maxVisibleDistanceInBGArenas; + static int32 m_visibility_notify_periodOnContinents; + static int32 m_visibility_notify_periodInInstances; + static int32 m_visibility_notify_periodInBGArenas; + std::string _realmName; // CLI command holder to be thread safe diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp index a260a786311544..6a64ba68f24afb 100644 --- a/src/server/scripts/Commands/cs_list.cpp +++ b/src/server/scripts/Commands/cs_list.cpp @@ -126,7 +126,7 @@ class list_commandscript : public CommandScript for (std::unordered_multimap::const_iterator itr = creBounds.first; itr != creBounds.second;) { if (handler->GetSession()) - handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId, itr->second->GetGUID().ToString().c_str(), itr->second->IsAlive() ? "*" : " "); + handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, cInfo->Entry, guid, cInfo->Name.c_str(), x, y, z, mapId, itr->second->GetGUID().ToString().c_str(), itr->second->IsAlive() ? "*" : " "); else handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId, itr->second->GetGUID().ToString().c_str(), itr->second->IsAlive() ? "*" : " "); ++itr; @@ -138,7 +138,7 @@ class list_commandscript : public CommandScript if (!liveFound) { if (handler->GetSession()) - handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId, "", ""); + handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, cInfo->Entry, guid, cInfo->Name.c_str(), x, y, z, mapId, "", ""); else handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId, "", ""); } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 080393da7add32..5fc4714fb6b746 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -88,6 +88,7 @@ class misc_commandscript : public CommandScript { static ChatCommandTable commandTable = { + { "commentator", HandleCommentatorCommand, SEC_MODERATOR, Console::No }, { "dev", HandleDevCommand, SEC_ADMINISTRATOR, Console::No }, { "gps", HandleGPSCommand, SEC_MODERATOR, Console::No }, { "aura", HandleAuraCommand, SEC_GAMEMASTER, Console::No }, @@ -451,6 +452,51 @@ class misc_commandscript : public CommandScript return true; } + static bool HandleCommentatorCommand(ChatHandler* handler, Optional enableArg) + { + WorldSession* session = handler->GetSession(); + + if (!session) + { + return false; + } + + auto SetCommentatorMod = [&](bool enable) + { + session->SendNotification(enable ? "Commentator mode on" : "Commentator mode off"); + session->GetPlayer()->SetCommentator(enable); + }; + + if (!enableArg) + { + if (!AccountMgr::IsPlayerAccount(session->GetSecurity()) && session->GetPlayer()->IsCommentator()) + { + SetCommentatorMod(true); + } + else + { + SetCommentatorMod(false); + } + + return true; + } + + if (*enableArg) + { + SetCommentatorMod(true); + return true; + } + else + { + SetCommentatorMod(false); + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + static bool HandleDevCommand(ChatHandler* handler, Optional enableArg) { WorldSession* session = handler->GetSession(); @@ -467,32 +513,29 @@ class misc_commandscript : public CommandScript sScriptMgr->OnHandleDevCommand(handler->GetSession()->GetPlayer(), enable); }; - if (WorldSession* session = handler->GetSession()) + if (!enableArg) { - if (!enableArg) - { - if (!AccountMgr::IsPlayerAccount(session->GetSecurity()) && session->GetPlayer()->IsDeveloper()) - { - SetDevMod(true); - } - else - { - SetDevMod(false); - } - - return true; - } - - if (*enableArg) + if (!AccountMgr::IsPlayerAccount(session->GetSecurity()) && session->GetPlayer()->IsDeveloper()) { SetDevMod(true); - return true; } else { SetDevMod(false); - return true; } + + return true; + } + + if (*enableArg) + { + SetDevMod(true); + return true; + } + else + { + SetDevMod(false); + return true; } handler->SendSysMessage(LANG_USE_BOL); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 7813f5e422ca48..3db1a22fe73ef3 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -15,13 +15,6 @@ * with this program. If not, see . */ -/* ScriptData -Name: npc_commandscript -%Complete: 100 -Comment: All npc related commands -Category: commandscripts -EndScriptData */ - #include "Chat.h" #include "CreatureAI.h" #include "CreatureGroups.h" @@ -719,7 +712,7 @@ class npc_commandscript : public CommandScript if (!creatureTemplate) continue; - handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, creatureTemplate->Name.c_str(), x, y, z, mapId, "", ""); + handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, entry, guid, creatureTemplate->Name.c_str(), x, y, z, mapId, "", ""); ++count; } while (result->NextRow()); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp index dc3a49443c3104..c61e28444e3645 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp @@ -290,7 +290,7 @@ class go_orb_of_domination : public GameObjectScript bool OnGossipHello(Player* player, GameObject* go) override { if (InstanceScript* instance = go->GetInstanceScript()) - if (instance->GetData(DATA_EGG_EVENT) != DONE && !player->HasAura(SPELL_MIND_EXHAUSTION)) + if (instance->GetData(DATA_EGG_EVENT) != DONE && !player->HasAura(SPELL_MIND_EXHAUSTION) && !player->GetPet()) if (Creature* razor = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_RAZORGORE_THE_UNTAMED))) { razor->AI()->SetGUID(player->GetGUID()); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_curator.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_curator.cpp index dfc07e01282962..c48253a901e946 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_curator.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_curator.cpp @@ -44,19 +44,27 @@ enum Spells struct boss_curator : public BossAI { - boss_curator(Creature* creature) : BossAI(creature, DATA_CURATOR) { } + boss_curator(Creature* creature) : BossAI(creature, DATA_CURATOR) + { + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } void Reset() override { BossAI::Reset(); - me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, true); + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_ARCANE, true); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_MANA_LEECH, true); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_POWER_BURN, true); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_POWER_BURN, true); ScheduleHealthCheckEvent(15, [&] { - DoCastSelf(SPELL_ARCANE_INFUSION, true); - Talk(SAY_ENRAGE); + me->InterruptNonMeleeSpells(true); + DoCastSelf(SPELL_ARCANE_INFUSION, true); + Talk(SAY_ENRAGE); }); + me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA)); } void KilledUnit(Unit* victim) override @@ -85,7 +93,7 @@ struct boss_curator : public BossAI DoCastSelf(SPELL_ASTRAL_DECONSTRUCTION, true); }).Schedule(10s, [this](TaskContext context) { - if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 0, 45.0f, true, false)) + if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 45.0f, true, false)) { DoCast(target, SPELL_HATEFUL_BOLT); } @@ -130,18 +138,6 @@ struct boss_curator : public BossAI } summon->SetInCombatWithZone(); } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - scheduler.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - DoMeleeAttackIfReady(); - } }; void AddSC_boss_curator() diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp index a86c05a0c40673..80f09e54706bbc 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp @@ -24,8 +24,8 @@ enum Emotes { - EMOTE_PHASE_PORTAL = 0, - EMOTE_PHASE_BANISH = 1 + EMOTE_PHASE_BANISH = 0, + EMOTE_PHASE_PORTAL = 1 }; enum Spells @@ -50,7 +50,7 @@ enum Portals enum Groups { PORTAL_PHASE = 0, - VANISH_PHASE = 1 + BANISH_PHASE = 1 }; const float PortalCoord[3][3] = @@ -121,23 +121,6 @@ struct boss_netherspite : public BossAI } } - void DestroyPortals() - { - for (int i = 0; i < 3; ++i) - { - if (Creature* portal = ObjectAccessor::GetCreature(*me, PortalGUID[i])) - { - portal->DisappearAndDie(); - } - if (Creature* portal = ObjectAccessor::GetCreature(*me, BeamerGUID[i])) - { - portal->DisappearAndDie(); - } - PortalGUID[i].Clear(); - BeamTarget[i].Clear(); - } - } - void UpdatePortals() // Here we handle the beams' behavior { for (int j = 0; j < 3; ++j) // j = color @@ -203,9 +186,14 @@ struct boss_netherspite : public BossAI } } - void SwitchToPortalPhase() + void SwitchToPortalPhase(bool aggro = false) { - scheduler.CancelGroup(VANISH_PHASE); + if (!aggro) + { + Talk(EMOTE_PHASE_PORTAL); + } + + scheduler.CancelGroup(BANISH_PHASE); me->RemoveAurasDueToSpell(SPELL_BANISH_ROOT); me->RemoveAurasDueToSpell(SPELL_BANISH_VISUAL); SummonPortals(); @@ -218,38 +206,60 @@ struct boss_netherspite : public BossAI } }).Schedule(10s, PORTAL_PHASE, [this](TaskContext context) { - UpdatePortals(); - context.Repeat(1s); + UpdatePortals(); + context.Repeat(1s); }).Schedule(10s, PORTAL_PHASE, [this](TaskContext context) { - DoCastSelf(SPELL_EMPOWERMENT); - me->AddAura(SPELL_NETHERBURN_AURA, me); - context.Repeat(90s); + DoCastSelf(SPELL_EMPOWERMENT); + me->AddAura(SPELL_NETHERBURN_AURA, me); + context.Repeat(90s); + }).Schedule(15s, PORTAL_PHASE, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_VOIDZONE, 1, 45.0f, true, true); + context.Repeat(15s); }); - Talk(EMOTE_PHASE_PORTAL); + } + + void DestroyPortals() + { + for (int i = 0; i < 3; ++i) + { + if (Creature* portal = ObjectAccessor::GetCreature(*me, PortalGUID[i])) + { + portal->DisappearAndDie(); + } + if (Creature* portal = ObjectAccessor::GetCreature(*me, BeamerGUID[i])) + { + portal->DisappearAndDie(); + } + + PortalGUID[i].Clear(); + BeamTarget[i].Clear(); + } } void SwitchToBanishPhase() { + Talk(EMOTE_PHASE_BANISH); scheduler.CancelGroup(PORTAL_PHASE); me->RemoveAurasDueToSpell(SPELL_EMPOWERMENT); me->RemoveAurasDueToSpell(SPELL_NETHERBURN_AURA); DoCastSelf(SPELL_BANISH_VISUAL, true); DoCastSelf(SPELL_BANISH_ROOT, true); + DestroyPortals(); - scheduler.Schedule(30s, [this](TaskContext /*context*/) + + scheduler.Schedule(30s, [this](TaskContext) { - if (!me->IsNonMeleeSpellCast(false)) - { - SwitchToPortalPhase(); - return; - } - }).Schedule(10s, VANISH_PHASE, [this](TaskContext context) + SwitchToPortalPhase(); + DoResetThreatList(); + return; + }).Schedule(10s, BANISH_PHASE, [this](TaskContext context) { DoCastRandomTarget(SPELL_NETHERBREATH, 0, 40.0f, true); context.Repeat(5s, 7s); }); - Talk(EMOTE_PHASE_BANISH); + for (uint8 i = 0; i < 3; ++i) { me->RemoveAurasDueToSpell(NetherBuff[i]); @@ -268,13 +278,9 @@ struct boss_netherspite : public BossAI { BossAI::JustEngagedWith(who); HandleDoors(false); - SwitchToPortalPhase(); + SwitchToPortalPhase(true); DoZoneInCombat(); - scheduler.Schedule(15s, [this](TaskContext context) - { - DoCastRandomTarget(SPELL_VOIDZONE, 1, 45.0f, true, true); - context.Repeat(15s); - }).Schedule(9min, [this](TaskContext /*context*/) + scheduler.Schedule(9min, [this](TaskContext /*context*/) { if (!berserk) { @@ -289,7 +295,6 @@ struct boss_netherspite : public BossAI { BossAI::JustDied(killer); HandleDoors(true); - DestroyPortals(); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp index fcb6986539580e..72ef3e5dd3e3f8 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp @@ -87,9 +87,19 @@ struct boss_nightbane : public BossAI { BossAI::Reset(); _skeletonscheduler.CancelAll(); - Phase = 1; - MovePhase = 0; - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + if (!_intro) + { + //when boss is reset and we're past the intro + //cannot despawn, but have to move to a location where he normally is + //me->SetHomePosition(IntroWay[7][0], IntroWay[7][1], IntroWay[7][2], 0); + Position preSpawnPosis = me->GetHomePosition(); + EnterEvadeMode(); + me->NearTeleportTo(preSpawnPosis); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + _intro = true; + Phase = 1; + MovePhase = 0; + } me->SetSpeed(MOVE_RUN, 2.0f); me->SetDisableGravity(_intro); @@ -109,19 +119,6 @@ struct boss_nightbane : public BossAI _flying = false; _movement = false; - if (!_intro) - { - //when boss is reset and we're past the intro - //cannot despawn, but have to move to a location where he normally is - //me->SetHomePosition(IntroWay[7][0], IntroWay[7][1], IntroWay[7][2], 0); - Position preSpawnPosis = me->GetHomePosition(); - me->NearTeleportTo(preSpawnPosis); - instance->SetData(DATA_NIGHTBANE, NOT_STARTED); - _intro = true; - Phase = 1; - MovePhase = 0; - } - ScheduleHealthCheckEvent({ 75, 50, 25 }, [&]{ TakeOff(); }); @@ -136,11 +133,10 @@ struct boss_nightbane : public BossAI } } - void JustEngagedWith(Unit* /*who*/) override + void JustEngagedWith(Unit* who) override { - _JustEngagedWith(); - if (instance) - instance->SetData(DATA_NIGHTBANE, IN_PROGRESS); + BossAI::JustEngagedWith(who); + _intro = false; HandleTerraceDoors(false); Talk(YELL_AGGRO); @@ -238,7 +234,6 @@ struct boss_nightbane : public BossAI { if (id >= 8) { - _intro = false; //me->SetHomePosition(IntroWay[7][0], IntroWay[7][1], IntroWay[7][2], 0); //doesn't need home position because we have to "despawn" boss on reset me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp index 31917b8a0b8b98..1f44a23d9becfd 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp @@ -18,6 +18,7 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "SpellInfo.h" +#include "SpellScript.h" #include "karazhan.h" enum PrinceSay @@ -156,7 +157,6 @@ struct boss_malchezaar : public BossAI if (Creature* infernal = relay->SummonCreature(NPC_NETHERSPITE_INFERNAL, target->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 180000)) { infernal->SetDisplayId(INFERNAL_MODEL_INVISIBLE); - relay->CastSpell(target, SPELL_INFERNAL_RELAY_TWO); relay->CastSpell(infernal, SPELL_INFERNAL_RELAY); infernal->SetFaction(me->GetFaction()); infernal->SetControlled(true, UNIT_STATE_ROOT); @@ -197,7 +197,7 @@ struct boss_malchezaar : public BossAI scheduler.Schedule(30s, [this](TaskContext context) { - EnfeebleHealthEffect(); + DoCastAOE(SPELL_ENFEEBLE); scheduler.Schedule(9s, [this](TaskContext) { @@ -205,13 +205,12 @@ struct boss_malchezaar : public BossAI }); context.SetGroup(GROUP_ENFEEBLE); - scheduler.DelayGroup(GROUP_SHADOW_NOVA, 5s); context.Repeat(); }).Schedule(35500ms, [this](TaskContext context) { DoCastAOE(SPELL_SHADOW_NOVA); context.SetGroup(GROUP_SHADOW_NOVA); - context.Repeat(); + context.Repeat(30s); }).Schedule(40s, [this](TaskContext context) { if (!MaxSpawns(infernalTargets)) // only spawn infernal when the area is not full @@ -246,23 +245,12 @@ struct boss_malchezaar : public BossAI }); } - void EnfeebleHealthEffect() + void SpellHitTarget(Unit* target, SpellInfo const* spell) override { - std::list targetList; - SelectTargetList(targetList, 5, SelectTargetMethod::Random, 1, [&](Unit* u) { return u->IsAlive() && u->IsPlayer(); }); - - if (targetList.empty()) - return; - - for (auto const& target : targetList) + if (spell->Id == SPELL_ENFEEBLE) { - if (target) - { - _enfeebleTargets[target->GetGUID()] = target->GetHealth(); - - me->CastSpell(target, SPELL_ENFEEBLE, true); - target->SetHealth(1); - } + _enfeebleTargets[target->GetGUID()] = target->GetHealth(); + target->SetHealth(1); } } @@ -378,9 +366,43 @@ struct npc_malchezaar_axe : public ScriptedAI TaskScheduler _scheduler; }; +// 30843 - Enfeeble +class spell_malchezaar_enfeeble : public SpellScript +{ + PrepareSpellScript(spell_malchezaar_enfeeble); + + bool Load() override + { + return GetCaster()->ToCreature(); + } + + void FilterTargets(std::list& targets) + { + uint8 maxSize = 5; + Unit* caster = GetCaster(); + + targets.remove_if([caster](WorldObject const* target) -> bool + { + // Should not target current victim. + return caster->GetVictim() == target; + }); + + if (targets.size() > maxSize) + { + Acore::Containers::RandomResize(targets, maxSize); + } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_malchezaar_enfeeble::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY); + } +}; + void AddSC_boss_malchezaar() { RegisterKarazhanCreatureAI(boss_malchezaar); RegisterKarazhanCreatureAI(npc_malchezaar_axe); RegisterKarazhanCreatureAI(npc_netherspite_infernal); + RegisterSpellScript(spell_malchezaar_enfeeble); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp index 5a0869bf96b9aa..01a3c39b56461f 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp @@ -22,46 +22,54 @@ #include "karazhan.h" #include "TaskScheduler.h" -enum ShadeOfAran +enum Texts { - SAY_AGGRO = 0, - SAY_FLAMEWREATH = 1, - SAY_BLIZZARD = 2, - SAY_EXPLOSION = 3, - SAY_DRINK = 4, - SAY_ELEMENTALS = 5, - SAY_KILL = 6, - SAY_TIMEOVER = 7, - SAY_DEATH = 8, + SAY_AGGRO = 0, + SAY_FLAMEWREATH = 1, + SAY_BLIZZARD = 2, + SAY_EXPLOSION = 3, + SAY_DRINK = 4, + SAY_ELEMENTALS = 5, + SAY_KILL = 6, + SAY_TIMEOVER = 7, + SAY_DEATH = 8, + SAY_ATIESH = 9, + EMOTE_ARCANE_EXPLOSION = 10 +}; +enum Spells +{ //Spells - SPELL_FROSTBOLT = 29954, - SPELL_FIREBALL = 29953, - SPELL_ARCMISSLE = 29955, - SPELL_CHAINSOFICE = 29991, - SPELL_DRAGONSBREATH = 29964, - SPELL_MASSSLOW = 30035, - SPELL_FLAME_WREATH = 29946, - SPELL_AOE_CS = 29961, - SPELL_PLAYERPULL = 32265, - SPELL_AEXPLOSION = 29973, - SPELL_MASS_POLY = 29963, - SPELL_BLINK_CENTER = 29967, - SPELL_ELEMENTALS = 29962, - SPELL_CONJURE = 29975, - SPELL_DRINK = 30024, - SPELL_POTION = 32453, - SPELL_AOE_PYROBLAST = 29978, - - //Creature Spells - SPELL_CIRCULAR_BLIZZARD = 29951, - SPELL_WATERBOLT = 31012, - SPELL_SHADOW_PYRO = 29978, - - //Creatures - NPC_WATER_ELEMENTAL = 17167, - NPC_SHADOW_OF_ARAN = 18254, - NPC_ARAN_BLIZZARD = 17161, + SPELL_FROSTBOLT = 29954, + SPELL_FIREBALL = 29953, + SPELL_ARCMISSLE = 29955, + SPELL_CHAINSOFICE = 29991, + SPELL_DRAGONSBREATH = 29964, + SPELL_MASSSLOW = 30035, + SPELL_FLAME_WREATH = 29946, + SPELL_AOE_CS = 29961, + SPELL_PLAYERPULL = 32265, + SPELL_AEXPLOSION = 29973, + SPELL_MASS_POLY = 29963, + SPELL_BLINK_CENTER = 29967, + SPELL_CONJURE = 29975, + SPELL_DRINK = 30024, + SPELL_POTION = 32453, + SPELL_AOE_PYROBLAST = 29978, + + SPELL_SUMMON_WELEMENTAL_1 = 29962, + SPELL_SUMMON_WELEMENTAL_2 = 37051, + SPELL_SUMMON_WELEMENTAL_3 = 37052, + SPELL_SUMMON_WELEMENTAL_4 = 37053, + + SPELL_SUMMON_BLIZZARD = 29969, // Activates the Blizzard NPC + + SPELL_SHADOW_PYRO = 29978 +}; + +enum Creatures +{ + NPC_SHADOW_OF_ARAN = 18254 }; enum SuperSpell @@ -77,6 +85,8 @@ enum Groups GROUP_DRINKING = 1 }; +Position const roomCenter = {-11158.f, -1920.f}; + Position const elementalPos[4] = { {-11168.1f, -1939.29f, 232.092f, 1.46f}, @@ -95,21 +105,11 @@ struct boss_shade_of_aran : public BossAI }); } - uint8 LastSuperSpell; - - ObjectGuid FlameWreathTarget[3]; - float FWTargPosX[3]; - float FWTargPosY[3]; - - uint32 CurrentNormalSpell; - - bool Drinking; - void Reset() override { BossAI::Reset(); - drinkScheduler.CancelAll(); - LastSuperSpell = rand() % 3; + _drinkScheduler.CancelAll(); + _lastSuperSpell = rand() % 3; for (uint8 i = 0; i < 3; ++i) FlameWreathTarget[i].Clear(); @@ -120,10 +120,8 @@ struct boss_shade_of_aran : public BossAI _fireCooledDown = true; _frostCooledDown = true; - Drinking = false; - - // Not in progress - instance->SetData(DATA_ARAN, NOT_STARTED); + _drinking = false; + _hasDrunk = false; if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR))) { @@ -134,21 +132,32 @@ struct boss_shade_of_aran : public BossAI ScheduleHealthCheckEvent(40, [&]{ Talk(SAY_ELEMENTALS); - for(Position pos : elementalPos) + std::vector elementalSpells = { SPELL_SUMMON_WELEMENTAL_1, SPELL_SUMMON_WELEMENTAL_2, SPELL_SUMMON_WELEMENTAL_3, SPELL_SUMMON_WELEMENTAL_4 }; + + for (auto const& spell : elementalSpells) { - if(Creature* elemental = me->SummonCreature(NPC_WATER_ELEMENTAL, pos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000)) - { - if(Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100, true)) - { - DoStartNoMovement(target); - elemental->SetInCombatWithZone(); - elemental->CombatStart(target); - } - } + DoCastAOE(spell, true); } }); } + bool CheckAranInRoom() + { + return me->GetDistance2d(roomCenter.GetPositionX(), roomCenter.GetPositionY()) < 45.0f; + } + + void AttackStart(Unit* who) override + { + if (who && who->isTargetableForAttack() && me->GetReactState() != REACT_PASSIVE) + { + if (me->Attack(who, false)) + { + me->GetMotionMaster()->MoveChase(who, 45.0f, 0); + me->AddThreat(who, 0.0f); + } + } + } + void KilledUnit(Unit* /*victim*/) override { Talk(SAY_KILL); @@ -181,8 +190,7 @@ struct boss_shade_of_aran : public BossAI void JustDied(Unit* /*killer*/) override { Talk(SAY_DEATH); - - instance->SetData(DATA_ARAN, DONE); + _JustDied(); if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR))) { @@ -191,13 +199,29 @@ struct boss_shade_of_aran : public BossAI } } - void JustEngagedWith(Unit* /*who*/) override + void DamageTaken(Unit* doneBy, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override { - Talk(SAY_AGGRO); + BossAI::DamageTaken(doneBy, damage, damagetype, damageSchoolMask); - instance->SetData(DATA_ARAN, IN_PROGRESS); + if ((damagetype == DIRECT_DAMAGE || damagetype == SPELL_DIRECT_DAMAGE) && _drinking && me->GetReactState() == REACT_PASSIVE) + { + me->RemoveAurasDueToSpell(SPELL_DRINK); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetReactState(REACT_AGGRESSIVE); + me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA) - 32000); + _drinkScheduler.CancelGroup(GROUP_DRINKING); + _drinkScheduler.Schedule(1s, [this](TaskContext) + { + DoCastSelf(SPELL_AOE_PYROBLAST, false); + _drinking = false; + }); + } + } - DoZoneInCombat(); + void JustEngagedWith(Unit* /*who*/) override + { + _JustEngagedWith(); + Talk(SAY_AGGRO); //handle timed closing door scheduler.Schedule(15s, [this](TaskContext) @@ -207,13 +231,16 @@ struct boss_shade_of_aran : public BossAI libraryDoor->SetGoState(GO_STATE_READY); libraryDoor->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); } - }).Schedule(1ms, [this](TaskContext context) + }).Schedule(1s, [this](TaskContext context) { - if (!me->IsNonMeleeSpellCast(false)) + context.Repeat(2s); + + if (!_drinking) { - Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true); - if (!target) + if (me->IsNonMeleeSpellCast(false)) + { return; + } uint32 Spells[3]; uint8 AvailableSpells = 0; @@ -235,98 +262,157 @@ struct boss_shade_of_aran : public BossAI ++AvailableSpells; } + // Should drink at 10%, need 10% mana for mass polymorph + if (!_hasDrunk && me->GetMaxPower(POWER_MANA) && (me->GetPower(POWER_MANA) * 100 / me->GetMaxPower(POWER_MANA)) < 13) + { + _drinking = true; + _hasDrunk = true; + me->InterruptNonMeleeSpells(true); + Talk(SAY_DRINK); + DoCastAOE(SPELL_MASS_POLY); + me->SetReactState(REACT_PASSIVE); + + // Start drinking after conjuring drinks + _drinkScheduler.Schedule(2s, GROUP_DRINKING, [this](TaskContext) + { + DoCastSelf(SPELL_CONJURE); + }).Schedule(4s, GROUP_DRINKING, [this](TaskContext) + { + me->SetStandState(UNIT_STAND_STATE_SIT); + DoCastSelf(SPELL_DRINK); + }); + + _drinkScheduler.Schedule(10s, GROUP_DRINKING, [this](TaskContext) + { + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetReactState(REACT_AGGRESSIVE); + me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA) - 32000); + DoCastSelf(SPELL_AOE_PYROBLAST); + _drinkScheduler.CancelGroup(GROUP_DRINKING); + _drinking = false; + }); + + return; + } + //If no available spells wait 1 second and try again if (AvailableSpells) { CurrentNormalSpell = Spells[rand() % AvailableSpells]; - DoCast(target, CurrentNormalSpell); + + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(CurrentNormalSpell)) + { + if (int32(me->GetPower(POWER_MANA)) < spellInfo->CalcPowerCost(me, (SpellSchoolMask)spellInfo->SchoolMask)) + { + DoCastSelf(SPELL_POTION); + } + else + { + if (!me->CanCastSpell(CurrentNormalSpell)) + { + me->SetWalk(false); + me->ResumeChasingVictim(); + } + else + { + DoCastRandomTarget(CurrentNormalSpell, 0, 100.0f); + if (me->GetVictim()) + { + me->GetMotionMaster()->MoveChase(me->GetVictim(), 45.0f); + } + } + } + } } } - context.Repeat(2s); }).Schedule(5s, [this](TaskContext context) { - switch (urand(0, 1)) + if (!_drinking) { - case 0: - DoCastSelf(SPELL_AOE_CS); - break; - case 1: - DoCastRandomTarget(SPELL_CHAINSOFICE); - break; + switch (urand(0, 1)) + { + case 0: + DoCastSelf(SPELL_AOE_CS); + break; + case 1: + DoCastRandomTarget(SPELL_CHAINSOFICE); + break; + } } context.Repeat(5s, 20s); - }).Schedule(35s, [this](TaskContext context) + }).Schedule(6s, [this](TaskContext context) { - uint8 Available[2]; - - switch (LastSuperSpell) + if (!_drinking) { - case SUPER_AE: - Available[0] = SUPER_FLAME; - Available[1] = SUPER_BLIZZARD; - break; - case SUPER_FLAME: - Available[0] = SUPER_AE; - Available[1] = SUPER_BLIZZARD; - break; - case SUPER_BLIZZARD: - Available[0] = SUPER_FLAME; - Available[1] = SUPER_AE; - break; - } + me->ClearProhibitedSpellTimers(); - LastSuperSpell = Available[urand(0, 1)]; + DoCastSelf(SPELL_BLINK_CENTER, true); - switch (LastSuperSpell) - { - case SUPER_AE: - Talk(SAY_EXPLOSION); + uint8 Available[2]; - DoCastSelf(SPELL_BLINK_CENTER, true); - DoCastSelf(SPELL_PLAYERPULL, true); - DoCastSelf(SPELL_MASSSLOW, true); - DoCastSelf(SPELL_AEXPLOSION, false); - break; + switch (_lastSuperSpell) + { + case SUPER_AE: + Available[0] = SUPER_FLAME; + Available[1] = SUPER_BLIZZARD; + break; + case SUPER_FLAME: + Available[0] = SUPER_AE; + Available[1] = SUPER_BLIZZARD; + break; + case SUPER_BLIZZARD: + Available[0] = SUPER_FLAME; + Available[1] = SUPER_AE; + break; + } - case SUPER_FLAME: - Talk(SAY_FLAMEWREATH); + _lastSuperSpell = Available[urand(0, 1)]; - scheduler.Schedule(20s, GROUP_FLAMEWREATH, [this](TaskContext) - { - scheduler.CancelGroup(GROUP_FLAMEWREATH); - }).Schedule(500ms, GROUP_FLAMEWREATH, [this](TaskContext context) - { - for (uint8 i = 0; i < 3; ++i) + switch (_lastSuperSpell) + { + case SUPER_AE: + Talk(SAY_EXPLOSION); + Talk(EMOTE_ARCANE_EXPLOSION); + DoCastSelf(SPELL_PLAYERPULL, true); + DoCastSelf(SPELL_MASSSLOW, true); + DoCastSelf(SPELL_AEXPLOSION, false); + break; + + case SUPER_FLAME: + Talk(SAY_FLAMEWREATH); + + scheduler.Schedule(20s, GROUP_FLAMEWREATH, [this](TaskContext) { - if (!FlameWreathTarget[i]) - continue; - - Unit* unit = ObjectAccessor::GetUnit(*me, FlameWreathTarget[i]); - if (unit && !unit->IsWithinDist2d(FWTargPosX[i], FWTargPosY[i], 3)) + scheduler.CancelGroup(GROUP_FLAMEWREATH); + }).Schedule(500ms, GROUP_FLAMEWREATH, [this](TaskContext context) + { + for (uint8 i = 0; i < 3; ++i) { - unit->CastSpell(unit, 20476, true, 0, 0, me->GetGUID()); - FlameWreathTarget[i].Clear(); + if (!FlameWreathTarget[i]) + continue; + + Unit* unit = ObjectAccessor::GetUnit(*me, FlameWreathTarget[i]); + if (unit && !unit->IsWithinDist2d(FWTargPosX[i], FWTargPosY[i], 3)) + { + unit->CastSpell(unit, 20476, true, 0, 0, me->GetGUID()); + FlameWreathTarget[i].Clear(); + } } - } - context.Repeat(500ms); - }); - - FlameWreathTarget[0].Clear(); - FlameWreathTarget[1].Clear(); - FlameWreathTarget[2].Clear(); + context.Repeat(500ms); + }); - FlameWreathEffect(); - break; + FlameWreathTarget[0].Clear(); + FlameWreathTarget[1].Clear(); + FlameWreathTarget[2].Clear(); - case SUPER_BLIZZARD: - Talk(SAY_BLIZZARD); + FlameWreathEffect(); + break; - if (Creature* pSpawn = me->SummonCreature(NPC_ARAN_BLIZZARD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 25000)) - { - pSpawn->SetFaction(me->GetFaction()); - pSpawn->CastSpell(me, SPELL_CIRCULAR_BLIZZARD, false); - } - break; + case SUPER_BLIZZARD: + Talk(SAY_BLIZZARD); + DoCastAOE(SPELL_SUMMON_BLIZZARD); + break; + } } context.Repeat(35s, 40s); }).Schedule(12min, [this](TaskContext context) @@ -384,70 +470,21 @@ struct boss_shade_of_aran : public BossAI void UpdateAI(uint32 diff) override { scheduler.Update(diff); - drinkScheduler.Update(diff); + _drinkScheduler.Update(diff); if (!UpdateVictim()) return; - if (!Drinking && me->GetMaxPower(POWER_MANA) && (me->GetPower(POWER_MANA) * 100 / me->GetMaxPower(POWER_MANA)) < 20) + if (!CheckAranInRoom()) { - Drinking = true; - me->InterruptNonMeleeSpells(false); - - Talk(SAY_DRINK); - - scheduler.DelayAll(10s); - DoCastSelf(SPELL_MASS_POLY, true); - DoCastSelf(SPELL_CONJURE, false); - me->SetReactState(REACT_PASSIVE); - me->SetStandState(UNIT_STAND_STATE_SIT); - DoCastSelf(SPELL_DRINK, true); - _currentHealth = me->GetHealth(); - drinkScheduler.Schedule(500ms, GROUP_DRINKING, [this](TaskContext context) - { - //check for damage to interrupt - if(CheckDamageDuringDrinking(_currentHealth)) - { - Drinking = false; - me->RemoveAurasDueToSpell(SPELL_DRINK); - me->SetStandState(UNIT_STAND_STATE_STAND); - me->SetReactState(REACT_AGGRESSIVE); - me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA) - 32000); - DoCastSelf(SPELL_POTION, false); - DoCastSelf(SPELL_AOE_PYROBLAST, false); - drinkScheduler.CancelGroup(GROUP_DRINKING); - } else { - context.Repeat(500ms); - } - }).Schedule(10s, GROUP_DRINKING, [this](TaskContext) - { - me->SetStandState(UNIT_STAND_STATE_STAND); - me->SetReactState(REACT_AGGRESSIVE); - me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA) - 32000); - DoCastSelf(SPELL_POTION, true); - DoCastSelf(SPELL_AOE_PYROBLAST, false); - - Drinking = false; - drinkScheduler.CancelGroup(GROUP_DRINKING); - }); + EnterEvadeMode(); + return; } - if (_arcaneCooledDown && _fireCooledDown && _frostCooledDown && !Drinking) + if (_arcaneCooledDown && _fireCooledDown && _frostCooledDown && !_drinking) DoMeleeAttackIfReady(); } - bool CheckDamageDuringDrinking(uint32 oldHealth) - { - if (Drinking) - { - if (me->GetHealth() < oldHealth) - { - return true; - } - } - return false; - } - void SpellHit(Unit* /*pAttacker*/, SpellInfo const* Spell) override { //We only care about interrupt effects and only if they are durring a spell currently being cast @@ -456,9 +493,6 @@ struct boss_shade_of_aran : public BossAI Spell->Effects[2].Effect != SPELL_EFFECT_INTERRUPT_CAST) || !me->IsNonMeleeSpellCast(false)) return; - //Interrupt effect - me->InterruptNonMeleeSpells(false); - //Normally we would set the cooldown equal to the spell duration //but we do not have access to the DurationStore @@ -476,52 +510,24 @@ struct boss_shade_of_aran : public BossAI } } private: - TaskScheduler drinkScheduler; + TaskScheduler _drinkScheduler; - bool _arcaneCooledDown; - bool _fireCooledDown; - bool _frostCooledDown; - uint32 _currentHealth; -}; + uint32 _lastSuperSpell; -struct npc_aran_elemental : public ScriptedAI -{ - npc_aran_elemental(Creature* creature) : ScriptedAI(creature) - { - SetCombatMovement(false); - _scheduler.SetValidator([this] - { - return !me->HasUnitState(UNIT_STATE_CASTING); - }); - } - - void Reset() override - { - _scheduler.CancelAll(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _scheduler.Schedule(2s, [this](TaskContext context) - { - DoCastVictim(SPELL_WATERBOLT); - context.Repeat(2s); - }); - } + ObjectGuid FlameWreathTarget[3]; + float FWTargPosX[3]; + float FWTargPosY[3]; - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + uint32 CurrentNormalSpell; - _scheduler.Update(diff); - } -private: - TaskScheduler _scheduler; + bool _arcaneCooledDown; + bool _fireCooledDown; + bool _frostCooledDown; + bool _drinking; + bool _hasDrunk; }; void AddSC_boss_shade_of_aran() { RegisterKarazhanCreatureAI(boss_shade_of_aran); - RegisterKarazhanCreatureAI(npc_aran_elemental); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp index b81b7cd8b7e1c7..956bd2b6f80fb1 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp @@ -52,7 +52,6 @@ enum Spells enum Creatures { NPC_DEMONCHAINS = 17248, - NPC_FIENDISHIMP = 17267, NPC_PORTAL = 17265 }; @@ -146,64 +145,6 @@ struct npc_demon_chain : public ScriptedAI ObjectGuid sacrificeGUID; }; -struct npc_fiendish_portal : public PassiveAI -{ - npc_fiendish_portal(Creature* creature) : PassiveAI(creature), summons(me) {} - - void Reset() override - { - DespawnAllImp(); - } - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - DoZoneInCombat(summon); - } - - void DespawnAllImp() - { - summons.DespawnAll(); - } - -private: - SummonList summons; -}; - -struct npc_fiendish_imp : public ScriptedAI -{ - npc_fiendish_imp(Creature* creature) : ScriptedAI(creature) {} - - void Reset() override - { - _scheduler.CancelAll(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _scheduler.Schedule(2s, [this](TaskContext context) - { - DoCastVictim(SPELL_FIREBOLT); - context.Repeat(2200ms); - }); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _scheduler.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - DoMeleeAttackIfReady(); - } - -private: - TaskScheduler _scheduler; -}; - struct boss_terestian_illhoof : public BossAI { boss_terestian_illhoof(Creature* creature) : BossAI(creature, DATA_TERESTIAN) @@ -218,20 +159,6 @@ struct boss_terestian_illhoof : public BossAI { _Reset(); SummonKilrek(); - portalsCount = 0; - berserk = false; - for (uint8 i = 0; i < 2; ++i) - { - if (portalGUID[i]) - { - if (Creature* pPortal = ObjectAccessor::GetCreature(*me, portalGUID[i])) - { - pPortal->AI()->Reset(); - pPortal->DespawnOrUnsummon(); - } - portalGUID[i].Clear(); - } - } } void SummonKilrek() @@ -256,10 +183,13 @@ struct boss_terestian_illhoof : public BossAI DoZoneInCombat(); scheduler.Schedule(30s, [this](TaskContext context) { - if (Unit * target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, false)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, false)) { DoCast(target, SPELL_SACRIFICE, true); - target->CastSpell(target, SPELL_SUMMON_DEMONCHAINS, true); + target->m_Events.AddEventAtOffset([target] { + target->CastSpell(target, SPELL_SUMMON_DEMONCHAINS, true); + }, 1s); + Talk(SAY_SACRIFICE); context.Repeat(30s); } @@ -267,31 +197,15 @@ struct boss_terestian_illhoof : public BossAI { DoCastVictim(SPELL_SHADOW_BOLT); context.Repeat(10s); - }).Schedule(10s, [this](TaskContext context) + }).Schedule(10s, [this](TaskContext) { - if (!portalGUID[0]) - { - DoCastVictim(SPELL_FIENDISH_PORTAL); - } - if (!portalGUID[1]) - { - DoCastVictim(SPELL_FIENDISH_PORTAL_1); - } - if (portalGUID[0] && portalGUID[1]) - { - if (Creature* pPortal = ObjectAccessor::GetCreature(*me, portalGUID[urand(0, 1)])) - { - pPortal->CastSpell(me->GetVictim(), SPELL_SUMMON_FIENDISIMP); - } - context.Repeat(5s); - } + DoCastAOE(SPELL_FIENDISH_PORTAL); + }).Schedule(11s, [this](TaskContext) + { + DoCastAOE(SPELL_FIENDISH_PORTAL_1); }).Schedule(10min, [this](TaskContext /*context*/) { - if (!berserk) - { - DoCastSelf(SPELL_BERSERK); - berserk = true; - } + DoCastSelf(SPELL_BERSERK); }); } @@ -299,13 +213,14 @@ struct boss_terestian_illhoof : public BossAI { if (summoned->GetEntry() == NPC_PORTAL) { - portalGUID[portalsCount] = summoned->GetGUID(); - ++portalsCount; + summoned->SetReactState(REACT_PASSIVE); if (summoned->GetUInt32Value(UNIT_CREATED_BY_SPELL) == SPELL_FIENDISH_PORTAL_1) { Talk(SAY_SUMMON); } } + + summons.Summon(summoned); } void KilledUnit(Unit* victim) override @@ -318,44 +233,14 @@ struct boss_terestian_illhoof : public BossAI void JustDied(Unit* /*killer*/) override { + _JustDied(); Talk(SAY_DEATH); - for (uint8 i = 0; i < 2; ++i) - { - if (portalGUID[i]) - { - if (Creature* pPortal = ObjectAccessor::GetCreature((*me), portalGUID[i])) - { - pPortal->AI()->Reset(); - pPortal->DespawnOrUnsummon(); - } - portalGUID[i].Clear(); - } - } } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - scheduler.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - DoMeleeAttackIfReady(); - } - -private: - bool berserk; - ObjectGuid portalGUID[2]; - uint8 portalsCount; }; void AddSC_boss_terestian_illhoof() { RegisterKarazhanCreatureAI(boss_terestian_illhoof); - RegisterKarazhanCreatureAI(npc_fiendish_imp); - RegisterKarazhanCreatureAI(npc_fiendish_portal); RegisterKarazhanCreatureAI(npc_kilrek); RegisterKarazhanCreatureAI(npc_demon_chain); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp index 3753a61bc9532a..59a348e6159c90 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp @@ -231,20 +231,12 @@ struct boss_dorothee : public ScriptedAI me->DespawnOrUnsummon(); } - void AttackStart(Unit* who) override + void SummonedCreatureDies(Creature* creature, Unit* /*killer*/) override { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::AttackStart(who); - } - - void MoveInLineOfSight(Unit* who) override - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::MoveInLineOfSight(who); + if (creature->GetEntry() == NPC_TITO) + { + Talk(SAY_DOROTHEE_TITO_DEATH); + } } void EnterEvadeMode(EvadeReason reason) override @@ -288,8 +280,6 @@ struct npc_tito : public ScriptedAI InstanceScript* instance; - void Reset() override { } - void JustEngagedWith(Unit* /*who*/) override { _scheduler.Schedule(10s, [this](TaskContext context) @@ -299,18 +289,6 @@ struct npc_tito : public ScriptedAI }); } - void JustDied(Unit* /*killer*/) override - { - if (Creature* Dorothee = instance->GetCreature(DATA_DOROTHEE)) - { - if (Dorothee->IsAlive()) - { - Talk(SAY_DOROTHEE_TITO_DEATH, Dorothee); - } - } - me->DespawnOrUnsummon(); - } - void UpdateAI(uint32 diff) override { if (!UpdateVictim()) @@ -351,17 +329,6 @@ struct boss_roar : public ScriptedAI } } - void Reset() override { } - - void MoveInLineOfSight(Unit* who) override - - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::MoveInLineOfSight(who); - } - void EnterEvadeMode(EvadeReason reason) override { ScriptedAI::EnterEvadeMode(reason); @@ -373,14 +340,6 @@ struct boss_roar : public ScriptedAI } } - void AttackStart(Unit* who) override - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::AttackStart(who); - } - void JustEngagedWith(Unit* /*who*/) override { Talk(SAY_ROAR_AGGRO); @@ -458,24 +417,6 @@ struct boss_strawman : public ScriptedAI } } - void Reset() override { } - - void AttackStart(Unit* who) override - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::AttackStart(who); - } - - void MoveInLineOfSight(Unit* who) override - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::MoveInLineOfSight(who); - } - void EnterEvadeMode(EvadeReason reason) override { ScriptedAI::EnterEvadeMode(reason); @@ -508,7 +449,7 @@ struct boss_strawman : public ScriptedAI void SpellHit(Unit* /*caster*/, SpellInfo const* Spell) override { - if ((Spell->SchoolMask == SPELL_SCHOOL_MASK_FIRE) && (!(rand() % 10))) + if ((Spell->SchoolMask == SPELL_SCHOOL_MASK_FIRE) && roll_chance_i(10)) { /* if (not direct damage(aoe, dot)) @@ -601,22 +542,6 @@ struct boss_tinhead : public ScriptedAI me->DespawnOrUnsummon(); } - void AttackStart(Unit* who) override - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::AttackStart(who); - } - - void MoveInLineOfSight(Unit* who) override - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::MoveInLineOfSight(who); - } - void EnterEvadeMode(EvadeReason reason) override { ScriptedAI::EnterEvadeMode(reason); @@ -763,6 +688,7 @@ enum RedRidingHood SPELL_LITTLE_RED_RIDING_HOOD = 30768, SPELL_TERRIFYING_HOWL = 30752, SPELL_WIDE_SWIPE = 30761, + SPELL_PICNIC_BASKET_SMELL = 30755, CREATURE_BIG_BAD_WOLF = 17521, @@ -826,16 +752,6 @@ struct boss_bigbadwolf : public ScriptedAI InstanceScript* instance; - ObjectGuid HoodGUID; - - void Reset() override - { - HoodGUID.Clear(); - _tempThreat = 0; - - _isChasing = false; - } - void JustEngagedWith(Unit* /*who*/) override { instance->DoUseDoorOrButton(instance->GetGuidData(DATA_GO_STAGEDOORLEFT)); @@ -844,40 +760,14 @@ struct boss_bigbadwolf : public ScriptedAI _scheduler.Schedule(30s, [this](TaskContext context) { - if (!_isChasing) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true)) { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true)) - { - Talk(SAY_WOLF_HOOD); - DoCast(target, SPELL_LITTLE_RED_RIDING_HOOD, true); - _tempThreat = DoGetThreat(target); - if (_tempThreat) - { - DoModifyThreatByPercent(target, -100); - } - HoodGUID = target->GetGUID(); - me->AddThreat(target, 1000000.0f); - _isChasing = true; - context.Repeat(20s); - } + Talk(SAY_WOLF_HOOD); + DoCast(target, SPELL_LITTLE_RED_RIDING_HOOD, true); + target->CastSpell(me, SPELL_PICNIC_BASKET_SMELL, true); } - else - { - _isChasing = false; - if (Unit* target = ObjectAccessor::GetUnit(*me, HoodGUID)) - { - HoodGUID.Clear(); - if (DoGetThreat(target)) - { - DoModifyThreatByPercent(target, -100); - } - me->AddThreat(target, _tempThreat); - _tempThreat = 0; - } - - context.Repeat(40s); - } + context.Repeat(40s); }).Schedule(25s, 35s, [this](TaskContext context) { DoCastAOE(SPELL_TERRIFYING_HOWL); @@ -920,15 +810,10 @@ struct boss_bigbadwolf : public ScriptedAI DoMeleeAttackIfReady(); - if (_isChasing) - return; - _scheduler.Update(diff); } private: TaskScheduler _scheduler; - bool _isChasing; - float _tempThreat; }; /**********************************************/ @@ -947,7 +832,7 @@ enum JulianneRomulo SAY_ROMULO_AGGRO = 0, SAY_ROMULO_DEATH = 1, - SAY_ROMULO_ENTER = 2, + SAY_ROMULO_DEATH2 = 2, SAY_ROMULO_RESURRECT = 3, SAY_ROMULO_SLAY = 4, @@ -985,12 +870,10 @@ enum RAJGroups enum RAJActions { - ACTION_DIED_ANNOUNCE = 0, - ACTION_PHASE_SET = 1, ACTION_FAKING_DEATH = 2, ACTION_COMBAT_SCHEDULE = 3, - ACTION_DO_RESURRECT = 4, - ACTION_EARLY_REVIVE = 5, + //ACTION_DO_RESURRECT = 4, + //ACTION_RESS_ROMULO = 5, ACTION_CANCEL_COMBAT = 6 }; @@ -999,7 +882,6 @@ void PretendToDie(Creature* creature) creature->AI()->DoAction(ACTION_CANCEL_COMBAT); creature->InterruptNonMeleeSpells(true); creature->RemoveAllAuras(); - creature->SetHealth(0); creature->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); creature->SetReactState(REACT_PASSIVE); creature->GetMotionMaster()->MovementExpired(false); @@ -1032,14 +914,6 @@ struct boss_julianne : public ScriptedAI isFakingDeath = false; } - InstanceScript* instance; - - uint32 phase; - - bool isFakingDeath; - bool summonedRomulo; - bool romuloDied; - void Reset() override { phase = PHASE_JULIANNE; @@ -1051,10 +925,8 @@ struct boss_julianne : public ScriptedAI } summonedRomulo = false; - romuloDied = false; me->SetImmuneToPC(true); - //intro sequence _scheduler.Schedule(1s, [this](TaskContext) { Talk(SAY_JULIANNE_ENTER); @@ -1071,38 +943,29 @@ struct boss_julianne : public ScriptedAI { switch(action) { - case ACTION_DIED_ANNOUNCE: - romuloDied = true; - break; - case ACTION_EARLY_REVIVE: - romuloDied = true; - _resurrectScheduler.Schedule(10s, [this](TaskContext) - { - Talk(SAY_JULIANNE_RESURRECT); - romuloDied = false; - }); - break; - case ACTION_PHASE_SET: - phase = PHASE_BOTH; - isFakingDeath = false; - break; case ACTION_FAKING_DEATH: isFakingDeath = false; break; case ACTION_COMBAT_SCHEDULE: ScheduleCombat(); break; - case ACTION_DO_RESURRECT: - _resurrectScheduler.Schedule(1s, [this](TaskContext) + case ACTION_RESS_ROMULO: + me->m_Events.AddEventAtOffset([this] { - if (Creature* Romulo = instance->GetCreature(DATA_ROMULO)) + if (Creature* romulo = instance->GetCreature(DATA_ROMULO)) { Talk(SAY_JULIANNE_RESURRECT); - Resurrect(Romulo); - Romulo->AI()->DoAction(ACTION_FAKING_DEATH); - romuloDied = false; + Resurrect(romulo); + romulo->AI()->DoAction(ACTION_FAKING_DEATH); + romulo->AI()->Talk(SAY_ROMULO_RESURRECT); } - }); + }, 1s); + break; + case ACTION_DO_RESURRECT: + phase = PHASE_BOTH; + isFakingDeath = false; + Resurrect(me); + me->ResumeChasingVictim(); break; case ACTION_CANCEL_COMBAT: _scheduler.CancelGroup(GROUP_COMBAT); @@ -1128,11 +991,11 @@ struct boss_julianne : public ScriptedAI { if (urand(0, 1) && summonedRomulo) { - if (Creature* Romulo = instance->GetCreature(DATA_ROMULO)) + if (Creature* romulo = instance->GetCreature(DATA_ROMULO)) { - if (Romulo->IsAlive() && !romuloDied) + if (!romulo->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) { - DoCast(Romulo, SPELL_ETERNAL_AFFECTION); + DoCast(romulo, SPELL_ETERNAL_AFFECTION); } } } @@ -1149,22 +1012,6 @@ struct boss_julianne : public ScriptedAI ScheduleCombat(); } - void AttackStart(Unit* who) override - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::AttackStart(who); - } - - void MoveInLineOfSight(Unit* who) override - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::MoveInLineOfSight(who); - } - void JustReachedHome() override { me->DespawnOrUnsummon(); @@ -1183,10 +1030,9 @@ struct boss_julianne : public ScriptedAI phase = PHASE_ROMULO; _scheduler.Schedule(10s, GROUP_RP, [this](TaskContext) { - if (Creature* pRomulo = me->SummonCreature(CREATURE_ROMULO, ROMULO_X, ROMULO_Y, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR * 2 * IN_MILLISECONDS)) + if (Creature* romulo = me->SummonCreature(CREATURE_ROMULO, ROMULO_X, ROMULO_Y, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR * 2 * IN_MILLISECONDS)) { - pRomulo->AI()->DoAction(ACTION_PHASE_SET); - pRomulo->SetInCombatWithZone(); + romulo->SetInCombatWithZone(); } summonedRomulo = true; }); @@ -1201,13 +1047,12 @@ struct boss_julianne : public ScriptedAI return; } - //anything below only used if incoming damage will kill + damage = me->GetHealth() - 1; if (phase == PHASE_JULIANNE) { - damage = 0; + me->ClearTarget(); - //this means already drinking, so return if (isFakingDeath) { return; @@ -1222,50 +1067,12 @@ struct boss_julianne : public ScriptedAI return; } - if (phase == PHASE_ROMULO) + if (phase == PHASE_BOTH && !isFakingDeath) { - //LOG_ERROR("scripts", "boss_julianneAI: cannot take damage in PHASE_ROMULO, why was i here?"); - damage = 0; - return; - } - - if (phase == PHASE_BOTH) - { - //if this is true then we have to kill romulo too - if (romuloDied) - { - if (Creature* Romulo = instance->GetCreature(DATA_ROMULO)) - { - _scheduler.CancelAll(); - _resurrectScheduler.CancelAll(); - Romulo->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - Romulo->GetMotionMaster()->Clear(); - Romulo->setDeathState(JUST_DIED); - Romulo->CombatStop(true); - Romulo->GetThreatMgr().ClearAllThreat(); - Romulo->ReplaceAllDynamicFlags(UNIT_DYNFLAG_LOOTABLE); - //this does not seem to really work - the lootable dynamic flags - } - - return; - } - - //if not already returned, then romulo is alive and we can pretend die - if (Creature* Romulo = instance->GetCreature(DATA_ROMULO)) - { - PretendToDie(me); - isFakingDeath = true; - Romulo->AI()->DoAction(ACTION_EARLY_REVIVE); - _scheduler.Schedule(10050ms, [this](TaskContext) - { - Resurrect(me); - isFakingDeath = false; - }); - damage = 0; - return; - } + PretendToDie(me); + isFakingDeath = true; + instance->DoAction(ACTION_SCHEDULE_RAJ_CHECK); } - //LOG_ERROR("scripts", "boss_julianneAI: DamageTaken reach end of code, that should not happen."); } void EnterEvadeMode(EvadeReason reason) override @@ -1286,15 +1093,17 @@ struct boss_julianne : public ScriptedAI instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE); } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* victim) override { - Talk(SAY_JULIANNE_SLAY); + if (victim != me) + { + Talk(SAY_JULIANNE_SLAY); + } } void UpdateAI(uint32 diff) override { _scheduler.Update(diff); - _resurrectScheduler.Update(diff); if (!UpdateVictim()) { @@ -1307,50 +1116,30 @@ struct boss_julianne : public ScriptedAI } } private: + InstanceScript* instance; + uint32 phase; + bool isFakingDeath; + bool summonedRomulo; TaskScheduler _scheduler; - TaskScheduler _resurrectScheduler; }; struct boss_romulo : public ScriptedAI { boss_romulo(Creature* creature) : ScriptedAI(creature) { - instance = creature->GetInstanceScript(); //not necessary + instance = creature->GetInstanceScript(); } - InstanceScript* instance; - - uint32 phase; - - bool isFakingDeath; - bool julianneDead; - void Reset() override { phase = PHASE_ROMULO; - isFakingDeath = false; - julianneDead = false; } void DoAction(int32 action) override { switch(action) { - case ACTION_DIED_ANNOUNCE: - julianneDead = true; - break; - case ACTION_EARLY_REVIVE: - julianneDead = true; - _resurrectScheduler.Schedule(10s, [this](TaskContext) - { - Talk(SAY_ROMULO_RESURRECT); - julianneDead = false; - }); - break; - case ACTION_PHASE_SET: - phase = PHASE_ROMULO; - break; case ACTION_FAKING_DEATH: isFakingDeath = false; break; @@ -1375,9 +1164,11 @@ struct boss_romulo : public ScriptedAI void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override { if (damage < me->GetHealth()) + { return; + } - //anything below only used if incoming damage will kill + damage = me->GetHealth() - 1; if (phase == PHASE_ROMULO) { @@ -1386,63 +1177,24 @@ struct boss_romulo : public ScriptedAI isFakingDeath = true; phase = PHASE_BOTH; - if (Creature* Julianne = instance->GetCreature(DATA_JULIANNE)) + me->m_Events.AddEventAtOffset([this] { - Julianne->AI()->DoAction(ACTION_DIED_ANNOUNCE); - //resurrect julianne - _scheduler.Schedule(10s, GROUP_RP, [this](TaskContext) + Resurrect(me); + isFakingDeath = false; + if (Creature* julliane = instance->GetCreature(DATA_JULIANNE)) { - if (Creature* Julianne = instance->GetCreature(DATA_JULIANNE)) - { - Resurrect(Julianne); - Julianne->AI()->DoAction(ACTION_PHASE_SET); - Julianne->AI()->DoAction(ACTION_DO_RESURRECT); - if (Julianne->GetVictim()) - { - AttackStart(Julianne->GetVictim()); - } - } - }); - } - - damage = 0; - return; + julliane->AI()->DoAction(ACTION_DO_RESURRECT); + } + }, 3s); } - if (phase == PHASE_BOTH) + if (phase == PHASE_BOTH && !isFakingDeath) { - if (julianneDead) - { - if (Creature* Julianne = instance->GetCreature(DATA_JULIANNE)) - { - _scheduler.CancelAll(); - _resurrectScheduler.CancelAll(); - Julianne->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - Julianne->GetMotionMaster()->Clear(); - Julianne->setDeathState(JUST_DIED); - Julianne->CombatStop(true); - Julianne->GetThreatMgr().ClearAllThreat(); - Julianne->ReplaceAllDynamicFlags(UNIT_DYNFLAG_LOOTABLE); - //this does not seem to really work - } - return; - } - - if (Creature* Julianne = instance->GetCreature(DATA_JULIANNE)) - { - PretendToDie(me); - isFakingDeath = true; - Julianne->AI()->DoAction(ACTION_EARLY_REVIVE); - _scheduler.Schedule(10050ms, [this](TaskContext) - { - Resurrect(me); - isFakingDeath = false; - }); - damage = 0; - return; - } + Talk(SAY_ROMULO_DEATH2); + PretendToDie(me); + instance->DoAction(ACTION_SCHEDULE_RAJ_CHECK); + isFakingDeath = true; } - //LOG_ERROR("scripts", "boss_romuloAI: DamageTaken reach end of code, that should not happen."); } void ScheduleCombat() @@ -1488,14 +1240,6 @@ struct boss_romulo : public ScriptedAI ScheduleCombat(); } - void MoveInLineOfSight(Unit* who) override - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::MoveInLineOfSight(who); - } - void EnterEvadeMode(EvadeReason reason) override { ScriptedAI::EnterEvadeMode(reason); @@ -1510,15 +1254,17 @@ struct boss_romulo : public ScriptedAI instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE); } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* victim) override { - Talk(SAY_ROMULO_SLAY); + if (victim != me) + { + Talk(SAY_ROMULO_SLAY); + } } void UpdateAI(uint32 diff) override { _scheduler.Update(diff); - _resurrectScheduler.Update(diff); if (!UpdateVictim()) { @@ -1531,8 +1277,10 @@ struct boss_romulo : public ScriptedAI } } private: + InstanceScript* instance; + uint32 phase; + bool isFakingDeath; TaskScheduler _scheduler; - TaskScheduler _resurrectScheduler; }; void AddSC_bosses_opera() diff --git a/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp index 6f4a47161b5402..a6dfff1c65d37e 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp @@ -44,6 +44,7 @@ ObjectData const creatureData[] = { NPC_ROMULO, DATA_ROMULO }, { NPC_JULIANNE, DATA_JULIANNE }, { NPC_NIGHTBANE, DATA_NIGHTBANE }, + { NPC_TERESTIAN_ILLHOOF, DATA_TERESTIAN }, { 0, 0 } }; @@ -122,6 +123,16 @@ class instance_karazhan : public InstanceMapScript case NPC_ECHO_OF_MEDIVH: _echoOfMedivhGUID = creature->GetGUID(); break; + case NPC_FIENDISH_IMP: + if (Creature* terestrian = GetCreature(DATA_TERESTIAN)) + { + if (terestrian->AI()) + { + terestrian->AI()->JustSummoned(creature); + creature->SetInCombatWithZone(); + } + } + break; default: break; } @@ -229,6 +240,9 @@ class instance_karazhan : public InstanceMapScript } } break; + case DONE: + HandleGameObject(m_uiGamesmansExitDoor, true); + break; } default: DoRemoveAurasDueToSpellOnPlayers(SPELL_GAME_IN_SESSION); @@ -360,9 +374,9 @@ class instance_karazhan : public InstanceMapScript case GO_SIDE_ENTRANCE_DOOR: m_uiSideEntranceDoor = go->GetGUID(); if (GetBossState(DATA_OPERA_PERFORMANCE) == DONE) - go->SetGameObjectFlag(GO_FLAG_LOCKED); - else go->RemoveGameObjectFlag(GO_FLAG_LOCKED); + else + go->SetGameObjectFlag(GO_FLAG_LOCKED); break; case GO_DUST_COVERED_CHEST: DustCoveredChest = go->GetGUID(); @@ -407,6 +421,42 @@ class instance_karazhan : public InstanceMapScript return 0; } + void DoAction(int32 actionId) override + { + if (actionId == ACTION_SCHEDULE_RAJ_CHECK) + { + scheduler.Schedule(10s, [this](TaskContext) + { + Creature* julliane = GetCreature(DATA_JULIANNE); + Creature* romulo = GetCreature(DATA_ROMULO); + + if (julliane && romulo) + { + if (julliane->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) + && romulo->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + julliane->KillSelf(); + julliane->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + romulo->KillSelf(); + romulo->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + } + else + { + if (romulo->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + julliane->AI()->DoAction(ACTION_RESS_ROMULO); + } + + if (julliane->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + julliane->AI()->DoAction(ACTION_DO_RESURRECT); + } + } + } + }); + } + } + ObjectGuid GetGuidData(uint32 data) const override { switch (data) diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h index 25a7fec00a8a84..7dbdbdb91d3035 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h @@ -117,6 +117,7 @@ enum KZCreatures NPC_ROAR = 17546, NPC_STRAWMAN = 17543, NPC_TINHEAD = 17547, + NPC_FIENDISH_IMP = 17267, // Chess Event NPC_ECHO_OF_MEDIVH = 16816, @@ -203,6 +204,14 @@ enum KarazhanChessGameFactions CHESS_FACTION_BOTH = 536 }; +enum InstanceActions +{ + ACTION_SCHEDULE_RAJ_CHECK, + + ACTION_DO_RESURRECT = 4, + ACTION_RESS_ROMULO = 5, +}; + template inline AI* GetKarazhanAI(T* obj) { diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index 333ef040fc1798..182b4588b4d7dd 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -105,7 +105,7 @@ class boss_felblood_kaelthas : public CreatureScript events.Reset(); summons.DespawnAll(); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); - instance->SetData(DATA_KAELTHAS_EVENT, NOT_STARTED); + instance->SetBossState(DATA_KAELTHAS, NOT_STARTED); me->SetImmuneToAll(false); } @@ -125,12 +125,17 @@ class boss_felblood_kaelthas : public CreatureScript void JustDied(Unit*) override { - instance->SetData(DATA_KAELTHAS_EVENT, DONE); + instance->SetBossState(DATA_KAELTHAS, DONE); + + if (GameObject* orb = instance->GetGameObject(DATA_ESCAPE_ORB)) + { + orb->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); + } } void JustEngagedWith(Unit* /*who*/) override { - instance->SetData(DATA_KAELTHAS_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_KAELTHAS, IN_PROGRESS); me->SetInCombatWithZone(); events.ScheduleEvent(EVENT_SPELL_FIREBALL, 0); diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp index f15de20a89f624..f47af976e77176 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp @@ -105,7 +105,7 @@ class boss_priestess_delrissa : public CreatureScript { PlayersKilled = SAY_PLAYER_KILLED; HelpersKilled = SAY_HELPER_DIED; - instance->SetData(DATA_DELRISSA_EVENT, NOT_STARTED); + instance->SetBossState(DATA_DELRISSA, NOT_STARTED); summons.Respawn(); me->SetLootMode(0); @@ -141,7 +141,7 @@ class boss_priestess_delrissa : public CreatureScript { me->loot.clear(); me->loot.FillLoot(me->GetCreatureTemplate()->lootid, LootTemplates_Creature, me->GetLootRecipient(), false, false, 1, me); - instance->SetData(DATA_DELRISSA_EVENT, DONE); + instance->SetBossState(DATA_DELRISSA, DONE); me->SetDynamicFlag(UNIT_DYNFLAG_LOOTABLE); } ++HelpersKilled; @@ -151,7 +151,7 @@ class boss_priestess_delrissa : public CreatureScript { Talk(SAY_AGGRO); summons.DoZoneInCombat(); - instance->SetData(DATA_DELRISSA_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_DELRISSA, IN_PROGRESS); events.ScheduleEvent(EVENT_SPELL_FLASH_HEAL, 15000); events.ScheduleEvent(EVENT_SPELL_RENEW, 10000); @@ -177,7 +177,7 @@ class boss_priestess_delrissa : public CreatureScript Talk(SAY_DEATH); if (HelpersKilled == MAX_ACTIVE_HELPERS + 1) - instance->SetData(DATA_DELRISSA_EVENT, DONE); + instance->SetBossState(DATA_DELRISSA, DONE); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp index d14c9ff3e4e794..2c14c0fba4b7c0 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp @@ -106,7 +106,7 @@ class boss_selin_fireheart : public CreatureScript events.Reset(); summons.DespawnAll(); SpawnCrystals(); - instance->SetData(DATA_SELIN_EVENT, NOT_STARTED); + instance->SetBossState(DATA_SELIN_FIREHEART, NOT_STARTED); CrystalGUID.Clear(); me->SetPower(POWER_MANA, 0); } @@ -114,7 +114,7 @@ class boss_selin_fireheart : public CreatureScript void JustEngagedWith(Unit* /*who*/) override { Talk(SAY_AGGRO); - instance->SetData(DATA_SELIN_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_SELIN_FIREHEART, IN_PROGRESS); events.ScheduleEvent(EVENT_SPELL_DRAIN_LIFE, 2500, 1); events.ScheduleEvent(EVENT_SPELL_FEL_EXPLOSION, 2000); @@ -134,7 +134,7 @@ class boss_selin_fireheart : public CreatureScript { Talk(SAY_DEATH); - instance->SetData(DATA_SELIN_EVENT, DONE); // Encounter complete! + instance->SetBossState(DATA_SELIN_FIREHEART, DONE); // Encounter complete! summons.DespawnAll(); } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp index 574afed7d025f6..f550b955447689 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp @@ -87,7 +87,7 @@ class boss_vexallus : public CreatureScript summons.DespawnAll(); IntervalHealthAmount = 1; - instance->SetData(DATA_VEXALLUS_EVENT, NOT_STARTED); + instance->SetBossState(DATA_VEXALLUS, NOT_STARTED); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ENERGY_FEEDBACK); } @@ -100,14 +100,14 @@ class boss_vexallus : public CreatureScript void JustDied(Unit* /*killer*/) override { summons.DespawnAll(); - instance->SetData(DATA_VEXALLUS_EVENT, DONE); + instance->SetBossState(DATA_VEXALLUS, DONE); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ENERGY_FEEDBACK); } void JustEngagedWith(Unit* /*who*/) override { Talk(SAY_AGGRO); - instance->SetData(DATA_VEXALLUS_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_VEXALLUS, IN_PROGRESS); events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 8000); events.ScheduleEvent(EVENT_SPELL_ARCANE_SHOCK, 5000); diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp index 7f812f34ccfb5b..bf73f90954c855 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp @@ -16,9 +16,33 @@ */ #include "InstanceScript.h" +#include "ScriptedCreature.h" #include "ScriptMgr.h" #include "magisters_terrace.h" +ObjectData const creatureData[] = +{ + { NPC_KALECGOS, DATA_KALECGOS }, + { 0, 0 } +}; + +ObjectData const gameobjectData[] = +{ + { GO_ESCAPE_ORB, DATA_ESCAPE_ORB }, + { 0, 0, } +}; + +DoorData const doorData[] = +{ + { GO_SELIN_DOOR, DATA_SELIN_FIREHEART, DOOR_TYPE_PASSAGE }, + { GO_SELIN_ENCOUNTER_DOOR, DATA_SELIN_FIREHEART, DOOR_TYPE_ROOM }, + { GO_VEXALLUS_DOOR, DATA_VEXALLUS, DOOR_TYPE_PASSAGE }, + { GO_DELRISSA_DOOR, DATA_DELRISSA, DOOR_TYPE_PASSAGE }, + { 0, 0, DOOR_TYPE_ROOM } // END +}; + +Position const KalecgosSpawnPos = { 164.3747f, -397.1197f, 2.151798f, 1.66219f }; + class instance_magisters_terrace : public InstanceMapScript { public: @@ -29,75 +53,32 @@ class instance_magisters_terrace : public InstanceMapScript instance_magisters_terrace_InstanceMapScript(Map* map) : InstanceScript(map) { SetHeaders(DataHeader); + SetBossNumber(MAX_ENCOUNTER); + LoadObjectData(creatureData, gameobjectData); + LoadDoorData(doorData); } - uint32 Encounter[MAX_ENCOUNTER]; - - ObjectGuid VexallusDoorGUID; - ObjectGuid SelinDoorGUID; - ObjectGuid SelinEncounterDoorGUID; - ObjectGuid DelrissaDoorGUID; - ObjectGuid KaelDoorGUID; ObjectGuid EscapeOrbGUID; ObjectGuid DelrissaGUID; ObjectGuid KaelGUID; - void Initialize() override - { - memset(&Encounter, 0, sizeof(Encounter)); - } - - bool IsEncounterInProgress() const override - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (Encounter[i] == IN_PROGRESS) - return true; - return false; - } - - uint32 GetData(uint32 identifier) const override - { - switch (identifier) - { - case DATA_SELIN_EVENT: - case DATA_VEXALLUS_EVENT: - case DATA_DELRISSA_EVENT: - case DATA_KAELTHAS_EVENT: - return Encounter[identifier]; - } - return 0; - } - - void SetData(uint32 identifier, uint32 data) override + void ProcessEvent(WorldObject* /*obj*/, uint32 eventId) override { - switch (identifier) + if (eventId == EVENT_SPAWN_KALECGOS) { - case DATA_SELIN_EVENT: - HandleGameObject(SelinDoorGUID, data == DONE); - HandleGameObject(SelinEncounterDoorGUID, data != IN_PROGRESS); - Encounter[identifier] = data; - break; - case DATA_VEXALLUS_EVENT: - if (data == DONE) - HandleGameObject(VexallusDoorGUID, true); - Encounter[identifier] = data; - break; - case DATA_DELRISSA_EVENT: - if (data == DONE) - HandleGameObject(DelrissaDoorGUID, true); - Encounter[identifier] = data; - break; - case DATA_KAELTHAS_EVENT: - HandleGameObject(KaelDoorGUID, data != IN_PROGRESS); - if (data == DONE) - if (GameObject* escapeOrb = instance->GetGameObject(EscapeOrbGUID)) - escapeOrb->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - Encounter[identifier] = data; - break; + if (!GetCreature(DATA_KALECGOS) && !scheduler.IsGroupScheduled(DATA_KALECGOS)) + { + scheduler.Schedule(1min, 1min, DATA_KALECGOS,[this](TaskContext) + { + if (Creature* kalecgos = instance->SummonCreature(NPC_KALECGOS, KalecgosSpawnPos)) + { + kalecgos->GetMotionMaster()->MovePath(PATH_KALECGOS_FLIGHT, false); + kalecgos->AI()->Talk(SAY_KALECGOS_SPAWN); + } + }); + } } - - SaveToDB(); } void OnCreatureCreate(Creature* creature) override @@ -116,62 +97,15 @@ class instance_magisters_terrace : public InstanceMapScript kael->AI()->JustSummoned(creature); break; } - } - void OnGameObjectCreate(GameObject* go) override - { - switch (go->GetEntry()) - { - case GO_SELIN_DOOR: - if (GetData(DATA_SELIN_EVENT) == DONE) - HandleGameObject(ObjectGuid::Empty, true, go); - SelinDoorGUID = go->GetGUID(); - break; - case GO_SELIN_ENCOUNTER_DOOR: - SelinEncounterDoorGUID = go->GetGUID(); - break; - - case GO_VEXALLUS_DOOR: - if (GetData(DATA_VEXALLUS_EVENT) == DONE) - HandleGameObject(ObjectGuid::Empty, true, go); - VexallusDoorGUID = go->GetGUID(); - break; - - case GO_DELRISSA_DOOR: - if (GetData(DATA_DELRISSA_EVENT) == DONE) - HandleGameObject(ObjectGuid::Empty, true, go); - DelrissaDoorGUID = go->GetGUID(); - break; - case GO_KAEL_DOOR: - KaelDoorGUID = go->GetGUID(); - break; - case GO_ESCAPE_ORB: - if (GetData(DATA_KAELTHAS_EVENT) == DONE) - go->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - EscapeOrbGUID = go->GetGUID(); - break; - } - } - - // @todo: Use BossStates. This is for code compatibility - void ReadSaveDataMore(std::istringstream& data) override - { - data >> Encounter[1]; - data >> Encounter[2]; - data >> Encounter[3]; - } - - void WriteSaveDataMore(std::ostringstream& data) override - { - data << Encounter[0] << ' ' << Encounter[1] << ' ' << Encounter[2] << ' ' << Encounter[3]; + InstanceScript::OnCreatureCreate(creature); } ObjectGuid GetGuidData(uint32 identifier) const override { - switch (identifier) + if (identifier == NPC_DELRISSA) { - case NPC_DELRISSA: - return DelrissaGUID; + return DelrissaGUID; } return ObjectGuid::Empty; @@ -184,7 +118,53 @@ class instance_magisters_terrace : public InstanceMapScript } }; +enum Spells +{ + SPELL_KALECGOS_TRANSFORM = 44670, + SPELL_TRANSFORM_VISUAL = 24085, + SPELL_CAMERA_SHAKE = 44762, + SPELL_ORB_KILL_CREDIT = 46307 +}; + +enum MovementPoints +{ + POINT_ID_PREPARE_LANDING = 6 +}; + +struct npc_kalecgos : public ScriptedAI +{ + npc_kalecgos(Creature* creature) : ScriptedAI(creature) { } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != WAYPOINT_MOTION_TYPE) + return; + + if (pointId == POINT_ID_PREPARE_LANDING) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + me->SetDisableGravity(false); + me->SetHover(false); + + me->m_Events.AddEventAtOffset([this]() + { + DoCastAOE(SPELL_CAMERA_SHAKE); + me->SetObjectScale(0.6f); + + me->m_Events.AddEventAtOffset([this]() + { + DoCastSelf(SPELL_ORB_KILL_CREDIT, true); + DoCastSelf(SPELL_TRANSFORM_VISUAL); + DoCastSelf(SPELL_KALECGOS_TRANSFORM); + me->UpdateEntry(NPC_HUMAN_KALECGOS); + }, 1s); + }, 2s); + } + } +}; + void AddSC_instance_magisters_terrace() { new instance_magisters_terrace(); + RegisterMagistersTerraceCreatureAI(npc_kalecgos); } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h index 20bb86b22a6640..e985711ac913f4 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h @@ -28,11 +28,14 @@ enum MTData { - DATA_SELIN_EVENT = 0, - DATA_VEXALLUS_EVENT = 1, - DATA_DELRISSA_EVENT = 2, - DATA_KAELTHAS_EVENT = 3, - MAX_ENCOUNTER = 4 + DATA_SELIN_FIREHEART = 0, + DATA_VEXALLUS = 1, + DATA_DELRISSA = 2, + DATA_KAELTHAS = 3, + MAX_ENCOUNTER = 4, + + DATA_KALECGOS = 5, + DATA_ESCAPE_ORB = 6 }; enum MTCreatures @@ -41,7 +44,9 @@ enum MTCreatures NPC_FEL_CRYSTAL = 24722, NPC_KAEL_THAS = 24664, NPC_PHOENIX = 21362, - NPC_PHOENIX_EGG = 21364 + NPC_PHOENIX_EGG = 21364, + NPC_KALECGOS = 24844, + NPC_HUMAN_KALECGOS = 24848 }; enum MTGameObjects @@ -54,10 +59,27 @@ enum MTGameObjects GO_ESCAPE_ORB = 188173 }; +enum InstanceEventIds +{ + EVENT_SPAWN_KALECGOS = 16547 +}; + +enum InstanceText +{ + SAY_KALECGOS_SPAWN = 0 +}; + +enum MovementData +{ + PATH_KALECGOS_FLIGHT = 248440 +}; + template inline AI* GetMagistersTerraceAI(T* obj) { return GetInstanceAI(obj, MTScriptName); } +#define RegisterMagistersTerraceCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetMagistersTerraceAI) + #endif diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp index d0024de85ee426..65b8c64f16cb81 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp @@ -695,106 +695,6 @@ class npc_fairbanks : public CreatureScript public: npc_fairbanks() : CreatureScript("npc_fairbanks") { } - bool OnGossipHello(Player* player, Creature* creature) override - { - AddGossipItemFor(player, 0, "Curse? What's going on here, Fairbanks?", GOSSIP_SENDER_MAIN, 1); - SendGossipMenuFor(player, 100100, creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*Sender*/, uint32 uiAction) override - { - ClearGossipMenuFor(player); - - switch (uiAction) - { - case 1: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "Mograine?", GOSSIP_SENDER_MAIN, 2); - SendGossipMenuFor(player, 100101, creature->GetGUID()); - return true; - case 2: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "What do you mean?", GOSSIP_SENDER_MAIN, 3); - SendGossipMenuFor(player, 100102, creature->GetGUID()); - return true; - case 3: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "I still do not fully understand.", GOSSIP_SENDER_MAIN, 4); - SendGossipMenuFor(player, 100103, creature->GetGUID()); - return true; - case 4: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "Incredible story. So how did he die?", GOSSIP_SENDER_MAIN, 5); - SendGossipMenuFor(player, 100104, creature->GetGUID()); - return true; - case 5: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "You mean...", GOSSIP_SENDER_MAIN, 6); - SendGossipMenuFor(player, 100105, creature->GetGUID()); - return true; - case 6: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "How do you know all of this?", GOSSIP_SENDER_MAIN, 7); - SendGossipMenuFor(player, 100106, creature->GetGUID()); - return true; - case 7: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "A thousand? For one man?", GOSSIP_SENDER_MAIN, 8); - SendGossipMenuFor(player, 100107, creature->GetGUID()); - return true; - case 8: - creature->HandleEmoteCommand(5); - AddGossipItemFor(player, 0, "Yet? Yet what?", GOSSIP_SENDER_MAIN, 9); - SendGossipMenuFor(player, 100108, creature->GetGUID()); - return true; - case 9: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "And did he?", GOSSIP_SENDER_MAIN, 10); - SendGossipMenuFor(player, 100109, creature->GetGUID()); - return true; - case 10: - creature->HandleEmoteCommand(274); - AddGossipItemFor(player, 0, "Continue please, Fairbanks.", GOSSIP_SENDER_MAIN, 11); - SendGossipMenuFor(player, 100110, creature->GetGUID()); - return true; - case 11: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "You mean...", GOSSIP_SENDER_MAIN, 12); - SendGossipMenuFor(player, 100111, creature->GetGUID()); - return true; - case 12: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "You were right, Fairbanks. That is tragic.", GOSSIP_SENDER_MAIN, 13); - SendGossipMenuFor(player, 100112, creature->GetGUID()); - return true; - case 13: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "And you did...", GOSSIP_SENDER_MAIN, 14); - SendGossipMenuFor(player, 100113, creature->GetGUID()); - return true; - case 14: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "You tell an incredible tale, Fairbanks. What of the blade? Is it beyond redemption?", GOSSIP_SENDER_MAIN, 15); - SendGossipMenuFor(player, 100114, creature->GetGUID()); - return true; - case 15: - creature->HandleEmoteCommand(1); - AddGossipItemFor(player, 0, "But his son is dead.", GOSSIP_SENDER_MAIN, 16); - SendGossipMenuFor(player, 100115, creature->GetGUID()); - return true; - case 16: - SendGossipMenuFor(player, 100116, creature->GetGUID()); - /// @todo: we need to play these 3 emote in sequence, we play only the last one right now. - creature->HandleEmoteCommand(274); - creature->HandleEmoteCommand(1); - creature->HandleEmoteCommand(397); - return true; - } - - return true; - } - struct npc_fairbanksAI : public SmartAI { npc_fairbanksAI(Creature* creature) : SmartAI(creature) { } @@ -812,7 +712,6 @@ class npc_fairbanks : public CreatureScript { me->SetFaction(FACTION_FRIENDLY); me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); - me->SetSheath(SHEATH_STATE_UNARMED); me->CastSpell(me, 57767, true); me->SetDisplayId(16179); me->SetFacingToObject(player); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp index 12ebadca618a49..af90c050c1504a 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp @@ -289,9 +289,6 @@ class boss_hexlord_malacrass : public CreatureScript ResetTimer = 5000; SpawnAdds(); - - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 46916); - me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); } void JustEngagedWith(Unit* /*who*/) override diff --git a/src/server/scripts/Events/brewfest.cpp b/src/server/scripts/Events/brewfest.cpp index badf22dd90f942..b202673cd96b12 100644 --- a/src/server/scripts/Events/brewfest.cpp +++ b/src/server/scripts/Events/brewfest.cpp @@ -1031,35 +1031,32 @@ class spell_brewfest_apple_trap : public SpellScript } }; -class spell_q11117_catch_the_wild_wolpertinger : public SpellScript +enum Catch { - PrepareSpellScript(spell_q11117_catch_the_wild_wolpertinger); + NPC_WILD_WOLPERTINGER = 23487, - SpellCastResult CheckTarget() - { - if (Unit* caster = GetCaster()) - if (caster->ToPlayer()) - if (Unit* target = caster->ToPlayer()->GetSelectedUnit()) - if (target->GetEntry() == 23487 && target->IsAlive()) - return SPELL_CAST_OK; + ITEM_STUNNED_WOLPERTINGER = 32906 +}; - return SPELL_FAILED_BAD_TARGETS; - } +class spell_catch_the_wild_wolpertinger : public AuraScript +{ + PrepareAuraScript(spell_catch_the_wild_wolpertinger); - void HandleDummyEffect(SpellEffIndex /*effIndex*/) + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (GetCaster() && GetCaster()->ToPlayer()) + if (Creature* wild = GetTarget()->ToCreature()) { - GetCaster()->ToPlayer()->AddItem(32906, 1); - if (Unit* target = GetCaster()->ToPlayer()->GetSelectedUnit()) - target->ToCreature()->DespawnOrUnsummon(500); + if (wild->GetEntry() == NPC_WILD_WOLPERTINGER) + { + wild->ToCreature()->DespawnOrUnsummon(1s, 0s); + GetCaster()->ToPlayer()->AddItem(ITEM_STUNNED_WOLPERTINGER, 1); + } } } void Register() override { - OnCheckCast += SpellCheckCastFn(spell_q11117_catch_the_wild_wolpertinger::CheckTarget); - OnEffectHitTarget += SpellEffectFn(spell_q11117_catch_the_wild_wolpertinger::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectApply += AuraEffectApplyFn(spell_catch_the_wild_wolpertinger::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL); } }; @@ -2072,7 +2069,7 @@ void AddSC_event_brewfest_scripts() RegisterSpellScript(spell_brewfest_ram_fatigue); RegisterSpellScript(spell_brewfest_apple_trap); // other - RegisterSpellScript(spell_q11117_catch_the_wild_wolpertinger); + RegisterSpellScript(spell_catch_the_wild_wolpertinger); RegisterSpellScript(spell_brewfest_fill_keg); RegisterSpellScript(spell_brewfest_unfill_keg); RegisterSpellScript(spell_brewfest_toss_mug); diff --git a/src/server/scripts/Events/midsummer.cpp b/src/server/scripts/Events/midsummer.cpp index a7b7d5ad708f68..998a6211b17b9d 100644 --- a/src/server/scripts/Events/midsummer.cpp +++ b/src/server/scripts/Events/midsummer.cpp @@ -46,6 +46,19 @@ class go_midsummer_bonfire : public GameObjectScript } }; +enum torchToss +{ + GO_TORCH_TARGET_BRAZIER = 187708, + NPC_TORCH_TOSS_TARGET_BUNNY = 25535, + + SPELL_TARGET_INDICATOR_RANK_1 = 43313, + SPELL_TORCH_TOSS_LAND = 46054, + SPELL_BRAZIERS_HIT_VISUAL = 45724, + SPELL_TORCH_TOSS_SUCCESS_A = 45719, + SPELL_TORCH_TOSS_SUCCESS_H = 46651, + SPELL_TORCH_TOSS_TRAINING = 45716, +}; + struct npc_midsummer_torch_target : public ScriptedAI { npc_midsummer_torch_target(Creature* creature) : ScriptedAI(creature) @@ -54,7 +67,7 @@ struct npc_midsummer_torch_target : public ScriptedAI startTimer = 1; posVec.clear(); playerGUID.Clear(); - me->CastSpell(me, 43313, true); + me->CastSpell(me, SPELL_TARGET_INDICATOR_RANK_1, true); counter = 0; maxCount = 0; } @@ -82,12 +95,12 @@ struct npc_midsummer_torch_target : public ScriptedAI if (posVec.empty()) return; // Triggered spell from torch - if (spellInfo->Id == 46054 && caster->GetTypeId() == TYPEID_PLAYER) + if (spellInfo->Id == SPELL_TORCH_TOSS_LAND && caster->GetTypeId() == TYPEID_PLAYER) { - me->CastSpell(me, 45724, true); // hit visual anim + me->CastSpell(me, SPELL_BRAZIERS_HIT_VISUAL, true); // hit visual anim if (++counter >= maxCount) { - caster->CastSpell(caster, (caster->ToPlayer()->GetTeamId() ? 46651 : 45719), true); // quest complete spell + caster->CastSpell(caster, (caster->ToPlayer()->GetTeamId() ? SPELL_TORCH_TOSS_SUCCESS_H : SPELL_TORCH_TOSS_SUCCESS_A), true); // quest complete spell me->DespawnOrUnsummon(1); return; } @@ -129,7 +142,7 @@ struct npc_midsummer_torch_target : public ScriptedAI void FillPositions() { std::list gobjList; - me->GetGameObjectListWithEntryInGrid(gobjList, 187708 /*TORCH_GO*/, 30.0f); + me->GetGameObjectListWithEntryInGrid(gobjList, GO_TORCH_TARGET_BRAZIER, 30.0f); for (std::list::const_iterator itr = gobjList.begin(); itr != gobjList.end(); ++itr) { Position pos; @@ -145,8 +158,6 @@ struct npc_midsummer_torch_target : public ScriptedAI int8 num = urand(0, posVec.size() - 1); Position pos; pos.Relocate(posVec.at(num)); - me->m_last_notify_position.Relocate(0.0f, 0.0f, 0.0f); - me->m_last_notify_mstime = GameTime::GetGameTimeMS().count() + 10000; me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); } @@ -169,7 +180,7 @@ class spell_gen_crab_disguise : public AuraScript bool Validate(SpellInfo const* /*spell*/) override { - return ValidateSpellInfo({ SPELL_CRAB_DISGUISE }); + return ValidateSpellInfo({ SPELL_APPLY_DIGUISE, SPELL_FADE_DIGUISE }); } void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) @@ -200,6 +211,10 @@ class spell_gen_crab_disguise : public AuraScript enum RibbonPole { SPELL_RIBBON_POLE_CHANNEL_VISUAL = 29172, + SPELL_RIBBON_POLE_CHANNEL_VISUAL_2 = 29531, + SPELL_TEST_RIBBON_POLE_CHANNEL_BLUE = 29705, + SPELL_TEST_RIBBON_POLE_CHANNEL_RED = 29726, + SPELL_TEST_RIBBON_POLE_CHANNEL_PINK = 29727, SPELL_RIBBON_POLE_XP = 29175, SPELL_RIBBON_POLE_FIREWORKS = 46971, @@ -210,6 +225,17 @@ class spell_midsummer_ribbon_pole : public AuraScript { PrepareAuraScript(spell_midsummer_ribbon_pole) + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo( + { + SPELL_RIBBON_POLE_XP, + SPELL_TEST_RIBBON_POLE_CHANNEL_BLUE, + SPELL_TEST_RIBBON_POLE_CHANNEL_RED, + SPELL_TEST_RIBBON_POLE_CHANNEL_PINK + }); + } + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) { PreventDefaultAction(); @@ -218,7 +244,9 @@ class spell_midsummer_ribbon_pole : public AuraScript Creature* cr = target->FindNearestCreature(NPC_RIBBON_POLE_DEBUG_TARGET, 10.0f); if (!cr) { - target->RemoveAura(SPELL_RIBBON_POLE_CHANNEL_VISUAL); + target->RemoveAura(SPELL_TEST_RIBBON_POLE_CHANNEL_BLUE); + target->RemoveAura(SPELL_TEST_RIBBON_POLE_CHANNEL_RED); + target->RemoveAura(SPELL_TEST_RIBBON_POLE_CHANNEL_PINK); SetDuration(1); return; } @@ -243,7 +271,19 @@ class spell_midsummer_ribbon_pole : public AuraScript void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* ar = GetTarget(); - ar->CastSpell(ar, SPELL_RIBBON_POLE_CHANNEL_VISUAL, true); + switch (urand(0, 2)) + { + case 0: + ar->CastSpell(ar, SPELL_TEST_RIBBON_POLE_CHANNEL_BLUE, true); + break; + case 1: + ar->CastSpell(ar, SPELL_TEST_RIBBON_POLE_CHANNEL_RED, true); + break; + case 2: + default: + ar->CastSpell(ar, SPELL_TEST_RIBBON_POLE_CHANNEL_PINK, true); + break; + } } void Register() override @@ -253,6 +293,39 @@ class spell_midsummer_ribbon_pole : public AuraScript } }; +class spell_midsummer_ribbon_pole_visual : public SpellScript +{ + PrepareSpellScript(spell_midsummer_ribbon_pole_visual) + + void UpdateTarget(WorldObject*& target) + { + if (!target) + return; + + // find NPC at ribbon pole top as target + // trap 181604 also spawns NPCs at pole bottom - ignore those + std::list crList; + target->GetCreaturesWithEntryInRange(crList, 30.0f, NPC_RIBBON_POLE_DEBUG_TARGET); + if (crList.empty()) + return; + + for (std::list::const_iterator itr = crList.begin(); itr != crList.end(); ++itr) + { + // NPC on ribbon pole top is no tempsummon + if (!(*itr)->ToTempSummon()) + { + target = *itr; + return; + } + } + } + + void Register() override + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_midsummer_ribbon_pole_visual::UpdateTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY); + } +}; + class spell_midsummer_torch_quest : public AuraScript { PrepareAuraScript(spell_midsummer_torch_quest) @@ -268,10 +341,10 @@ class spell_midsummer_torch_quest : public AuraScript void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* ar = GetTarget(); - if (Creature* cr = ar->SummonCreature(25535, ar->GetPositionX(), ar->GetPositionY(), ar->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 90000)) + if (Creature* cr = ar->SummonCreature(NPC_TORCH_TOSS_TARGET_BUNNY, ar->GetPositionX(), ar->GetPositionY(), ar->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 90000)) { torchGUID = cr->GetGUID(); - CAST_AI(npc_midsummer_torch_target, cr->AI())->SetPlayerGUID(ar->GetGUID(), (GetId() == 45716 ? 8 : 20)); + CAST_AI(npc_midsummer_torch_target, cr->AI())->SetPlayerGUID(ar->GetGUID(), (GetId() == SPELL_TORCH_TOSS_TRAINING ? 8 : 20)); } } @@ -296,12 +369,32 @@ enum flingTorch SPELL_FLING_TORCH_DUMMY = 46747, SPELL_MISSED_TORCH = 45676, SPELL_TORCH_COUNTER = 45693, + SPELL_TORCH_SHADOW = 46105, + SPELL_TORCH_CATCH_SUCCESS_A = 46081, + SPELL_TORCH_CATCH_SUCCESS_H = 46654, + SPELL_JUGGLE_TORCH = 45671, + + QUEST_MORE_TORCH_TOSS_A = 11924, + QUEST_MORE_TORCH_TOSS_H = 11925, }; class spell_midsummer_fling_torch : public SpellScript { PrepareSpellScript(spell_midsummer_fling_torch); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_FLING_TORCH, + SPELL_TORCH_SHADOW, + SPELL_MISSED_TORCH, + SPELL_TORCH_CATCH_SUCCESS_A, + SPELL_TORCH_CATCH_SUCCESS_H, + SPELL_TORCH_COUNTER + }); + } + bool handled; bool Load() override { handled = false; return true; } @@ -339,7 +432,10 @@ class spell_midsummer_fling_torch : public SpellScript // we have any pos if (pos.GetPositionX()) + { caster->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_FLING_TORCH, true); + caster->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_TORCH_SHADOW, true); + } } void HandleFinish() @@ -375,13 +471,13 @@ class spell_midsummer_fling_torch : public SpellScript { aur->ModStackAmount(1); uint8 count = 4; - if (target->GetQuestStatus(target->GetTeamId() ? 11925 : 11924) == QUEST_STATUS_INCOMPLETE) // More Torch Catching quests + if (target->GetQuestStatus(target->GetTeamId() ? QUEST_MORE_TORCH_TOSS_H : QUEST_MORE_TORCH_TOSS_A) == QUEST_STATUS_INCOMPLETE) // More Torch Catching quests count = 10; if (aur->GetStackAmount() >= count) { //target->CastSpell(target, 46711, true); // Set Flag: all torch returning quests are complete - target->CastSpell(target, (target->GetTeamId() ? 46654 : 46081), true); // Quest completion + target->CastSpell(target, (target->GetTeamId() ? SPELL_TORCH_CATCH_SUCCESS_H : SPELL_TORCH_CATCH_SUCCESS_A), true); // Quest completion aur->SetDuration(1); return; } @@ -396,7 +492,7 @@ class spell_midsummer_fling_torch : public SpellScript void Register() override { AfterCast += SpellCastFn(spell_midsummer_fling_torch::HandleFinish); - if (m_scriptSpellId == 45671) + if (m_scriptSpellId == SPELL_JUGGLE_TORCH) { OnCheckCast += SpellCheckCastFn(spell_midsummer_fling_torch::CheckCast); OnEffectHitTarget += SpellEffectFn(spell_midsummer_fling_torch::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); @@ -417,15 +513,33 @@ enum eJuggle SPELL_TORCH_CHECK = 45644, SPELL_GIVE_TORCH = 45280, QUEST_TORCH_CATCHING_A = 11657, - QUEST_TORCH_CATCHING_H = 11923 + QUEST_TORCH_CATCHING_H = 11923, + + SPELL_TORCH_SHADOW_SELF = 46121, + SPELL_TORCH_SHADOW_SLOW = 46120, + SPELL_TORCH_SHADOW_MED = 46118, + SPELL_TORCH_SHADOW_FAST = 46117 }; class spell_midsummer_juggling_torch : public SpellScript { PrepareSpellScript(spell_midsummer_juggling_torch); - bool handled; - bool Load() override { handled = false; return true; } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_JUGGLE_SELF, + SPELL_JUGGLE_SLOW, + SPELL_JUGGLE_MED, + SPELL_JUGGLE_FAST, + SPELL_TORCH_SHADOW_SELF, + SPELL_TORCH_SHADOW_SLOW, + SPELL_TORCH_SHADOW_MED, + SPELL_TORCH_SHADOW_FAST + }); + } + void HandleFinish() { Unit* caster = GetCaster(); @@ -435,39 +549,36 @@ class spell_midsummer_juggling_torch : public SpellScript if (const WorldLocation* loc = GetExplTargetDest()) { if (loc->GetExactDist(caster) < 3.0f) + { caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_SELF, true); + caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_SELF, true); + } else if (loc->GetExactDist(caster) < 10.0f) + { caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_SLOW, true); + caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_SLOW, true); + } else if (loc->GetExactDist(caster) < 25.0f) + { caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_MED, true); + caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_MED, true); + } else + { caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_FAST, true); + caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_FAST, true); + } } else + { caster->CastSpell(caster, SPELL_JUGGLE_SELF, true); - } - - void HandleDummy(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - Unit* caster = GetCaster(); - if (!caster || caster->GetTypeId() != TYPEID_PLAYER) - return; - - if (Player* target = GetHitPlayer()) - if (!handled && target->GetQuestRewardStatus(target->GetTeamId() == TEAM_ALLIANCE ? 11657 : 11923)) - { - handled = true; - caster->CastSpell(target, SPELL_GIVE_TORCH, true); - } + caster->CastSpell(caster, SPELL_TORCH_SHADOW_SELF, true); + } } void Register() override { - if (m_scriptSpellId == SPELL_TORCH_CHECK) - OnEffectHitTarget += SpellEffectFn(spell_midsummer_juggling_torch::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - else - AfterCast += SpellCastFn(spell_midsummer_juggling_torch::HandleFinish); + AfterCast += SpellCastFn(spell_midsummer_juggling_torch::HandleFinish); } }; @@ -510,6 +621,7 @@ void AddSC_event_midsummer_scripts() // Spells RegisterSpellScript(spell_gen_crab_disguise); RegisterSpellScript(spell_midsummer_ribbon_pole); + RegisterSpellScript(spell_midsummer_ribbon_pole_visual); RegisterSpellScript(spell_midsummer_torch_quest); RegisterSpellScript(spell_midsummer_fling_torch); RegisterSpellScript(spell_midsummer_juggling_torch); diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp index b575abeb33275e..bd6ce0bf797ae5 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp @@ -154,8 +154,8 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript switch (type) { case DATA_RAJAXX_WAVE_ENGAGED: - _scheduler.CancelGroup(GROUP_RAJAXX_WAVE_TIMER); - _scheduler.Schedule(2min, [this](TaskContext context) + scheduler.CancelGroup(GROUP_RAJAXX_WAVE_TIMER); + scheduler.Schedule(2min, [this](TaskContext context) { CallNextRajaxxLeader(); context.SetGroup(GROUP_RAJAXX_WAVE_TIMER); @@ -195,8 +195,8 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript case NPC_YEGGETH: case NPC_PAKKON: case NPC_ZERRAN: - _scheduler.CancelAll(); - _scheduler.Schedule(1s, [this, formation](TaskContext /*context*/) + scheduler.CancelAll(); + scheduler.Schedule(1s, [this, formation](TaskContext /*context*/) { if (!formation->IsAnyMemberAlive()) { @@ -212,11 +212,6 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript } } - void Update(uint32 diff) override - { - _scheduler.Update(diff); - } - void SetGuidData(uint32 type, ObjectGuid data) override { if (type == DATA_PARALYZED) @@ -285,7 +280,7 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript void ResetRajaxxWaves() { _rajaxWaveCounter = 0; - _scheduler.CancelAll(); + scheduler.CancelAll(); for (auto const& data : RajaxxWavesData) { if (Creature* creature = GetCreature(data.at(0))) @@ -308,7 +303,6 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript ObjectGuid _andorovGUID; uint32 _rajaxWaveCounter; uint8 _buruPhase; - TaskScheduler _scheduler; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/instance_temple_of_ahnqiraj.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/instance_temple_of_ahnqiraj.cpp index 1909fe48acce80..daa2c2e4ef7140 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/instance_temple_of_ahnqiraj.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/instance_temple_of_ahnqiraj.cpp @@ -210,15 +210,9 @@ class instance_temple_of_ahnqiraj : public InstanceMapScript return true; } - void Update(uint32 diff) override - { - scheduler.Update(diff); - } - private: GuidVector CThunGraspGUIDs; uint32 BugTrioDeathCount; - TaskScheduler scheduler; }; }; diff --git a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp index 1689944cf54e64..80862401e5c6af 100644 --- a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp +++ b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp @@ -1,7 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. - * Copyright (C) 2008-2016 TrinityCore - * Copyright (C) 2005-2009 MaNGOS + * 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 diff --git a/src/server/scripts/Kalimdor/zone_darkshore.cpp b/src/server/scripts/Kalimdor/zone_darkshore.cpp index 768eb3b5164045..3e048e3c99a614 100644 --- a/src/server/scripts/Kalimdor/zone_darkshore.cpp +++ b/src/server/scripts/Kalimdor/zone_darkshore.cpp @@ -175,6 +175,7 @@ enum Kerlonian SPELL_SLEEP_VISUAL = 25148, SPELL_AWAKEN = 17536, + SPELL_BEAR_FORM = 18309, QUEST_SLEEPER_AWAKENED = 5321, NPC_LILADRIS = 11219 //attackers entries unknown }; @@ -194,6 +195,8 @@ class npc_kerlonian : public CreatureScript void Reset() override { FallAsleepTimer = urand(10000, 45000); + + DoCastSelf(SPELL_BEAR_FORM); } void MoveInLineOfSight(Unit* who) override diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp index c722ce8243819b..79ba973bd87bca 100644 --- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp +++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp @@ -15,99 +15,12 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Dustwallow_Marsh -SD%Complete: 95 -SDComment: Quest support: 11180, 11126, 11174 -SDCategory: Dustwallow Marsh -EndScriptData */ - -/* ContentData -npc_cassa_crimsonwing - handled by npc_taxi -EndContentData */ - #include "Player.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" #include "SpellScript.h" -/*###### -## npc_zelfrax -######*/ - -Position const MovePosition = {-2967.030f, -3872.1799f, 35.620f, 0.0f}; - -enum Zelfrax -{ - SAY_ZELFRAX1 = 0, - SAY_ZELFRAX2 = 1 -}; - -class npc_zelfrax : public CreatureScript -{ -public: - npc_zelfrax() : CreatureScript("npc_zelfrax") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_zelfraxAI(creature); - } - - struct npc_zelfraxAI : public ScriptedAI - { - npc_zelfraxAI(Creature* creature) : ScriptedAI(creature) - { - MoveToDock(); - } - - void AttackStart(Unit* who) override - { - if (!who) - return; - - if (me->Attack(who, true)) - { - me->SetInCombatWith(who); - who->SetInCombatWith(me); - - if (IsCombatMovementAllowed()) - me->GetMotionMaster()->MoveChase(who); - } - } - - void MovementInform(uint32 Type, uint32 /*Id*/) override - { - if (Type != POINT_MOTION_TYPE) - return; - - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - me->SetImmuneToPC(false); - SetCombatMovement(true); - - if (me->IsInCombat()) - if (Unit* unit = me->GetVictim()) - me->GetMotionMaster()->MoveChase(unit); - } - - void MoveToDock() - { - SetCombatMovement(false); - me->GetMotionMaster()->MovePoint(0, MovePosition); - Talk(SAY_ZELFRAX1); - Talk(SAY_ZELFRAX2); - } - - void UpdateAI(uint32 /*Diff*/) override - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - enum SpellScripts { SPELL_OOZE_ZAP = 42489, @@ -243,7 +156,6 @@ class spell_energize_aoe : public SpellScriptLoader void AddSC_dustwallow_marsh() { - new npc_zelfrax(); new spell_ooze_zap(); new spell_ooze_zap_channel_end(); new spell_energize_aoe(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index f187c85a500746..86fc029040ea70 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -366,6 +366,9 @@ class boss_algalon_the_observer : public CreatureScript return; } + if (m_pInstance) + m_pInstance->SetData(TYPE_ALGALON, FAIL); + ScriptedAI::EnterEvadeMode(why); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 52a25f4382e6da..df114d77d7c954 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -786,6 +786,18 @@ class instance_ulduar : public InstanceMapScript go->SetGoState(data == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY); go->EnableCollision(false); } + + if (data == FAIL) + { + scheduler.Schedule(5s, [this](TaskContext) + { + if (m_algalonTimer && (m_algalonTimer <= 60 || m_algalonTimer == TIMER_ALGALON_TO_SUMMON)) + { + instance->SummonCreature(NPC_ALGALON, AlgalonLandPos); + } + }); + } + break; // Achievement @@ -1109,6 +1121,8 @@ class instance_ulduar : public InstanceMapScript void Update(uint32 diff) override { + InstanceScript::Update(diff); + if (_events.Empty()) return; diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp index c13ec226efc722..fe184a9c7b1e50 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp @@ -83,13 +83,13 @@ struct boss_anzu : public BossAI uint32 talkTimer; - void SummonedCreatureDies(Creature* summon, Unit*) override + void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override { if (summon->GetEntry() == NPC_BROOD_OF_ANZU) { summons.Despawn(summon); summons.RemoveNotExisting(); - if (summons.empty()) + if (!summons.HasEntry(NPC_BROOD_OF_ANZU)) { me->RemoveAurasDueToSpell(SPELL_BANISH_SELF); } diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp index ef979b2c9296d9..832a11dcf6419e 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp @@ -18,6 +18,7 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "serpent_shrine.h" +#include "TaskScheduler.h" enum Talk { @@ -32,26 +33,41 @@ enum Talk enum Spells { + //Fathomlord Karathress SPELL_CATACLYSMIC_BOLT = 38441, SPELL_SEAR_NOVA = 38445, SPELL_ENRAGE = 24318, - SPELL_BLESSING_OF_THE_TIDES = 38449 + SPELL_BLESSING_OF_THE_TIDES = 38449, + //Fathomguard Sharkkis + SPELL_HURL_TRIDENT = 38374, + SPELL_LEECHING_THROW = 29436, + SPELL_MULTI_TOSS = 38366, + SPELL_SUMMON_FATHOM_SPOREBAT = 38431, + SPELL_SUMMON_FATHOM_LURKER = 38433, + SPELL_THE_BEAST_WITHIN = 38373, + SPELL_BESTIAL_WRATH = 38371, + SPELL_POWER_OF_SHARKKIS = 38455, + //Fathomguard Tidalvess + SPELL_FROST_SHOCK = 38234, + SPELL_EARTHBIND_TOTEM = 38304, + SPELL_POISON_CLEANSING_TOTEM = 38306, + SPELL_SPITFIRE_TOTEM = 38236, + SPELL_POWER_OF_TIDALVESS = 38452, + //Fathomguard Caribdis + SPELL_SUMMON_CYCLONE = 38337, + SPELL_WATER_BOLT_VOLLEY = 38335, + SPELL_TIDAL_SURGE = 38358, + SPELL_HEALING_WAVE = 38330, + SPELL_POWER_OF_CARIBDIS = 38451, + //Spitfire Totem + SPELL_ATTACK = 38296 }; enum Misc { MAX_ADVISORS = 3, - NPC_FATHOM_GUARD_CARIBDIS = 21964, - NPC_FATHOM_GUARD_TIDALVESS = 21965, - NPC_FATHOM_GUARD_SHARKKIS = 21966, NPC_SEER_OLUM = 22820, GO_CAGE = 185952, - - EVENT_SPELL_CATACLYSMIC_BOLT = 1, - EVENT_SPELL_ENRAGE = 2, - EVENT_SPELL_SEAR_NOVA = 3, - EVENT_HEALTH_CHECK = 4, - EVENT_KILL_TALK = 5 }; const Position advisorsPosition[MAX_ADVISORS + 2] = @@ -63,124 +79,463 @@ const Position advisorsPosition[MAX_ADVISORS + 2] = {457.37f, -544.71f, -7.54f, 0.00f} }; -class boss_fathomlord_karathress : public CreatureScript +struct boss_fathomlord_karathress : public BossAI { -public: - boss_fathomlord_karathress() : CreatureScript("boss_fathomlord_karathress") { } + boss_fathomlord_karathress(Creature* creature) : BossAI(creature, DATA_FATHOM_LORD_KARATHRESS) + { + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetSerpentShrineAI(creature); + BossAI::Reset(); + _recentlySpoken = false; + + me->SummonCreature(NPC_FATHOM_GUARD_TIDALVESS, advisorsPosition[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000); + me->SummonCreature(NPC_FATHOM_GUARD_SHARKKIS, advisorsPosition[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000); + me->SummonCreature(NPC_FATHOM_GUARD_CARIBDIS, advisorsPosition[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000); + + ScheduleHealthCheckEvent(75, [&]{ + for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) + { + if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr)) + { + if (summon->GetMaxHealth() > 500000) + { + summon->CastSpell(me, SPELL_BLESSING_OF_THE_TIDES, true); + } + } + } + if (me->HasAura(SPELL_BLESSING_OF_THE_TIDES)) + { + Talk(SAY_GAIN_BLESSING); + } + }); } - struct boss_fathomlord_karathressAI : public BossAI + void JustSummoned(Creature* summon) override { - boss_fathomlord_karathressAI(Creature* creature) : BossAI(creature, DATA_FATHOM_LORD_KARATHRESS) + summons.Summon(summon); + if (summon->GetEntry() == NPC_SEER_OLUM) { + summon->SetWalk(true); + summon->GetMotionMaster()->MovePoint(0, advisorsPosition[MAX_ADVISORS + 1], false); } + } + + void SummonedCreatureDies(Creature* summon, Unit*) override + { + summons.Despawn(summon); + if (summon->GetEntry() == NPC_FATHOM_GUARD_TIDALVESS) + Talk(SAY_GAIN_ABILITY1); + if (summon->GetEntry() == NPC_FATHOM_GUARD_SHARKKIS) + Talk(SAY_GAIN_ABILITY2); + if (summon->GetEntry() == NPC_FATHOM_GUARD_CARIBDIS) + Talk(SAY_GAIN_ABILITY3); + } - void Reset() override + void KilledUnit(Unit* /*victim*/) override + { + if (!_recentlySpoken) { - BossAI::Reset(); + Talk(SAY_SLAY); + _recentlySpoken = true; + } + scheduler.Schedule(6s, [this](TaskContext) + { + _recentlySpoken = false; + }); + } - me->SummonCreature(NPC_FATHOM_GUARD_TIDALVESS, advisorsPosition[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000); - me->SummonCreature(NPC_FATHOM_GUARD_SHARKKIS, advisorsPosition[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000); - me->SummonCreature(NPC_FATHOM_GUARD_CARIBDIS, advisorsPosition[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000); + void JustDied(Unit* killer) override + { + Talk(SAY_DEATH); + BossAI::JustDied(killer); + me->SummonCreature(NPC_SEER_OLUM, advisorsPosition[MAX_ADVISORS], TEMPSUMMON_TIMED_DESPAWN, 3600000); + if (GameObject* gobject = me->FindNearestGameObject(GO_CAGE, 100.0f)) + { + gobject->SetGoState(GO_STATE_ACTIVE); } + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); - void JustSummoned(Creature* summon) override + instance->DoForAllMinions(DATA_FATHOM_LORD_KARATHRESS, [&](Creature* fathomguard) { + fathomguard->SetInCombatWithZone(); + }); + + scheduler.Schedule(10s, [this](TaskContext context) { - summons.Summon(summon); - if (summon->GetEntry() == NPC_SEER_OLUM) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 50.0f, true))) { - summon->SetWalk(true); - summon->GetMotionMaster()->MovePoint(0, advisorsPosition[MAX_ADVISORS + 1], false); + me->CastSpell(target, SPELL_CATACLYSMIC_BOLT); } - } + context.Repeat(6s); + }).Schedule(25s, [this](TaskContext context) + { + DoCastSelf(SPELL_SEAR_NOVA); + context.Repeat(20s, 40s); + }).Schedule(10min, [this](TaskContext) + { + DoCastSelf(SPELL_ENRAGE, true); + }); + } +private: + bool _recentlySpoken; +}; + +struct LeechingThrowSelector +{ +public: + explicit LeechingThrowSelector(WorldObject const* source) : _source(source) { } + + bool operator() (Unit* unit) const + { + return unit->getPowerType() == POWER_MANA && _source->GetDistance(unit) < 50.0f; + } +private: + WorldObject const* _source; +}; - void SummonedCreatureDies(Creature* summon, Unit*) override +struct boss_fathomguard_sharkkis : public ScriptedAI +{ + boss_fathomguard_sharkkis(Creature* creature) : ScriptedAI(creature), summons(creature) + { + summons.clear(); + + _instance = creature->GetInstanceScript(); + + _scheduler.SetValidator([this] { - summons.Despawn(summon); - if (summon->GetEntry() == NPC_FATHOM_GUARD_TIDALVESS) - Talk(SAY_GAIN_ABILITY1); - if (summon->GetEntry() == NPC_FATHOM_GUARD_SHARKKIS) - Talk(SAY_GAIN_ABILITY2); - if (summon->GetEntry() == NPC_FATHOM_GUARD_CARIBDIS) - Talk(SAY_GAIN_ABILITY3); - } + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } + + SummonList summons; + + void Reset() override + { + _scheduler.CancelAll(); + + summons.DespawnAll(); + } + + void JustSummoned(Creature* summon) override + { + summon->SetInCombatWithZone(); + summons.Summon(summon); + } - void KilledUnit(Unit* /*victim*/) override + void JustEngagedWith(Unit* /*who*/) override + { + _scheduler.Schedule(2500ms, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_HURL_TRIDENT); + context.Repeat(5s); + }).Schedule(20650ms, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_MULTI_TOSS); + context.Repeat(12150ms, 26350ms); + }).Schedule(6050ms, [this](TaskContext context) { - if (events.GetNextEventTime(EVENT_KILL_TALK) == 0) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, LeechingThrowSelector(me))) { - Talk(SAY_SLAY); - events.ScheduleEvent(EVENT_KILL_TALK, 6000); + me->CastSpell(target, SPELL_LEECHING_THROW); } + context.Repeat(6050ms, 22250ms); + }).Schedule(41250ms, [this](TaskContext context) + { + DoCastSelf(SPELL_THE_BEAST_WITHIN); + summons.DoForAllSummons([&](WorldObject* summon) + { + me->CastSpell(summon->ToCreature(), SPELL_BESTIAL_WRATH, true); + }); + context.Repeat(39950ms, 46050ms); + }).Schedule(14550ms, [this](TaskContext context) + { + DoCastSelf(urand(0, 1) ? SPELL_SUMMON_FATHOM_LURKER : SPELL_SUMMON_FATHOM_SPOREBAT); + context.Repeat(30300ms); + }); + } + + void JustDied(Unit* /*killer*/) override + { + if (Creature* karathress = _instance->GetCreature(DATA_FATHOM_LORD_KARATHRESS)) + { + me->CastSpell(karathress, SPELL_POWER_OF_SHARKKIS); } + } - void JustDied(Unit* killer) override + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) { - Talk(SAY_DEATH); - BossAI::JustDied(killer); - me->SummonCreature(NPC_SEER_OLUM, advisorsPosition[MAX_ADVISORS], TEMPSUMMON_TIMED_DESPAWN, 3600000); - if (GameObject* gobject = me->FindNearestGameObject(GO_CAGE, 100.0f)) - gobject->SetGoState(GO_STATE_ACTIVE); + return; } - void JustEngagedWith(Unit* who) override + _scheduler.Update(diff); + + DoMeleeAttackIfReady(); + } + +private: + TaskScheduler _scheduler; + InstanceScript* _instance; +}; + +enum NPCTotems +{ + NPC_SPITFIRE_TOTEM = 22091, + NPC_GREATER_EARTHBIND_TOTEM = 22486, + NPC_GREATER_POISON_CLEANSING_TOTEM = 22487 +}; + +enum TidalActions +{ + ACTION_REMOVE_SPITFIRE = 1, + ACTION_REMOVE_EARTHBIND = 2, + ACTION_REMOVE_CLEANSING = 3 +}; + +enum TotemChoice +{ + SPITFIRE = 1, + EARTHBIND = 2, + CLEANSING = 3 +}; + +struct boss_fathomguard_tidalvess : public ScriptedAI +{ + boss_fathomguard_tidalvess(Creature* creature) : ScriptedAI(creature), summons(creature) + { + _instance = creature->GetInstanceScript(); + + _scheduler.SetValidator([this] { - BossAI::JustEngagedWith(who); - Talk(SAY_AGGRO); - me->CallForHelp(10.0f); + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } + + SummonList summons; + + std::list entryList; + + void Reset() override + { + _scheduler.CancelAll(); + _choice = 0; + + summons.DespawnAll(); + + entryList.clear(); + + entryList = {NPC_SPITFIRE_TOTEM, NPC_GREATER_EARTHBIND_TOTEM, NPC_GREATER_POISON_CLEANSING_TOTEM}; + } - events.ScheduleEvent(EVENT_SPELL_CATACLYSMIC_BOLT, 10000); - events.ScheduleEvent(EVENT_SPELL_ENRAGE, 600000); - events.ScheduleEvent(EVENT_SPELL_SEAR_NOVA, 25000); - events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000); + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + summon->Attack(me->GetVictim(), false); + summon->SetInCombatWithZone(); + } + + void ScheduleRemoval(uint32 entry) + { + std::chrono::seconds timer = 0s; + int32 action = 0; + uint8 group = 0; + + switch(entry) + { + case NPC_SPITFIRE_TOTEM: + timer = 59s; + action = ACTION_REMOVE_SPITFIRE; + group = SPITFIRE; + break; + case NPC_GREATER_EARTHBIND_TOTEM: + timer = 44s; + action = ACTION_REMOVE_EARTHBIND; + group = EARTHBIND; + break; + case NPC_GREATER_POISON_CLEANSING_TOTEM: + timer = 29s; + action = ACTION_REMOVE_CLEANSING; + group = CLEANSING; + break; + default: + timer = 29s; } + _totemScheduler.Schedule(timer, group, [this, action](TaskContext) + { + me->AI()->DoAction(action); + }); + } - void UpdateAI(uint32 diff) override + void DoAction(int32 action) override + { + switch (action) { - if (!UpdateVictim()) + case ACTION_REMOVE_SPITFIRE: + _totemScheduler.CancelGroup(SPITFIRE); + entryList.push_back(NPC_SPITFIRE_TOTEM); + break; + case ACTION_REMOVE_EARTHBIND: + _totemScheduler.CancelGroup(EARTHBIND); + entryList.push_back(NPC_GREATER_EARTHBIND_TOTEM); + break; + case ACTION_REMOVE_CLEANSING: + _totemScheduler.CancelGroup(CLEANSING); + entryList.push_back(NPC_GREATER_POISON_CLEANSING_TOTEM); + break; + default: return; + } + } - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) + void SummonTotem(uint32 entry) + { + switch(entry) + { + case NPC_SPITFIRE_TOTEM: + DoCastSelf(SPELL_SPITFIRE_TOTEM); + break; + case NPC_GREATER_EARTHBIND_TOTEM: + DoCastSelf(SPELL_EARTHBIND_TOTEM); + break; + case NPC_GREATER_POISON_CLEANSING_TOTEM: + DoCastSelf(SPELL_POISON_CLEANSING_TOTEM); + break; + default: return; + } + } - switch (events.ExecuteEvent()) + void JustEngagedWith(Unit* /*who*/) override + { + _scheduler.Schedule(10900ms, [this](TaskContext context) + { + DoCastVictim(SPELL_FROST_SHOCK); + context.Repeat(10900ms, 14700ms); + }).Schedule(15800ms, [this](TaskContext context) + { + if (entryList.size() != 0) //don't summon when all totems are up { - case EVENT_SPELL_ENRAGE: - me->CastSpell(me, SPELL_ENRAGE, true); - break; - case EVENT_SPELL_CATACLYSMIC_BOLT: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 50.0f, true))) - me->CastSpell(target, SPELL_CATACLYSMIC_BOLT, false); - events.ScheduleEvent(EVENT_SPELL_CATACLYSMIC_BOLT, 6000); - break; - case EVENT_SPELL_SEAR_NOVA: - me->CastSpell(me, SPELL_SEAR_NOVA, false); - events.ScheduleEvent(EVENT_SPELL_SEAR_NOVA, 20000 + urand(0, 20000)); - break; - case EVENT_HEALTH_CHECK: - if (me->HealthBelowPct(76)) - { - for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) - if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr)) - if (summon->GetMaxHealth() > 500000) - summon->CastSpell(me, SPELL_BLESSING_OF_THE_TIDES, true); - - if (me->HasAura(SPELL_BLESSING_OF_THE_TIDES)) - Talk(SAY_GAIN_BLESSING); - break; - } - events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000); - break; + uint32 totemEntry = entryList.front(); + entryList.pop_front(); + SummonTotem(totemEntry); + ScheduleRemoval(totemEntry); } + context.Repeat(13350ms, 24250ms); + }); + } - DoMeleeAttackIfReady(); + void JustDied(Unit* /*killer*/) override + { + if (Creature* karathress = _instance->GetCreature(DATA_FATHOM_LORD_KARATHRESS)) + { + me->CastSpell(karathress, SPELL_POWER_OF_TIDALVESS); } - }; + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + { + return; + } + + _scheduler.Update(diff); + _totemScheduler.Update(diff); + + DoMeleeAttackIfReady(); + } + +private: + TaskScheduler _scheduler; + TaskScheduler _totemScheduler; + InstanceScript* _instance; + uint8 _choice; +}; + +struct boss_fathomguard_caribdis : public ScriptedAI +{ + boss_fathomguard_caribdis(Creature* creature) : ScriptedAI(creature), summons(creature) + { + _instance = creature->GetInstanceScript(); + + _scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } + + SummonList summons; + + void Reset() override + { + _scheduler.CancelAll(); + + summons.DespawnAll(); + } + + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + } + + void JustEngagedWith(Unit* /*who*/) override + { + _scheduler.Schedule(27900ms, [this](TaskContext context) + { + DoCastSelf(SPELL_WATER_BOLT_VOLLEY); + context.Repeat(6050ms, 19750ms); + }).Schedule(23050ms, [this](TaskContext context) + { + DoCastSelf(SPELL_TIDAL_SURGE); + context.Repeat(24250ms, 33250ms); + }).Schedule(15750ms, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_SUMMON_CYCLONE); + context.Repeat(47250ms, 51550ms); + }).Schedule(20s, [this](TaskContext context) + { + if (Unit* target = DoSelectLowestHpFriendly(60.0f, 150000)) + { + DoCast(target, SPELL_HEALING_WAVE); + } + context.Repeat(20s); + }); + } + + void JustDied(Unit* /*killer*/) override + { + if (Creature* karathress = _instance->GetCreature(DATA_FATHOM_LORD_KARATHRESS)) + { + me->CastSpell(karathress, SPELL_POWER_OF_CARIBDIS); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + { + return; + } + + _scheduler.Update(diff); + + DoMeleeAttackIfReady(); + } + +private: + TaskScheduler _scheduler; + InstanceScript* _instance; }; class spell_karathress_power_of_caribdis : public SpellScriptLoader @@ -213,6 +568,9 @@ class spell_karathress_power_of_caribdis : public SpellScriptLoader void AddSC_boss_fathomlord_karathress() { - new boss_fathomlord_karathress(); + RegisterSerpentShrineAI(boss_fathomlord_karathress); + RegisterSerpentShrineAI(boss_fathomguard_sharkkis); + RegisterSerpentShrineAI(boss_fathomguard_tidalvess); + RegisterSerpentShrineAI(boss_fathomguard_caribdis); new spell_karathress_power_of_caribdis(); } diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp index a3c94d269f4d8d..446f61ef8f1ad4 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp @@ -69,219 +69,185 @@ enum Misc { GROUP_ABILITIES = 1, NPC_PURE_SPAWN_OF_HYDROSS = 22035, - - EVENT_SPELL_MARK_OF_CORRUPTION1 = 1, - EVENT_SPELL_MARK_OF_CORRUPTION2 = 2, - EVENT_SPELL_MARK_OF_CORRUPTION3 = 3, - EVENT_SPELL_MARK_OF_CORRUPTION4 = 4, - EVENT_SPELL_MARK_OF_CORRUPTION5 = 5, - EVENT_SPELL_MARK_OF_CORRUPTION6 = 6, - EVENT_SPELL_MARK_OF_HYDROSS1 = 7, - EVENT_SPELL_MARK_OF_HYDROSS2 = 8, - EVENT_SPELL_MARK_OF_HYDROSS3 = 9, - EVENT_SPELL_MARK_OF_HYDROSS4 = 10, - EVENT_SPELL_MARK_OF_HYDROSS5 = 11, - EVENT_SPELL_MARK_OF_HYDROSS6 = 12, - EVENT_SPELL_WATER_TOMB = 13, - EVENT_SPELL_VILE_SLUDGE = 14, - EVENT_SPELL_ENRAGE = 15, - EVENT_CHECK_AURA = 16, - EVENT_KILL_TALK = 17 }; -class boss_hydross_the_unstable : public CreatureScript +struct boss_hydross_the_unstable : public BossAI { -public: - boss_hydross_the_unstable() : CreatureScript("boss_hydross_the_unstable") { } + boss_hydross_the_unstable(Creature* creature) : BossAI(creature, DATA_HYDROSS_THE_UNSTABLE) + { + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetSerpentShrineAI(creature); + BossAI::Reset(); + + _recentlySpoken = false; } - struct boss_hydross_the_unstableAI : public BossAI + void JustReachedHome() override { - boss_hydross_the_unstableAI(Creature* creature) : BossAI(creature, DATA_HYDROSS_THE_UNSTABLE) + BossAI::JustReachedHome(); + if (!me->HasAura(SPELL_BLUE_BEAM)) { + me->RemoveAurasDueToSpell(SPELL_CLEANSING_FIELD_AURA); } + } - void Reset() override - { - BossAI::Reset(); - } + void SetForm(bool corrupt, bool initial) + { + scheduler.CancelGroup(GROUP_ABILITIES); + DoResetThreatList(); - void JustReachedHome() override + if (corrupt) { - BossAI::JustReachedHome(); - if (!me->HasAura(SPELL_BLUE_BEAM)) - me->RemoveAurasDueToSpell(SPELL_CLEANSING_FIELD_AURA); - } + me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE); + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, false); + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); + DoCastSelf(SPELL_CORRUPTION, true); - void SetForm(bool corrupt, bool initial) + scheduler.Schedule(0s, GROUP_ABILITIES, [this](TaskContext) + { + DoCastSelf(SPELL_MARK_OF_CORRUPTION1); + }).Schedule(15s, GROUP_ABILITIES, [this](TaskContext) + { + DoCastSelf(SPELL_MARK_OF_CORRUPTION2); + }).Schedule(30s, GROUP_ABILITIES, [this](TaskContext) + { + DoCastSelf(SPELL_MARK_OF_CORRUPTION3); + }).Schedule(45s, GROUP_ABILITIES, [this](TaskContext) + { + DoCastSelf(SPELL_MARK_OF_CORRUPTION4); + }).Schedule(60s, GROUP_ABILITIES, [this](TaskContext) + { + DoCastSelf(SPELL_MARK_OF_CORRUPTION5); + }).Schedule(75s, GROUP_ABILITIES, [this](TaskContext) + { + DoCastSelf(SPELL_MARK_OF_CORRUPTION6); + }).Schedule(12150ms, GROUP_ABILITIES, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_VILE_SLUDGE, true); + context.Repeat(9700ms, 32800ms); + }); + } + else { - events.CancelEventGroup(GROUP_ABILITIES); - DoResetThreatList(); + me->SetMeleeDamageSchool(SPELL_SCHOOL_FROST); + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false); + me->RemoveAurasDueToSpell(SPELL_CORRUPTION); - if (corrupt) + scheduler.Schedule(0s, GROUP_ABILITIES, [this](TaskContext) { - me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE); - me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, false); - me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); - me->CastSpell(me, SPELL_CORRUPTION, true); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_CORRUPTION1, 0, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_CORRUPTION2, 15000, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_CORRUPTION3, 30000, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_CORRUPTION4, 45000, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_CORRUPTION5, 60000, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_CORRUPTION6, 75000, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_VILE_SLUDGE, 7000, GROUP_ABILITIES); - } - else + DoCastSelf(SPELL_MARK_OF_HYDROSS1); + }).Schedule(15s, GROUP_ABILITIES, [this](TaskContext) { - me->SetMeleeDamageSchool(SPELL_SCHOOL_FROST); - me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); - me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false); - me->RemoveAurasDueToSpell(SPELL_CORRUPTION); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_HYDROSS1, 0, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_HYDROSS2, 15000, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_HYDROSS3, 30000, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_HYDROSS4, 45000, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_HYDROSS5, 60000, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_HYDROSS6, 75000, GROUP_ABILITIES); - events.ScheduleEvent(EVENT_SPELL_WATER_TOMB, 7000, GROUP_ABILITIES); - } - - if (initial) - return; - - if (corrupt) + DoCastSelf(SPELL_MARK_OF_HYDROSS2); + }).Schedule(30s, GROUP_ABILITIES, [this](TaskContext) { - Talk(SAY_SWITCH_TO_CORRUPT); - for (uint32 i = SPELL_SUMMON_CORRUPTED1; i <= SPELL_SUMMON_CORRUPTED4; ++i) - me->CastSpell(me, i, true); - } - else + DoCastSelf(SPELL_MARK_OF_HYDROSS3); + }).Schedule(45s, GROUP_ABILITIES, [this](TaskContext) { - Talk(SAY_SWITCH_TO_CLEAN); - for (uint32 i = SPELL_SUMMON_PURIFIED1; i <= SPELL_SUMMON_PURIFIED4; ++i) - me->CastSpell(me, i, true); - } + DoCastSelf(SPELL_MARK_OF_HYDROSS4); + }).Schedule(60s, GROUP_ABILITIES, [this](TaskContext) + { + DoCastSelf(SPELL_MARK_OF_HYDROSS5); + }).Schedule(75s, GROUP_ABILITIES, [this](TaskContext) + { + DoCastSelf(SPELL_MARK_OF_HYDROSS6); + }).Schedule(12150ms, GROUP_ABILITIES, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_WATER_TOMB, true); + context.Repeat(9700ms, 32800ms); + }); } - void JustEngagedWith(Unit* who) override + if (initial) { - BossAI::JustEngagedWith(who); - Talk(SAY_AGGRO); - - events.ScheduleEvent(EVENT_SPELL_ENRAGE, 600000); - events.ScheduleEvent(EVENT_CHECK_AURA, 1000); - SetForm(false, true); + return; } - void KilledUnit(Unit* /*victim*/) override + if (corrupt) { - if (events.GetNextEventTime(EVENT_KILL_TALK) == 0) + Talk(SAY_SWITCH_TO_CORRUPT); + for (uint32 spellId = SPELL_SUMMON_CORRUPTED1; spellId <= SPELL_SUMMON_CORRUPTED4; ++spellId) { - Talk(me->HasAura(SPELL_CORRUPTION) ? SAY_CORRUPT_SLAY : SAY_CLEAN_SLAY); - events.ScheduleEvent(EVENT_KILL_TALK, 6000); + DoCastSelf(spellId, true); } } - - void JustSummoned(Creature* summon) override + else { - summons.Summon(summon); - summon->CastSpell(summon, SPELL_ELEMENTAL_SPAWNIN, true); - summon->SetInCombatWithZone(); - - if (summon->GetEntry() == NPC_PURE_SPAWN_OF_HYDROSS) - summon->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); - else - summon->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); + Talk(SAY_SWITCH_TO_CLEAN); + for (uint32 spellId = SPELL_SUMMON_PURIFIED1; spellId <= SPELL_SUMMON_PURIFIED4; ++spellId) + { + DoCastSelf(spellId, true); + } } + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); + SetForm(false, true); - void SummonedCreatureDespawn(Creature* summon) override + scheduler.Schedule(1s, [this](TaskContext context) { - summons.Despawn(summon); - } + if (me->HasAura(SPELL_BLUE_BEAM) == me->HasAura(SPELL_CORRUPTION)) + { + SetForm(!me->HasAura(SPELL_BLUE_BEAM), false); + } + context.Repeat(1s); + }).Schedule(10min, [this](TaskContext) + { + DoCastSelf(SPELL_ENRAGE, true); + }); + } - void JustDied(Unit* killer) override + void KilledUnit(Unit* /*victim*/) override + { + if (!_recentlySpoken) { - Talk(me->HasAura(SPELL_CORRUPTION) ? SAY_CORRUPT_DEATH : SAY_CLEAN_DEATH); - BossAI::JustDied(killer); + Talk(me->HasAura(SPELL_CORRUPTION) ? SAY_CORRUPT_SLAY : SAY_CLEAN_SLAY); + _recentlySpoken = true; } - - void UpdateAI(uint32 diff) override + scheduler.Schedule(6s, [this](TaskContext) { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + _recentlySpoken = false; + }); + } - switch (events.ExecuteEvent()) - { - case EVENT_CHECK_AURA: - if (me->HasAura(SPELL_BLUE_BEAM) == me->HasAura(SPELL_CORRUPTION)) - SetForm(!me->HasAura(SPELL_BLUE_BEAM), false); - events.ScheduleEvent(EVENT_CHECK_AURA, 1000); - break; - case EVENT_SPELL_ENRAGE: - me->CastSpell(me, SPELL_ENRAGE, true); - break; - case EVENT_SPELL_MARK_OF_HYDROSS1: - me->CastSpell(me, SPELL_MARK_OF_HYDROSS1, false); - break; - case EVENT_SPELL_MARK_OF_HYDROSS2: - me->CastSpell(me, SPELL_MARK_OF_HYDROSS2, false); - break; - case EVENT_SPELL_MARK_OF_HYDROSS3: - me->CastSpell(me, SPELL_MARK_OF_HYDROSS3, false); - break; - case EVENT_SPELL_MARK_OF_HYDROSS4: - me->CastSpell(me, SPELL_MARK_OF_HYDROSS4, false); - break; - case EVENT_SPELL_MARK_OF_HYDROSS5: - me->CastSpell(me, SPELL_MARK_OF_HYDROSS5, false); - break; - case EVENT_SPELL_MARK_OF_HYDROSS6: - me->CastSpell(me, SPELL_MARK_OF_HYDROSS6, false); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_HYDROSS6, 15000, GROUP_ABILITIES); - break; - case EVENT_SPELL_MARK_OF_CORRUPTION1: - me->CastSpell(me, SPELL_MARK_OF_CORRUPTION1, false); - break; - case EVENT_SPELL_MARK_OF_CORRUPTION2: - me->CastSpell(me, SPELL_MARK_OF_CORRUPTION2, false); - break; - case EVENT_SPELL_MARK_OF_CORRUPTION3: - me->CastSpell(me, SPELL_MARK_OF_CORRUPTION3, false); - break; - case EVENT_SPELL_MARK_OF_CORRUPTION4: - me->CastSpell(me, SPELL_MARK_OF_CORRUPTION4, false); - break; - case EVENT_SPELL_MARK_OF_CORRUPTION5: - me->CastSpell(me, SPELL_MARK_OF_CORRUPTION5, false); - break; - case EVENT_SPELL_MARK_OF_CORRUPTION6: - me->CastSpell(me, SPELL_MARK_OF_CORRUPTION6, false); - events.ScheduleEvent(EVENT_SPELL_MARK_OF_CORRUPTION6, 15000, GROUP_ABILITIES); - break; - case EVENT_SPELL_WATER_TOMB: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 60.0f, true)) - me->CastSpell(target, SPELL_WATER_TOMB, false); - events.ScheduleEvent(EVENT_SPELL_WATER_TOMB, 7000, GROUP_ABILITIES); - break; - case EVENT_SPELL_VILE_SLUDGE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 60.0f, true)) - me->CastSpell(target, SPELL_VILE_SLUDGE, false); - events.ScheduleEvent(EVENT_SPELL_VILE_SLUDGE, 15000, GROUP_ABILITIES); - break; - } + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + summon->CastSpell(summon, SPELL_ELEMENTAL_SPAWNIN, true); + summon->SetInCombatWithZone(); - DoMeleeAttackIfReady(); + if (summon->GetEntry() == NPC_PURE_SPAWN_OF_HYDROSS) + { + summon->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); } - }; + else + { + summon->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); + } + } + + void SummonedCreatureDespawn(Creature* summon) override + { + summons.Despawn(summon); + } + + void JustDied(Unit* killer) override + { + Talk(me->HasAura(SPELL_CORRUPTION) ? SAY_CORRUPT_DEATH : SAY_CLEAN_DEATH); + BossAI::JustDied(killer); + } +private: + bool _recentlySpoken; }; class spell_hydross_cleansing_field_aura : public SpellScriptLoader @@ -377,7 +343,7 @@ class spell_hydross_mark_of_hydross : public SpellScriptLoader void AddSC_boss_hydross_the_unstable() { - new boss_hydross_the_unstable(); + RegisterSerpentShrineAI(boss_hydross_the_unstable); new spell_hydross_cleansing_field_aura(); new spell_hydross_cleansing_field_command(); new spell_hydross_mark_of_hydross(); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp index 4ecb9e585d82bf..b496d3e25f384b 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp @@ -64,20 +64,6 @@ enum Misc ITEM_TAINTED_CORE = 31088, POINT_HOME = 1, - - EVENT_SPELL_SHOCK_BLAST = 1, - EVENT_SPELL_STATIC_CHARGE = 2, - EVENT_SPELL_ENTANGLE = 3, - EVENT_CHECK_HEALTH = 4, - EVENT_SPELL_FORKED_LIGHTNING = 5, - EVENT_SUMMON_A = 6, - EVENT_SUMMON_B = 7, - EVENT_SUMMON_C = 8, - EVENT_SUMMON_D = 9, - EVENT_CHECK_HEALTH2 = 10, - EVENT_SUMMON_SPOREBAT = 11, - - EVENT_KILL_TALK = 20 }; class startFollow : public BasicEvent @@ -88,215 +74,223 @@ class startFollow : public BasicEvent bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override { if (InstanceScript* instance = _owner->GetInstanceScript()) + { if (Creature* vashj = ObjectAccessor::GetCreature(*_owner, instance->GetGuidData(NPC_LADY_VASHJ))) + { _owner->GetMotionMaster()->MoveFollow(vashj, 3.0f, vashj->GetAngle(_owner), MOTION_SLOT_CONTROLLED); + } + } return true; } - private: Unit* _owner; }; -class boss_lady_vashj : public CreatureScript +struct boss_lady_vashj : public BossAI { -public: - boss_lady_vashj() : CreatureScript("boss_lady_vashj") { } + boss_lady_vashj(Creature* creature) : BossAI(creature, DATA_LADY_VASHJ) + { + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + + _intro = false; + } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetSerpentShrineAI(creature); + _count = 0; + _recentlySpoken = false; + _batTimer = 20s; + BossAI::Reset(); + + ScheduleHealthCheckEvent(70, [&]{ + Talk(SAY_PHASE2); + me->SetReactState(REACT_PASSIVE); + me->GetMotionMaster()->MovePoint(POINT_HOME, me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY(), me->GetHomePosition().GetPositionZ(), true, true); + }); } - struct boss_lady_vashjAI : public BossAI + void KilledUnit(Unit* /*victim*/) override { - boss_lady_vashjAI(Creature* creature) : BossAI(creature, DATA_LADY_VASHJ) + if(!_recentlySpoken) { - intro = false; + Talk(SAY_SLAY); + _recentlySpoken = true; } + scheduler.Schedule(6s, [this](TaskContext) + { + _recentlySpoken = false; + }); + } - bool intro; - int32 count; + void JustDied(Unit* killer) override + { + Talk(SAY_DEATH); + BossAI::JustDied(killer); + } - void Reset() override - { - count = 0; - BossAI::Reset(); - } + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); + DoCastSelf(SPELL_REMOVE_TAINTED_CORES, true); - void KilledUnit(Unit* /*victim*/) override - { - if (events.GetNextEventTime(EVENT_KILL_TALK) == 0) - { - Talk(SAY_SLAY); - events.ScheduleEvent(EVENT_KILL_TALK, 6000); - } - } + ScheduleSpells(); + } - void JustDied(Unit* killer) override + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + if (summon->GetEntry() == WORLD_TRIGGER) { - Talk(SAY_DEATH); - BossAI::JustDied(killer); + summon->CastSpell(summon, SPELL_MAGIC_BARRIER); } - - void JustEngagedWith(Unit* who) override + else if (summon->GetEntry() == NPC_ENCHANTED_ELEMENTAL) { - BossAI::JustEngagedWith(who); - Talk(SAY_AGGRO); - - me->CastSpell(me, SPELL_REMOVE_TAINTED_CORES, true); - events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, 10000); - events.ScheduleEvent(EVENT_SPELL_STATIC_CHARGE, 15000); - events.ScheduleEvent(EVENT_SPELL_ENTANGLE, 20000); - events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); + summon->SetWalk(true); + summon->m_Events.AddEvent(new startFollow(summon), summon->m_Events.CalculateTime(0)); } - - void JustSummoned(Creature* summon) override + else if (summon->GetEntry() == NPC_TOXIC_SPOREBAT) { - summons.Summon(summon); - if (summon->GetEntry() == WORLD_TRIGGER) - summon->CastSpell(summon, SPELL_MAGIC_BARRIER, false); - else if (summon->GetEntry() == NPC_ENCHANTED_ELEMENTAL) - { - summon->SetWalk(true); - summon->m_Events.AddEvent(new startFollow(summon), summon->m_Events.CalculateTime(0)); - } - else if (summon->GetEntry() == NPC_TOXIC_SPOREBAT) - summon->GetMotionMaster()->MoveRandom(30.0f); - else if (summon->GetEntry() != NPC_TAINTED_ELEMENTAL) - summon->GetMotionMaster()->MovePoint(POINT_HOME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), true, true); + summon->GetMotionMaster()->MoveRandom(30.0f); } - - void MoveInLineOfSight(Unit* who) override + else if (summon->GetEntry() != NPC_TAINTED_ELEMENTAL) { - if (!intro && who->GetTypeId() == TYPEID_PLAYER) - { - intro = true; - Talk(SAY_INTRO); - } - - BossAI::MoveInLineOfSight(who); + summon->GetMotionMaster()->MovePoint(POINT_HOME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), true, true); } + } - void MovementInform(uint32 type, uint32 id) override + void ScheduleSpells() + { + scheduler.Schedule(14550ms, [this](TaskContext context) { - if (type != POINT_MOTION_TYPE || id != POINT_HOME) - return; + DoCastVictim(SPELL_SHOCK_BLAST); + context.Repeat(10850ms, 25100ms); + }).Schedule(18150ms, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_STATIC_CHARGE); + context.Repeat(7250ms, 27050ms); + }).Schedule(25450ms, [this](TaskContext context) + { + DoCastSelf(SPELL_ENTANGLE); + context.Repeat(18200ms, 51500ms); + }); + } - me->SetFacingTo(me->GetHomePosition().GetOrientation()); - instance->SetData(DATA_ACTIVATE_SHIELD, 0); - events.Reset(); - events.ScheduleEvent(EVENT_SPELL_FORKED_LIGHTNING, 3000); - events.ScheduleEvent(EVENT_SUMMON_A, 0); - events.ScheduleEvent(EVENT_SUMMON_B, 45000); - events.ScheduleEvent(EVENT_SUMMON_C, 60000); - events.ScheduleEvent(EVENT_SUMMON_D, 50000); - events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); + void MoveInLineOfSight(Unit* who) override + { + if (!_intro && who->GetTypeId() == TYPEID_PLAYER) + { + _intro = true; + Talk(SAY_INTRO); } - void UpdateAI(uint32 diff) override + BossAI::MoveInLineOfSight(who); + } + + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE || id != POINT_HOME) { - if (!UpdateVictim()) - return; + return; + } - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + me->SetFacingTo(me->GetHomePosition().GetOrientation()); + instance->SetData(DATA_ACTIVATE_SHIELD, 0); + scheduler.CancelAll(); - switch (events.ExecuteEvent()) + scheduler.Schedule(2400ms, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_FORKED_LIGHTNING); + context.Repeat(2400ms, 12450ms); + }).Schedule(0s, [this](TaskContext context) + { + DoCastSelf(SPELL_SUMMON_ENCHANTED_ELEMENTAL, true); + context.Repeat(2500ms); + }).Schedule(45s, [this](TaskContext context) + { + DoCastSelf(SPELL_SUMMON_COILFANG_ELITE, true); + context.Repeat(45s); + }).Schedule(60s, [this](TaskContext context) + { + DoCastSelf(SPELL_SUMMON_COILFANG_STRIDER, true); + context.Repeat(60s); + }).Schedule(50s, [this](TaskContext context) + { + DoCastSelf(SPELL_SUMMON_TAINTED_ELEMENTAL, true); + context.Repeat(50s); + }).Schedule(1s, [this](TaskContext context) + { + if (!me->HasAura(SPELL_MAGIC_BARRIER)) { - case EVENT_SPELL_SHOCK_BLAST: - me->CastSpell(me->GetVictim(), SPELL_SHOCK_BLAST, false); - events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, urand(10000, 20000)); - break; - case EVENT_SPELL_STATIC_CHARGE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f)) - me->CastSpell(target, SPELL_STATIC_CHARGE, false); - events.ScheduleEvent(EVENT_SPELL_STATIC_CHARGE, 20000); - break; - case EVENT_SPELL_ENTANGLE: - me->CastSpell(me, SPELL_ENTANGLE, false); - events.ScheduleEvent(EVENT_SPELL_ENTANGLE, 30000); - break; - case EVENT_CHECK_HEALTH: - if (me->HealthBelowPct(71)) - { - Talk(SAY_PHASE2); - me->SetReactState(REACT_PASSIVE); - me->GetMotionMaster()->MovePoint(POINT_HOME, me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY(), me->GetHomePosition().GetPositionZ(), true, true); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); - break; - case EVENT_SPELL_FORKED_LIGHTNING: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 60.0f)) - me->CastSpell(target, SPELL_FORKED_LIGHTNING, false); - events.ScheduleEvent(EVENT_SPELL_FORKED_LIGHTNING, urand(2500, 5000)); - break; - case EVENT_SUMMON_A: - me->CastSpell(me, SPELL_SUMMON_ENCHANTED_ELEMENTAL, true); - events.ScheduleEvent(EVENT_SUMMON_A, 2500); - break; - case EVENT_SUMMON_B: - me->CastSpell(me, SPELL_SUMMON_COILFANG_ELITE, true); - events.ScheduleEvent(EVENT_SUMMON_B, 45000); - break; - case EVENT_SUMMON_C: - me->CastSpell(me, SPELL_SUMMON_COILFANG_STRIDER, true); - events.ScheduleEvent(EVENT_SUMMON_C, 60000); - break; - case EVENT_SUMMON_D: - me->CastSpell(me, SPELL_SUMMON_TAINTED_ELEMENTAL, true); - events.ScheduleEvent(EVENT_SUMMON_D, 50000); - break; - case EVENT_CHECK_HEALTH2: - if (!me->HasAura(SPELL_MAGIC_BARRIER)) - { - Talk(SAY_PHASE3); - me->SetReactState(REACT_AGGRESSIVE); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - events.Reset(); - events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, 10000); - events.ScheduleEvent(EVENT_SPELL_STATIC_CHARGE, 15000); - events.ScheduleEvent(EVENT_SPELL_ENTANGLE, 20000); - events.ScheduleEvent(EVENT_SUMMON_SPOREBAT, 5000); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); - break; - case EVENT_SUMMON_SPOREBAT: - me->CastSpell(me, SPELL_SUMMON_TOXIC_SPOREBAT, true); - events.ScheduleEvent(EVENT_SUMMON_SPOREBAT, 20000 - 1000 * std::min(count++, 16)); - break; - } + Talk(SAY_PHASE3); + me->SetReactState(REACT_AGGRESSIVE); + me->GetMotionMaster()->MoveChase(me->GetVictim()); + scheduler.CancelAll(); - if (me->GetReactState() != REACT_AGGRESSIVE || !me->isAttackReady()) - return; - - if (!me->IsWithinMeleeRange(me->GetVictim())) - { - me->resetAttackTimer(); - me->SetSheath(SHEATH_STATE_RANGED); - me->CastSpell(me->GetVictim(), roll_chance_i(33) ? SPELL_MULTI_SHOT : SPELL_SHOOT, false); - if (roll_chance_i(15)) - Talk(SAY_BOWSHOT); + ScheduleSpells(); + scheduler.Schedule(5s, [this](TaskContext context) + { + DoCastSelf(SPELL_SUMMON_TOXIC_SPOREBAT, true); + _batTimer = 20s - static_cast(std::min(_count++, 16)); + context.Repeat(_batTimer); + }); } else { - me->SetSheath(SHEATH_STATE_MELEE); - DoMeleeAttackIfReady(); + context.Repeat(1s); } + }); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + scheduler.Update(diff); + + if (me->GetReactState() != REACT_AGGRESSIVE || !me->isAttackReady()) + { + return; } - bool CheckEvadeIfOutOfCombatArea() const override + if (!me->IsWithinMeleeRange(me->GetVictim())) { - return me->GetHomePosition().GetExactDist2d(me) > 80.0f || !SelectTargetFromPlayerList(100.0f); + me->resetAttackTimer(); + me->SetSheath(SHEATH_STATE_RANGED); + me->CastSpell(me->GetVictim(), roll_chance_i(33) ? SPELL_MULTI_SHOT : SPELL_SHOOT, false); + if (roll_chance_i(15)) + { + Talk(SAY_BOWSHOT); + } } - }; + else + { + me->SetSheath(SHEATH_STATE_MELEE); + DoMeleeAttackIfReady(); + } + } + + bool CheckEvadeIfOutOfCombatArea() const override + { + return me->GetHomePosition().GetExactDist2d(me) > 80.0f || !SelectTargetFromPlayerList(100.0f); + } + +private: + bool _recentlySpoken; + bool _intro; + int32 _count; + std::chrono::seconds _batTimer; }; + /* //Toxic Sporebat //Toxic Spores: Used in Phase 3 by the Spore Bats, it creates a contaminated green patch of ground, dealing about 2775-3225 nature damage every second to anyone who stands in it. +//deprecated -- adds do work class npc_toxic_sporebat : public CreatureScript { public: @@ -433,7 +427,9 @@ class spell_lady_vashj_remove_tainted_cores : public SpellScriptLoader { PreventHitDefaultEffect(effIndex); if (Player* target = GetHitPlayer()) + { target->DestroyItemCount(ITEM_TAINTED_CORE, -1, true); + } } void Register() override @@ -488,7 +484,9 @@ class spell_lady_vashj_spore_drop_effect : public SpellScriptLoader { PreventHitDefaultEffect(effIndex); if (Unit* target = GetHitUnit()) + { target->CastSpell(target, SPELL_TOXIC_SPORES, true, nullptr, nullptr, GetCaster()->GetGUID()); + } } void Register() override @@ -505,7 +503,7 @@ class spell_lady_vashj_spore_drop_effect : public SpellScriptLoader void AddSC_boss_lady_vashj() { - new boss_lady_vashj(); + RegisterSerpentShrineAI(boss_lady_vashj); new spell_lady_vashj_magic_barrier(); new spell_lady_vashj_remove_tainted_cores(); new spell_lady_vashj_summon_sporebat(); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp index 79bd3180deda58..1c14da53f07cac 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp @@ -19,6 +19,7 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "serpent_shrine.h" +#include "TaskScheduler.h" enum Talk { @@ -59,18 +60,12 @@ enum Misc NPC_GREYHEART_SPELLBINDER = 21806, NPC_SHADOW_OF_LEOTHERAS = 21875, +}; - EVENT_SPELL_BERSERK = 1, - EVENT_HEALTH_CHECK = 2, - EVENT_SWITCH_TO_DEMON = 3, - EVENT_SPELL_WHIRLWIND = 4, - EVENT_KILL_TALK = 5, - EVENT_SWITCH_TO_ELF = 6, - EVENT_SPELL_INSIDIOUS_WHISPER = 7, - EVENT_SUMMON_DEMON = 8, - EVENT_RESTORE_FIGHT = 9, - - EVENT_SPELL_SHADOW_BOLT = 20 +enum Groups +{ + GROUP_COMBAT = 1, + GROUP_DEMON = 2 }; const Position channelersPos[MAX_CHANNELERS] = @@ -80,267 +75,231 @@ const Position channelersPos[MAX_CHANNELERS] = {362.11f, -437.48f, 29.52f, 0.9f} }; -class boss_leotheras_the_blind : public CreatureScript +struct boss_leotheras_the_blind : public BossAI { -public: - boss_leotheras_the_blind() : CreatureScript("boss_leotheras_the_blind") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_leotheras_the_blind(Creature* creature) : BossAI(creature, DATA_LEOTHERAS_THE_BLIND) { - return GetSerpentShrineAI(creature); + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); } - struct boss_leotheras_the_blindAI : public BossAI + void Reset() override { - boss_leotheras_the_blindAI(Creature* creature) : BossAI(creature, DATA_LEOTHERAS_THE_BLIND) - { - } + BossAI::Reset(); + DoCastSelf(SPELL_CLEAR_CONSUMING_MADNESS, true); + DoCastSelf(SPELL_DUAL_WIELD, true); + me->SetStandState(UNIT_STAND_STATE_KNEEL); + me->LoadEquipment(0, true); + me->SetReactState(REACT_PASSIVE); + _recentlySpoken = false; + SummonChannelers(); + + ScheduleHealthCheckEvent(15, [&]{ + if (me->GetDisplayId() != me->GetNativeDisplayId()) + { + //is currently in metamorphosis + DoResetThreatList(); + me->LoadEquipment(); + me->RemoveAurasDueToSpell(SPELL_METAMORPHOSIS); + + scheduler.RescheduleGroup(GROUP_COMBAT, 10s); + } + scheduler.CancelGroup(GROUP_DEMON); + scheduler.DelayAll(10s); - void Reset() override - { - BossAI::Reset(); - me->CastSpell(me, SPELL_CLEAR_CONSUMING_MADNESS, true); - me->CastSpell(me, SPELL_DUAL_WIELD, true); me->SetStandState(UNIT_STAND_STATE_KNEEL); - me->LoadEquipment(0, true); me->SetReactState(REACT_PASSIVE); - } + me->GetMotionMaster()->Clear(); + me->StopMoving(); + Talk(SAY_FINAL_FORM); - void InitializeAI() override - { - BossAI::InitializeAI(); - SummonChannelers(); - } + scheduler.Schedule(4s, [this](TaskContext) + { + DoCastSelf(SPELL_SUMMON_SHADOW_OF_LEOTHERAS); + }).Schedule(6s, [this](TaskContext) + { + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetReactState(REACT_AGGRESSIVE); + me->GetMotionMaster()->MoveChase(me->GetVictim()); + }); + }); + } - void JustReachedHome() override - { - BossAI::JustReachedHome(); - SummonChannelers(); - } + void SummonChannelers() + { + me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, false); + DoCastSelf(SPELL_BANISH); + me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true); - void SummonChannelers() + //probably needs a spell instead + summons.DespawnAll(); + for (uint8 i = 0; i < MAX_CHANNELERS; ++i) { - me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, false); - me->CastSpell(me, SPELL_BANISH, true); - me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true); - - summons.DespawnAll(); - for (uint8 i = 0; i < MAX_CHANNELERS; ++i) - me->SummonCreature(NPC_GREYHEART_SPELLBINDER, channelersPos[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + me->SummonCreature(NPC_GREYHEART_SPELLBINDER, channelersPos[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); } + } - void MoveInLineOfSight(Unit* /*who*/) override { } + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + } - void JustSummoned(Creature* summon) override + void SummonedCreatureDies(Creature* summon, Unit*) override + { + me->SetInCombatWithZone(); + summons.Despawn(summon); + if (summon->GetEntry() == NPC_GREYHEART_SPELLBINDER) { - summons.Summon(summon); - } + if (!summons.HasEntry(NPC_GREYHEART_SPELLBINDER)) + { + me->RemoveAllAuras(); + me->LoadEquipment(); + me->SetReactState(REACT_AGGRESSIVE); + me->SetStandState(UNIT_STAND_STATE_STAND); + Talk(SAY_AGGRO); - void SummonedCreatureDies(Creature* summon, Unit*) override - { - me->SetInCombatWithZone(); - summons.Despawn(summon); - if (summon->GetEntry() == NPC_GREYHEART_SPELLBINDER) - if (!summons.HasEntry(NPC_GREYHEART_SPELLBINDER)) + scheduler.Schedule(10min, [this](TaskContext) { - me->RemoveAllAuras(); - me->LoadEquipment(); - me->SetReactState(REACT_AGGRESSIVE); - me->SetStandState(UNIT_STAND_STATE_STAND); - Talk(SAY_AGGRO); - - events.ScheduleEvent(EVENT_SPELL_BERSERK, 600000); - events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000); - events.ScheduleEvent(EVENT_SWITCH_TO_DEMON, 55000); - events.ScheduleEvent(EVENT_SPELL_WHIRLWIND, 10000); - } - } + DoCastSelf(SPELL_BERSERK); + }); - void KilledUnit(Unit* /*victim*/) override - { - if (events.GetNextEventTime(EVENT_KILL_TALK) == 0) - { - Talk(me->GetDisplayId() != me->GetNativeDisplayId() ? SAY_DEMON_SLAY : SAY_NIGHTELF_SLAY); - events.ScheduleEvent(EVENT_KILL_TALK, 6000); + ElfTime(); } } + } - void JustDied(Unit* killer) override - { - me->CastSpell(me, SPELL_CLEAR_CONSUMING_MADNESS, true); - Talk(SAY_DEATH); - BossAI::JustDied(killer); - } - - void JustEngagedWith(Unit* who) override + void ElfTime() + { + scheduler.Schedule(25050ms, 32550ms, GROUP_COMBAT, [this](TaskContext context) { - BossAI::JustEngagedWith(who); - me->SetStandState(UNIT_STAND_STATE_KNEEL); - } - - void AttackStart(Unit* who) override + DoCastSelf(SPELL_WHIRLWIND); + context.Repeat(30250ms, 34900ms); + }).Schedule(60350ms, GROUP_DEMON, [this](TaskContext) { - if (who && me->Attack(who, true)) - me->GetMotionMaster()->MoveChase(who, me->GetDisplayId() == me->GetNativeDisplayId() ? 0.0f : 25.0f); - } + DoResetThreatList(); + Talk(SAY_SWITCH_TO_DEMON); + DemonTime(); + }); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void DemonTime() + { + me->LoadEquipment(0, true); + me->GetMotionMaster()->MoveChase(me->GetVictim(), 25.0f); + DoCastSelf(SPELL_METAMORPHOSIS, true); + + scheduler.CancelGroup(GROUP_COMBAT); + scheduler.Schedule(24250ms, GROUP_DEMON, [this](TaskContext) + { + Talk(SAY_INNER_DEMONS); + me->CastCustomSpell(SPELL_INSIDIOUS_WHISPER, SPELLVALUE_MAX_TARGETS, 5, me, false); + }).Schedule(60s, [this](TaskContext) + { + DoResetThreatList(); + me->LoadEquipment(); + me->GetMotionMaster()->MoveChase(me->GetVictim(), 0.0f); + me->RemoveAurasDueToSpell(SPELL_METAMORPHOSIS); + ElfTime(); + }); + } - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_BERSERK: - me->CastSpell(me, SPELL_BERSERK, true); - break; - case EVENT_HEALTH_CHECK: - if (me->HealthBelowPct(15)) - { - if (me->GetDisplayId() != me->GetNativeDisplayId()) - { - DoResetThreatList(); - me->LoadEquipment(); - me->RemoveAurasDueToSpell(SPELL_METAMORPHOSIS); - events.ScheduleEvent(EVENT_SPELL_WHIRLWIND, 10000); - } - events.CancelEvent(EVENT_SWITCH_TO_DEMON); - events.CancelEvent(EVENT_SPELL_INSIDIOUS_WHISPER); - events.DelayEvents(10000); - events.ScheduleEvent(EVENT_SUMMON_DEMON, 4000); - events.ScheduleEvent(EVENT_RESTORE_FIGHT, 6000); - me->SetStandState(UNIT_STAND_STATE_KNEEL); - me->SetReactState(REACT_PASSIVE); - me->GetMotionMaster()->Clear(); - me->StopMoving(); - Talk(SAY_FINAL_FORM); - break; - } - events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000); - break; - case EVENT_SWITCH_TO_DEMON: - DoResetThreatList(); - Talk(SAY_SWITCH_TO_DEMON); - me->LoadEquipment(0, true); - me->GetMotionMaster()->MoveChase(me->GetVictim(), 25.0f); - me->CastSpell(me, SPELL_METAMORPHOSIS, true); - - events.CancelEvent(EVENT_SPELL_WHIRLWIND); - events.ScheduleEvent(EVENT_SPELL_INSIDIOUS_WHISPER, 25000); - events.ScheduleEvent(EVENT_SWITCH_TO_ELF, 60000); - break; - case EVENT_SWITCH_TO_ELF: - DoResetThreatList(); - me->LoadEquipment(); - me->GetMotionMaster()->MoveChase(me->GetVictim(), 0.0f); - me->RemoveAurasDueToSpell(SPELL_METAMORPHOSIS); - events.ScheduleEvent(EVENT_SWITCH_TO_DEMON, 55000); - events.ScheduleEvent(EVENT_SPELL_WHIRLWIND, 10000); - break; - case EVENT_SPELL_WHIRLWIND: - me->CastSpell(me, SPELL_WHIRLWIND, false); - events.ScheduleEvent(EVENT_SPELL_WHIRLWIND, 27000); - break; - case EVENT_SPELL_INSIDIOUS_WHISPER: - Talk(SAY_INNER_DEMONS); - me->CastCustomSpell(SPELL_INSIDIOUS_WHISPER, SPELLVALUE_MAX_TARGETS, 5, me, false); - break; - case EVENT_SUMMON_DEMON: - me->CastSpell(me, SPELL_SUMMON_SHADOW_OF_LEOTHERAS, true); - break; - case EVENT_RESTORE_FIGHT: - me->SetStandState(UNIT_STAND_STATE_STAND); - me->SetReactState(REACT_AGGRESSIVE); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - break; - } + scheduler.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - if (me->GetDisplayId() == me->GetNativeDisplayId()) - DoMeleeAttackIfReady(); - else if (me->isAttackReady(BASE_ATTACK)) - { - me->CastSpell(me->GetVictim(), SPELL_CHAOS_BLAST, false); - me->setAttackTimer(BASE_ATTACK, 2000); - } + if (me->GetDisplayId() == me->GetNativeDisplayId()) + { + DoMeleeAttackIfReady(); } - }; + else if (me->isAttackReady(BASE_ATTACK)) + { + me->CastSpell(me->GetVictim(), SPELL_CHAOS_BLAST, false); + me->setAttackTimer(BASE_ATTACK, 2000); + } + } +private: + bool _recentlySpoken; }; -class npc_inner_demon : public CreatureScript +struct npc_inner_demon : public ScriptedAI { -public: - npc_inner_demon() : CreatureScript("npc_inner_demon") { } - - CreatureAI* GetAI(Creature* creature) const override + npc_inner_demon(Creature* creature) : ScriptedAI(creature) { - return GetSerpentShrineAI(creature); + _scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + + _instance = creature->GetInstanceScript(); } - struct npc_inner_demonAI : public ScriptedAI + void EnterEvadeMode(EvadeReason /*why*/) override { - npc_inner_demonAI(Creature* creature) : ScriptedAI(creature) - { - } - - ObjectGuid ownerGUID; - EventMap events; + me->DespawnOrUnsummon(1); + } - void EnterEvadeMode(EvadeReason /*why*/) override - { - me->DespawnOrUnsummon(1); - } + void IsSummonedBy(WorldObject* summoner) override + { + if (!summoner) + return; - void IsSummonedBy(WorldObject* summoner) override + _scheduler.CancelAll(); + _scheduler.Schedule(4s, [this](TaskContext context) { - if (!summoner) - return; - - ownerGUID = summoner->GetGUID(); - events.Reset(); - events.ScheduleEvent(EVENT_SPELL_SHADOW_BOLT, 4000); - } + DoCastVictim(SPELL_SHADOW_BOLT); + context.Repeat(6s); + }); + } - void JustDied(Unit* /*killer*/) override + void JustDied(Unit* /*killer*/) override + { + if (Creature* leotheras = _instance->GetCreature(DATA_LEOTHERAS_THE_BLIND)) { - if (Unit* unit = ObjectAccessor::GetUnit(*me, ownerGUID)) - unit->RemoveAurasDueToSpell(SPELL_INSIDIOUS_WHISPER); + leotheras->RemoveAurasDueToSpell(SPELL_INSIDIOUS_WHISPER); } + } - void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override + void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (Creature* leotheras = _instance->GetCreature(DATA_LEOTHERAS_THE_BLIND)) { - if (!who || who->GetGUID() != ownerGUID) + if (!who || who->GetGUID() != leotheras->GetGUID()) + { damage = 0; + } } + } - bool CanAIAttack(Unit const* who) const override + bool CanAIAttack(Unit const* who) const override + { + if (Creature* leotheras = _instance->GetCreature(DATA_LEOTHERAS_THE_BLIND)) { - return who->GetGUID() == ownerGUID; + return who->GetGUID() == leotheras->GetGUID(); } + return false; + } - void UpdateAI(uint32 diff) override + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + return; + } - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_SHADOW_BOLT: - me->CastSpell(me->GetVictim(), SPELL_SHADOW_BOLT, false); - events.ScheduleEvent(EVENT_SPELL_SHADOW_BOLT, 6000); - break; - } + _scheduler.Update(diff); - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } +private: + TaskScheduler _scheduler; + InstanceScript* _instance; }; class spell_leotheras_whirlwind : public SpellScriptLoader @@ -516,8 +475,8 @@ class spell_leotheras_clear_consuming_madness : public SpellScriptLoader void AddSC_boss_leotheras_the_blind() { - new boss_leotheras_the_blind(); - new npc_inner_demon(); + RegisterSerpentShrineAI(boss_leotheras_the_blind); + RegisterSerpentShrineAI(npc_inner_demon); new spell_leotheras_whirlwind(); new spell_leotheras_chaos_blast(); new spell_leotheras_insidious_whisper(); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp index 34349e80ac903d..c2287f8ba7d6f4 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp @@ -26,7 +26,10 @@ enum Spells SPELL_GEYSER = 37478, SPELL_SPOUT_VISUAL = 37431, SPELL_SPOUT_PERIODIC = 37430, - SPELL_LURKER_SPAWN_TRIGGER = 54587 // Needed for achievement + SPELL_LURKER_SPAWN_TRIGGER = 54587, // Needed for achievement + + SPELL_CLEAR_ALL_DEBUFFS = 34098, + SPELL_SUBMERGE_VISUAL = 28819, }; enum Misc @@ -37,13 +40,12 @@ enum Misc NPC_COILFANG_GUARDIAN = 21873, NPC_COILFANG_AMBUSHER = 21865, +}; - EVENT_PHASE_1 = 1, - EVENT_PHASE_2 = 2, - EVENT_SPELL_WHIRL = 3, - EVENT_SPELL_SPOUT = 4, - EVENT_SPELL_GEYSER = 5, - EVENT_SPELL_SPOUT_PERIODIC = 6 +enum Groups +{ + GROUP_WHIRL = 1, + GROUP_GEYSER = 2 }; const Position positions[MAX_SUMMONS] = @@ -59,152 +61,149 @@ const Position positions[MAX_SUMMONS] = {42.471519f, -445.115295f, -19.769423f, 0.0f} }; -class boss_the_lurker_below : public CreatureScript +struct boss_the_lurker_below : public BossAI { -public: - boss_the_lurker_below() : CreatureScript("boss_the_lurker_below") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_the_lurker_below(Creature* creature) : BossAI(creature, DATA_THE_LURKER_BELOW) { - return GetSerpentShrineAI(creature); + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); } - struct boss_the_lurker_belowAI : public BossAI + void Reset() override { - boss_the_lurker_belowAI(Creature* creature) : BossAI(creature, DATA_THE_LURKER_BELOW) { } + BossAI::Reset(); + me->SetReactState(REACT_PASSIVE); + me->SetStandState(UNIT_STAND_STATE_SUBMERGED); + me->SetVisible(false); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + } - void Reset() override + void DoAction(int32 action) override + { + if (action == ACTION_START_EVENT) { - BossAI::Reset(); - me->SetReactState(REACT_PASSIVE); - me->SetStandState(UNIT_STAND_STATE_SUBMERGED); - me->SetVisible(false); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - - // Reset summons - summons.DespawnAll(); + me->SetReactState(REACT_AGGRESSIVE); + me->setAttackTimer(BASE_ATTACK, 6000); + me->SetVisible(true); + me->UpdateObjectVisibility(true); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetInCombatWithZone(); } + } - void JustSummoned(Creature* summon) override + void AttackStart(Unit* who) override + { + if (who && me->GetReactState() == REACT_AGGRESSIVE) { - summon->SetInCombatWithZone(); - summons.Summon(summon); + me->Attack(who, true); } + } - void DoAction(int32 param) override - { - if (param == ACTION_START_EVENT) - { - me->SetReactState(REACT_AGGRESSIVE); - me->setAttackTimer(BASE_ATTACK, 6000); - me->SetVisible(true); - me->UpdateObjectVisibility(true); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetStandState(UNIT_STAND_STATE_STAND); - me->SetInCombatWithZone(); - } - } + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); - void JustDied(Unit* killer) override - { - BossAI::JustDied(killer); - } + SchedulerPhaseOne(38800ms, 91000ms); + } - void AttackStart(Unit* who) override + void SchedulerPhaseOne(std::chrono::milliseconds spoutTimer, std::chrono::milliseconds p2Timer) + { + scheduler.Schedule(10900ms, GROUP_GEYSER, [this](TaskContext context) { - if (who && me->GetReactState() == REACT_AGGRESSIVE) - me->Attack(who, true); - } - - void JustEngagedWith(Unit* /*who*/) override + DoCastRandomTarget(SPELL_GEYSER); + context.Repeat(10200ms, 54900ms); + }).Schedule(18150ms, GROUP_WHIRL, [this](TaskContext context) { - events.ScheduleEvent(EVENT_SPELL_WHIRL, 18000); - events.ScheduleEvent(EVENT_SPELL_SPOUT, 45000); - events.ScheduleEvent(EVENT_SPELL_GEYSER, 10000); - events.ScheduleEvent(EVENT_PHASE_2, 125000); - } + DoCastSelf(SPELL_WHIRL); + context.Repeat(34150ms, 68550ms); + }).Schedule(spoutTimer, [this](TaskContext context) + { + Talk(EMOTE_TAKE_BREATH); + me->CastSpell(me, SPELL_SPOUT_VISUAL, TRIGGERED_IGNORE_SET_FACING); + me->SetReactState(REACT_PASSIVE); + me->SetFacingToObject(me->GetVictim()); + me->SetTarget(); + scheduler.RescheduleGroup(GROUP_GEYSER, 25s); + scheduler.RescheduleGroup(GROUP_WHIRL, 18s); + scheduler.Schedule(3s, [this](TaskContext) + { + me->InterruptNonMeleeSpells(false); + DoCastSelf(SPELL_SPOUT_PERIODIC, true); + }); + context.Repeat(60s); + }).Schedule(p2Timer, [this](TaskContext) + { + //phase2 + scheduler.CancelAll(); + DoCastSelf(SPELL_SUBMERGE_VISUAL, true); + DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS, true); + me->SetStandState(UNIT_STAND_STATE_SUBMERGED); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + for (uint8 i = 0; i < MAX_SUMMONS; ++i) + { + //needs sniffed spell probably + me->SummonCreature(i < 6 ? NPC_COILFANG_AMBUSHER : NPC_COILFANG_GUARDIAN, positions[i].GetPositionX(), positions[i].GetPositionY(), positions[i].GetPositionZ(), positions[i].GetAngle(me), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); + } + SchedulerPhaseTwo(); + }); + } - void UpdateAI(uint32 diff) override + void SchedulerPhaseTwo() + { + scheduler.Schedule(60s, [this](TaskContext) { - if (!UpdateVictim()) - return; + me->setAttackTimer(BASE_ATTACK, 6000); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + scheduler.CancelAll(); + SchedulerPhaseOne(10000ms, 90750ms); + }); + } - events.Update(diff); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_WHIRL: - me->CastSpell(me, SPELL_WHIRL, false); - events.ScheduleEvent(EVENT_SPELL_WHIRL, 18000); - break; - case EVENT_SPELL_GEYSER: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target, SPELL_GEYSER, false); - events.ScheduleEvent(EVENT_SPELL_GEYSER, 10000); - break; - case EVENT_SPELL_SPOUT: - Talk(EMOTE_TAKE_BREATH); - me->CastSpell(me, SPELL_SPOUT_VISUAL, TRIGGERED_IGNORE_SET_FACING); - me->SetReactState(REACT_PASSIVE); - me->SetFacingToObject(me->GetVictim()); - me->SetTarget(); - events.ScheduleEvent(EVENT_SPELL_SPOUT, 60000); - events.RescheduleEvent(EVENT_SPELL_WHIRL, 18000); - events.RescheduleEvent(EVENT_SPELL_GEYSER, 25000); - events.ScheduleEvent(EVENT_SPELL_SPOUT_PERIODIC, 3000); - break; - case EVENT_SPELL_SPOUT_PERIODIC: - me->InterruptNonMeleeSpells(false); - me->CastSpell(me, SPELL_SPOUT_PERIODIC, true); - break; - case EVENT_PHASE_2: - events.Reset(); - events.ScheduleEvent(EVENT_PHASE_1, 60000); - me->SetStandState(UNIT_STAND_STATE_SUBMERGED); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - for (uint8 i = 0; i < MAX_SUMMONS; ++i) - me->SummonCreature(i < 6 ? NPC_COILFANG_AMBUSHER : NPC_COILFANG_GUARDIAN, positions[i].GetPositionX(), positions[i].GetPositionY(), positions[i].GetPositionZ(), positions[i].GetAngle(me), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - break; - case EVENT_PHASE_1: - me->setAttackTimer(BASE_ATTACK, 6000); - me->SetStandState(UNIT_STAND_STATE_STAND); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - - events.Reset(); - events.ScheduleEvent(EVENT_SPELL_SPOUT, 10000); - events.ScheduleEvent(EVENT_PHASE_2, 120000); - break; - } + scheduler.Update(diff); - if (me->getStandState() != UNIT_STAND_STATE_STAND || !me->isAttackReady() || me->GetReactState() != REACT_AGGRESSIVE) - return; + if (me->getStandState() != UNIT_STAND_STATE_STAND || !me->isAttackReady() || me->GetReactState() != REACT_AGGRESSIVE) + return; - Unit* target = nullptr; - if (me->IsWithinMeleeRange(me->GetVictim())) - target = me->GetVictim(); - else + Unit* target = nullptr; + if (me->IsWithinMeleeRange(me->GetVictim())) + { + target = me->GetVictim(); + } + else + { + ThreatContainer::StorageType const& t_list = me->GetThreatMgr().GetThreatList(); + for (ThreatReference const* ref : t_list) { - ThreatContainer::StorageType const& t_list = me->GetThreatMgr().GetThreatList(); - for (ThreatContainer::StorageType::const_iterator itr = t_list.begin(); itr != t_list.end(); ++itr) - if (Unit* threatTarget = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid())) - if (me->IsWithinMeleeRange(threatTarget)) - { - target = threatTarget; - break; - } + if (Unit* threatTarget = ObjectAccessor::GetUnit(*me, ref->getUnitGuid())) + { + if (me->IsWithinMeleeRange(threatTarget)) + { + target = threatTarget; + break; + } + } } - - if (target) - me->AttackerStateUpdate(target); - else if ((target = SelectTarget(SelectTargetMethod::Random, 0))) - me->CastSpell(target, SPELL_WATER_BOLT, false); - - me->resetAttackTimer(); } - }; + if (target) + { + me->AttackerStateUpdate(target); + } + else if ((target = SelectTarget(SelectTargetMethod::Random, 0))) + { + me->CastSpell(target, SPELL_WATER_BOLT, false); + } + me->resetAttackTimer(); + } }; class go_strange_pool : public GameObjectScript @@ -315,7 +314,7 @@ class spell_lurker_below_spout_cone : public SpellScriptLoader void AddSC_boss_the_lurker_below() { - new boss_the_lurker_below(); + RegisterSerpentShrineAI(boss_the_lurker_below); new go_strange_pool(); new spell_lurker_below_spout(); new spell_lurker_below_spout_cone(); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp index 34411df6a33aa6..e16d84e75b6dcb 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp @@ -112,7 +112,7 @@ struct boss_morogrim_tidewalker : public BossAI else { Talk(EMOTE_WATERY_GLOBULES); - for (uint8 waterGlobuleId : waterGlobuleIds) + for (uint32 waterGlobuleId : waterGlobuleIds) { DoCastSelf(waterGlobuleId, true); } diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp index d22cd4c470dc59..90d4c5e6c3d11b 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp @@ -29,6 +29,20 @@ DoorData const doorData[] = { GO_COILFANG_BRIDGE3, DATA_BRIDGE_EMERGED, DOOR_TYPE_PASSAGE } }; +ObjectData const creatureData[] = +{ + { NPC_FATHOM_LORD_KARATHRESS, DATA_FATHOM_LORD_KARATHRESS }, + { 0, 0 } +}; + +MinionData const minionData[] = +{ + { NPC_FATHOM_GUARD_SHARKKIS, DATA_FATHOM_LORD_KARATHRESS }, + { NPC_FATHOM_GUARD_TIDALVESS, DATA_FATHOM_LORD_KARATHRESS }, + { NPC_FATHOM_GUARD_CARIBDIS, DATA_FATHOM_LORD_KARATHRESS }, + { 0, 0, } +}; + class instance_serpent_shrine : public InstanceMapScript { public: @@ -45,6 +59,8 @@ class instance_serpent_shrine : public InstanceMapScript SetHeaders(DataHeader); SetBossNumber(MAX_ENCOUNTERS); LoadDoorData(doorData); + LoadObjectData(creatureData, nullptr); + LoadMinionData(minionData); AliveKeepersCount = 0; } diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h index 3963cb6c2494bf..8e10302b953451 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h @@ -53,8 +53,13 @@ enum SSNPCs NPC_THE_LURKER_BELOW = 21217, NPC_LEOTHERAS_THE_BLIND = 21215, NPC_CYCLONE_KARATHRESS = 22104, + NPC_FATHOM_LORD_KARATHRESS = 21214, NPC_LADY_VASHJ = 21212, + NPC_FATHOM_GUARD_SHARKKIS = 21966, + NPC_FATHOM_GUARD_TIDALVESS = 21965, + NPC_FATHOM_GUARD_CARIBDIS = 21964, + NPC_COILFANG_SHATTERER = 21301, NPC_COILFANG_PRIESTESS = 21220, diff --git a/src/server/scripts/Outland/CoilfangReservoir/SlavePens/boss_quagmirran.cpp b/src/server/scripts/Outland/CoilfangReservoir/SlavePens/boss_quagmirran.cpp index 105b17616d3e63..136348fa6e7f67 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SlavePens/boss_quagmirran.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SlavePens/boss_quagmirran.cpp @@ -23,8 +23,7 @@ enum Spells { SPELL_ACID_SPRAY = 38153, SPELL_CLEAVE = 40504, - SPELL_POISON_BOLT_VOLLEY_N = 34780, - SPELL_POISON_BOLT_VOLLEY_H = 39340, + SPELL_POISON_BOLT_VOLLEY = 34780, SPELL_UPPERCUT = 32055 }; @@ -38,11 +37,6 @@ struct boss_quagmirran : public BossAI }); } - void Reset() override - { - _Reset(); - } - void JustEngagedWith(Unit* /*who*/) override { _JustEngagedWith(); @@ -57,11 +51,11 @@ struct boss_quagmirran : public BossAI context.Repeat(21800ms); }).Schedule(25200ms, [this](TaskContext context) { - DoCastVictim(SPELL_ACID_SPRAY); + DoCastRandomTarget(SPELL_ACID_SPRAY); context.Repeat(25s); }).Schedule(31800ms, [this](TaskContext context) { - DoCastSelf(DUNGEON_MODE(SPELL_POISON_BOLT_VOLLEY_N, SPELL_POISON_BOLT_VOLLEY_H)); + DoCastAOE(SPELL_POISON_BOLT_VOLLEY); context.Repeat(24400ms); }); } @@ -70,4 +64,4 @@ struct boss_quagmirran : public BossAI void AddSC_boss_quagmirran() { RegisterTheSlavePensCreatureAI(boss_quagmirran); -} \ No newline at end of file +} diff --git a/src/server/scripts/Outland/CoilfangReservoir/underbog/instance_the_underbog.cpp b/src/server/scripts/Outland/CoilfangReservoir/underbog/instance_the_underbog.cpp index c06178bb399bb1..557afea8d512cd 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/underbog/instance_the_underbog.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/underbog/instance_the_underbog.cpp @@ -1,14 +1,14 @@ /* - * Copyright (C) 2008-2018 TrinityCore + * 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 General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your + * 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 General Public License for + * 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 diff --git a/src/server/scripts/Outland/GruulsLair/instance_gruuls_lair.cpp b/src/server/scripts/Outland/GruulsLair/instance_gruuls_lair.cpp index 5fbfadbcb4ca15..a826f8857e869b 100644 --- a/src/server/scripts/Outland/GruulsLair/instance_gruuls_lair.cpp +++ b/src/server/scripts/Outland/GruulsLair/instance_gruuls_lair.cpp @@ -26,6 +26,12 @@ DoorData const doorData[] = { 0, 0, DOOR_TYPE_ROOM } // END }; +ObjectData const creatureData[] = +{ + { NPC_MAULGAR, DATA_MAULGAR }, + { 0, 0 } +}; + MinionData const minionData[] = { { NPC_MAULGAR, DATA_MAULGAR }, @@ -46,64 +52,13 @@ class instance_gruuls_lair : public InstanceMapScript { SetHeaders(DataHeader); SetBossNumber(MAX_ENCOUNTER); + LoadObjectData(creatureData, nullptr); LoadDoorData(doorData); LoadMinionData(minionData); _addsKilled = 0; } - void OnCreatureCreate(Creature* creature) override - { - switch (creature->GetEntry()) - { - case NPC_MAULGAR: - _maulgarGUID = creature->GetGUID(); - [[fallthrough]]; - case NPC_KROSH_FIREHAND: - case NPC_OLM_THE_SUMMONER: - case NPC_KIGGLER_THE_CRAZED: - case NPC_BLINDEYE_THE_SEER: - AddMinion(creature, true); - break; - } - } - - void OnCreatureRemove(Creature* creature) override - { - switch (creature->GetEntry()) - { - case NPC_MAULGAR: - case NPC_KROSH_FIREHAND: - case NPC_OLM_THE_SUMMONER: - case NPC_KIGGLER_THE_CRAZED: - case NPC_BLINDEYE_THE_SEER: - AddMinion(creature, false); - break; - } - } - - void OnGameObjectCreate(GameObject* go) override - { - switch (go->GetEntry()) - { - case GO_MAULGAR_DOOR: - case GO_GRUUL_DOOR: - AddDoor(go, true); - break; - } - } - - void OnGameObjectRemove(GameObject* go) override - { - switch (go->GetEntry()) - { - case GO_MAULGAR_DOOR: - case GO_GRUUL_DOOR: - AddDoor(go, false); - break; - } - } - bool SetBossState(uint32 id, EncounterState state) override { if (!InstanceScript::SetBossState(id, state)) @@ -117,8 +72,12 @@ class instance_gruuls_lair : public InstanceMapScript void SetData(uint32 type, uint32 /*id*/) override { if (type == DATA_ADDS_KILLED) - if (Creature* maulgar = instance->GetCreature(_maulgarGUID)) + { + if (Creature* maulgar = GetCreature(DATA_MAULGAR)) + { maulgar->AI()->DoAction(++_addsKilled); + } + } } uint32 GetData(uint32 type) const override @@ -130,7 +89,6 @@ class instance_gruuls_lair : public InstanceMapScript protected: uint32 _addsKilled; - ObjectGuid _maulgarGUID; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp index 580e51d848b9b4..baee4273231504 100644 --- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp @@ -55,8 +55,10 @@ enum Spells SPELL_QUAKE_KNOCKBACK = 30571, SPELL_COLLAPSE_DAMAGE = 36449, SPELL_CAMERA_SHAKE = 36455, + SPELL_DEBRIS_TARGET = 30629, + SPELL_DEBRIS_SPAWN = 30630, + SPELL_DEBRIS_DAMAGE = 30631, SPELL_DEBRIS_VISUAL = 30632, - SPELL_DEBRIS_DAMAGE = 30631 }; enum Groups @@ -70,26 +72,9 @@ enum Actions ACTION_INCREASE_HELLFIRE_CHANNELER_DEATH_COUNT = 1 }; -class DealDebrisDamage : public BasicEvent -{ -public: - DealDebrisDamage(Creature& creature, ObjectGuid targetGUID) : _owner(creature), _targetGUID(targetGUID) { } - - bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override - { - if (Unit* target = ObjectAccessor::GetUnit(_owner, _targetGUID)) - target->CastSpell(target, SPELL_DEBRIS_DAMAGE, true, nullptr, nullptr, _owner.GetGUID()); - return true; - } - -private: - Creature& _owner; - ObjectGuid _targetGUID; -}; - struct boss_magtheridon : public BossAI { - boss_magtheridon(Creature* creature) : BossAI(creature, TYPE_MAGTHERIDON) + boss_magtheridon(Creature* creature) : BossAI(creature, DATA_MAGTHERIDON) { scheduler.SetValidator([this] { @@ -137,11 +122,7 @@ struct boss_magtheridon : public BossAI _currentPhase = 0; scheduler.Schedule(20s, [this](TaskContext context) { - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - { - target->CastSpell(target, SPELL_DEBRIS_VISUAL, true, nullptr, nullptr, me->GetGUID()); - me->m_Events.AddEvent(new DealDebrisDamage(*me, target->GetGUID()), me->m_Events.CalculateTime(5000)); - } + DoCastAOE(SPELL_DEBRIS_TARGET); context.Repeat(20s); }); }); @@ -185,7 +166,7 @@ struct boss_magtheridon : public BossAI { me->CastCustomSpell(SPELL_BLAZE, SPELLVALUE_MAX_TARGETS, 1); context.Repeat(11s, 39s); - }).Schedule(40s, [this](TaskContext context) + }).Schedule(28300ms, [this](TaskContext context) { DoCastSelf(SPELL_QUAKE); _castingQuake = true; @@ -194,29 +175,33 @@ struct boss_magtheridon : public BossAI me->SetOrientation(me->GetAngle(me->GetVictim())); me->SetTarget(ObjectGuid::Empty); scheduler.DelayAll(6999ms); - scheduler.Schedule(7s, [this](TaskContext /*context*/) + scheduler.Schedule(7s, [this](TaskContext) { _castingQuake = false; me->SetReactState(REACT_AGGRESSIVE); me->GetMotionMaster()->MoveChase(me->GetVictim()); - DoCastSelf(SPELL_BLAST_NOVA); + }); + context.Repeat(56300ms, 64300ms); + }).Schedule(55650ms, [this](TaskContext context) + { + DoCastSelf(SPELL_BLAST_NOVA); + scheduler.DelayAll(10s); - _interruptScheduler.Schedule(50ms, GROUP_INTERRUPT_CHECK, [this](TaskContext context) - { - if (me->GetAuraCount(SPELL_SHADOW_GRASP_VISUAL) == 5) - { - Talk(SAY_BANISH); - me->InterruptNonMeleeSpells(true); - scheduler.CancelGroup(GROUP_INTERRUPT_CHECK); - } - else - context.Repeat(50ms); - }).Schedule(12s, GROUP_INTERRUPT_CHECK, [this](TaskContext /*context*/) + _interruptScheduler.Schedule(50ms, GROUP_INTERRUPT_CHECK, [this](TaskContext context) + { + if (me->GetAuraCount(SPELL_SHADOW_GRASP_VISUAL) == 5) { - _interruptScheduler.CancelGroup(GROUP_INTERRUPT_CHECK); - }); + Talk(SAY_BANISH); + me->InterruptNonMeleeSpells(true); + scheduler.CancelGroup(GROUP_INTERRUPT_CHECK); + } + else + context.Repeat(50ms); + }).Schedule(12s, GROUP_INTERRUPT_CHECK, [this](TaskContext /*context*/) + { + _interruptScheduler.CancelGroup(GROUP_INTERRUPT_CHECK); }); - context.Repeat(53s, 56s); + context.Repeat(54350ms, 55400ms); }).Schedule(22min, [this](TaskContext /*context*/) { DoCastSelf(SPELL_BERSERK, true); @@ -248,7 +233,7 @@ struct boss_magtheridon : public BossAI BossAI::JustEngagedWith(who); Talk(SAY_EMOTE_BEGIN); - instance->DoForAllMinions(TYPE_MAGTHERIDON, [&](Creature* creature) { + instance->DoForAllMinions(DATA_MAGTHERIDON, [&](Creature* creature) { creature->SetInCombatWithZone(); }); @@ -289,6 +274,37 @@ struct boss_magtheridon : public BossAI TaskScheduler _interruptScheduler; }; +struct npc_target_trigger : public ScriptedAI +{ + npc_target_trigger(Creature* creature) : ScriptedAI(creature), _cast(false) + { + me->SetReactState(REACT_PASSIVE); + } + + void Reset() override + { + if (!_cast) + { + DoCastSelf(SPELL_DEBRIS_VISUAL); + _cast = true; + _scheduler.Schedule(5s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_DEBRIS_DAMAGE); + me->DespawnOrUnsummon(6000); + }); + } + } + + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + } + +protected: + TaskScheduler _scheduler; + bool _cast; +}; + class spell_magtheridon_blaze : public SpellScript { PrepareSpellScript(spell_magtheridon_blaze); @@ -348,6 +364,33 @@ class spell_magtheridon_quake : public SpellScript } }; +class spell_magtheridon_debris_target_selector : public SpellScript +{ + PrepareSpellScript(spell_magtheridon_debris_target_selector); + + void FilterTargets(std::list& targets) + { + targets.remove_if([&](WorldObject* target) -> bool + { + return target->GetEntry() != NPC_TARGET_TRIGGER; + }); + + Acore::Containers::RandomResize(targets, 1); + } + + void HandleHit() + { + if (Unit* target = GetHitUnit()) + target->CastSpell(target, SPELL_DEBRIS_SPAWN); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_magtheridon_debris_target_selector::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnHit += SpellHitFn(spell_magtheridon_debris_target_selector::HandleHit); + } +}; + class go_manticron_cube : public GameObjectScript { public: @@ -369,8 +412,10 @@ class go_manticron_cube : public GameObjectScript void AddSC_boss_magtheridon() { RegisterMagtheridonsLairCreatureAI(boss_magtheridon); + RegisterMagtheridonsLairCreatureAI(npc_target_trigger); RegisterSpellScript(spell_magtheridon_blaze); RegisterSpellScript(spell_magtheridon_shadow_grasp); RegisterSpellScript(spell_magtheridon_quake); + RegisterSpellScript(spell_magtheridon_debris_target_selector); new go_manticron_cube(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp index 454479e9c75fec..33b1c111364293 100644 --- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp @@ -21,18 +21,18 @@ BossBoundaryData const boundaries = { - { TYPE_MAGTHERIDON, new CircleBoundary(Position(-18.70f, 2.24f), 52.30) } + { DATA_MAGTHERIDON, new CircleBoundary(Position(-18.70f, 2.24f), 52.30) } }; DoorData const doorData[] = { - { GO_MAGTHERIDON_DOORS, TYPE_MAGTHERIDON, DOOR_TYPE_ROOM }, + { GO_MAGTHERIDON_DOORS, DATA_MAGTHERIDON, DOOR_TYPE_ROOM }, { 0, 0, DOOR_TYPE_ROOM } // END }; MinionData const minionData[] = { - { NPC_HELLFIRE_CHANNELER, TYPE_MAGTHERIDON } + { NPC_HELLFIRE_CHANNELER, DATA_MAGTHERIDON } }; class instance_magtheridons_lair : public InstanceMapScript @@ -133,7 +133,7 @@ class instance_magtheridons_lair : public InstanceMapScript if (!InstanceScript::SetBossState(id, state)) return false; - if (id == TYPE_MAGTHERIDON) + if (id == DATA_MAGTHERIDON) { if (state == IN_PROGRESS) { @@ -163,7 +163,7 @@ class instance_magtheridons_lair : public InstanceMapScript switch (type) { case DATA_CHANNELER_COMBAT: - if (GetBossState(TYPE_MAGTHERIDON) != IN_PROGRESS) + if (GetBossState(DATA_MAGTHERIDON) != IN_PROGRESS) if (Creature* magtheridon = instance->GetCreature(_magtheridonGUID)) magtheridon->SetInCombatWithZone(); break; diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h index a65282235aa19a..4e28280165f672 100644 --- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h +++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h @@ -27,7 +27,7 @@ enum DataTypes { - TYPE_MAGTHERIDON = 0, + DATA_MAGTHERIDON = 0, MAX_ENCOUNTER = 1, DATA_CHANNELER_COMBAT = 10, @@ -41,6 +41,7 @@ enum NpcIds NPC_HELLFIRE_CHANNELER = 17256, NPC_HELLFIRE_WARDER = 18829, NPC_HELLFIRE_RAID_TRIGGER = 17376, + NPC_TARGET_TRIGGER = 17474 }; enum GoIds diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp index 726e2523bfadb1..4817b8d86171cc 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp @@ -443,8 +443,6 @@ class spell_alar_ember_blast_death : public SpellScriptLoader GetUnitOwner()->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); GetUnitOwner()->SetStandState(UNIT_STAND_STATE_DEAD); - GetUnitOwner()->m_last_notify_position.Relocate(0.0f, 0.0f, 0.0f); - GetUnitOwner()->m_delayed_unit_relocation_timer = 1000; } void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) diff --git a/src/server/scripts/Outland/zone_netherstorm.cpp b/src/server/scripts/Outland/zone_netherstorm.cpp index 2f615ec5019859..cee8cf3398f190 100644 --- a/src/server/scripts/Outland/zone_netherstorm.cpp +++ b/src/server/scripts/Outland/zone_netherstorm.cpp @@ -22,6 +22,8 @@ #include "ScriptedEscortAI.h" #include "ScriptedGossip.h" #include "SpellInfo.h" +#include "SpellAuras.h" +#include "SpellScript.h" // Ours enum saeed @@ -697,9 +699,6 @@ class npc_phase_hunter : public CreatureScript { Drained = true; int32 uHpPct = int32(me->GetHealthPct()); - - me->UpdateEntry(NPC_DRAINED_PHASE_HUNTER_ENTRY); - me->SetHealth(me->CountPctFromMaxHealth(uHpPct)); me->LowerPlayerDamageReq(me->GetMaxHealth() - me->GetHealth()); me->SetInCombatWith(player); @@ -911,6 +910,45 @@ class npc_maxx_a_million_escort : public CreatureScript } }; +class spell_q10190_battery_recharging_blaster : public SpellScript +{ + PrepareSpellScript(spell_q10190_battery_recharging_blaster); + + SpellCastResult CheckCast() + { + if (Unit* target = GetExplTargetUnit()) + if (target->GetHealthPct() <= 25.0f) + return SPELL_CAST_OK; + + return SPELL_FAILED_BAD_TARGETS; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_q10190_battery_recharging_blaster::CheckCast); + } + }; + +class spell_q10190_battery_recharging_blaster_aura : public AuraScript +{ + PrepareAuraScript(spell_q10190_battery_recharging_blaster_aura); + + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + return; + + if (Creature* phasehunter = GetTarget()->ToCreature()) + if (phasehunter->GetEntry() == NPC_PHASE_HUNTER_ENTRY) + phasehunter->UpdateEntry(NPC_DRAINED_PHASE_HUNTER_ENTRY); + } + + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_q10190_battery_recharging_blaster_aura::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + void AddSC_netherstorm() { // Ours @@ -922,5 +960,5 @@ void AddSC_netherstorm() new npc_phase_hunter(); new npc_bessy(); new npc_maxx_a_million_escort(); - + RegisterSpellAndAuraScriptPair(spell_q10190_battery_recharging_blaster, spell_q10190_battery_recharging_blaster_aura); } diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 98738a8c9d4845..c909bbce3aaa86 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -148,6 +148,18 @@ class spell_dk_raise_ally : public SpellScript { PrepareSpellScript(spell_dk_raise_ally); + SpellCastResult CheckCast() + { + Player* unitTarget = GetHitPlayer(); + if (!unitTarget) + return SPELL_FAILED_BAD_TARGETS; + + if (unitTarget->IsAlive()) // not discovered attributeEx5? + return SPELL_FAILED_TARGET_NOT_DEAD; + + return SPELL_CAST_OK; + } + void HandleDummy(SpellEffIndex /*effIndex*/) { if (Player* unitTarget = GetHitPlayer()) @@ -239,6 +251,7 @@ class spell_dk_raise_ally : public SpellScript void Register() override { + OnCheckCast += SpellCheckCastFn(spell_dk_raise_ally::CheckCast); OnEffectHitTarget += SpellEffectFn(spell_dk_raise_ally::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 2b5d248d0561e7..60d35121e31b32 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -389,20 +389,45 @@ class spell_dru_treant_scaling : public AuraScript }; // -1850 - Dash -class spell_dru_dash : public AuraScript +class spell_dru_dash : public SpellScript { - PrepareAuraScript(spell_dru_dash); + PrepareSpellScript(spell_dru_dash); + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (caster->GetShapeshiftForm() != FORM_CAT) + { + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_BE_IN_CAT_FORM); + return SPELL_FAILED_CUSTOM_ERROR; + } + + return SPELL_CAST_OK; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_dru_dash::CheckCast); + } +}; + +// -1850 - Dash +class spell_dru_dash_aura : public AuraScript +{ + PrepareAuraScript(spell_dru_dash_aura); void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) { // do not set speed if not in cat form if (GetUnitOwner()->GetShapeshiftForm() != FORM_CAT) + { amount = 0; + } } void Register() override { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_dash::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_INCREASE_SPEED); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_dash_aura::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_INCREASE_SPEED); } }; @@ -1183,7 +1208,7 @@ void AddSC_druid_spell_scripts() RegisterSpellScript(spell_dru_barkskin); RegisterSpellScript(spell_dru_treant_scaling); RegisterSpellScript(spell_dru_berserk); - RegisterSpellScript(spell_dru_dash); + RegisterSpellAndAuraScriptPair(spell_dru_dash, spell_dru_dash_aura); RegisterSpellScript(spell_dru_enrage); RegisterSpellScript(spell_dru_glyph_of_starfire); RegisterSpellScript(spell_dru_idol_lifebloom); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index ed26575b37f14a..a6c8c993b8b617 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -5023,6 +5023,32 @@ class spell_gen_spirit_of_competition_winner : public SpellScript } }; +// 27360 - Lord Valthalak's Amulet +enum Valthalak +{ + SPELL_INSTILL_LORD_VALTHALAK_SPIRIT = 27360, + NPC_LORD_VALTHALAK = 16042 +}; + +class spell_gen_valthalak_amulet : public SpellScript +{ + PrepareSpellScript(spell_gen_valthalak_amulet) + + SpellCastResult CheckCast() + { + if (Unit* target = GetExplTargetUnit()) + if (target->GetEntry() == NPC_LORD_VALTHALAK && target->isDead()) + return SPELL_CAST_OK; + + return SPELL_FAILED_BAD_TARGETS; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_gen_valthalak_amulet::CheckCast); + } +}; + void AddSC_generic_spell_scripts() { RegisterSpellScript(spell_silithyst); @@ -5171,4 +5197,5 @@ void AddSC_generic_spell_scripts() RegisterSpellScript(spell_gen_curse_of_pain); RegisterSpellScript(spell_gen_spirit_of_competition_participant); RegisterSpellScript(spell_gen_spirit_of_competition_winner); + RegisterSpellScript(spell_gen_valthalak_amulet); } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 442758b291c64d..09b14929741b9b 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -1316,6 +1316,31 @@ class spell_hun_bestial_wrath : public SpellScript } }; +// -24604 - Furious Howl +// 53434 - Call of the Wild +class spell_hun_target_self_and_pet : public SpellScript +{ + PrepareSpellScript(spell_hun_target_self_and_pet); + + bool Load() override + { + return GetCaster()->IsPet(); + } + + void FilterTargets(std::list& targets) + { + targets.remove_if([&](WorldObject const* target) -> bool + { + return target != GetCaster() && target != GetCaster()->ToPet()->GetOwner(); + }); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_hun_target_self_and_pet::FilterTargets, EFFECT_ALL, TARGET_UNIT_CASTER_AREA_PARTY); + } +}; + void AddSC_hunter_spell_scripts() { RegisterSpellScript(spell_hun_check_pet_los); @@ -1346,4 +1371,5 @@ void AddSC_hunter_spell_scripts() RegisterSpellScript(spell_hun_lock_and_load); RegisterSpellScript(spell_hun_intimidation); RegisterSpellScript(spell_hun_bestial_wrath); + RegisterSpellScript(spell_hun_target_self_and_pet); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index a1cc175c881eca..584e389bb21856 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -3342,9 +3342,9 @@ class spell_item_rocket_boots : public SpellScript } }; -class spell_item_runic_healing_injector : public SpellScript +class spell_item_healing_injector : public SpellScript { - PrepareSpellScript(spell_item_runic_healing_injector); + PrepareSpellScript(spell_item_healing_injector); bool Load() override { @@ -3360,7 +3360,33 @@ class spell_item_runic_healing_injector : public SpellScript void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_item_runic_healing_injector::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); + OnEffectHitTarget += SpellEffectFn(spell_item_healing_injector::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); + } +}; + +class spell_item_mana_injector : public SpellScript +{ + PrepareSpellScript(spell_item_mana_injector); + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleEnergize(SpellEffIndex /*effIndex*/) + { + if (Player* caster = GetCaster()->ToPlayer()) + { + if (caster->HasSkill(SKILL_ENGINEERING)) + { + SetEffectValue(GetEffectValue() * 1.25f); + } + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_mana_injector::HandleEnergize, EFFECT_0, SPELL_EFFECT_ENERGIZE); } }; @@ -3857,6 +3883,64 @@ class spell_item_worn_troll_dice : public SpellScript } }; +enum VenomhideHatchling +{ + NPC_VENOMHIDE_HATCHLING = 34320 +}; + +class spell_item_venomhide_feed : public SpellScript +{ + PrepareSpellScript(spell_item_venomhide_feed) + + SpellCastResult CheckCast() + { + if (Player* player = GetCaster()->ToPlayer()) + { + std::list hatchling; + player->GetAllMinionsByEntry(hatchling, NPC_VENOMHIDE_HATCHLING); + if (!hatchling.empty()) + { + return SPELL_CAST_OK; + } + } + + return SPELL_FAILED_BAD_TARGETS; + } + + void UpdateTarget(WorldObject*& target) + { + if (!target) + { + return; + } + + if (Player* player = GetCaster()->ToPlayer()) + { + std::list hatchling; + player->GetAllMinionsByEntry(hatchling, NPC_VENOMHIDE_HATCHLING); + if (hatchling.empty()) + { + return; + } + + for (Creature* creature : hatchling) + { + if (creature) + { + target = creature; + return; + } + } + } + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_item_venomhide_feed::CheckCast); + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_item_venomhide_feed::UpdateTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY); + } +}; + void AddSC_item_spell_scripts() { RegisterSpellScript(spell_item_massive_seaforium_charge); @@ -3959,7 +4043,8 @@ void AddSC_item_spell_scripts() RegisterSpellScript(spell_item_nitro_boots); RegisterSpellScript(spell_item_teach_language); RegisterSpellScript(spell_item_rocket_boots); - RegisterSpellScript(spell_item_runic_healing_injector); + RegisterSpellScript(spell_item_healing_injector); + RegisterSpellScript(spell_item_mana_injector); RegisterSpellScript(spell_item_pygmy_oil); RegisterSpellScript(spell_item_unusual_compass); RegisterSpellScript(spell_item_chicken_cover); @@ -3976,4 +4061,5 @@ void AddSC_item_spell_scripts() RegisterSpellScript(spell_item_green_whelp_armor); RegisterSpellScript(spell_item_elixir_of_shadows); RegisterSpellScript(spell_item_worn_troll_dice); + RegisterSpellScript(spell_item_venomhide_feed); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 14dfc2e240fa04..55945914e41045 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -302,7 +302,8 @@ class spell_pal_ardent_defender : public AuraScript enum Spell { - PAL_SPELL_ARDENT_DEFENDER_HEAL = 66235 + PAL_SPELL_ARDENT_DEFENDER_DEBUFF = 66233, + PAL_SPELL_ARDENT_DEFENDER_HEAL = 66235 }; bool Validate(SpellInfo const* /*spellInfo*/) override @@ -329,7 +330,7 @@ class spell_pal_ardent_defender : public AuraScript int32 remainingHealth = victim->GetHealth() - dmgInfo.GetDamage(); uint32 allowedHealth = victim->CountPctFromMaxHealth(35); // If damage kills us - if (remainingHealth <= 0 && !victim->ToPlayer()->HasSpellCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL)) + if (remainingHealth <= 0 && !victim->ToPlayer()->HasAura(PAL_SPELL_ARDENT_DEFENDER_DEBUFF)) { // Cast healing spell, completely avoid damage absorbAmount = dmgInfo.GetDamage(); @@ -344,7 +345,6 @@ class spell_pal_ardent_defender : public AuraScript int32 healAmount = int32(victim->CountPctFromMaxHealth(uint32(healPct * pctFromDefense))); victim->CastCustomSpell(PAL_SPELL_ARDENT_DEFENDER_HEAL, SPELLVALUE_BASE_POINT0, healAmount, victim, true, nullptr, aurEff); - victim->ToPlayer()->AddSpellCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL, 0, 120000); } else if (remainingHealth < int32(allowedHealth)) { diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 8de8fbb1edaddd..f683796c300a80 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -48,6 +48,7 @@ enum PriestSpells SPELL_PRIEST_SHADOW_WORD_DEATH = 32409, SPELL_PRIEST_T9_HEALING_2P = 67201, SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL = 64085, + SPELL_PRIEST_T4_4P_FLEXIBILITY = 37565, SPELL_GENERIC_ARENA_DAMPENING = 74410, SPELL_GENERIC_BATTLEGROUND_DAMPENING = 74411, @@ -932,6 +933,28 @@ class spell_pri_mind_control : public AuraScript } }; +// 37565 - Flexibility | Item - Priest T4 Holy/Discipline 4P Bonus +class spell_pri_t4_4p_bonus : public AuraScript +{ + PrepareAuraScript(spell_pri_t4_4p_bonus); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_T4_4P_FLEXIBILITY }); + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->RemoveAurasDueToSpell(SPELL_PRIEST_T4_4P_FLEXIBILITY); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pri_t4_4p_bonus::HandleProc, EFFECT_ALL, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + } +}; + void AddSC_priest_spell_scripts() { RegisterSpellScript(spell_pri_shadowfiend_scaling); @@ -955,4 +978,5 @@ void AddSC_priest_spell_scripts() RegisterSpellScript(spell_pri_shadow_word_death); RegisterSpellScript(spell_pri_vampiric_touch); RegisterSpellScript(spell_pri_mind_control); + RegisterSpellScript(spell_pri_t4_4p_bonus); } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 6977a082449103..d0045cb4be3342 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -37,6 +37,7 @@ enum ShamanSpells SPELL_SHAMAN_CLEANSING_TOTEM_EFFECT = 52025, SPELL_SHAMAN_EARTH_SHIELD_HEAL = 379, SPELL_SHAMAN_ELEMENTAL_MASTERY = 16166, + SPELL_SHAMAN_ELECTRIFIED = 64930, SPELL_SHAMAN_EXHAUSTION = 57723, SPELL_SHAMAN_FIRE_NOVA_R1 = 1535, SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1 = 8349, @@ -59,7 +60,8 @@ enum ShamanSpells SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL = 52042, SPELL_SHAMAN_BLESSING_OF_THE_ETERNALS_R1 = 51554, SPELL_SHAMAN_STORMSTRIKE = 17364, - SPELL_SHAMAN_LAVA_LASH = 60103 + SPELL_SHAMAN_LAVA_LASH = 60103, + SPELL_SHAMAN_LIGHTNING_BOLT_OVERLOAD = 45284, }; enum ShamanSpellIcons @@ -1104,6 +1106,45 @@ class spell_sha_flurry_proc : public AuraScript } }; +// 64928 - Item - Shaman T8 Elemental 4P Bonus +class spell_sha_t8_electrified : public AuraScript +{ + PrepareAuraScript(spell_sha_t8_electrified); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_ELECTRIFIED }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + // Do not proc from Lightning Overload (patch 3.1~) + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) + { + if (spellInfo->Id == SPELL_SHAMAN_LIGHTNING_BOLT_OVERLOAD) + { + return; + } + } + + SpellInfo const* electrifiedDot = sSpellMgr->AssertSpellInfo(SPELL_SHAMAN_ELECTRIFIED); + int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()) / electrifiedDot->GetMaxTicks()); + + eventInfo.GetProcTarget()->CastDelayedSpellWithPeriodicAmount(eventInfo.GetActor(), SPELL_SHAMAN_ELECTRIFIED, SPELL_AURA_PERIODIC_DAMAGE, amount); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_t8_electrified::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + void AddSC_shaman_spell_scripts() { RegisterSpellScript(spell_sha_totem_of_wrath); @@ -1135,4 +1176,5 @@ void AddSC_shaman_spell_scripts() RegisterSpellScript(spell_sha_sentry_totem); RegisterSpellScript(spell_sha_thunderstorm); RegisterSpellScript(spell_sha_flurry_proc); + RegisterSpellScript(spell_sha_t8_electrified); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 822d7bf642754d..a41ae5ba5a425c 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -63,7 +63,8 @@ enum WarlockSpells SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117, SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_R1 = 18213, SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC = 18371, - SPELL_WARLOCK_EYE_OF_KILROGG_FLY = 58083 + SPELL_WARLOCK_EYE_OF_KILROGG_FLY = 58083, + SPELL_WARLOCK_PET_VOID_STAR_TALISMAN = 37386, // Void Star Talisman }; enum WarlockSpellIcons @@ -284,6 +285,11 @@ class spell_warl_generic_scaling : public AuraScript SpellSchoolMask schoolMask = SpellSchoolMask(aurEff->GetSpellInfo()->Effects[aurEff->GetEffIndex()].MiscValue); int32 modifier = schoolMask == SPELL_SCHOOL_MASK_NORMAL ? 35 : 40; amount = CalculatePct(std::max(0, owner->GetResistance(schoolMask)), modifier); + if (owner->HasAura(SPELL_WARLOCK_PET_VOID_STAR_TALISMAN) && schoolMask != SPELL_SCHOOL_MASK_NORMAL) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARLOCK_PET_VOID_STAR_TALISMAN); + amount += spellInfo->Effects[EFFECT_0].CalcValue(); // 130 + } } } @@ -390,6 +396,11 @@ class spell_warl_infernal_scaling : public AuraScript SpellSchoolMask schoolMask = SpellSchoolMask(aurEff->GetSpellInfo()->Effects[aurEff->GetEffIndex()].MiscValue); int32 modifier = schoolMask == SPELL_SCHOOL_MASK_NORMAL ? 35 : 40; amount = CalculatePct(std::max(0, owner->GetResistance(schoolMask)), modifier); + if (owner->HasAura(SPELL_WARLOCK_PET_VOID_STAR_TALISMAN) && schoolMask != SPELL_SCHOOL_MASK_NORMAL) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARLOCK_PET_VOID_STAR_TALISMAN); + amount += spellInfo->Effects[EFFECT_0].CalcValue(); // 130 + } } } @@ -1267,6 +1278,45 @@ class spell_warl_glyph_of_felguard : public AuraScript } }; +class spell_warl_glyph_of_voidwalker : public AuraScript +{ + PrepareAuraScript(spell_warl_glyph_of_voidwalker); + + void HandleApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Player* player = GetCaster()->ToPlayer()) + { + if (Pet* pet = player->GetPet()) + { + if (pet->GetEntry() == NPC_VOIDWALKER) + { + pet->HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_PCT, aurEff->GetAmount(), true); + } + } + } + } + + void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Player* player = GetCaster()->ToPlayer()) + { + if (Pet* pet = player->GetPet()) + { + if (pet->GetEntry() == NPC_VOIDWALKER) + { + pet->HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_PCT, aurEff->GetAmount(), false); + } + } + } + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_warl_glyph_of_voidwalker::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_warl_glyph_of_voidwalker::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + void AddSC_warlock_spell_scripts() { RegisterSpellScript(spell_warl_eye_of_kilrogg); @@ -1299,4 +1349,5 @@ void AddSC_warlock_spell_scripts() RegisterSpellScript(spell_warl_drain_soul); RegisterSpellScript(spell_warl_shadowburn); RegisterSpellScript(spell_warl_glyph_of_felguard); + RegisterSpellScript(spell_warl_glyph_of_voidwalker); } diff --git a/src/server/scripts/World/chat_log.cpp b/src/server/scripts/World/chat_log.cpp index 186398009a0dee..103fb50b657983 100644 --- a/src/server/scripts/World/chat_log.cpp +++ b/src/server/scripts/World/chat_log.cpp @@ -19,12 +19,7 @@ #include "Group.h" #include "Guild.h" #include "ScriptMgr.h" - -#define LOG_CHAT(TYPE, ...) \ - if (lang != LANG_ADDON) \ - LOG_DEBUG("chat.log." TYPE, __VA_ARGS__); \ - else \ - LOG_DEBUG("chat.log.addon." TYPE, __VA_ARGS__); +#include "Log.h" class ChatLogScript : public PlayerScript { @@ -36,66 +31,67 @@ class ChatLogScript : public PlayerScript switch (type) { case CHAT_MSG_SAY: - LOG_CHAT("say", "Player {} says (language {}): {}", + LOG_INFO("chat.say", "Player {} says (language {}): {}", player->GetName(), lang, msg); break; case CHAT_MSG_EMOTE: - LOG_CHAT("emote", "Player {} emotes: {}", + LOG_INFO("chat.emote", "Player {} emotes: {}", player->GetName(), msg); break; case CHAT_MSG_YELL: - LOG_CHAT("yell", "Player {} yells (language {}): {}", + LOG_INFO("chat.yell", "Player {} yells (language {}): {}", player->GetName(), lang, msg); break; } } - void OnChat(Player* player, uint32 /*type*/, uint32 lang, std::string& msg, Player* receiver) override + void OnChat(Player* player, uint32 /*type*/, uint32 /*lang*/, std::string& msg, Player* receiver) override { - LOG_CHAT("whisper", "Player {} tells {}: {}", + LOG_INFO("chat.whisper", "Player {} tells {}: {}", player->GetName(), receiver ? receiver->GetName() : "", msg); } void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group) override { + std::string str = lang != LANG_ADDON ? "chat." : "chat.addon."; //! NOTE: //! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER" switch (type) { case CHAT_MSG_PARTY: - LOG_CHAT("party", "Player {} tells group with leader {}: {}", + LOG_INFO(str + "party", "Player {} tells group with leader {}: {}", player->GetName(), group ? group->GetLeaderName() : "", msg); break; case CHAT_MSG_PARTY_LEADER: - LOG_CHAT("party", "Leader {} tells group: {}", + LOG_INFO(str + "party", "Leader {} tells group: {}", player->GetName(), msg); break; case CHAT_MSG_RAID: - LOG_CHAT("raid", "Player {} tells raid with leader {}: {}", + LOG_INFO(str + "raid", "Player {} tells raid with leader {}: {}", player->GetName(), group ? group->GetLeaderName() : "", msg); break; case CHAT_MSG_RAID_LEADER: - LOG_CHAT("raid", "Leader player {} tells raid: {}", + LOG_INFO(str + "raid", "Leader player {} tells raid: {}", player->GetName(), msg); break; case CHAT_MSG_RAID_WARNING: - LOG_CHAT("raid", "Leader player {} warns raid with: {}", + LOG_INFO(str + "raid", "Leader player {} sends raid warning: {}", player->GetName(), msg); break; case CHAT_MSG_BATTLEGROUND: - LOG_CHAT("bg", "Player {} tells battleground with leader {}: {}", + LOG_INFO(str + "bg", "Player {} tells battleground with leader {}: {}", player->GetName(), group ? group->GetLeaderName() : "", msg); break; case CHAT_MSG_BATTLEGROUND_LEADER: - LOG_CHAT("bg", "Leader player {} tells battleground: {}", + LOG_INFO(str + "bg", "Leader player {} tells battleground: {}", player->GetName(), msg); break; } @@ -103,21 +99,22 @@ class ChatLogScript : public PlayerScript void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) override { + std::string str = lang != LANG_ADDON ? "chat." : "chat.addon."; switch (type) { case CHAT_MSG_GUILD: - LOG_CHAT("guild", "Player {} tells guild {}: {}", + LOG_INFO(str + "guild", "Player {} tells guild {}: {}", player->GetName(), guild ? guild->GetName() : "", msg); break; case CHAT_MSG_OFFICER: - LOG_CHAT("guild.officer", "Player {} tells guild {} officers: {}", + LOG_INFO(str + "guild.officer", "Player {} tells guild {} officers: {}", player->GetName(), guild ? guild->GetName() : "", msg); break; } } - void OnChat(Player* player, uint32 /*type*/, uint32 lang, std::string& msg, Channel* channel) override + void OnChat(Player* player, uint32 /*type*/, uint32 /*lang*/, std::string& msg, Channel* channel) override { bool isSystem = channel && (channel->HasFlag(CHANNEL_FLAG_TRADE) || @@ -127,13 +124,15 @@ class ChatLogScript : public PlayerScript if (isSystem) { - LOG_CHAT("system", "Player {} tells channel {}: {}", + LOG_INFO("chat.channel", "Player {} tells channel {}: {}", player->GetName(), channel->GetName(), msg); } else { + // Allow to log custom channels. i.e. world channel + // in that case set config: Logger.channel.world=6,Chat std::string channelName = channel ? channel->GetName() : ""; - LOG_CHAT("channel." + channelName, "Player {} tells channel {}: {}", + LOG_INFO("chat.channel." + channelName, "Player {} tells channel {}: {}", player->GetName(), channelName, msg); } } diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index 65f7cbaf8ec44f..7c173713d4c6cb 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -15,34 +15,8 @@ * with this program. If not, see . */ -/* ContentData -go_cat_figurine (the "trap" version of GO, two different exist) -go_barov_journal -go_ethereum_prison -go_ethereum_stasis -go_sacred_fire_of_life -go_shrine_of_the_birds -go_southfury_moonstone -go_resonite_cask -go_tablet_of_the_seven -go_tele_to_dalaran_crystal -go_tele_to_violet_stand -go_scourge_cage -go_jotunheim_cage -go_table_theka -go_soulwell -go_bashir_crystalforge -go_soulwell -go_dragonflayer_cage -go_tadpole_cage -go_amberpine_outhouse -go_hive_pod -go_veil_skith_cage -EndContentData */ - #include "CellImpl.h" #include "GameObjectAI.h" -#include "GameTime.h" #include "GridNotifiersImpl.h" #include "Player.h" #include "ScriptMgr.h" @@ -1385,41 +1359,6 @@ class go_table_theka : public GameObjectScript } }; -/*###### -## go_inconspicuous_landmark -######*/ - -enum InconspicuousLandmark -{ - SPELL_SUMMON_PIRATES_TREASURE_AND_TRIGGER_MOB = 11462, - ITEM_CUERGOS_KEY = 9275, -}; - -class go_inconspicuous_landmark : public GameObjectScript -{ -public: - go_inconspicuous_landmark() : GameObjectScript("go_inconspicuous_landmark") - { - _lastUsedTime = GameTime::GetGameTime().count(); - } - - bool OnGossipHello(Player* player, GameObject* /*go*/) override - { - if (player->HasItemCount(ITEM_CUERGOS_KEY)) - return true; - - if (_lastUsedTime > GameTime::GetGameTime().count()) - return true; - - _lastUsedTime = GameTime::GetGameTime().count() + MINUTE; - player->CastSpell(player, SPELL_SUMMON_PIRATES_TREASURE_AND_TRIGGER_MOB, true); - return true; - } - -private: - uint32 _lastUsedTime; -}; - /*###### ## go_soulwell ######*/ @@ -1989,7 +1928,6 @@ void AddSC_go_scripts() new go_arcane_prison(); new go_jotunheim_cage(); new go_table_theka(); - new go_inconspicuous_landmark(); new go_soulwell(); new go_dragonflayer_cage(); new go_amberpine_outhouse(); diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 3092303258de94..7a13b68815b37b 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -2506,9 +2506,9 @@ enum VenomhideHatchlingMisc ITEM_VENOMHIDE_BABY_TOOTH = 47196, MODEL_BABY_RAPTOR = 29251, - MODEL_BABY_RAPTOR_REPTILE_EYES = 29809, - MODEL_ADOLESCENT_RAPTOR = 29103, - MODEL_FULL_RAPTOR = 5291, + MODEL_BABY_RAPTOR_REPTILE_EYES = 29274, + MODEL_ADOLESCENT_RAPTOR = 29275, + MODEL_FULL_RAPTOR = 29276, }; enum VenomhideHatchlingTexts diff --git a/src/server/shared/DataStores/DBCEnums.h b/src/server/shared/DataStores/DBCEnums.h index c9ea4a6325c6fe..63c0b40667813d 100644 --- a/src/server/shared/DataStores/DBCEnums.h +++ b/src/server/shared/DataStores/DBCEnums.h @@ -225,6 +225,7 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113, ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114, ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS = 115, + ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT = 117, ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS = 119, ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 124, // 0..123 => 124 criteria types total }; diff --git a/src/server/shared/Secrets/SecretMgr.h b/src/server/shared/Secrets/SecretMgr.h index 9dad199213e7a8..8e891aa027bb88 100644 --- a/src/server/shared/Secrets/SecretMgr.h +++ b/src/server/shared/Secrets/SecretMgr.h @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#ifndef __WARHEAD_SECRETMGR_H__ -#define __WARHEAD_SECRETMGR_H__ +#ifndef __ACORE_SECRETMGR_H__ +#define __ACORE_SECRETMGR_H__ #include "BigNumber.h" #include "Common.h" diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index c5d8e077d8d353..9bb4e2fa490f67 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -1461,8 +1461,8 @@ enum Targets { TARGET_UNIT_CASTER = 1, TARGET_UNIT_NEARBY_ENEMY = 2, - TARGET_UNIT_NEARBY_PARTY = 3, - TARGET_UNIT_NEARBY_ALLY = 4, + TARGET_UNIT_NEARBY_ALLY = 3, + TARGET_UNIT_NEARBY_PARTY = 4, TARGET_UNIT_PET = 5, TARGET_UNIT_TARGET_ENEMY = 6, TARGET_UNIT_SRC_AREA_ENTRY = 7,