diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 70bbbbcae..8103861f7 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,12 +1,12 @@ name: Feature request description: Suggest an idea for this project title: "Feature: " -labels: [Suggestion] +type: "Feature" body: - type: markdown attributes: value: | - Thank you for taking your time to fill out a feature request. Remember to fill out all fields including the title above. + Thank you for taking the time to fill out a feature request. Remember to fill out all fields including the title above. An issue that is not properly filled out will be closed. - type: textarea id: description diff --git a/apps/codestyle/codestyle-sql.py b/apps/codestyle/codestyle-sql.py index d93646d09..f15dceed6 100644 --- a/apps/codestyle/codestyle-sql.py +++ b/apps/codestyle/codestyle-sql.py @@ -15,6 +15,7 @@ results = { "Multiple blank lines check": "Passed", "Trailing whitespace check": "Passed", "SQL codestyle check": "Passed", + "INSERT safety usage check": "Passed", "Missing semicolon check": "Passed" } @@ -43,6 +44,7 @@ def parsing_file(files: list) -> None: multiple_blank_lines_check(file, file_path) trailing_whitespace_check(file, file_path) sql_check(file, file_path) + insert_safety_check(file, file_path) semicolon_check(file, file_path) except UnicodeDecodeError: print(f"\nCould not decode file {file_path}") @@ -108,6 +110,10 @@ def sql_check(file: io, file_path: str) -> None: print( f"DON'T EDIT broadcast_text TABLE UNLESS YOU KNOW WHAT YOU ARE DOING!\nThis error can safely be ignored if the changes are approved to be sniffed: {file_path} at line {line_number}") check_failed = True + if "EntryOrGuid" in line: + print( + f"Please use entryorguid syntax instead of EntryOrgGuid in {file_path} at line {line_number}\nWe recommend to use keira to have the right syntax in auto-query generation") + check_failed = True if [match for match in [';;'] if match in line]: print( f"Double semicolon (;;) found in {file_path} at line {line_number}") @@ -128,6 +134,24 @@ def sql_check(file: io, file_path: str) -> None: error_handler = True results["SQL codestyle check"] = "Failed" +def insert_safety_check(file: io, file_path: str) -> None: + global error_handler, results + file.seek(0) # Reset file pointer to the beginning + check_failed = False + previous_line = "" + + # Parse all the file + for line_number, line in enumerate(file, start = 1): + if "INSERT" in line and "DELETE" not in previous_line: + print(f"No DELETE keyword found after the INSERT in {file_path} at line {line_number}\nIf this error is intended, please advert a maintainer") + check_failed = True + previous_line = line + + # Handle the script error and update the result output + if check_failed: + error_handler = True + results["INSERT safety usage check"] = "Failed" + def semicolon_check(file: io, file_path: str) -> None: global error_handler, results file.seek(0) # Reset file pointer to the beginning diff --git a/apps/docker/Dockerfile.dev-server b/apps/docker/Dockerfile.dev-server index 8924c4688..fab54bd35 100644 --- a/apps/docker/Dockerfile.dev-server +++ b/apps/docker/Dockerfile.dev-server @@ -7,7 +7,7 @@ # #================================================================= -FROM ubuntu:22.04 as dev +FROM ubuntu:24.04 as dev ARG USER_ID=1000 ARG GROUP_ID=1000 ARG DOCKER_USER=acore @@ -29,13 +29,37 @@ ENV TZ=$TZ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update \ - && apt-get install -y \ - gdb gdbserver git dos2unix lsb-core sudo curl unzip \ - make cmake clang libmysqlclient-dev libboost-all-dev \ - build-essential libtool cmake-data openssl libgoogle-perftools-dev google-perftools \ - libssl-dev libmysql++-dev libreadline6-dev zlib1g-dev libbz2-dev mysql-client \ - libncurses5-dev ccache tzdata \ - && rm -rf /var/lib/apt/lists/* + && apt-get install -y --no-install-recommends \ + # Classic install + git \ + clang lldb lld clang-format clang-tidy \ + make cmake \ + gcc g++ \ + libmysqlclient-dev \ + libssl-dev \ + libbz2-dev \ + libreadline-dev \ + libncurses-dev \ + mysql-server \ + libboost-all-dev \ + # Other + curl \ + unzip \ + sudo \ + gdb gdbserver \ + libtool \ + build-essential \ + cmake-data \ + openssl \ + google-perftools libgoogle-perftools-dev \ + libmysql++-dev \ + ccache \ + tzdata \ + # Utility for column command used by dashboard + util-linux \ + # Certificates for downloading client data + ca-certificates \ + && rm -rf /var/lib/apt/lists/* # Ensure git will work with the AzerothCore source directory RUN git config --global --add safe.directory /azerothcore @@ -45,10 +69,11 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ && echo $TZ > /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata # Create a non-root user -RUN addgroup --gid "$GROUP_ID" "$DOCKER_USER" && \ - adduser --disabled-password --gecos '' --uid "$USER_ID" --gid "$GROUP_ID" "$DOCKER_USER" && \ - passwd -d "$DOCKER_USER" && \ - echo "$DOCKER_USER ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers +RUN userdel --remove ubuntu \ + && addgroup --gid "$GROUP_ID" "$DOCKER_USER" \ + && adduser --disabled-password --gecos '' --uid "$USER_ID" --gid "$GROUP_ID" "$DOCKER_USER" \ + && passwd -d "$DOCKER_USER" \ + && echo "$DOCKER_USER ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers # must be created to set the correct permissions on them RUN mkdir -p \ diff --git a/data/sql/updates/db_world/2025_01_15_04.sql b/data/sql/updates/db_world/2025_01_15_04.sql new file mode 100644 index 000000000..c1e39703a --- /dev/null +++ b/data/sql/updates/db_world/2025_01_15_04.sql @@ -0,0 +1,6 @@ +-- DB update 2025_01_15_03 -> 2025_01_15_04 +-- +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 23597) AND (`source_type` = 0) AND (`id` IN (12, 18)); +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 +(23597, 0, 12, 0, 1, 1, 100, 515, 6200, 6200, 6200, 6200, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Amani\'shi Guardian - Out of Combat - Remove Flags Immune To Players & Immune To NPC\'s (Phase 1) (No Repeat) (Normal Dungeon)'), +(23597, 0, 18, 0, 1, 2, 100, 515, 7600, 7600, 7600, 7600, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Amani\'shi Guardian - Out of Combat - Remove Flags Immune To Players & Immune To NPC\'s (Phase 2) (No Repeat) (Normal Dungeon)'); diff --git a/data/sql/updates/db_world/2025_01_16_00.sql b/data/sql/updates/db_world/2025_01_16_00.sql new file mode 100644 index 000000000..f860fe4ea --- /dev/null +++ b/data/sql/updates/db_world/2025_01_16_00.sql @@ -0,0 +1,3 @@ +-- DB update 2025_01_15_04 -> 2025_01_16_00 +-- +UPDATE `creature_template` SET `ScriptName` = 'npc_deathstalker_fearleia' WHERE `entry` = 2058; diff --git a/data/sql/updates/db_world/2025_01_16_01.sql b/data/sql/updates/db_world/2025_01_16_01.sql new file mode 100644 index 000000000..952e42aa0 --- /dev/null +++ b/data/sql/updates/db_world/2025_01_16_01.sql @@ -0,0 +1,3 @@ +-- DB update 2025_01_16_00 -> 2025_01_16_01 +-- +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 24043) AND (`source_type` = 0) AND (`id` IN (2)); diff --git a/data/sql/updates/db_world/2025_01_16_02.sql b/data/sql/updates/db_world/2025_01_16_02.sql new file mode 100644 index 000000000..01939b2db --- /dev/null +++ b/data/sql/updates/db_world/2025_01_16_02.sql @@ -0,0 +1,8 @@ +-- DB update 2025_01_16_01 -> 2025_01_16_02 +-- +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24138; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 24138) AND (`source_type` = 0) AND (`id` IN (0, 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 +(24138, 0, 0, 0, 0, 0, 100, 0, 4000, 8000, 8000, 16000, 0, 0, 11, 43353, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tamed Amani Crocolisk - In Combat - Cast \'Infected Bite\''), +(24138, 0, 1, 0, 0, 0, 100, 0, 5000, 10000, 15000, 30000, 0, 0, 11, 43352, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tamed Amani Crocolisk - In Combat - Cast \'Tail Swipe\''); diff --git a/data/sql/updates/db_world/2025_01_16_03.sql b/data/sql/updates/db_world/2025_01_16_03.sql new file mode 100644 index 000000000..640de06e4 --- /dev/null +++ b/data/sql/updates/db_world/2025_01_16_03.sql @@ -0,0 +1,4 @@ +-- DB update 2025_01_16_02 -> 2025_01_16_03 +DELETE FROM `spell_target_position` WHERE `ID` = 41234 AND `EffectIndex` = 0; +INSERT INTO `spell_target_position` (`ID`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `VerifiedBuild`) VALUES +(41234, 0, 530, -3560.52, 583.353, 10.9431, 4.751223087310791015, 58558); diff --git a/data/sql/updates/db_world/2025_01_16_04.sql b/data/sql/updates/db_world/2025_01_16_04.sql new file mode 100644 index 000000000..520c85e42 --- /dev/null +++ b/data/sql/updates/db_world/2025_01_16_04.sql @@ -0,0 +1,10 @@ +-- DB update 2025_01_16_03 -> 2025_01_16_04 + +-- Bloodscalp Witch Doctor SmartAI +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 660; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 660); +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 +(660, 0, 0, 0, 0, 0, 100, 1, 8000, 12000, 0, 0, 0, 0, 11, 8376, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Bloodscalp Witch Doctor - In Combat - Cast \'Earthgrab Totem\' (No Repeat)'), +(660, 0, 1, 0, 2, 0, 100, 513, 0, 30, 0, 0, 0, 0, 11, 8599, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Bloodscalp Witch Doctor - Between 0-30% Health - Cast \'Enrage\' (No Repeat)'), +(660, 0, 2, 0, 2, 0, 100, 1, 0, 50, 0, 0, 0, 0, 11, 5605, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Bloodscalp Witch Doctor - Between 0-50% Health - Cast \'Healing Ward\' (No Repeat)'); diff --git a/data/sql/updates/db_world/2025_01_17_00.sql b/data/sql/updates/db_world/2025_01_17_00.sql new file mode 100644 index 000000000..1b42e6d9b --- /dev/null +++ b/data/sql/updates/db_world/2025_01_17_00.sql @@ -0,0 +1,3 @@ +-- DB update 2025_01_16_04 -> 2025_01_17_00 +-- +UPDATE `creature_template_movement` SET `Rooted` = 0 WHERE `CreatureId` = 21221; diff --git a/data/sql/updates/db_world/2025_01_17_01.sql b/data/sql/updates/db_world/2025_01_17_01.sql new file mode 100644 index 000000000..278a00f12 --- /dev/null +++ b/data/sql/updates/db_world/2025_01_17_01.sql @@ -0,0 +1,9 @@ +-- DB update 2025_01_17_00 -> 2025_01_17_01 +-- +UPDATE `acore_string` SET +`content_default` = "No waypoint information was found for Creature (GUID: {}). Make sure 'wp show on' command was properly executed.", +`locale_deDE` = "Keine Wegpunktinformationen wurden für das Wesen (GUID: {}) gefunden. Stellen Sie sicher, dass der Befehl 'wp show on' korrekt ausgeführt wurde.", +`locale_zhCN` = "未找到生物(GUID: {})的路径点信息。请确保正确执行了“wp show on”命令。", +`locale_esES` = "No se encontraron información de punto de ruta para la criatura (GUID: {}). Asegúrese de que el comando 'wp show on' se haya ejecutado correctamente.", +`locale_esMX` = "No se encontraron información de punto de ruta para la criatura (GUID: {}). Asegúrese de que el comando 'wp show on' se haya ejecutado correctamente." +WHERE `entry` = 223; diff --git a/data/sql/updates/db_world/2025_01_18_00.sql b/data/sql/updates/db_world/2025_01_18_00.sql new file mode 100644 index 000000000..be3353142 --- /dev/null +++ b/data/sql/updates/db_world/2025_01_18_00.sql @@ -0,0 +1,148 @@ +-- DB update 2025_01_17_01 -> 2025_01_18_00 +-- Update gameobject 'Giant Clam' with sniffed values and add pooling +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (19018)) +AND (`guid` IN (100079, 100080, 14630, 32609, 32617, 32619, 32934, 47894, 48528)); +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 +(100079, 19018, 0, 0, 0, 1, 1, -2646.4091796875, -1246.5653076171875, -14.4196491241455078, 0.069811686873435974, 0, 0, 0.034898757934570312, 0.999390840530395507, 120, 255, 1, "", 49345, NULL), +(100080, 19018, 0, 0, 0, 1, 1, -2517.143310546875, -1307.2694091796875, -42.1596260070800781, 1.239183306694030761, 0, 0, 0.580702781677246093, 0.814115643501281738, 120, 255, 1, "", 50664, NULL), +(14630, 19018, 0, 0, 0, 1, 1, -2506.34912109375, -1474.3740234375, -28.1449832916259765, 1.361356139183044433, 0, 0, 0.629320144653320312, 0.77714616060256958, 120, 255, 1, "", 45854, NULL), +(32609, 19018, 48, 0, 0, 1, 1, -347.47064208984375, 76.08115386962890625, -61.8706207275390625, 5.70722818374633789, 0, 0, -0.28401470184326171, 0.958819925785064697, 7200, 255, 1, "", 52237, NULL), +(32617, 19018, 48, 0, 0, 1, 1, -400.426910400390625, 279.811859130859375, -71.1439132690429687, 2.740161895751953125, 0, 0, 0.979924201965332031, 0.199370384216308593, 7200, 255, 1, "", 52237, NULL), +(32619, 19018, 48, 0, 0, 1, 1, -410.671173095703125, 348.6953125, -71.7385101318359375, 0.558503925800323486, 0, 0, 0.275636672973632812, 0.961261868476867675, 7200, 255, 1, "", 53622, NULL), +(32934, 19018, 48, 0, 0, 1, 1, -781.43231201171875, -165.56109619140625, -47.9077644348144531, 5.829400539398193359, 0, 0, -0.22495079040527343, 0.974370121955871582, 7200, 255, 1, "", 53622, NULL), +(47894, 19018, 1, 0, 0, 1, 1, 4348.44482421875, 851.246337890625, -21.0694580078125, 2.652894020080566406, 0, 0, 0.970294952392578125, 0.241925001144409179, 120, 255, 1, "", 47720, NULL), +(48528, 19018, 1, 0, 0, 1, 1, 4311.09130859375, 949.97003173828125, -22.5520610809326171, 5.253442287445068359, 0, 0, -0.49242305755615234, 0.870355963706970214, 120, 255, 1, "", 50664, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (19018)) +AND (`guid` BETWEEN 3055 AND 3100); +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 +(3055, 19018, 0, 0, 0, 1, 1, -2516.3125, -1265.5015869140625, -47.1902122497558593, 0.314158439636230468, 0, 0, 0.156434059143066406, 0.987688362598419189, 120, 255, 1, "", 46902, NULL), +(3056, 19018, 0, 0, 0, 1, 1, -2526.524658203125, -1371.18505859375, -40.4460182189941406, 0.261798173189163208, 0, 0, 0.130525588989257812, 0.991444945335388183, 120, 255, 1, "", 50664, NULL), +(3057, 19018, 0, 0, 0, 1, 1, -2561.040771484375, -1548.825439453125, -13.6164684295654296, 2.67034769058227539, 0, 0, 0.972369194030761718, 0.233448356389999389, 120, 255, 1, "", 50375, NULL), +(3058, 19018, 0, 0, 0, 1, 1, -2615.08251953125, -1484.8092041015625, -12.9359779357910156, 6.230826377868652343, 0, 0, -0.02617645263671875, 0.999657332897186279, 120, 255, 1, "", 49345, NULL), +(3059, 19018, 0, 0, 0, 1, 1, -2631.943359375, -1345.4796142578125, -12.8757905960083007, 1.48352813720703125, 0, 0, 0.675589561462402343, 0.737277925014495849, 120, 255, 1, "", 49345, NULL), +(3060, 19018, 0, 0, 0, 1, 1, -2652.344482421875, -1172.9991455078125, -14.9990730285644531, 0.506144583225250244, 0, 0, 0.250379562377929687, 0.968147754669189453, 120, 255, 1, "", 50664, NULL), +(3061, 19018, 0, 0, 0, 1, 1, -2693.152587890625, -1125.627197265625, -14.4795026779174804, 2.513273954391479492, 0, 0, 0.951056480407714843, 0.309017121791839599, 120, 255, 1, "", 49345, NULL), +(3062, 19018, 0, 0, 0, 1, 1, -2758.241455078125, -951.86102294921875, -13.6005315780639648, 3.90954136848449707, 0, 0, -0.92718315124511718, 0.37460830807685852, 120, 255, 1, "", 50375, NULL), +(3063, 19018, 0, 0, 0, 1, 1, -2787.666748046875, -1068.8414306640625, -11.7275295257568359, 6.213373661041259765, 0, 0, -0.03489875793457031, 0.999390840530395507, 120, 255, 1, "", 52237, NULL), +(3064, 19018, 0, 0, 0, 1, 1, -2792.83349609375, -851.74847412109375, -13.051919937133789, 5.375615119934082031, 0, 0, -0.4383707046508789, 0.898794233798980712, 120, 255, 1, "", 50375, NULL), +(3065, 19018, 0, 0, 0, 1, 1, -2858.221923828125, -885.32574462890625, -10.7018337249755859, 5.637413978576660156, 0, 0, -0.31730461120605468, 0.948323667049407958, 120, 255, 1, "", 49822, NULL), +(3066, 19018, 0, 0, 0, 1, 1, -2879.617431640625, -975.7791748046875, -13.6781578063964843, 1.186823248863220214, 0, 0, 0.559192657470703125, 0.829037725925445556, 120, 255, 1, "", 50664, NULL), +(3067, 19018, 0, 0, 0, 1, 1, -2973.353515625, -804.2197265625, -12.3123130798339843, 0.226892471313476562, 0, 0, 0.113203048706054687, 0.993571877479553222, 120, 255, 1, "", 48632, NULL), +(3068, 19018, 0, 0, 0, 1, 1, -2994.040283203125, -903.63714599609375, -7.62413215637207031, 1.692969322204589843, 0, 0, 0.748955726623535156, 0.662620067596435546, 120, 255, 1, "", 50664, NULL), +(3069, 19018, 0, 0, 0, 1, 1, -3047.309326171875, -740.7490234375, -13.4887809753417968, 5.969027042388916015, 0, 0, -0.1564340591430664, 0.987688362598419189, 120, 255, 1, "", 50375, NULL), +(3070, 19018, 0, 0, 0, 1, 1, -3053.877197265625, -858.911865234375, -11.5110082626342773, 1.570795774459838867, 0, 0, 0.707106590270996093, 0.707106947898864746, 120, 255, 1, "", 49345, NULL), +(3071, 19018, 0, 0, 0, 1, 1, -3149.630615234375, -691.31689453125, -34.9023246765136718, 5.096362113952636718, 0, 0, -0.55919265747070312, 0.829037725925445556, 120, 255, 1, "", 49345, NULL), +(3072, 19018, 0, 0, 0, 1, 1, -3154.08251953125, -878.17523193359375, -10.8227548599243164, 0.767943859100341796, 0, 0, 0.374606132507324218, 0.927184045314788818, 120, 255, 1, "", 46902, NULL), +(3073, 19018, 0, 0, 0, 1, 1, -3229.396240234375, -774.949462890625, -17.9715137481689453, 2.426007747650146484, 0, 0, 0.936672210693359375, 0.350207358598709106, 120, 255, 1, "", 51943, NULL), +(3074, 19018, 0, 0, 0, 1, 1, -3276.936767578125, -618.36737060546875, -19.3885517120361328, 2.635444164276123046, 0, 0, 0.96814727783203125, 0.250381410121917724, 120, 255, 1, "", 50375, NULL), +(3075, 19018, 0, 0, 0, 1, 1, -3278.245361328125, -873.4765625, -12.4649734497070312, 1.989672422409057617, 0, 0, 0.838669776916503906, 0.544640243053436279, 120, 255, 1, "", 48632, NULL), +(3076, 19018, 0, 0, 0, 1, 1, -3294.763916015625, -725.89404296875, -10.2694530487060546, 1.32644820213317871, 0, 0, 0.615660667419433593, 0.788011372089385986, 120, 255, 1, "", 51943, NULL), +(3077, 19018, 0, 0, 0, 1, 1, -3431.91357421875, -719.76348876953125, -10.6346702575683593, 1.902408957481384277, 0, 0, 0.814115524291992187, 0.580702960491180419, 120, 255, 1, "", 48632, NULL), +(3078, 19018, 0, 0, 0, 1, 1, -3494.998779296875, -614.75115966796875, -15.8588886260986328, 5.6897735595703125, 0, 0, -0.29237174987792968, 0.956304728984832763, 120, 255, 1, "", 48632, NULL), +(3079, 19018, 0, 0, 0, 1, 1, -3772.385986328125, -1127.484375, -32.0519866943359375, 5.480334281921386718, 0, 0, -0.39073085784912109, 0.920504987239837646, 120, 255, 1, "", 50172, NULL), +(3080, 19018, 0, 0, 0, 1, 1, -3818.381103515625, -1027.3331298828125, -32.0284156799316406, 1.937312245368957519, 0, 0, 0.824125289916992187, 0.566407561302185058, 120, 255, 1, "", 50664, NULL), +(3081, 19018, 0, 0, 0, 1, 1, -3889.245361328125, -917.22613525390625, -16.3200283050537109, 1.064649581909179687, 0, 0, 0.507537841796875, 0.861629426479339599, 120, 255, 1, "", 50664, NULL), +(3082, 19018, 0, 0, 0, 1, 1, -3970.02001953125, -825.5369873046875, -15.9225664138793945, 3.071766138076782226, 0, 0, 0.999390602111816406, 0.034906134009361267, 120, 255, 1, "", 52237, NULL), +(3083, 19018, 0, 0, 0, 1, 1, -4033.75, -762.57843017578125, -12.864654541015625, 2.216565132141113281, 0, 0, 0.894933700561523437, 0.44619917869567871, 120, 255, 1, "", 50375, NULL), +(3084, 19018, 1, 0, 0, 1, 1, 4289.03857421875, 988.9013671875, -25.8320999145507812, 4.799657344818115234, 0, 0, -0.67558956146240234, 0.737277925014495849, 120, 255, 1, "", 49345, NULL), +(3085, 19018, 1, 0, 0, 1, 1, 4350.62744140625, 890.24761962890625, -21.13616943359375, 3.874631166458129882, 0, 0, -0.93358039855957031, 0.358368009328842163, 120, 255, 1, "", 46248, NULL), +(3086, 19018, 48, 0, 0, 1, 1, -331.169464111328125, -27.6077117919921875, -72.2552108764648437, 0.471238493919372558, 0, 0, 0.233445167541503906, 0.972369968891143798, 7200, 255, 1, "", 52237, NULL), +(3087, 19018, 48, 0, 0, 1, 1, -346.6336669921875, 291.60455322265625, -70.7872161865234375, 3.106652259826660156, 0, 0, 0.999847412109375, 0.017469281330704689, 7200, 255, 1, "", 52237, NULL), +(3088, 19018, 48, 0, 0, 1, 1, -348.721710205078125, -34.5047073364257812, -68.4577102661132812, 3.45575571060180664, 0, 0, -0.98768806457519531, 0.156436234712600708, 7200, 255, 1, "", 53622, NULL), +(3089, 19018, 48, 0, 0, 1, 1, -354.931182861328125, 308.108734130859375, -69.8227081298828125, 2.984498262405395507, 0, 0, 0.996916770935058593, 0.078466430306434631, 7200, 255, 1, "", 52237, NULL), +(3090, 19018, 48, 0, 0, 1, 1, -421.11395263671875, 121.5354385375976562, -70.3830795288085937, 4.956737518310546875, 0, 0, -0.61566066741943359, 0.788011372089385986, 7200, 255, 1, "", 53622, NULL), +(3091, 19018, 48, 0, 0, 1, 1, -427.4090576171875, 311.43017578125, -65.8169937133789062, 0.139624491333961486, 0, 0, 0.06975555419921875, 0.997564136981964111, 7200, 255, 1, "", 53622, NULL), +(3092, 19018, 48, 0, 0, 1, 1, -489.73443603515625, 144.3833770751953125, -72.4147415161132812, 1.588248729705810546, 0, 0, 0.713250160217285156, 0.700909554958343505, 7200, 255, 1, "", 52237, NULL), +(3093, 19018, 48, 0, 0, 1, 1, -686.755126953125, -34.1224174499511718, -36.9233741760253906, 2.164205789566040039, 0, 0, 0.882946968078613281, 0.469472706317901611, 7200, 255, 1, "", 52237, NULL), +(3094, 19018, 48, 0, 0, 1, 1, -713.4542236328125, -21.8693408966064453, -39.3413848876953125, 2.932138919830322265, 0, 0, 0.994521141052246093, 0.104535527527332305, 7200, 255, 1, "", 52237, NULL), +(3095, 19018, 48, 0, 0, 1, 1, -756.04718017578125, -176.359329223632812, -54.1190109252929687, 1.605701684951782226, 0, 0, 0.719339370727539062, 0.694658815860748291, 7200, 255, 1, "", 52237, NULL), +(3096, 19018, 48, 0, 0, 1, 1, -760.38995361328125, -52.2364158630371093, -41.6094551086425781, 0.977383077144622802, 0, 0, 0.469470977783203125, 0.882947921752929687, 7200, 255, 1, "", 52237, NULL), +(3097, 19018, 48, 0, 0, 1, 1, -760.68328857421875, -155.533584594726562, -51.5061683654785156, 0.471238493919372558, 0, 0, 0.233445167541503906, 0.972369968891143798, 7200, 255, 1, "", 53622, NULL), +(3098, 19018, 48, 0, 0, 1, 1, -770.51202392578125, -189.07220458984375, -48.8139495849609375, 5.777040958404541015, 0, 0, -0.25037956237792968, 0.968147754669189453, 7200, 255, 1, "", 52237, NULL), +(3099, 19018, 48, 0, 0, 1, 1, -835.62677001953125, -47.6639022827148437, -35.6944770812988281, 3.45575571060180664, 0, 0, -0.98768806457519531, 0.156436234712600708, 7200, 255, 1, "", 53622, NULL), +(3100, 19018, 48, 0, 0, 1, 1, -870.4945068359375, -105.115287780761718, -35.4094352722167968, 1.710421562194824218, 0, 0, 0.754709243774414062, 0.656059443950653076, 7200, 255, 1, "", 52237, NULL); + +-- remaining spawns (no sniffed values available) +-- map 48 - Blackfathom Deeps +-- (`guid` IN (32607, 32618, 32615, 32687, 32689, 32691, 32685, 32692)) + +-- pooling +-- the spawn count for each pool has been estimated from the currently available sniffs +DELETE FROM `pool_template` WHERE (`entry` IN (139, 140, 141)); +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(139, 10, 'Eastern Kingdoms - Giant Clam - 10/32'), +(140, 2, 'Kalimdor - Giant Clam - 2/4'), +(141, 12, 'Blackfathom Deeps - Giant Clam - 12/27'); + +DELETE FROM `pool_gameobject` WHERE (`pool_entry` IN (139, 140, 141)) AND (`guid` IN (100079, 100080, 14630, 32609, 32617, 32619, 32934, 47894, 48528, 32607, 32618, 32615, 32687, 32689, 32691, 32685, 32692)); +DELETE FROM `pool_gameobject` WHERE (`pool_entry` IN (139, 140, 141)) AND (`guid` BETWEEN 3055 AND 3100); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +-- map 0 - Eastern Kingdoms +(100079, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(100080, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(14630, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3055, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3056, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3057, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3058, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3059, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3060, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3061, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3062, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3063, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3064, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3065, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3066, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3067, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3068, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3069, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3070, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3071, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3072, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3073, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3074, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3075, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3076, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3077, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3078, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3079, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3080, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3081, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3082, 139, 0, 'Eastern Kingdoms - Giant Clam'), +(3083, 139, 0, 'Eastern Kingdoms - Giant Clam'), +-- map 1 - Kalimdor +(47894, 140, 0, 'Kalimdor - Giant Clam'), +(48528, 140, 0, 'Kalimdor - Giant Clam'), +(3084, 140, 0, 'Kalimdor - Giant Clam'), +(3085, 140, 0, 'Kalimdor - Giant Clam'), +-- map 48 - Blackfathom Deeps +(32609, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32617, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32619, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32934, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32607, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32618, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32615, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32687, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32689, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32691, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32685, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(32692, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3086, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3087, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3088, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3089, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3090, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3091, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3092, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3093, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3094, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3095, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3096, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3097, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3098, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3099, 141, 0, 'Blackfathom Deeps - Giant Clam'), +(3100, 141, 0, 'Blackfathom Deeps - Giant Clam'); diff --git a/data/sql/updates/db_world/2025_01_18_01.sql b/data/sql/updates/db_world/2025_01_18_01.sql new file mode 100644 index 000000000..855f86e00 --- /dev/null +++ b/data/sql/updates/db_world/2025_01_18_01.sql @@ -0,0 +1,4 @@ +-- DB update 2025_01_18_00 -> 2025_01_18_01 + +-- Change Unit Flags (IMMUNE_TO_PC, IMMUNE_TO_NPC) +UPDATE `creature_template` SET `unit_flags` = `unit_flags`|768 WHERE `entry` IN (25465); diff --git a/data/sql/updates/db_world/2025_01_19_00.sql b/data/sql/updates/db_world/2025_01_19_00.sql new file mode 100644 index 000000000..f1776f554 --- /dev/null +++ b/data/sql/updates/db_world/2025_01_19_00.sql @@ -0,0 +1,183 @@ +-- DB update 2025_01_18_01 -> 2025_01_19_00 +-- Update gameobject 'Giant Clam' with sniffed values and add pooling +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (2744)) +AND (`guid` IN (11029, 11030, 11686, 11687, 11811, 11818, 32097)); +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 +(11029, 2744, 0, 0, 0, 1, 1, -12212.314453125, 429.674102783203125, -101.356117248535156, 4.729844093322753906, 0, 0, -0.70090866088867187, 0.713251054286956787, 300, 255, 1, "", 45613, NULL), +(11030, 2744, 0, 0, 0, 1, 1, -12127.8740234375, 525.8162841796875, -49.4669418334960937, 3.996806621551513671, 0, 0, -0.90996074676513671, 0.414694398641586303, 300, 255, 1, "", 45572, NULL), +(11686, 2744, 0, 0, 0, 1, 1, -12189.05859375, 481.9610595703125, -71.9975967407226562, 4.747295856475830078, 0, 0, -0.69465827941894531, 0.719339847564697265, 300, 255, 1, "", 45613, NULL), +(11687, 2744, 0, 0, 0, 1, 1, -12173.8779296875, 439.629791259765625, -35.3151359558105468, 1.815141916275024414, 0, 0, 0.788010597229003906, 0.615661680698394775, 300, 255, 1, "", 48120, NULL), +(11811, 2744, 0, 0, 0, 1, 1, -12194.5107421875, 597.6055908203125, -66.1562118530273437, 0.925023794174194335, 0, 0, 0.446197509765625, 0.894934535026550292, 300, 255, 1, "", 45572, NULL), +(11818, 2744, 0, 0, 0, 1, 1, -12140.9033203125, 558.23614501953125, -30.8249416351318359, 5.619962215423583984, 0, 0, -0.32556724548339843, 0.945518851280212402, 300, 255, 1, "", 49345, NULL), +(32097, 2744, 0, 0, 0, 1, 1, -12211.3408203125, 689.1170654296875, -72.4632949829101562, 2.775068521499633789, 0, 0, 0.983254432678222656, 0.182238012552261352, 300, 255, 1, "", 49345, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (2744)) +AND (`guid` BETWEEN 3442 AND 3514); +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 +(3442, 2744, 0, 0, 0, 1, 1, -12119.9814453125, 499.054107666015625, -55.3000259399414062, 1.762782454490661621, 0, 0, 0.771624565124511718, 0.636078238487243652, 300, 255, 1, "", 49345, NULL), +(3443, 2744, 0, 0, 0, 1, 1, -12133, 598.65399169921875, -35.3210601806640625, 3.281238555908203125, 0, 0, -0.99756336212158203, 0.069766148924827575, 300, 255, 1, "", 47168, NULL), +(3444, 2744, 0, 0, 0, 1, 1, -12142.7939453125, 466.66937255859375, -30.6373634338378906, 4.1538848876953125, 0, 0, -0.8746194839477539, 0.484810054302215576, 300, 255, 1, "", 45572, NULL), +(3445, 2744, 0, 0, 0, 1, 1, -12144.0556640625, 581.7142333984375, -28.6632328033447265, 1.361356139183044433, 0, 0, 0.629320144653320312, 0.77714616060256958, 300, 255, 1, "", 47168, NULL), +(3446, 2744, 0, 0, 0, 1, 1, -12150.5673828125, 445.523284912109375, -11.8544530868530273, 0.209439441561698913, 0, 0, 0.104528427124023437, 0.994521915912628173, 300, 255, 1, "", 45613, NULL), +(3447, 2744, 0, 0, 0, 1, 1, -12152.19921875, 490.97894287109375, -60.2821731567382812, 0.820303261280059814, 0, 0, 0.398748397827148437, 0.917060375213623046, 300, 255, 1, "", 49345, NULL), +(3448, 2744, 0, 0, 0, 1, 1, -12164.212890625, 477.830902099609375, -38.8802566528320312, 1.396261811256408691, 0, 0, 0.642786979675292968, 0.766044974327087402, 300, 255, 1, "", 45613, NULL), +(3449, 2744, 0, 0, 0, 1, 1, -12166.3798828125, 715.30059814453125, -49.3524208068847656, 0.820303261280059814, 0, 0, 0.398748397827148437, 0.917060375213623046, 300, 255, 1, "", 50375, NULL), +(3450, 2744, 0, 0, 0, 1, 1, -12173.4111328125, 515.21826171875, -66.0793228149414062, 5.550147056579589843, 0, 0, -0.358367919921875, 0.933580458164215087, 300, 255, 1, "", 45572, NULL), +(3451, 2744, 0, 0, 0, 1, 1, -12177.61328125, 575.85736083984375, -28.9876232147216796, 1.466075778007507324, 0, 0, 0.669130325317382812, 0.74314504861831665, 300, 255, 1, "", 47168, NULL), +(3452, 2744, 0, 0, 0, 1, 1, -12197.0478515625, 466.8428955078125, -54.4156036376953125, 0.488691210746765136, 0, 0, 0.241921424865722656, 0.970295846462249755, 300, 255, 1, "", 48632, NULL), +(3453, 2744, 0, 0, 0, 1, 1, -12208.8564453125, 571.423828125, -36.9531364440917968, 3.752462387084960937, 0, 0, -0.95371627807617187, 0.300707906484603881, 300, 255, 1, "", 45572, NULL), +(3454, 2744, 0, 0, 0, 1, 1, -12210.11328125, 714.8321533203125, -58.2952194213867187, 1.32644820213317871, 0, 0, 0.615660667419433593, 0.788011372089385986, 300, 255, 1, "", 49345, NULL), +(3455, 2744, 0, 0, 0, 1, 1, -12210.4990234375, 528.47882080078125, -65.7092056274414062, 3.351046562194824218, 0, 0, -0.99452114105224609, 0.104535527527332305, 300, 255, 1, "", 47168, NULL), +(3456, 2744, 0, 0, 0, 1, 1, -12223.4404296875, 506.735015869140625, -95.9059524536132812, 1.535889506340026855, 0, 0, 0.694658279418945312, 0.719339847564697265, 300, 255, 1, "", 47168, NULL), +(3457, 2744, 0, 0, 0, 1, 1, -12223.8876953125, 441.446685791015625, -88.0880050659179687, 5.829400539398193359, 0, 0, -0.22495079040527343, 0.974370121955871582, 300, 255, 1, "", 45613, NULL), +(3458, 2744, 0, 0, 0, 1, 1, -12234.59375, 604.07232666015625, -65.1342086791992187, 6.248279094696044921, 0, 0, -0.01745223999023437, 0.999847710132598876, 300, 255, 1, "", 45572, NULL), +(3459, 2744, 0, 0, 0, 1, 1, -12244.26171875, 581.7044677734375, -74.9788742065429687, 6.108653545379638671, 0, 0, -0.08715534210205078, 0.996194720268249511, 300, 255, 1, "", 50664, NULL), +(3460, 2744, 0, 0, 0, 1, 1, -12247.6884765625, 688.15435791015625, -71.0500640869140625, 2.583080768585205078, 0, 0, 0.961260795593261718, 0.275640487670898437, 300, 255, 1, "", 47168, NULL), +(3461, 2744, 0, 0, 0, 1, 1, -12248.431640625, 443.0244140625, -32.4327278137207031, 4.712389945983886718, 0, 0, -0.70710659027099609, 0.707106947898864746, 300, 255, 1, "", 48019, NULL), +(3462, 2744, 0, 0, 0, 1, 1, -12249.8251953125, 607.121337890625, -101.612106323242187, 1.570795774459838867, 0, 0, 0.707106590270996093, 0.707106947898864746, 300, 255, 1, "", 47168, NULL), +(3463, 2744, 0, 0, 0, 1, 1, -12252.9453125, 483.68072509765625, -72.6024169921875, 5.602506637573242187, 0, 0, -0.33380699157714843, 0.942641437053680419, 300, 255, 1, "", 47168, NULL), +(3464, 2744, 0, 0, 0, 1, 1, -12257.2880859375, 455.25238037109375, -46.6031379699707031, 1.588248729705810546, 0, 0, 0.713250160217285156, 0.700909554958343505, 300, 255, 1, "", 47168, NULL), +(3465, 2744, 0, 0, 0, 1, 1, -12261.4013671875, 650.3587646484375, -91.6953125, 4.258606910705566406, 0, 0, -0.84804725646972656, 0.529920578002929687, 300, 255, 1, "", 45772, NULL), +(3466, 2744, 0, 0, 0, 1, 1, -12266.814453125, 541.2694091796875, -109.597816467285156, 2.809975385665893554, 0, 0, 0.986285209655761718, 0.165049895644187927, 300, 255, 1, "", 45572, NULL), +(3467, 2744, 0, 0, 0, 1, 1, -12276.982421875, 694.41302490234375, -98.2943572998046875, 4.206246376037597656, 0, 0, -0.86162853240966796, 0.50753939151763916, 300, 255, 1, "", 51831, NULL), +(3468, 2744, 0, 0, 0, 1, 1, -12280.021484375, 598.15081787109375, -102.022453308105468, 0.017452461645007133, 0, 0, 0.008726119995117187, 0.999961912631988525, 300, 255, 1, "", 49345, NULL), +(3469, 2744, 0, 0, 0, 1, 1, -12282.7177734375, 538.59326171875, -84.8114852905273437, 4.939284324645996093, 0, 0, -0.6225137710571289, 0.78260880708694458, 300, 255, 1, "", 45572, NULL), +(3470, 2744, 0, 0, 0, 1, 1, -12287.6552734375, 479.775390625, -58.4963035583496093, 5.148722648620605468, 0, 0, -0.53729915618896484, 0.843391716480255126, 300, 255, 1, "", 45613, NULL), +(3471, 2744, 0, 0, 0, 1, 1, -12293.0048828125, 607.82000732421875, -79.2215652465820312, 4.363324165344238281, 0, 0, -0.81915187835693359, 0.573576688766479492, 300, 255, 1, "", 54261, NULL), +(3472, 2744, 0, 0, 0, 1, 1, -12294.1396484375, 650.81317138671875, -82.8747940063476562, 2.338739633560180664, 0, 0, 0.920504570007324218, 0.3907318115234375, 300, 255, 1, "", 50664, NULL), +(3473, 2744, 0, 0, 0, 1, 1, -12297.1015625, 488.23089599609375, -78.2284469604492187, 4.625123500823974609, 0, 0, -0.73727703094482421, 0.67559051513671875, 300, 255, 1, "", 47168, NULL), +(3474, 2744, 0, 0, 0, 1, 1, -12305.6669921875, 435.504241943359375, -20.5355720520019531, 3.926995515823364257, 0, 0, -0.92387866973876953, 0.38268551230430603, 300, 255, 1, "", 49345, NULL), +(3475, 2744, 0, 0, 0, 1, 1, -12306.8349609375, 527.46429443359375, -83.1399383544921875, 0.104719325900077819, 0, 0, 0.052335739135742187, 0.998629570007324218, 300, 255, 1, "", 49345, NULL), +(3476, 2744, 0, 0, 0, 1, 1, -12313.84375, 601.927490234375, -59.0801734924316406, 1.535889506340026855, 0, 0, 0.694658279418945312, 0.719339847564697265, 300, 255, 1, "", 50664, NULL), +(3477, 2744, 0, 0, 0, 1, 1, -12314.4111328125, 616.9012451171875, -43.5424957275390625, 2.181660413742065429, 0, 0, 0.887010574340820312, 0.461749136447906494, 300, 255, 1, "", 49345, NULL), +(3478, 2744, 0, 0, 0, 1, 1, -12324.0830078125, 535.95367431640625, -65.3733749389648437, 0.663223206996917724, 0, 0, 0.325567245483398437, 0.945518851280212402, 300, 255, 1, "", 45772, NULL), +(3479, 2744, 0, 0, 0, 1, 1, -12328.40625, 709.5440673828125, -45.4184150695800781, 4.502951622009277343, 0, 0, -0.7771453857421875, 0.629321098327636718, 300, 255, 1, "", 45772, NULL), +(3480, 2744, 0, 0, 0, 1, 1, -12328.4462890625, 572.81036376953125, -65.9415054321289062, 3.874631166458129882, 0, 0, -0.93358039855957031, 0.358368009328842163, 300, 255, 1, "", 47168, NULL), +(3481, 2744, 0, 0, 0, 1, 1, -12329.5849609375, 650.5650634765625, -42.0246963500976562, 1.186823248863220214, 0, 0, 0.559192657470703125, 0.829037725925445556, 300, 255, 1, "", 50664, NULL), +(3482, 2744, 0, 0, 0, 1, 1, -12339.1826171875, 605.053955078125, -66.5669021606445312, 0.209439441561698913, 0, 0, 0.104528427124023437, 0.994521915912628173, 300, 255, 1, "", 45772, NULL), +(3483, 2744, 0, 0, 0, 1, 1, -12348.8857421875, 442.909454345703125, -38.4705696105957031, 4.45059061050415039, 0, 0, -0.79335308074951171, 0.608761727809906005, 300, 255, 1, "", 45572, NULL), +(3484, 2744, 0, 0, 0, 1, 1, -12355.35546875, 544.90972900390625, -84.1712570190429687, 2.775068521499633789, 0, 0, 0.983254432678222656, 0.182238012552261352, 300, 255, 1, "", 49345, NULL), +(3485, 2744, 0, 0, 0, 1, 1, -12357.2529296875, 576.179931640625, -71.4578628540039062, 5.235987663269042968, 0, 0, -0.5, 0.866025388240814208, 300, 255, 1, "", 52237, NULL), +(3486, 2744, 0, 0, 0, 1, 1, -12357.548828125, 690.5987548828125, -21.5122146606445312, 3.595378875732421875, 0, 0, -0.97437000274658203, 0.224951311945915222, 300, 255, 1, "", 45772, NULL), +(3487, 2744, 0, 0, 0, 1, 1, -12357.7109375, 475.235626220703125, -90.5011749267578125, 1.623155713081359863, 0, 0, 0.725374221801757812, 0.688354730606079101, 300, 255, 1, "", 48019, NULL), +(3488, 2744, 0, 0, 0, 1, 1, -12359.6318359375, 665.0457763671875, -37.03369140625, 3.543023586273193359, 0, 0, -0.97992420196533203, 0.199370384216308593, 300, 255, 1, "", 45572, NULL), +(3489, 2744, 0, 0, 0, 1, 1, -12372.958984375, 576.60809326171875, -88.2532806396484375, 1.658061861991882324, 0, 0, 0.737277030944824218, 0.67559051513671875, 300, 255, 1, "", 45572, NULL), +(3490, 2744, 0, 0, 0, 1, 1, -12378.8916015625, 647.649658203125, -64.9648818969726562, 5.009094715118408203, 0, 0, -0.59482288360595703, 0.80385679006576538, 300, 255, 1, "", 45572, NULL), +(3491, 2744, 0, 0, 0, 1, 1, -12387.9462890625, 685.329345703125, -53.21832275390625, 0.017452461645007133, 0, 0, 0.008726119995117187, 0.999961912631988525, 300, 255, 1, "", 48120, NULL), +(3492, 2744, 0, 0, 0, 1, 1, -12390.2548828125, 608.60711669921875, -106.115257263183593, 5.270895957946777343, 0, 0, -0.48480892181396484, 0.87462007999420166, 300, 255, 1, "", 45772, NULL), +(3493, 2744, 0, 0, 0, 1, 1, -12406.4111328125, 706.82012939453125, -33.0999336242675781, 1.291541695594787597, 0, 0, 0.60181427001953125, 0.798636078834533691, 300, 255, 1, "", 48019, NULL), +(3494, 2744, 0, 0, 0, 1, 1, -12406.908203125, 440.619537353515625, -41.5363845825195312, 2.70525527000427246, 0, 0, 0.97629547119140625, 0.216442063450813293, 300, 255, 1, "", 45613, NULL), +(3495, 2744, 0, 0, 0, 1, 1, -12407.181640625, 633.13824462890625, -89.5317153930664062, 3.176533222198486328, 0, 0, -0.999847412109375, 0.017469281330704689, 300, 255, 1, "", 50664, NULL), +(3496, 2744, 0, 0, 0, 1, 1, -12409.3525390625, 503.579803466796875, -75.6299819946289062, 3.385940074920654296, 0, 0, -0.99254608154296875, 0.121869951486587524, 300, 255, 1, "", 48019, NULL), +(3497, 2744, 0, 0, 0, 1, 1, -12410.47265625, 455.93707275390625, -63.8843536376953125, 6.021387100219726562, 0, 0, -0.13052558898925781, 0.991444945335388183, 300, 255, 1, "", 48120, NULL), +(3498, 2744, 0, 0, 0, 1, 1, -12415.205078125, 674.24493408203125, -67.7239303588867187, 2.44346022605895996, 0, 0, 0.939692497253417968, 0.34202045202255249, 300, 255, 1, "", 48120, NULL), +(3499, 2744, 0, 0, 0, 1, 1, -12420.8681640625, 564.3009033203125, -96.0813217163085937, 5.654868602752685546, 0, 0, -0.30901622772216796, 0.95105677843093872, 300, 255, 1, "", 45572, NULL), +(3500, 2744, 0, 0, 0, 1, 1, -12422.203125, 529.30615234375, -92.2594985961914062, 0.802850961685180664, 0, 0, 0.390730857849121093, 0.920504987239837646, 300, 255, 1, "", 52237, NULL), +(3501, 2744, 0, 0, 0, 1, 1, -12424.3798828125, 635.39898681640625, -99.6658477783203125, 4.398232460021972656, 0, 0, -0.80901622772216796, 0.587786316871643066, 300, 255, 1, "", 48019, NULL), +(3502, 2744, 0, 0, 0, 1, 1, -12431.9970703125, 487.49945068359375, -69.9343032836914062, 1.972219824790954589, 0, 0, 0.83388519287109375, 0.55193793773651123, 300, 255, 1, "", 48019, NULL), +(3503, 2744, 0, 0, 0, 1, 1, -12433.3994140625, 709.91156005859375, -53.2276840209960937, 0, 0, 0, 0, 1, 300, 255, 1, "", 45572, NULL), +(3504, 2744, 0, 0, 0, 1, 1, -12435.99609375, 582.399169921875, -103.410621643066406, 1.134462952613830566, 0, 0, 0.537299156188964843, 0.843391716480255126, 300, 255, 1, "", 49822, NULL), +(3505, 2744, 0, 0, 0, 1, 1, -12439.669921875, 455.67724609375, -47.6966323852539062, 0.750490784645080566, 0, 0, 0.3665008544921875, 0.93041771650314331, 300, 255, 1, "", 45572, NULL), +(3506, 2744, 0, 0, 0, 1, 1, -12441.2568359375, 545.54913330078125, -81.1741485595703125, 6.021387100219726562, 0, 0, -0.13052558898925781, 0.991444945335388183, 300, 255, 1, "", 45572, NULL), +(3507, 2744, 0, 0, 0, 1, 1, -12446.66015625, 653.4971923828125, -76.8185958862304687, 1.413715124130249023, 0, 0, 0.649447441101074218, 0.760406434535980224, 300, 255, 1, "", 47168, NULL), +(3508, 2744, 0, 0, 0, 1, 1, -12453.314453125, 688.5665283203125, -67.7992324829101562, 2.024578809738159179, 0, 0, 0.848047256469726562, 0.529920578002929687, 300, 255, 1, "", 48019, NULL), +(3509, 2744, 0, 0, 0, 1, 1, -12453.5244140625, 519.727294921875, -72.177520751953125, 5.794494152069091796, 0, 0, -0.24192142486572265, 0.970295846462249755, 300, 255, 1, "", 47168, NULL), +(3510, 2744, 0, 0, 0, 1, 1, -12458.4033203125, 454.407012939453125, -43.0031089782714843, 2.687806606292724609, 0, 0, 0.974370002746582031, 0.224951311945915222, 300, 255, 1, "", 45772, NULL), +(3511, 2744, 0, 0, 0, 1, 1, -12466.10546875, 567.4268798828125, -69.4961624145507812, 0.436331570148468017, 0, 0, 0.216439247131347656, 0.976296067237854003, 300, 255, 1, "", 45613, NULL), +(3512, 2744, 0, 0, 0, 1, 1, -12472.2548828125, 554.970458984375, -60.8499641418457031, 0.069811686873435974, 0, 0, 0.034898757934570312, 0.999390840530395507, 300, 255, 1, "", 48120, NULL), +(3513, 2744, 0, 0, 0, 1, 1, -12472.4443359375, 594.99560546875, -87.6874771118164062, 3.874631166458129882, 0, 0, -0.93358039855957031, 0.358368009328842163, 300, 255, 1, "", 45572, NULL), +(3514, 2744, 0, 0, 0, 1, 1, -12481.4423828125, 505.266510009765625, -61.46136474609375, 1.972219824790954589, 0, 0, 0.83388519287109375, 0.55193793773651123, 300, 255, 1, "", 48019, NULL); + +-- remaining spawns (no sniffed values available) +-- (`guid` IN (2134849, 2134854, 2134739, 2134863, 2134862, 2134864, 2134840, 2134848, 2134839, 2134853, 2134851)) + +-- pooling +DELETE FROM `pool_template` WHERE (`entry` IN (142)); +INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES +(142, 20, 'Eastern Kingdoms - Giant Clam - 20/80'); + +DELETE FROM `pool_gameobject` WHERE (`pool_entry` IN (142)) AND (`guid` IN (11029, 11030, 11686, 11687, 11811, 11818, 32097)); +DELETE FROM `pool_gameobject` WHERE (`pool_entry` IN (142)) AND (`guid` BETWEEN 3442 AND 3514); +INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES +(11029, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(11030, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(11686, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(11687, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(11811, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(11818, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(32097, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3442, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3443, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3444, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3445, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3446, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3447, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3448, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3449, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3450, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3451, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3452, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3453, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3454, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3455, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3456, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3457, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3458, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3459, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3460, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3461, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3462, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3463, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3464, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3465, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3466, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3467, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3468, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3469, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3470, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3471, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3472, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3473, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3474, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3475, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3476, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3477, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3478, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3479, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3480, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3481, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3482, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3483, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3484, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3485, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3486, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3487, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3488, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3489, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3490, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3491, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3492, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3493, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3494, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3495, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3496, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3497, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3498, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3499, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3500, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3501, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3502, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3503, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3504, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3505, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3506, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3507, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3508, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3509, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3510, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3511, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3512, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3513, 142, 0, 'Eastern Kingdoms - Giant Clam'), +(3514, 142, 0, 'Eastern Kingdoms - Giant Clam'); diff --git a/data/sql/updates/db_world/2025_01_19_01.sql b/data/sql/updates/db_world/2025_01_19_01.sql new file mode 100644 index 000000000..e5e13a07b --- /dev/null +++ b/data/sql/updates/db_world/2025_01_19_01.sql @@ -0,0 +1,11 @@ +-- DB update 2025_01_19_00 -> 2025_01_19_01 +-- +-- Deletes `LANG_PASSWORD_TOO_LONG` and `LANG_ACCOUNT_TOO_LONG`. +DELETE FROM `acore_string` WHERE `entry` IN (55, 1005); + +INSERT INTO `acore_string` (`entry`, `content_default`, `locale_koKR`, `locale_frFR`, `locale_deDE`, `locale_zhCN`, `locale_zhTW`, `locale_esES`, `locale_esMX`, `locale_ruRU`) VALUES +-- Added the missing texts (LANG_PASSWORD_TOO_LONG) for "French" and "Russian". +(55, "Your password can't be longer than 16 characters (client limit), password not changed!", NULL, "Le mot de passe ne doit pas dépasser 16 caractères (limitation technique du client), le mot de passe n'a pas été changé!", "Das Passwort kann nicht länger als 16 Zeichen sein (Client Limit). Das Passwort wurde nicht geändert!", "你的新密码不能超过16个字符 (客户端限制), 密码没有修改!", NULL, "Su contraseña no puede tener más de 16 caracteres (límite del cliente), ¡la contraseña no se cambia!", "Su contraseña no puede tener más de 16 caracteres (límite del cliente), ¡la contraseña no se cambia!", "Ваш пароль не может быть длиннее 16 символов (клиентский лимит), пароль не изменен!"), +-- Added the missing texts (LANG_ACCOUNT_TOO_LONG) for "French", "Spain Spanish", "Mexican Spanish" and "Russian. +-- Corrcted ALL the character "client limit" to 17 (from 20). +(1005, "Account name can't be longer than 17 characters (client limit), account not created!", NULL, "Le nom de compte ne doit pas dépasser 17 caractères (limitation technique du client), le compte n'a pas été créé!", "Der Account Name kann nicht länger als 17 Zeichen sein (Client Limit). Account wurde nicht erstellt!", "帐号名长度不能超过17个字符(客户端限制),帐户创建失败!", NULL, "El nombre de la cuenta no puede tener más de 17 caracteres (límite de cliente), ¡cuenta no creada!", "El nombre de la cuenta no puede tener más de 17 caracteres (límite de cliente), ¡cuenta no creada!", "Имя учетной записи не может быть длиннее 17 символов (ограничение для клиента), учетная запись не создана!"); diff --git a/data/sql/updates/db_world/2025_01_19_02.sql b/data/sql/updates/db_world/2025_01_19_02.sql new file mode 100644 index 000000000..3fe6f534b --- /dev/null +++ b/data/sql/updates/db_world/2025_01_19_02.sql @@ -0,0 +1,259 @@ +-- DB update 2025_01_19_01 -> 2025_01_19_02 +-- Ashbringer is buff +DELETE +FROM `spell_custom_attr` +WHERE `spell_id` = 28282; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (28282, 67108864); + +-- It takes time to open the door with a key in Blizzard servers +UPDATE `gameobject_template_addon` SET `flags` = `flags`|2|32 +WHERE (`entry` = 104591); + +-- Clientside area trigger 4089 smart ai +SET @ENTRY := 4089; +DELETE FROM `areatrigger_scripts` WHERE `entry` = @ENTRY; +INSERT INTO `areatrigger_scripts` (`entry`, `ScriptName`) VALUES (@ENTRY, 'SmartTrigger'); +DELETE FROM `smart_scripts` WHERE `source_type` = 2 AND `entryOrGuid` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 2, 0, 1, 46, 0, 100, 1, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'On trigger - Self: storedTarget[0] = Triggering player'), +(@ENTRY, 2, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 34, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'On trigger - Set instance data #2 to 1'), +(@ENTRY, 2, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 10, 40029, 3976, 0, 0, 0, 0, 0, 'On trigger - Send stored target storedTarget[0] to Creature Scarlet Commander Mograine (3976) with guid 40029 (fetching)'), +(@ENTRY, 2, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 10, 40029, 3976, 0, 0, 0, 0, 0, 'On trigger - Creature Scarlet Commander Mograine (3976) with guid 40029 (fetching): Set creature data #0 to 1'); +-- smart conditions +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = @ENTRY AND `SourceId` = 2; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `Comment`) VALUES +(22, 1, @ENTRY, 2, 0, 1, 0, 28282, 0, 0, 0, 'Action invoker has aura of spell Ashbringer (28282), effect EFFECT_0'), +(22, 1, @ENTRY, 2, 0, 13, 0, 2, 0, 0, 0, 'instance data 2 equals 0'); + +-- Scarlet Commander Mograine smart ai + +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 3976; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 3976); +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 +(3976, 0, 0, 0, 38, 0, 100, 0, 0, 1, 0, 0, 0, 0, 1, 6, 0, 1, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Data Set 0 1 - Say Line 6'), +(3976, 0, 1, 0, 0, 0, 100, 1, 0, 0, 0, 0, 0, 0, 11, 8990, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - In Combat - Cast \'Retribution Aura\' (No Repeat)'), +(3976, 0, 2, 0, 0, 0, 100, 1, 1000, 1000, 0, 0, 0, 0, 34, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - In Combat - Set Instance Data 1 to 1 (No Repeat)'), +(3976, 0, 3, 0, 0, 0, 100, 0, 1000, 5000, 10000, 10000, 0, 0, 11, 14518, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - In Combat - Cast \'Crusader Strike\''), +(3976, 0, 4, 0, 0, 0, 100, 0, 6000, 11000, 60000, 60000, 0, 0, 11, 5589, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - In Combat - Cast \'Hammer of Justice\''), +(3976, 0, 5, 6, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Respawn - Set Active Off'), +(3976, 0, 6, 7, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 33554432, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Respawn - Remove Flags Not Selectable'), +(3976, 0, 7, 8, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Respawn - Set Reactstate Aggressive'), +(3976, 0, 8, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 91, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Respawn - Remove FlagStandstate Dead'), +(3976, 0, 9, 10, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Aggro - Set Invincibility Hp 1'), +(3976, 0, 10, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Aggro - Say Line 0'), +(3976, 0, 11, 12, 7, 0, 100, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Evade - Stop motion (StopMoving: 0, MovementExpired: 0)'), +(3976, 0, 12, 13, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 96, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Evade - Remove Dynamic Flags Dead'), +(3976, 0, 13, 14, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 34, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Evade - Set Instance Data 1 to 2'), +(3976, 0, 14, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 33554432, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Evade - Remove Flags Not Selectable'), +(3976, 0, 15, 0, 5, 0, 100, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Killed Unit - Say Line 1'), +(3976, 0, 16, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 34, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Just Died - Set Instance Data 1 to 3'), +(3976, 0, 17, 0, 2, 0, 100, 1, 0, 1, 0, 0, 0, 0, 80, 397600, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Between 0-1% Health - Run Script (No Repeat)'), +(3976, 0, 18, 0, 8, 1, 100, 512, 9232, 0, 0, 0, 0, 0, 80, 397601, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Spellhit \'Scarlet Resurrection\' - Run Script (Phase 1)'), +(3976, 0, 19, 20, 34, 0, 100, 0, 8, 1, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Reached Point 1 - Reset Invincibility Hp'), +(3976, 0, 20, 21, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 33554432, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Reached Point 1 - Remove Flags Not Selectable'), +(3976, 0, 21, 22, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Reached Point 1 - Set Reactstate Aggressive'), +(3976, 0, 22, 23, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 8990, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Reached Point 1 - Cast \'Retribution Aura\''), +(3976, 0, 23, 24, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Reached Point 1 - Start Attacking'), +(3976, 0, 24, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Reached Point 1 - Start Attacking'), +(3976, 0, 25, 0, 8, 0, 100, 1, 28441, 0, 0, 0, 0, 0, 80, 397602, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Spellhit \'AB Effect 000\' - Run Script (No Repeat)'), +(3976, 0, 26, 0, 8, 0, 100, 1, 28441, 0, 0, 0, 0, 0, 67, 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Spellhit \'AB Effect 000\' - Create Timed Event (No Repeat)'), +(3976, 0, 27, 0, 59, 0, 100, 0, 1, 0, 0, 0, 0, 0, 12, 16062, 8, 0, 0, 0, 0, 8, 0, 0, 0, 0, 1033.46, 1399.1, 27.3374, 6.25796, 'Scarlet Commander Mograine - On Timed Event 1 Triggered - Summon Creature \'Highlord Mograine\''), +(3976, 0, 28, 0, 8, 0, 100, 0, 28697, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - On Spellhit \'Forgiveness\' - Kill Self'); + +-- Scarlet Commander Mograine suspended animation +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 397600); +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 +(397600, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Stop Attack'), +(397600, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 10, 39946, 3977, 0, 0, 0, 0, 0, 0, 'Creature High Inquisitor Whitemane (3977) with guid 39946 (fetching): Set creature data #0 to 1'), +(397600, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 212, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Stop motion (StopMoving: 0, MovementExpired: 1)'), +(397600, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Start Random Movement'), +(397600, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 4, 1326, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Play Sound 1326'), +(397600, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 28, 8990, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Remove Aura \'Retribution Aura\''), +(397600, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 90, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Set Flag Standstate Dead'), +(397600, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 33554432, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Set Flags Not Selectable'), +(397600, 9, 8, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Set Reactstate Passive'), +(397600, 9, 9, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Set Event Phase 1'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 397601); +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 +(397601, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Set Reactstate Passive'), +(397601, 9, 1, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 0, 0, 91, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Remove FlagStandstate Dead'), +(397601, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 9257, 0, 0, 0, 0, 0, 10, 39946, 3977, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Cast \'Lay on Hands\''), +(397601, 9, 3, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 0, 10, 39946, 3977, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Say Line 2'), +(397601, 9, 4, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 10, 39946, 3977, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Move To Closest Creature \'High Inquisitor Whitemane\''); + +-- Scarlet Commander Mograine Ashbringer Event +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 397602); +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 +(397602, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Set Active On'), +(397602, 9, 1, 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, 'Scarlet Commander Mograine - Actionlist - Set Faction 35'), +(397602, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Start Random Movement'), +(397602, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Set Orientation Invoker'), +(397602, 9, 4, 0, 0, 0, 100, 0, 1000, 3000, 0, 0, 0, 0, 90, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Set Flag Standstate Kneel'), +(397602, 9, 5, 0, 0, 0, 100, 0, 1000, 2000, 0, 0, 0, 0, 1, 3, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Scarlet Commander Mograine - Actionlist - Say Line 3'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 3976 AND `SourceId` = 0; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `Comment`) VALUES +(22, 1, 3976, 0, 0, 21, 1, 16384, 0, 0, 1, 'Object doesn\'t have unit state UNIT_STATE_ATTACK_PLAYER'), +(22, 1, 3976, 0, 0, 36, 1, 0, 0, 0, 0, 'Object is alive'), +(22, 3, 3976, 0, 0, 4, 1, 796, 0, 0, 0, 'Object in zone (796)'), +(22, 18, 3976, 0, 0, 4, 1, 796, 0, 0, 0, 'Object in zone (796)'), +(22, 19, 3976, 0, 0, 4, 1, 796, 0, 0, 0, 'Object in zone (796)'), +(22, 26, 3976, 0, 0, 4, 1, 796, 0, 0, 0, 'Object in zone (796)'), +(22, 26, 3976, 0, 0, 36, 1, 0, 0, 0, 0, 'Object is alive'), +(22, 27, 3976, 0, 0, 4, 1, 796, 0, 0, 0, 'Object in zone (796)'), +(22, 27, 3976, 0, 0, 36, 1, 0, 0, 0, 0, 'Object is alive'); + +-- Scarlet Commander Mograine say +DELETE FROM `creature_text` WHERE `CreatureID` = 3976; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(3976, 0, 0, 'Infidels! They must be purified!', 14, 0, 100, 0, 0, 5835, 2847, 0, 'Scarlet Commander Mograine // mograine SAY_MO_AGGRO'), +(3976, 1, 0, 'Unworthy.', 14, 0, 100, 0, 0, 5836, 6197, 0, 'Scarlet Commander Mograine // mograine SAY_MO_KILL'), +(3976, 2, 0, 'At your side, milady!', 14, 0, 100, 15, 0, 5837, 18026, 0, 'Scarlet Commander Mograine // mograine SAY_MO_RESSURECTED'), +(3976, 3, 0, 'You hold my father\'s blade, $n. My soldiers are yours TO control, my $g Lord:Lady;. Take them... LEAD them... The impure must be purged. They must be cleansed of their taint.', 12, 0, 100, 1, 0, 0, 12390, 0, 'Scarlet Commander Mograine // mograine SAY_ASHBRINGER_ONE'), +(3976, 4, 0, 'Father... But... How?', 12, 0, 100, 6, 0, 0, 12470, 0, 'Scarlet Commander Mograine // mograine SAY_ASHBRINGER_TWO'), +(3976, 5, 0, 'Forgive me, father! Please...', 12, 0, 100, 20, 0, 0, 12472, 0, 'Scarlet Commander Mograine // mograine SAY_ASHBRINGER_THREE'), +(3976, 6, 0, 'Bow down! Kneel BEFORE the Ashbringer! A NEW dawn approaches, brothers AND sisters! Our message will be delivered TO the filth of this world through the chosen one!', 14, 0, 100, 0, 0, 0, 12389, 3, 'Scarlet Commander Mograine // Ashbringer EVENT intro yell'); + +-- Highlord Mograine smart_scripts + +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 16062; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 16062); +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 +(16062, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - On Just Summoned - Set Active On'), +(16062, 0, 1, 2, 61, 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, 'Highlord Mograine - On Just Summoned - Set Faction 35'), +(16062, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - On Just Summoned - Change Equipment'), +(16062, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 16180, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - On Just Summoned - Morph To Model 16180'), +(16062, 0, 4, 5, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 28688, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - On Just Summoned - Cast \'Mograine Cometh DND\''), +(16062, 0, 5, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 53, 0, 16062, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - On Just Summoned - Start Waypoint Path 16062'), +(16062, 0, 6, 7, 40, 0, 100, 0, 12, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 19, 3976, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - On Point 12 of Path Any Reached - Set Orientation Closest Creature \'Scarlet Commander Mograine\''), +(16062, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 1606200, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - On Point 12 of Path Any Reached - Run Script'); + +-- Highlord Mograine Ashbringer Event + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 1606200); +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 +(1606200, 9, 0, 0, 0, 0, 100, 0, 200, 200, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - Actionlist - Say Line 0'), +(1606200, 9, 1, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 231, 2, 0, 0, 0, 0, 0, 19, 3976, 5, 0, 0, 0, 0, 0, 0, 'Closest alive creature Scarlet Commander Mograine (3976) in 5 yards: - Actionlist - Set Target Orientation'), +(1606200, 9, 2, 0, 0, 0, 100, 0, 400, 400, 0, 0, 0, 0, 91, 8, 0, 0, 0, 0, 0, 19, 3976, 5, 0, 0, 0, 0, 0, 0, 'Closest alive creature Scarlet Commander Mograine (3976) in 5 yards: - Actionlist - Remove FlagStandstate Kneel'), +(1606200, 9, 3, 0, 0, 0, 100, 0, 1200, 1200, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 19, 3976, 5, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - Actionlist - Say Line 4'), +(1606200, 9, 4, 0, 0, 0, 100, 0, 4600, 4600, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - Actionlist - Say Line 1'), +(1606200, 9, 5, 0, 0, 0, 100, 0, 3400, 3400, 0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - Actionlist - Play Emote 6'), +(1606200, 9, 6, 0, 0, 0, 100, 0, 3200, 3200, 0, 0, 0, 0, 5, 25, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - Actionlist - Play Emote 25'), +(1606200, 9, 7, 0, 0, 0, 100, 0, 3200, 3200, 0, 0, 0, 0, 5, 15, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - Actionlist - Play Emote 15'), +(1606200, 9, 8, 0, 0, 0, 100, 0, 3200, 3200, 0, 0, 0, 0, 231, 2, 0, 0, 0, 0, 0, 19, 3976, 5, 0, 0, 0, 0, 0, 0, 'Closest alive creature Scarlet Commander Mograine (3976) in 5 yards: - Actionlist - Set Target Orientation'), +(1606200, 9, 9, 0, 0, 0, 100, 0, 1200, 1200, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 19, 3976, 5, 0, 0, 0, 0, 0, 0, 'Closest alive creature Scarlet Commander Mograine (3976) in 5 yards: - Actionlist - Say Line 5'), +(1606200, 9, 10, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 11, 28697, 0, 0, 0, 0, 0, 19, 3976, 10, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - Actionlist - Cast \'Forgiveness\''), +(1606200, 9, 11, 0, 0, 0, 100, 0, 3700, 3700, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - Actionlist - Say Line 2'), +(1606200, 9, 12, 0, 0, 0, 100, 0, 3400, 3400, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Highlord Mograine - Actionlist - Despawn Instant'); + +-- Highlord Mograine Say +DELETE FROM `creature_text` WHERE `CreatureID`=16062; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `Type`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(16062, 0, 0, 'Renault...', 0, 100, 25, 0, 0, 12, 12469, 0, 'mograine MOGRAINE_ONE'), +(16062, 1, 0, 'Did you think that your betrayal would be forgotten? Lost in the carefully planned cover up of my death? Blood of my blood, the blade felt your cruelty long after my heart had stopped beating. And in death, I knew what you had done. But now, the chains of Kel\'thuzad hold me NO more. I come TO serve justice. I AM ASHBRINGER.', 0, 100, 6, 0, 0, 12, 12471, 0, 'mograine MOGRAINE_TWO'), +(16062, 2, 0, 'You are forgiven...', 0, 100, 0, 0, 0, 12, 12473, 0, 'mograine MOGRAINE_THREE'); + +DELETE +FROM `waypoints` +WHERE `entry`=16062; +INSERT INTO `waypoints` (`entry`, `pointid`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `point_comment`) VALUES +(16062, 1, 1033.4642, 1399.1022, 27.337427, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 2, 1034.9252, 1399.0653, 27.393204, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 3, 1036.3861, 1399.0284, 27.44898, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 4, 1045.484, 1398.7991, 27.448977, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 5, 1059.524, 1399.0273, 28.271557, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 6, 1068.8096, 1399.2064, 30.7867, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 7, 1086.6564, 1399.2048, 30.44898, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 8, 1101.5681, 1399.3694, 30.485447, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 9, 1116.6019, 1399.4752, 30.485447, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 10, 1129.5881, 1399.2926, 30.524086, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 11, 1149.4045, 1399.0231, 32.528877, NULL, 0, 'Ashbringer Event Move Points'), +(16062, 12, 1150.3911, 1398.723, 32.54613, NULL, 0, 'Ashbringer Event Move Points'); + +-- Highlord Mograine Condition +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 8990) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 31) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 3) AND (`ConditionValue2` = 16062) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 8990, 0, 0, 31, 0, 3, 16062, 0, 1, 0, 0, '', 'Potential target of the spell is not creature, entry is 16062'); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` = 1) AND (`SourceEntry` = 16062) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 4) AND (`ConditionTarget` = 1) AND (`ConditionValue1` = 796) AND (`ConditionValue2` = 0) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22, 1, 16062, 0, 0, 4, 1, 796, 0, 0, 0, 0, 0, '', 'Object in zone (796)'); + +-- High Inquisitor Whitemane Smart ai +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 3977; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 3977); +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 +(3977, 0, 0, 1, 38, 0, 100, 0, 0, 1, 0, 0, 0, 0, 118, 2, 0, 0, 0, 0, 0, 14, 11877, 104600, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Data Set 0 1 - Set GO State To 2'), +(3977, 0, 1, 2, 61, 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, 'High Inquisitor Whitemane - On Data Set 0 1 - Say Line 0'), +(3977, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 10, 40029, 3976, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Data Set 0 1 - Move To Closest Creature \'Scarlet Commander Mograine\''), +(3977, 0, 3, 4, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Aggro - Set Invincibility Hp 1'), +(3977, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Aggro - Set Event Phase 1'), +(3977, 0, 5, 0, 0, 3, 100, 0, 1000, 1000, 2600, 4000, 0, 0, 11, 9481, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - In Combat - Cast \'Holy Smite\' (Phases 1 & 2)'), +(3977, 0, 6, 0, 16, 3, 100, 0, 22187, 40, 5000, 10000, 1, 0, 11, 22187, 32, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Friendly Unit Missing Buff \'Power Word: Shield\' - Cast \'Power Word: Shield\' (Phases 1 & 2)'), +(3977, 0, 7, 0, 0, 2, 100, 0, 45000, 45000, 20000, 30000, 0, 0, 11, 14515, 64, 0, 0, 0, 0, 6, 20, 1, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - In Combat - Cast \'Dominate Mind\' (Phase 2)'), +(3977, 0, 8, 0, 74, 2, 100, 0, 5000, 15000, 5000, 15000, 75, 40, 11, 12039, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Friendly Below 75% Health - Cast \'Heal\' (Phase 2)'), +(3977, 0, 9, 0, 5, 0, 100, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Killed Unit - Say Line 1'), +(3977, 0, 10, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 118, 1, 0, 0, 0, 0, 0, 14, 11877, 104600, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Respawn - Set GO State To 1'), +(3977, 0, 11, 12, 7, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Evade - Set Reactstate Aggressive'), +(3977, 0, 12, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 34, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Evade - Set Instance Data 1 to 2'), +(3977, 0, 13, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 34, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Just Died - Set Instance Data 1 to 3'), +(3977, 0, 14, 15, 2, 0, 100, 513, 0, 50, 0, 0, 0, 0, 80, 397700, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Between 0-50% Health - Run Script (No Repeat)'), +(3977, 0, 15, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Between 0-50% Health - Set Event Phase 1 (No Repeat)'), +(3977, 0, 16, 0, 38, 0, 100, 0, 1, 1, 0, 0, 0, 0, 67, 1, 200, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Data Set 1 1 - Create Timed Event'), +(3977, 0, 17, 0, 59, 0, 100, 0, 1, 0, 0, 0, 0, 0, 80, 397701, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Timed Event 1 Triggered - Run Script'), +(3977, 0, 18, 0, 38, 0, 100, 0, 1, 1, 0, 0, 0, 0, 69, 2, 0, 0, 2, 0, 0, 10, 40029, 3976, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Data Set 1 1 - Move To Closest Creature \'Scarlet Commander Mograine\''), +(3977, 0, 19, 0, 34, 0, 100, 512, 8, 2, 0, 0, 0, 0, 80, 397701, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - On Reached Point 2 - Run Script'); + +-- Health less than 50% Hypnotize the player +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 397700); +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 +(397700, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Stop Attack'), +(397700, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Set Event Phase 0'), +(397700, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Set Reactstate Passive'), +(397700, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 9256, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Cast \'Deep Sleep\''), +(397700, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'After 0 seconds - Self: Set data[1] to 1'); + +-- Resurrect Mograini +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 397701); +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 +(397701, 9, 0, 0, 0, 0, 100, 0, 4500, 4500, 0, 0, 0, 0, 11, 9232, 0, 0, 0, 0, 0, 19, 3976, 50, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Cast \'Scarlet Resurrection\''), +(397701, 9, 1, 0, 0, 0, 100, 0, 1900, 1900, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Say Line 2'), +(397701, 9, 2, 0, 0, 0, 100, 0, 1400, 1400, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Set Sheath Unarmed'), +(397701, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 5, 66, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Play Emote 66'), +(397701, 9, 4, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Reset Invincibility Hp'), +(397701, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Set Reactstate Aggressive'), +(397701, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Set Event Phase 2'), +(397701, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Whitemane - Actionlist - Start Attacking'); + +-- High Inquisitor Whitemane say + +DELETE FROM `creature_text` WHERE `CreatureID` = 3977; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(3977, 0, 0, 'Mograine has fallen! You shall pay for this treachery! Arise, my champion! Arise!', 14, 0, 100, 0, 0, 5838, 18023, 0, 'High Inquisitor Whitemane // whitemane SAY_WH_INTRO'), +(3977, 1, 0, 'The Light has spoken!', 14, 0, 100, 0, 0, 5839, 6198, 0, 'High Inquisitor Whitemane // whitemane SAY_WH_KILL'), +(3977, 2, 0, 'Arise, my champion!', 14, 0, 100, 0, 0, 5840, 6532, 0, 'High Inquisitor Whitemane // whitemane SAY_WH_RESSURECT'); + +-- High Inquisitor Whitemane Conditions +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 3977 AND `SourceId` = 0; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `Comment`) VALUES +(22, 17, 3977, 0, 0, 29, 1, 3976, 5, 0, 0, 'There is creature Scarlet Commander Mograine (3976) within range 5 yards to Object'), +(22, 19, 3977, 0, 0, 29, 1, 3976, 5, 0, 1, 'There is no creature Scarlet Commander Mograine (3976) within range 5 yards to Object'); + +-- High Inquisitor Fairbanks smart ai + +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 4542; +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 4542) AND (`source_type` = 0) AND (`id` IN (11)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(4542, 0, 11, 0, 8, 0, 100, 1, 28441, 0, 0, 0, 0, 0, 80, 454205, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Fairbanks - On Spellhit \'AB Effect 000\' - Run Script (No Repeat)'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 454205); +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 +(454205, 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, 'High Inquisitor Fairbanks - Actionlist - Set Faction 35'), +(454205, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Fairbanks - Actionlist - Set Orientation Invoker'), +(454205, 9, 2, 0, 0, 0, 100, 0, 500, 500, 0, 0, 0, 0, 11, 28443, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Fairbanks - Actionlist - Cast \'Transform Ghost\''), +(454205, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 16179, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Fairbanks - Actionlist - Morph To Model 16179'), +(454205, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Fairbanks - Actionlist - Add Npc Flags Gossip'); diff --git a/data/sql/updates/db_world/2025_01_22_00.sql b/data/sql/updates/db_world/2025_01_22_00.sql new file mode 100644 index 000000000..0bbf39f8e --- /dev/null +++ b/data/sql/updates/db_world/2025_01_22_00.sql @@ -0,0 +1,8 @@ +-- DB update 2025_01_19_02 -> 2025_01_22_00 + +-- Change creature template flags (before: IMMUNE_TO_PC, IMMUNE_TO_NPC, NOT_SELECTABLE. now: STUNNED, NOT_SELECTABLE). +UPDATE `creature_template` SET `unit_flags`=`unit_flags`& ~33555200 WHERE (`entry` = 24722); +UPDATE `creature_template` SET `unit_flags`=`unit_flags`|33816576 WHERE (`entry` = 24722); + +-- Add Rooted and Flight (Sniffed Flags). +UPDATE `creature_template_movement` SET `Flight` = 1, `Rooted` = 1 WHERE (`CreatureId` = 24722); diff --git a/data/sql/updates/db_world/2025_01_22_01.sql b/data/sql/updates/db_world/2025_01_22_01.sql new file mode 100644 index 000000000..b971d26e3 --- /dev/null +++ b/data/sql/updates/db_world/2025_01_22_01.sql @@ -0,0 +1,45 @@ +-- DB update 2025_01_22_00 -> 2025_01_22_01 + +-- Shoveltusk Stag +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23691; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23691); +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 +(23691, 0, 0, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 55860, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shoveltusk Stag - On Aggro - Cast \'Shoveltusk Charge\''), +(23691, 0, 1, 0, 0, 0, 100, 0, 8000, 12000, 20000, 30000, 0, 0, 11, 32019, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Shoveltusk Stag - In Combat - Cast \'Gore\''); + +-- Shoveltusk Forager +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 29479; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 29479); +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 +(29479, 0, 0, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 55860, 32, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shoveltusk Stag - On Aggro - Cast \'Shoveltusk Charge\''), +(29479, 0, 1, 0, 0, 0, 100, 0, 8000, 12000, 20000, 30000, 0, 0, 11, 32019, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Shoveltusk Stag - In Combat - Cast \'Gore\''); + +-- Shoveltuck +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 23690; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 23690); +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 +(23690, 0, 0, 0, 0, 0, 100, 0, 8000, 14000, 15000, 24000, 0, 0, 11, 42320, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Shoveltusk - In Combat - Cast \'Head Butt\''); + +-- Shoveltuck Calf +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24791; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24791); +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 +(24791, 0, 0, 0, 0, 0, 100, 0, 8000, 14000, 15000, 24000, 0, 0, 11, 42320, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Shoveltusk - In Combat - Cast \'Head Butt\''); + +-- Tamed Shoveltusk +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 29486; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 29486); +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 +(29486, 0, 0, 0, 0, 0, 100, 0, 8000, 14000, 15000, 24000, 0, 0, 11, 42320, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Shoveltusk - In Combat - Cast \'Head Butt\''); + +-- Tamed Shoveltusk +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 29487; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 29487); +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 +(29487, 0, 0, 0, 0, 0, 100, 0, 8000, 14000, 15000, 24000, 0, 0, 11, 42320, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Shoveltusk - In Combat - Cast \'Head Butt\''); diff --git a/data/sql/updates/db_world/2025_01_22_02.sql b/data/sql/updates/db_world/2025_01_22_02.sql new file mode 100644 index 000000000..6871b288a --- /dev/null +++ b/data/sql/updates/db_world/2025_01_22_02.sql @@ -0,0 +1,8 @@ +-- DB update 2025_01_22_01 -> 2025_01_22_02 + +-- Change timers and update comments on SmartAI +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24777; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24777); +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 +(24777, 0, 0, 0, 0, 0, 100, 0, 5000, 10000, 4000, 8000, 0, 0, 11, 46479, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Sunblade Sentinel - In Combat - Cast \'Fel Lightning\''); diff --git a/data/sql/updates/db_world/2025_01_23_00.sql b/data/sql/updates/db_world/2025_01_23_00.sql new file mode 100644 index 000000000..10a65fb3d --- /dev/null +++ b/data/sql/updates/db_world/2025_01_23_00.sql @@ -0,0 +1,13 @@ +-- DB update 2025_01_22_02 -> 2025_01_23_00 + +-- Phoenix +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24674; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24674); +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 +(24674, 0, 0, 0, 37, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 44196, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Initialize - Cast \'Rebirth\''), +(24674, 0, 1, 0, 60, 0, 100, 257, 2000, 2000, 0, 0, 0, 0, 11, 44197, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Update - Cast \'Burn\' (No Repeat)'), +(24674, 0, 2, 0, 24, 0, 100, 0, 44226, 1, 5000, 5000, 0, 0, 11, 44202, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Target Buffed With \'Gravity Lapse\' - Cast \'Fireball\''), +(24674, 0, 3, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 21, 40, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Reset - Start Attacking'), +(24674, 0, 4, 5, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 12, 24675, 3, 20000, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Just Died - Summon Creature \'Phoenix Egg\''), +(24674, 0, 5, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 1000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Phoenix - On Just Died - Despawn In 1000 ms'); diff --git a/data/sql/updates/db_world/2025_01_23_01.sql b/data/sql/updates/db_world/2025_01_23_01.sql new file mode 100644 index 000000000..f95205a0f --- /dev/null +++ b/data/sql/updates/db_world/2025_01_23_01.sql @@ -0,0 +1,3 @@ +-- DB update 2025_01_23_00 -> 2025_01_23_01 +-- +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|2147483648 WHERE `entry` IN (24664, 24857); diff --git a/data/sql/updates/db_world/2025_01_23_02.sql b/data/sql/updates/db_world/2025_01_23_02.sql new file mode 100644 index 000000000..5029882cc --- /dev/null +++ b/data/sql/updates/db_world/2025_01_23_02.sql @@ -0,0 +1,5 @@ +-- DB update 2025_01_23_01 -> 2025_01_23_02 +-- +DELETE FROM `creature_text` WHERE `CreatureID` = 24664 AND `GroupID` = 7; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(24664, 7, 0, 'Oh no, he was merely an instrument, a stepping stone to a much larger plan! It has all led to this... and this time you will not interfere!', 14, 0, 100, 25387, 0, 'kaelthas MT SAY_AGGRO_2'); diff --git a/data/sql/updates/db_world/2025_01_23_03.sql b/data/sql/updates/db_world/2025_01_23_03.sql new file mode 100644 index 000000000..0ba022314 --- /dev/null +++ b/data/sql/updates/db_world/2025_01_23_03.sql @@ -0,0 +1,5 @@ +-- DB update 2025_01_23_02 -> 2025_01_23_03 +-- +UPDATE `creature_template` SET `AIName` = '' WHERE `entry` = 24777; +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 24777) AND (`source_type` = 0); +UPDATE `creature_addon` SET `auras` = '44537' WHERE `guid` IN (96944, 96945, 96946); diff --git a/docker-compose.yml b/docker-compose.yml index 6c3aceeb3..6aaba04fd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -189,6 +189,8 @@ services: AC_LOGIN_DATABASE_INFO: "ac-database;3306;root;${DOCKER_DB_ROOT_PASSWORD:-password};acore_auth" AC_WORLD_DATABASE_INFO: "ac-database;3306;root;${DOCKER_DB_ROOT_PASSWORD:-password};acore_world" AC_CHARACTER_DATABASE_INFO: "ac-database;3306;root;${DOCKER_DB_ROOT_PASSWORD:-password};acore_characters" + networks: + - ac-network ports: - ${DOCKER_AUTH_EXTERNAL_PORT:-3724}:3724 - ${DOCKER_WORLD_EXTERNAL_PORT:-8085}:8085 diff --git a/src/common/Threading/LockedQueue.h b/src/common/Threading/LockedQueue.h index 04ff6fca8..76266a6b2 100644 --- a/src/common/Threading/LockedQueue.h +++ b/src/common/Threading/LockedQueue.h @@ -18,40 +18,49 @@ #ifndef LOCKEDQUEUE_H #define LOCKEDQUEUE_H +#include #include +#include #include template > class LockedQueue { - //! Lock access to the queue. - std::mutex _lock; + mutable std::mutex _lock; ///< Mutex to protect access to the queue - //! Storage backing the queue. - StorageType _queue; + std::atomic _canceled{false}; ///< Flag indicating if the queue is canceled - //! Cancellation flag. - volatile bool _canceled{false}; + StorageType _queue; ///< Storage container for the queue public: - //! Create a LockedQueue. + /** + * @brief Default constructor to create an empty LockedQueue. + */ LockedQueue() = default; - //! Destroy a LockedQueue. + /** + * @brief Destructor for LockedQueue. + */ virtual ~LockedQueue() = default; - //! Adds an item to the queue. + /** + * @brief Adds an item to the back of the queue. + * + * @param item The item to be added to the queue. + */ void add(const T& item) { - lock(); - - _queue.push_back(item); - - unlock(); + std::lock_guard lock(_lock); + _queue.push_back(std::move(item)); } - //! Adds items back to front of the queue + /** + * @brief Adds a range of items to the front of the queue. + * + * @param begin Iterator pointing to the beginning of the range of items to be added. + * @param end Iterator pointing to the end of the range of items to be added. + */ template void readd(Iterator begin, Iterator end) { @@ -59,33 +68,42 @@ public: _queue.insert(_queue.begin(), begin, end); } - //! Gets the next result in the queue, if any. + /** + * @brief Gets the next item in the queue and removes it. + * + * @param result The variable where the next item will be stored. + * @return true if an item was retrieved and removed, false if the queue is empty. + */ bool next(T& result) { std::lock_guard lock(_lock); - if (_queue.empty()) { return false; } - result = _queue.front(); + result = std::move(_queue.front()); _queue.pop_front(); - return true; } + /** + * @brief Retrieves the next item from the queue if it satisfies the provided checker. + * + * @param result The variable where the next item will be stored. + * @param check A checker object that will be used to validate the item. + * @return true if an item was retrieved, checked, and removed; false otherwise. + */ template bool next(T& result, Checker& check) { std::lock_guard lock(_lock); - if (_queue.empty()) { return false; } - result = _queue.front(); + result = std::move(_queue.front()); if (!check.Process(result)) { return false; @@ -95,60 +113,54 @@ public: return true; } - //! Peeks at the top of the queue. Check if the queue is empty before calling! Remember to unlock after use if autoUnlock == false. - T& peek(bool autoUnlock = false) + /** + * @brief Peeks at the top of the queue without removing it. + * + * @return A reference to the item at the front of the queue, assuming there's an item in the queue (as per previous implementation) + */ + T& peek() { - lock(); - - T& result = _queue.front(); - - if (autoUnlock) - { - unlock(); - } - - return result; + std::lock_guard lock(_lock); + return _queue.front(); } - //! Cancels the queue. + /** + * @brief Cancels the queue, preventing further processing of items. + */ void cancel() { - std::lock_guard lock(_lock); - - _canceled = true; + _canceled.store(true, std::memory_order_release); } - //! Checks if the queue is cancelled. - bool cancelled() + /** + * @brief Checks if the queue has been canceled. + * + * @return true if the queue is canceled, false otherwise. + */ + bool cancelled() const + { + return _canceled.load(std::memory_order_acquire); + } + + /** + * @brief Checks if the queue is empty. + * + * @return true if the queue is empty, false otherwise. + */ + bool empty() const { std::lock_guard lock(_lock); - return _canceled; + return _queue.empty(); } - //! Locks the queue for access. - void lock() - { - this->_lock.lock(); - } - - //! Unlocks the queue. - void unlock() - { - this->_lock.unlock(); - } - - ///! Calls pop_front of the queue + /** + * @brief Removes the item at the front of the queue. + */ void pop_front() { std::lock_guard lock(_lock); _queue.pop_front(); } - - ///! Checks if we're empty or not with locks held - bool empty() - { - std::lock_guard lock(_lock); - return _queue.empty(); - } }; + #endif diff --git a/src/common/Threading/MPSCQueue.h b/src/common/Threading/MPSCQueue.h index 15176178b..2bc2ec826 100644 --- a/src/common/Threading/MPSCQueue.h +++ b/src/common/Threading/MPSCQueue.h @@ -19,41 +19,81 @@ #define MPSCQueue_h__ #include +#include namespace Acore::Impl { - // C++ implementation of Dmitry Vyukov's lock free MPSC queue - // http://www.1024cores.net/home/lock-free-algorithms/queues/non-intrusive-mpsc-node-based-queue + /** + * @brief C++ implementation of Dmitry Vyukov's lock-free MPSC queue (Non-Intrusive). + * + * This queue allows multiple producers to enqueue items concurrently, but only one consumer + * can dequeue items. The queue is lock-free and non-intrusive, meaning it does not modify + * the data types that are enqueued. + * + * @tparam T The type of data that is being enqueued in the queue. + */ template class MPSCQueueNonIntrusive { public: - MPSCQueueNonIntrusive() : _head(new Node()), _tail(_head.load(std::memory_order_relaxed)) + /** + * @brief Constructs a new MPSCQueueNonIntrusive object. + * + * Initializes the queue with a dummy node and sets up atomic pointers to the head and tail. + */ + MPSCQueueNonIntrusive() + : _head(new Node(nullptr)), _tail(_head.load(std::memory_order_acquire)) { - Node* front = _head.load(std::memory_order_relaxed); - front->Next.store(nullptr, std::memory_order_relaxed); + Node* front = _head.load(std::memory_order_acquire); + front->Next.store(nullptr, std::memory_order_release); ///< Store with release to ensure visibility } + /** + * @brief Destroys the MPSCQueueNonIntrusive object. + * + * Dequeues all items and deletes them, followed by proper cleanup of remaining nodes in the queue. + */ ~MPSCQueueNonIntrusive() { T* output; while (Dequeue(output)) delete output; - Node* front = _head.load(std::memory_order_relaxed); - delete front; + // Properly delete remaining nodes + Node* front = _head.load(std::memory_order_acquire); + while (front) + { + Node* next = front->Next.load(std::memory_order_acquire); + delete front; + front = next; + } } + /** + * @brief Enqueues a new item in the queue. + * + * This function adds a new item at the head of the queue. + * + * @param input Pointer to the item to be enqueued. + */ void Enqueue(T* input) { Node* node = new Node(input); - Node* prevHead = _head.exchange(node, std::memory_order_acq_rel); + Node* prevHead = _head.exchange(node, std::memory_order_acq_rel); ///< Exchange with acquire-release semantics prevHead->Next.store(node, std::memory_order_release); } + /** + * @brief Dequeues an item from the queue. + * + * This function removes the item at the front of the queue and returns it. + * + * @param result Reference to a pointer where the dequeued item will be stored. + * @return True if an item was successfully dequeued, false if the queue was empty. + */ bool Dequeue(T*& result) { - Node* tail = _tail.load(std::memory_order_relaxed); + Node* tail = _tail.load(std::memory_order_acquire); Node* next = tail->Next.load(std::memory_order_acquire); if (!next) return false; @@ -65,39 +105,63 @@ namespace Acore::Impl } private: + /** + * @brief A structure representing a node in the queue. + * + * Each node holds a pointer to data and an atomic pointer to the next node in the queue. + */ struct Node { Node() = default; explicit Node(T* data) : Data(data) { - Next.store(nullptr, std::memory_order_relaxed); + Next.store(nullptr, std::memory_order_release); } - T* Data; - std::atomic Next; + T* Data; ///< Data stored in the node + std::atomic Next; ///< Atomic pointer to the next node }; - std::atomic _head; - std::atomic _tail; + std::atomic _head; ///< Atomic pointer to the head node of the queue + std::atomic _tail; ///< Atomic pointer to the tail node of the queue - MPSCQueueNonIntrusive(MPSCQueueNonIntrusive const&) = delete; - MPSCQueueNonIntrusive& operator=(MPSCQueueNonIntrusive const&) = delete; + MPSCQueueNonIntrusive(MPSCQueueNonIntrusive const&) = delete; ///< Deleted copy constructor + MPSCQueueNonIntrusive& operator=(MPSCQueueNonIntrusive const&) = delete; ///< Deleted copy assignment operator }; - // C++ implementation of Dmitry Vyukov's lock free MPSC queue - // http://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue + /** + * @brief C++ implementation of Dmitry Vyukov's lock-free MPSC queue (Intrusive). + * + * This queue allows multiple producers to enqueue items concurrently, but only one consumer + * can dequeue items. The queue is lock-free and intrusive, meaning that the enqueued objects + * must have an atomic link to the next item in the queue. + * + * @tparam T The type of data that is being enqueued in the queue. + * @tparam IntrusiveLink A member pointer to the atomic link used for linking the nodes. + */ template T::* IntrusiveLink> class MPSCQueueIntrusive { public: - MPSCQueueIntrusive() : _dummyPtr(reinterpret_cast(std::addressof(_dummy))), _head(_dummyPtr), _tail(_dummyPtr) + /** + * @brief Constructs a new MPSCQueueIntrusive object. + * + * Initializes the queue with a dummy node and sets up atomic pointers to the head and tail. + * The dummy node's atomic link is initialized. + */ + MPSCQueueIntrusive() + : _dummyPtr(reinterpret_cast(std::addressof(_dummy))), _head(_dummyPtr), _tail(_dummyPtr) { - // _dummy is constructed from aligned_storage and is intentionally left uninitialized (it might not be default constructible) - // so we init only its IntrusiveLink here + // Initialize the intrusive link in the dummy node std::atomic* dummyNext = new (&(_dummyPtr->*IntrusiveLink)) std::atomic(); - dummyNext->store(nullptr, std::memory_order_relaxed); + dummyNext->store(nullptr, std::memory_order_release); } + /** + * @brief Destroys the MPSCQueueIntrusive object. + * + * Dequeues all items and deletes them. + */ ~MPSCQueueIntrusive() { T* output; @@ -105,16 +169,32 @@ namespace Acore::Impl delete output; } + /** + * @brief Enqueues a new item in the queue. + * + * This function adds a new item at the head of the queue. + * + * @param input Pointer to the item to be enqueued. + */ void Enqueue(T* input) { + // Set the next link to nullptr initially (input->*IntrusiveLink).store(nullptr, std::memory_order_release); - T* prevHead = _head.exchange(input, std::memory_order_acq_rel); + T* prevHead = _head.exchange(input, std::memory_order_acq_rel); ///< Exchange with acquire-release semantics (prevHead->*IntrusiveLink).store(input, std::memory_order_release); } + /** + * @brief Dequeues an item from the queue. + * + * This function removes the item at the front of the queue and returns it. + * + * @param result Reference to a pointer where the dequeued item will be stored. + * @return True if an item was successfully dequeued, false if the queue was empty. + */ bool Dequeue(T*& result) { - T* tail = _tail.load(std::memory_order_relaxed); + T* tail = _tail.load(std::memory_order_acquire); T* next = (tail->*IntrusiveLink).load(std::memory_order_acquire); if (tail == _dummyPtr) { @@ -149,16 +229,25 @@ namespace Acore::Impl } private: - std::aligned_storage_t _dummy; - T* _dummyPtr; - std::atomic _head; - std::atomic _tail; + std::aligned_storage_t _dummy; ///< Storage for the dummy object + T* _dummyPtr; ///< Pointer to the dummy object + std::atomic _head; ///< Atomic pointer to the head node of the queue + std::atomic _tail; ///< Atomic pointer to the tail node of the queue - MPSCQueueIntrusive(MPSCQueueIntrusive const&) = delete; - MPSCQueueIntrusive& operator=(MPSCQueueIntrusive const&) = delete; + MPSCQueueIntrusive(MPSCQueueIntrusive const&) = delete; ///< Deleted copy constructor + MPSCQueueIntrusive& operator=(MPSCQueueIntrusive const&) = delete; ///< Deleted copy assignment operator }; } +/** + * @brief Conditional type alias for MPSCQueue. + * + * This alias provides the appropriate type of MPSCQueue based on whether the queue is intrusive + * or non-intrusive. + * + * @tparam T The type of data that is being enqueued in the queue. + * @tparam IntrusiveLink If provided, the queue will be intrusive, otherwise, it will be non-intrusive. + */ template T::* IntrusiveLink = nullptr> using MPSCQueue = std::conditional_t, Acore::Impl::MPSCQueueNonIntrusive>; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index ab81002ea..f79ed9e14 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -27,14 +27,15 @@ #include "ScriptedCreature.h" #include "SpellMgr.h" -#define AC_SAI_IS_BOOLEAN_VALID(e, value) \ -{ \ - if (value > 1) \ - { \ - LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} uses param {} of type Boolean with value {}, valid values are 0 or 1, skipped.", \ - e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), STRINGIZE(value), value); \ - return false; \ - } \ +bool SmartAIMgr::IsSAIBoolValid(SmartScriptHolder const& e, SAIBool value) +{ + if (value != 0 && value != 1) + { + LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} uses param {} of type Boolean with value {}, valid values are 0 or 1, skipped.", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), STRINGIZE(value), value); + return false; + } + return true; } SmartWaypointMgr* SmartWaypointMgr::instance() @@ -513,23 +514,22 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) case SMART_TARGET_HOSTILE_LAST_AGGRO: case SMART_TARGET_HOSTILE_RANDOM: case SMART_TARGET_HOSTILE_RANDOM_NOT_TOP: - AC_SAI_IS_BOOLEAN_VALID(e, e.target.hostileRandom.playerOnly); - break; + return IsSAIBoolValid(e, e.target.hostileRandom.playerOnly); case SMART_TARGET_FARTHEST: - AC_SAI_IS_BOOLEAN_VALID(e, e.target.farthest.playerOnly); - AC_SAI_IS_BOOLEAN_VALID(e, e.target.farthest.isInLos); + return IsSAIBoolValid(e, e.target.farthest.playerOnly) && + IsSAIBoolValid(e, e.target.farthest.isInLos); break; case SMART_TARGET_CLOSEST_CREATURE: - AC_SAI_IS_BOOLEAN_VALID(e, e.target.unitClosest.dead); + return IsSAIBoolValid(e, e.target.unitClosest.dead); break; case SMART_TARGET_CLOSEST_ENEMY: - AC_SAI_IS_BOOLEAN_VALID(e, e.target.closestAttackable.playerOnly); + return IsSAIBoolValid(e, e.target.closestAttackable.playerOnly); break; case SMART_TARGET_CLOSEST_FRIENDLY: - AC_SAI_IS_BOOLEAN_VALID(e, e.target.closestFriendly.playerOnly); + return IsSAIBoolValid(e, e.target.closestFriendly.playerOnly); break; case SMART_TARGET_OWNER_OR_SUMMONER: - AC_SAI_IS_BOOLEAN_VALID(e, e.target.owner.useCharmerOrOwner); + return IsSAIBoolValid(e, e.target.owner.useCharmerOrOwner); break; case SMART_TARGET_STORED: case SMART_TARGET_PLAYER_WITH_AURA: @@ -1079,9 +1079,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_EVENT_OOC_LOS: case SMART_EVENT_IC_LOS: if (!IsMinMaxValid(e, e.event.los.cooldownMin, e.event.los.cooldownMax)) - { return false; - } if (e.event.los.hostilityMode >= AsUnderlyingType(SmartEvent::LOSHostilityMode::End)) { @@ -1090,8 +1088,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } - AC_SAI_IS_BOOLEAN_VALID(e, e.event.los.playerOnly); - break; + return IsSAIBoolValid(e, e.event.los.playerOnly); case SMART_EVENT_RESPAWN: if (e.event.respawn.type == SMART_SCRIPT_RESPAWN_CONDITION_MAP && !sMapStore.LookupEntry(e.event.respawn.map)) { @@ -1134,8 +1131,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) if (e.event.kill.creature && !IsCreatureValid(e, e.event.kill.creature)) return false; - AC_SAI_IS_BOOLEAN_VALID(e, e.event.kill.playerOnly); - break; + return IsSAIBoolValid(e, e.event.kill.playerOnly); case SMART_EVENT_VICTIM_CASTING: if (e.event.targetCasting.spellId > 0 && !sSpellMgr->GetSpellInfo(e.event.targetCasting.spellId)) { @@ -1164,14 +1160,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_EVENT_ACCEPTED_QUEST: case SMART_EVENT_REWARD_QUEST: if (e.event.quest.quest && !IsQuestValid(e, e.event.quest.quest)) - { return false; - } if (!IsMinMaxValid(e, e.event.quest.cooldownMin, e.event.quest.cooldownMax)) - { return false; - } break; case SMART_EVENT_RECEIVE_EMOTE: { @@ -1464,8 +1456,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_SOUND: if (!IsSoundValid(e, e.action.sound.sound)) return false; - AC_SAI_IS_BOOLEAN_VALID(e, e.action.sound.onlySelf); - break; + return IsSAIBoolValid(e, e.action.sound.onlySelf); case SMART_ACTION_RANDOM_SOUND: if (e.action.randomSound.sound1 && !IsSoundValid(e, e.action.randomSound.sound1)) return false; @@ -1505,8 +1496,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) if (!IsQuestValid(e, e.action.questOffer.questID)) return false; - AC_SAI_IS_BOOLEAN_VALID(e, e.action.questOffer.directAdd); - break; + return IsSAIBoolValid(e, e.action.questOffer.directAdd); case SMART_ACTION_FAIL_QUEST: if (!IsQuestValid(e, e.action.quest.quest)) return false; @@ -1651,8 +1641,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } - AC_SAI_IS_BOOLEAN_VALID(e, e.action.summonCreature.attackInvoker); - break; + return IsSAIBoolValid(e, e.action.summonCreature.attackInvoker); case SMART_ACTION_CALL_KILLEDMONSTER: if (!IsCreatureValid(e, e.action.killedMonster.creature)) return false; @@ -1660,8 +1649,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_UPDATE_TEMPLATE: if (!IsCreatureValid(e, e.action.updateTemplate.creature)) return false; - AC_SAI_IS_BOOLEAN_VALID(e, e.action.updateTemplate.updateLevel); - break; + return IsSAIBoolValid(e, e.action.updateTemplate.updateLevel); case SMART_ACTION_SET_SHEATH: if (e.action.setSheath.sheath && e.action.setSheath.sheath >= MAX_SHEATH_STATE) { @@ -1707,8 +1695,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_WP_STOP: if (e.action.wpStop.quest && !IsQuestValid(e, e.action.wpStop.quest)) return false; - AC_SAI_IS_BOOLEAN_VALID(e, e.action.wpStop.fail); - break; + return IsSAIBoolValid(e, e.action.wpStop.fail); case SMART_ACTION_WP_START: { if (!sSmartWaypointMgr->GetPath(e.action.wpStart.pathID)) @@ -1729,9 +1716,8 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } - AC_SAI_IS_BOOLEAN_VALID(e, e.action.wpStart.run); - AC_SAI_IS_BOOLEAN_VALID(e, e.action.wpStart.repeat); - break; + return IsSAIBoolValid(e, e.action.wpStart.run) && + IsSAIBoolValid(e, e.action.wpStart.repeat); } case SMART_ACTION_CREATE_TIMED_EVENT: { @@ -1872,85 +1858,42 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) break; } case SMART_ACTION_AUTO_ATTACK: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.autoAttack.attack); - break; - } + return IsSAIBoolValid(e, e.action.autoAttack.attack); case SMART_ACTION_ALLOW_COMBAT_MOVEMENT: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.combatMove.move); - break; - } + return IsSAIBoolValid(e, e.action.combatMove.move); case SMART_ACTION_CALL_FOR_HELP: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.callHelp.withEmote); - break; - } + return IsSAIBoolValid(e, e.action.callHelp.withEmote); case SMART_ACTION_SET_VISIBILITY: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.visibility.state); - break; - } + return IsSAIBoolValid(e, e.action.visibility.state); case SMART_ACTION_SET_RUN: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.setRun.run); - break; - } + return IsSAIBoolValid(e, e.action.setRun.run); case SMART_ACTION_SET_CAN_FLY: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.setFly.fly); - break; - } + return IsSAIBoolValid(e, e.action.setFly.fly); case SMART_ACTION_SET_SWIM: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.setSwim.swim); - break; - } + return IsSAIBoolValid(e, e.action.setSwim.swim); case SMART_ACTION_SET_COUNTER: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.setCounter.reset); - break; - } + return IsSAIBoolValid(e, e.action.setCounter.reset); case SMART_ACTION_INTERRUPT_SPELL: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.interruptSpellCasting.withDelayed); - AC_SAI_IS_BOOLEAN_VALID(e, e.action.interruptSpellCasting.withInstant); - break; - } + return IsSAIBoolValid(e, e.action.interruptSpellCasting.withDelayed) && + IsSAIBoolValid(e, e.action.interruptSpellCasting.withInstant); case SMART_ACTION_SET_ROOT: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.setRoot.root); - break; - } + return IsSAIBoolValid(e, e.action.setRoot.root); case SMART_ACTION_DISABLE_EVADE: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.disableEvade.disable); - break; - } + return IsSAIBoolValid(e, e.action.disableEvade.disable); case SMART_ACTION_LOAD_EQUIPMENT: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.loadEquipment.force); - break; - } + return IsSAIBoolValid(e, e.action.loadEquipment.force); case SMART_ACTION_TALK: - AC_SAI_IS_BOOLEAN_VALID(e, e.action.talk.useTalkTarget); if (!IsTextValid(e, e.action.talk.textGroupID)) return false; - break; + return IsSAIBoolValid(e, e.action.talk.useTalkTarget); case SMART_ACTION_SIMPLE_TALK: if (!IsTextValid(e, e.action.simpleTalk.textGroupID)) return false; break; case SMART_ACTION_SET_HEALTH_REGEN: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.setHealthRegen.regenHealth); - break; - } + return IsSAIBoolValid(e, e.action.setHealthRegen.regenHealth); case SMART_ACTION_CALL_TIMED_ACTIONLIST: - { - AC_SAI_IS_BOOLEAN_VALID(e, e.action.timedActionList.allowOverride); - break; - } + return IsSAIBoolValid(e, e.action.timedActionList.allowOverride); case SMART_ACTION_FLEE_FOR_ASSIST: case SMART_ACTION_MOVE_TO_POS: case SMART_ACTION_EVADE: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 7ca18d2f6..159f8cb87 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -2219,6 +2219,7 @@ private: return true; } + static bool IsSAIBoolValid(SmartScriptHolder const& e, SAIBool value); static bool IsTextValid(SmartScriptHolder const& e, uint32 id); static bool CheckUnusedEventParams(SmartScriptHolder const& e); static bool CheckUnusedActionParams(SmartScriptHolder const& e); diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index 49361db16..15af979a6 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -32,7 +32,7 @@ enum AccountOpResult AOR_DB_INTERNAL_ERROR }; -#define MAX_ACCOUNT_STR 20 +#define MAX_ACCOUNT_STR 17 #define MAX_PASS_STR 16 #define MAX_EMAIL_STR 255 diff --git a/src/server/game/ArenaSpectator/ArenaSpectator.cpp b/src/server/game/ArenaSpectator/ArenaSpectator.cpp index 412a607ea..df7f4b7aa 100644 --- a/src/server/game/ArenaSpectator/ArenaSpectator.cpp +++ b/src/server/game/ArenaSpectator/ArenaSpectator.cpp @@ -85,7 +85,7 @@ bool ArenaSpectator::HandleSpectatorSpectateCommand(ChatHandler* handler, std::s if (player->IsInCombat()) errors.push_back("Can't be in combat."); - if (player->isUsingLfg()) + if (player->IsUsingLfg()) errors.push_back("Can't spectate while using LFG system."); if (player->InBattlegroundQueue()) diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 8d459d4ec..e818508ed 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -185,10 +185,7 @@ void Channel::JoinChannel(Player* player, std::string const& pass) return; } - if (HasFlag(CHANNEL_FLAG_LFG) && - sWorld->getBoolConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && - AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && - player->GetGroup()) + if (IsLFG() && sWorld->getBoolConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && !player->IsUsingLfg()) { WorldPacket data; MakeNotInLfg(&data); diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index 3afccc3ad..e2d1bd9a1 100644 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -181,7 +181,7 @@ public: [[nodiscard]] uint32 GetChannelDBId() const { return _channelDBId; } [[nodiscard]] bool IsConstant() const { return _channelId != 0; } [[nodiscard]] bool IsAnnounce() const { return _announce; } - [[nodiscard]] bool IsLFG() const { return GetFlags() & CHANNEL_FLAG_LFG; } + [[nodiscard]] bool IsLFG() const { return HasFlag(CHANNEL_FLAG_LFG); } [[nodiscard]] std::string const& GetPassword() const { return _password; } void SetPassword(std::string const& npassword) { _password = npassword; } [[nodiscard]] uint32 GetNumPlayers() const { return playersStore.size(); } diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 163e390f2..fc7d04c61 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1001,43 +1001,25 @@ void GameObject::Delete() AddObjectToRemoveList(); } -void GameObject::GetFishLoot(Loot* fishloot, Player* loot_owner) +void GameObject::GetFishLoot(Loot* fishLoot, Player* lootOwner, bool junk /*= false*/) { - fishloot->clear(); + fishLoot->clear(); - uint32 zone, subzone; - uint32 defaultzone = 1; - GetZoneAndAreaId(zone, subzone); + uint32 zone, area; + uint32 defaultZone = 1; + GetZoneAndAreaId(zone, area); - // if subzone loot exist use it - fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner, true, true); - if (fishloot->empty()) //use this becase if zone or subzone has set LOOT_MODE_JUNK_FISH,Even if no normal drop, fishloot->FillLoot return true. it wrong. + uint16 lootMode = junk ? LOOT_MODE_JUNK_FISH : LOOT_MODE_DEFAULT; + // Check to fill loot in the order area - zone - defaultZone. + // This is because area and zone is not set in some places, like Off the coast of Storm Peaks. + uint32 lootZones[] = { area, zone, defaultZone }; + for (uint32 fillZone : lootZones) { - //subzone no result,use zone loot - fishloot->FillLoot(zone, LootTemplates_Fishing, loot_owner, true, true); - //use zone 1 as default, somewhere fishing got nothing,becase subzone and zone not set, like Off the coast of Storm Peaks. - if (fishloot->empty()) - fishloot->FillLoot(defaultzone, LootTemplates_Fishing, loot_owner, true, true); - } -} + fishLoot->FillLoot(fillZone, LootTemplates_Fishing, lootOwner, true, true, lootMode); -void GameObject::GetFishLootJunk(Loot* fishloot, Player* loot_owner) -{ - fishloot->clear(); - - uint32 zone, subzone; - uint32 defaultzone = 1; - GetZoneAndAreaId(zone, subzone); - - // if subzone loot exist use it - fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner, true, true, LOOT_MODE_JUNK_FISH); - if (fishloot->empty()) //use this becase if zone or subzone has normal mask drop, then fishloot->FillLoot return true. - { - //use zone loot - fishloot->FillLoot(zone, LootTemplates_Fishing, loot_owner, true, true, LOOT_MODE_JUNK_FISH); - if (fishloot->empty()) - //use zone 1 as default - fishloot->FillLoot(defaultzone, LootTemplates_Fishing, loot_owner, true, true, LOOT_MODE_JUNK_FISH); + // If the loot is filled and the loot is eligible, then we break out of the loop. + if (!fishLoot->empty() && !fishLoot->isLooted()) + break; } } diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 5a214226d..9c7f50bf4 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -198,8 +198,7 @@ public: void Refresh(); void DespawnOrUnsummon(Milliseconds delay = 0ms, Seconds forcedRespawnTime = 0s); void Delete(); - void GetFishLoot(Loot* loot, Player* loot_owner); - void GetFishLootJunk(Loot* loot, Player* loot_owner); + void GetFishLoot(Loot* fishLoot, Player* lootOwner, bool junk = false); [[nodiscard]] GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); } void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); } [[nodiscard]] GOState GetGoState() const { return GOState(GetByteValue(GAMEOBJECT_BYTES_1, 0)); } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e1a274afe..fed41c4e2 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7896,7 +7896,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type) if (loot_type == LOOT_FISHING) go->GetFishLoot(loot, this); else if (loot_type == LOOT_FISHING_JUNK) - go->GetFishLootJunk(loot, this); + go->GetFishLoot(loot, this, true); if (go->GetGOInfo()->type == GAMEOBJECT_TYPE_CHEST && go->GetGOInfo()->chest.groupLootRules) { @@ -13111,7 +13111,7 @@ PartyResult Player::CanUninviteFromGroup(ObjectGuid targetPlayerGUID) const return ERR_PARTY_RESULT_OK; } -bool Player::isUsingLfg() +bool Player::IsUsingLfg() { return sLFGMgr->GetState(GetGUID()) != lfg::LFG_STATE_NONE; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index cca7f3fb2..842f87d33 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2062,6 +2062,7 @@ public: bool IsInChannel(const Channel* c); void CleanupChannels(); void ClearChannelWatch(); + void UpdateLFGChannel(); void UpdateLocalChannels(uint32 newZone); void UpdateDefense(); @@ -2397,7 +2398,7 @@ public: void SetAtLoginFlag(AtLoginFlags f) { m_atLoginFlags |= f; } void RemoveAtLoginFlag(AtLoginFlags flags, bool persist = false); - bool isUsingLfg(); + bool IsUsingLfg(); bool inRandomLfgDungeon(); typedef std::set DFQuestsDoneList; diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 3e878976d..0cf697bca 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -5687,7 +5687,8 @@ void Player::_LoadActions(PreparedQueryResult result) ab->uState = ACTIONBUTTON_UNCHANGED; else { - LOG_ERROR("entities.player", "ActionButton loading problem, will be deleted from db..."); + + LOG_ERROR("entities.player", "ActionButton loading problem, will be deleted from db. player: {}, guid: {}, button: {}, action: {}, type: {}", GetName(), GetGUID().GetCounter(), button, action, type); // Will deleted in DB at next save (it can create data until save but marked as deleted) m_actionButtons[button].uState = ACTIONBUTTON_DELETED; diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 606a5bfa5..4fec71887 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -462,6 +462,44 @@ void Player::UpdateNextMailTimeAndUnreads() } } +void Player::UpdateLFGChannel() +{ + if (!sWorld->getBoolConfig(CONFIG_RESTRICTED_LFG_CHANNEL)) + return; + + ChannelMgr* cMgr = ChannelMgr::forTeam(GetTeamId()); + if (!cMgr) + return; + + ChatChannelsEntry const* cce = sChatChannelsStore.LookupEntry(26); /*LookingForGroup*/ + Channel* cLFG = cMgr->GetJoinChannel(cce->pattern[m_session->GetSessionDbcLocale()], cce->ChannelID); + if (!cLFG) + return; + + Channel* cUsed = nullptr; + for (Channel* channel : m_channels) + if (channel && channel->GetChannelId() == cce->ChannelID) + { + cUsed = cLFG; + break; + } + + if (IsUsingLfg()) + { + if (cUsed == cLFG) + return; + + cLFG->JoinChannel(this, ""); + } + else + { + if (cLFG != cUsed) + return; + + cLFG->LeaveChannel(this, true); + } +} + void Player::UpdateLocalChannels(uint32 newZone) { // pussywizard: mutex needed (tc changed opcode to THREAD UNSAFE) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 1865db88e..3facbbad0 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -10401,6 +10401,10 @@ bool Unit::Attack(Unit* victim, bool meleeAttack) if (meleeAttack) AddUnitState(UNIT_STATE_MELEE_ATTACKING); + // Update leash timer when attacking creatures + if (victim->IsCreature()) + victim->ToCreature()->UpdateLeashExtensionTime(); + // set position before any AI calls/assistance //if (IsCreature()) // ToCreature()->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ()); @@ -10410,6 +10414,7 @@ bool Unit::Attack(Unit* victim, bool meleeAttack) SetInCombatWith(victim); if (victim->IsPlayer()) victim->SetInCombatWith(this); + AddThreat(victim, 0.0f); creature->SendAIReaction(AI_REACTION_HOSTILE); @@ -13640,9 +13645,6 @@ void Unit::SetInCombatWith(Unit* enemy, uint32 duration) } } - if (Creature* pCreature = ToCreature()) - pCreature->UpdateLeashExtensionTime(); - SetInCombatState(false, enemy, duration); } @@ -13717,6 +13719,10 @@ void Unit::CombatStart(Unit* victim, bool initialAggro) SetInCombatWith(victim); victim->SetInCombatWith(this); + // Update leash timer when attacking creatures + if (victim->IsCreature()) + victim->ToCreature()->UpdateLeashExtensionTime(); + // Xinef: If pet started combat - put owner in combat if (!alreadyInCombat && IsInCombat()) { @@ -13753,6 +13759,12 @@ void Unit::CombatStartOnCast(Unit* target, bool initialAggro, uint32 duration) // Xinef: If pet started combat - put owner in combat if (Unit* owner = GetOwner()) owner->SetInCombatWith(target, duration); + + // Update leash timer when attacking creatures + if (target->IsCreature()) + target->ToCreature()->UpdateLeashExtensionTime(); + else if (ToCreature()) // Reset leash if it is a spell caster, else it may evade inbetween casts + ToCreature()->UpdateLeashExtensionTime(); } Unit* who = target->GetCharmerOrOwnerOrSelf(); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 423db19e1..f2bc1fe4b 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -8688,7 +8688,7 @@ bool ObjectMgr::LoadModuleStringsLocale() std::string const* ObjectMgr::GetModuleString(std::string module, uint32 id, LocaleConstant locale) const { ModuleString const* ms = GetModuleString(module, id); - if (ms->Content.size()) + if (ms && !ms->Content.empty()) { if (ms->Content.size() > size_t(locale) && !ms->Content[locale].empty()) return &ms->Content[locale]; diff --git a/src/server/game/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp index 9e5239127..37c7a34c7 100644 --- a/src/server/game/Handlers/ChannelHandler.cpp +++ b/src/server/game/Handlers/ChannelHandler.cpp @@ -47,15 +47,11 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket) return; if (channelName.size() >= 100 || !DisallowHyperlinksAndMaybeKick(channelName)) - { return; - } if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeamId())) - { if (Channel* channel = cMgr->GetJoinChannel(channelName, channelId)) channel->JoinChannel(GetPlayer(), password); - } } void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket) @@ -70,10 +66,8 @@ void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket) return; if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeamId())) - { if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer())) channel->LeaveChannel(GetPlayer(), true); - } } void WorldSession::HandleChannelList(WorldPacket& recvPacket) diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 4599347f8..4a2fbbf1b 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -71,6 +71,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPackets::LFG::LFGJoin& packet) GetPlayerInfo(), packet.Roles, newDungeons.size(), packet.Comment); sLFGMgr->JoinLfg(GetPlayer(), uint8(packet.Roles), newDungeons, packet.Comment); + GetPlayer()->UpdateLFGChannel(); } void WorldSession::HandleLfgLeaveOpcode(WorldPackets::LFG::LFGLeave& /*packet*/) @@ -87,6 +88,7 @@ void WorldSession::HandleLfgLeaveOpcode(WorldPackets::LFG::LFGLeave& /*packet*/) sLFGMgr->LeaveLfg(sLFGMgr->GetState(guid) == lfg::LFG_STATE_RAIDBROWSER ? guid : gguid); sLFGMgr->LeaveAllLfgQueues(guid, true, group ? group->GetGUID() : ObjectGuid::Empty); } + GetPlayer()->UpdateLFGChannel(); } void WorldSession::HandleLfgProposalResultOpcode(WorldPacket& recvData) diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 050905416..bb510cf12 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -55,6 +55,18 @@ void InstanceScript::SaveToDB() CharacterDatabase.Execute(stmt); } +void InstanceScript::OnPlayerEnter(Player* player) +{ + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && IsTwoFactionInstance()) + player->SetFaction((_teamIdInInstance == TEAM_HORDE) ? 1610 /*FACTION_HORDE*/ : 1 /*FACTION_ALLIANCE*/); +} + +void InstanceScript::OnPlayerLeave(Player* player) +{ + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && IsTwoFactionInstance()) + player->SetFactionForRace(player->getRace()); +} + void InstanceScript::OnCreatureCreate(Creature* creature) { AddObject(creature); @@ -584,6 +596,12 @@ void InstanceScript::DoRespawnGameObject(ObjectGuid uiGuid, uint32 uiTimeToDespa LOG_DEBUG("scripts", "InstanceScript: DoRespawnGameObject failed"); } +void InstanceScript::DoRespawnGameObject(uint32 type) +{ + if (GameObject* go = instance->GetGameObject(GetObjectGuid(type))) + go->Respawn(); +} + void InstanceScript::DoRespawnCreature(ObjectGuid guid, bool force) { if (Creature* creature = instance->GetCreature(guid)) @@ -848,3 +866,21 @@ bool InstanceHasScript(WorldObject const* obj, char const* scriptName) return false; } + +bool InstanceScript::IsTwoFactionInstance() const +{ + switch (instance->GetId()) + { + case 540: // Shattered Halls + case 576: // Nexus + case 631: // Icecrown Citadel + case 632: // Forge of Souls + case 649: // Trial of the Champion + case 650: // Trial of the Crusader + case 658: // Pit of Saron + case 668: // Halls of Reflection + return true; + } + + return false; +} diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index cae3994ed..89246ed96 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -141,7 +141,7 @@ typedef std::map ObjectStateMa class InstanceScript : public ZoneScript { public: - explicit InstanceScript(Map* map) : instance(map), completedEncounters(0) {} + explicit InstanceScript(Map* map) : instance(map), completedEncounters(0), _teamIdInInstance(TEAM_NEUTRAL) {} ~InstanceScript() override {} @@ -182,10 +182,10 @@ public: GameObject* GetGameObject(uint32 type); //Called when a player successfully enters the instance. - virtual void OnPlayerEnter(Player* /*player*/) {} + virtual void OnPlayerEnter(Player* /*player*/); //Called when a player successfully leaves the instance. - virtual void OnPlayerLeave(Player* /*player*/) {} + virtual void OnPlayerLeave(Player* /*player*/); virtual void OnPlayerAreaUpdate(Player* /*player*/, uint32 /*oldArea*/, uint32 /*newArea*/) {} @@ -203,6 +203,9 @@ public: //Respawns a GO having negative spawntimesecs in gameobject-table void DoRespawnGameObject(ObjectGuid guid, uint32 timeToDespawn = MINUTE); + // Respawns a GO by instance storage index + void DoRespawnGameObject(uint32 type); + // Respawns a creature. void DoRespawnCreature(ObjectGuid guid, bool force = false); @@ -282,6 +285,10 @@ public: [[nodiscard]] bool AllBossesDone() const; [[nodiscard]] bool AllBossesDone(std::initializer_list bossIds) const; + TeamId GetTeamIdInInstance() const { return _teamIdInInstance; } + void SetTeamIdInInstance(TeamId teamId) { _teamIdInInstance = teamId; } + bool IsTwoFactionInstance() const; + TaskScheduler scheduler; protected: void SetHeaders(std::string const& dataHeaders); @@ -336,6 +343,7 @@ private: ObjectGuidMap _objectGuids; ObjectStateMap _objectStateMap; uint32 completedEncounters; // completed encounter mask, bit indexes are DungeonEncounter.dbc boss numbers, used for packets + TeamId _teamIdInInstance; std::unordered_set _activatedAreaTriggers; }; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 9a64b583c..92b9248e4 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -103,7 +103,7 @@ bool Map::ExistMap(uint32 mapid, int gx, int gy) { if (header.mapMagic != MapMagic.asUInt || header.versionMagic != MapVersionMagic) { - LOG_ERROR("maps", "Map file '{}' is from an incompatible map version (%.*u v{}), %.*s v{} is expected. Please pull your source, recompile tools and recreate maps using the updated mapextractor, then replace your old map files with new files.", + LOG_ERROR("maps", "Map file '{}' is from an incompatible map version ({:.4u} v{}), {:.4s} v{} is expected. Please pull your source, recompile tools and recreate maps using the updated mapextractor, then replace your old map files with new files.", tmp, 4, header.mapMagic, header.versionMagic, 4, MapMagic.asChar, MapVersionMagic); } @@ -3026,6 +3026,15 @@ bool InstanceMap::AddPlayerToMap(Player* player) m_resetAfterUnload = false; m_unloadWhenEmpty = false; + if (instance_data && instance_data->IsTwoFactionInstance() + && instance_data->GetTeamIdInInstance() == TEAM_NEUTRAL) + { + instance_data->SetTeamIdInInstance(player->GetTeamId()); + if (Group* group = player->GetGroup()) + if (Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID())) + instance_data->SetTeamIdInInstance(leader->GetTeamId()); + } + // this will acquire the same mutex so it cannot be in the previous block Map::AddPlayerToMap(player); diff --git a/src/server/game/Scripting/ScriptDefines/AllSpellScript.cpp b/src/server/game/Scripting/ScriptDefines/AllSpellScript.cpp index 0c3fea4fa..44f0866ee 100644 --- a/src/server/game/Scripting/ScriptDefines/AllSpellScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/AllSpellScript.cpp @@ -84,6 +84,21 @@ void ScriptMgr::OnDummyEffect(WorldObject* caster, uint32 spellID, SpellEffIndex CALL_ENABLED_HOOKS(AllSpellScript, ALLSPELLHOOK_ON_DUMMY_EFFECT_ITEM, script->OnDummyEffect(caster, spellID, effIndex, itemTarget)); } +void ScriptMgr::OnSpellCastCancel(Spell* spell, Unit* caster, SpellInfo const* spellInfo, bool bySelf) +{ + CALL_ENABLED_HOOKS(AllSpellScript, ALLSPELLHOOK_ON_CAST_CANCEL, script->OnSpellCastCancel(spell, caster, spellInfo, bySelf)); +} + +void ScriptMgr::OnSpellCast(Spell* spell, Unit* caster, SpellInfo const* spellInfo, bool skipCheck) +{ + CALL_ENABLED_HOOKS(AllSpellScript, ALLSPELLHOOK_ON_CAST, script->OnSpellCast(spell, caster, spellInfo, skipCheck)); +} + +void ScriptMgr::OnSpellPrepare(Spell* spell, Unit* caster, SpellInfo const* spellInfo) +{ + CALL_ENABLED_HOOKS(AllSpellScript, ALLSPELLHOOK_ON_PREPARE, script->OnSpellPrepare(spell, caster, spellInfo)); +} + AllSpellScript::AllSpellScript(char const* name, std::vector enabledHooks) : ScriptObject(name, ALLSPELLHOOK_END) { diff --git a/src/server/game/Scripting/ScriptDefines/AllSpellScript.h b/src/server/game/Scripting/ScriptDefines/AllSpellScript.h index 9f1682f2f..3dd2711bd 100644 --- a/src/server/game/Scripting/ScriptDefines/AllSpellScript.h +++ b/src/server/game/Scripting/ScriptDefines/AllSpellScript.h @@ -36,6 +36,9 @@ enum AllSpellHook ALLSPELLHOOK_ON_DUMMY_EFFECT_GAMEOBJECT, ALLSPELLHOOK_ON_DUMMY_EFFECT_CREATURE, ALLSPELLHOOK_ON_DUMMY_EFFECT_ITEM, + ALLSPELLHOOK_ON_CAST_CANCEL, + ALLSPELLHOOK_ON_CAST, + ALLSPELLHOOK_ON_PREPARE, ALLSPELLHOOK_END }; @@ -100,6 +103,12 @@ public: * @param itemTarget Contains information about the Item */ virtual void OnDummyEffect(WorldObject* /*caster*/, uint32 /*spellID*/, SpellEffIndex /*effIndex*/, Item* /*itemTarget*/) { } + + virtual void OnSpellCastCancel(Spell* /*spell*/, Unit* /*caster*/, SpellInfo const* /*spellInfo*/, bool /*bySelf*/) { } + + virtual void OnSpellCast(Spell* /*spell*/, Unit* /*caster*/, SpellInfo const* /*spellInfo*/, bool /*skipCheck*/) { } + + virtual void OnSpellPrepare(Spell* /*spell*/, Unit* /*caster*/, SpellInfo const* /*spellInfo*/) { } }; // Compatibility for old scripts diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index f3915a554..9cf654fb1 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -648,6 +648,9 @@ public: /* SpellSC */ void OnDummyEffect(WorldObject* caster, uint32 spellID, SpellEffIndex effIndex, GameObject* gameObjTarget); void OnDummyEffect(WorldObject* caster, uint32 spellID, SpellEffIndex effIndex, Creature* creatureTarget); void OnDummyEffect(WorldObject* caster, uint32 spellID, SpellEffIndex effIndex, Item* itemTarget); + void OnSpellCastCancel(Spell* spell, Unit* caster, SpellInfo const* spellInfo, bool bySelf); + void OnSpellCast(Spell* spell, Unit* caster, SpellInfo const* spellInfo, bool skipCheck); + void OnSpellPrepare(Spell* spell, Unit* caster, SpellInfo const* spellInfo); public: /* GameEventScript */ void OnGameEventStart(uint16 EventID); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 7f05148cc..a1f6907de 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3717,6 +3717,8 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const TriggerGlobalCooldown(); } + sScriptMgr->OnSpellPrepare(this, m_caster, m_spellInfo); + return SPELL_CAST_OK; } @@ -3788,6 +3790,8 @@ void Spell::cancel(bool bySelf) //set state back so finish will be processed m_spellState = oldState; + sScriptMgr->OnSpellCastCancel(this, m_caster, m_spellInfo, bySelf); + finish(false); } @@ -4114,6 +4118,8 @@ void Spell::_cast(bool skipCheck) if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN)) m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true); + sScriptMgr->OnSpellCast(this, m_caster, m_spellInfo, skipCheck); + SetExecutedCurrently(false); } diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 421f96a5d..1126614ca 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -2644,8 +2644,6 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const // some explicitly required dummy effect sets switch (Id) { - case 28441: - return false; // AB Effect 000 default: break; } diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp index 92d4a3683..da8688f54 100644 --- a/src/server/scripts/Commands/cs_ban.cpp +++ b/src/server/scripts/Commands/cs_ban.cpp @@ -207,14 +207,14 @@ public: switch (mode) { case BAN_ACCOUNT: - banReturn = sBan->BanAccount(nameOrIP, durationStr, reasonStr, handler->GetSession() ? handler->GetSession()->GetPlayerName() : ""); + banReturn = sBan->BanAccount(nameOrIP, durationStr, reasonStr, handler->GetSession() ? handler->GetSession()->GetPlayerName() : "Console"); break; case BAN_CHARACTER: - banReturn = sBan->BanAccountByPlayerName(nameOrIP, durationStr, reasonStr, handler->GetSession() ? handler->GetSession()->GetPlayerName() : ""); + banReturn = sBan->BanAccountByPlayerName(nameOrIP, durationStr, reasonStr, handler->GetSession() ? handler->GetSession()->GetPlayerName() : "Console"); break; case BAN_IP: default: - banReturn = sBan->BanIP(nameOrIP, durationStr, reasonStr, handler->GetSession() ? handler->GetSession()->GetPlayerName() : ""); + banReturn = sBan->BanIP(nameOrIP, durationStr, reasonStr, handler->GetSession() ? handler->GetSession()->GetPlayerName() : "Console"); break; } @@ -444,7 +444,7 @@ public: if (banResult) { Field* fields2 = banResult->Fetch(); - handler->PSendSysMessage("%s", fields2[0].Get()); + handler->PSendSysMessage("{}", fields2[0].Get()); } } while (result->NextRow()); } @@ -480,14 +480,14 @@ public: if (fields2[0].Get() == fields2[1].Get()) { - handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", + handler->PSendSysMessage("|{:<15.15}|{:02}-{:02}-{:02} {:02}:{:02}| permanent |{:<15.15}|{:<15.15}|", accountName, tmBan.tm_year % 100, tmBan.tm_mon + 1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min, fields2[2].Get(), fields2[3].Get()); } else { tm tmUnban = Acore::Time::TimeBreakdown(fields2[1].Get()); - handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", + handler->PSendSysMessage("|{:<15.15}|{:02}-{:02}-{:02} {:02}:{:02}|{:02}-{:02}-{:02} {:02}:{:02}|{:<15.15}|{:<15.15}|", accountName, tmBan.tm_year % 100, tmBan.tm_mon + 1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min, tmUnban.tm_year % 100, tmUnban.tm_mon + 1, tmUnban.tm_mday, tmUnban.tm_hour, tmUnban.tm_min, fields2[2].Get(), fields2[3].Get()); @@ -534,7 +534,7 @@ public: PreparedQueryResult banResult = CharacterDatabase.Query(stmt2); if (banResult) - handler->PSendSysMessage("%s", (*banResult)[0].Get()); + handler->PSendSysMessage("{}", (*banResult)[0].Get()); } while (result->NextRow()); } // Console wide output @@ -564,14 +564,14 @@ public: if (banFields[0].Get() == banFields[1].Get()) { - handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", + handler->PSendSysMessage("|{:<15.15}|{:02}-{:02}-{:02} {:02}:{:02}| permanent |{:<15.15}|{:<15.15}|", char_name, tmBan.tm_year % 100, tmBan.tm_mon + 1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min, banFields[2].Get(), banFields[3].Get()); } else { tm tmUnban = Acore::Time::TimeBreakdown(banFields[1].Get()); - handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", + handler->PSendSysMessage("|{:<15.15}|{:02}-{:02}-{:02} {:02}:{:02}|{:02}-{:02}-{:02} {:02}:{:02}|{:<15.15}|{:<15.15}|", char_name, tmBan.tm_year % 100, tmBan.tm_mon + 1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min, tmUnban.tm_year % 100, tmUnban.tm_mon + 1, tmUnban.tm_mday, tmUnban.tm_hour, tmUnban.tm_min, banFields[2].Get(), banFields[3].Get()); @@ -621,7 +621,7 @@ public: do { Field* fields = result->Fetch(); - handler->PSendSysMessage("%s", fields[0].Get()); + handler->PSendSysMessage("{}", fields[0].Get()); } while (result->NextRow()); } // Console wide output @@ -637,14 +637,14 @@ public: tm tmBan = Acore::Time::TimeBreakdown(fields[1].Get()); if (fields[1].Get() == fields[2].Get()) { - handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", + handler->PSendSysMessage("{:<15.15}|{:02}-{:02}-{:02} {:02}:{:02}| permanent |{:<15.15}|{:<15.15}|", fields[0].Get(), tmBan.tm_year % 100, tmBan.tm_mon + 1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min, fields[3].Get(), fields[4].Get()); } else { tm tmUnban = Acore::Time::TimeBreakdown(fields[2].Get()); - handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", + handler->PSendSysMessage("|{:<15.15}|{:02}-{:02}-{:02} {:02}:{:02}|{:02}-{:02}-{:02} {:02}:{:02}|{:<15.15}|{:<15.15}|", fields[0].Get(), tmBan.tm_year % 100, tmBan.tm_mon + 1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min, tmUnban.tm_year % 100, tmUnban.tm_mon + 1, tmUnban.tm_mday, tmUnban.tm_hour, tmUnban.tm_min, fields[3].Get(), fields[4].Get()); diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 28a35073a..a8d767dfd 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -924,7 +924,7 @@ public: passenger->EnterVehicle(target, *seatId); } - handler->PSendSysMessage("Unit {} entered vehicle %hhd", entry, *seatId); + handler->PSendSysMessage("Unit {} entered vehicle {:d}", entry, *seatId); return true; } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index b1487eb3c..096e8fb62 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -280,7 +280,7 @@ public: break; } - if (plr->isUsingLfg()) + if (plr->IsUsingLfg()) { error = 4; break; diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index dba16fab4..76201a55c 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -217,7 +217,7 @@ public: static bool HandleMmapStatsCommand(ChatHandler* handler) { handler->PSendSysMessage("mmap stats:"); - //handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(mapId) ? "en" : "dis"); + //handler->PSendSysMessage(" global mmap pathfinding is {}abled", DisableMgr::IsPathfindingEnabled(mapId) ? "en" : "dis"); MMAP::MMapMgr* manager = MMAP::MMapFactory::createOrGetMMapMgr(); handler->PSendSysMessage(" {} maps loaded with {} tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount()); diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index 2d5b9b23e..c5acb086c 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -807,8 +807,8 @@ public: if (!result) { - handler->SendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM); - return true; + handler->SendErrorMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetSpawnId()); + return false; } handler->SendSysMessage("|cff00ffffDEBUG: wp show info:|r"); @@ -912,15 +912,16 @@ public: return false; } + wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + // Set "wpguid" column to the visual waypoint WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); - stmt->SetData(0, int32(wpCreature->GetSpawnId())); + stmt->SetData(0, wpCreature->GetSpawnId()); stmt->SetData(1, pathid); stmt->SetData(2, point); WorldDatabase.Execute(stmt); - wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); if (!wpCreature->LoadCreatureFromDB(wpCreature->GetSpawnId(), map, true, true)) { diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index aa2c80ede..110fd2c41 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -31,7 +31,8 @@ enum Says SAY_GRAVITY_LAPSE = 3, SAY_TIRED = 4, SAY_RECAST_GRAVITY = 5, - SAY_DEATH = 6 + SAY_DEATH = 6, + SAY_AGGRO_2 = 7 }; enum Spells @@ -78,6 +79,8 @@ struct boss_felblood_kaelthas : public BossAI _gravityLapseCounter = 0; me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); me->SetImmuneToAll(false); + summons.DespawnAll(); + ScheduleHealthCheckEvent(50, [&]{ me->CastStop(); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true); @@ -170,6 +173,7 @@ struct boss_felblood_kaelthas : public BossAI if (!_hasDoneIntro && me->IsWithinDistInMap(who, 40.0f) && who->IsPlayer()) { Talk(SAY_AGGRO); + Talk(SAY_AGGRO_2, 20s); _hasDoneIntro = true; _OOCScheduler.Schedule(35s, [this](TaskContext){ me->SetReactState(REACT_AGGRESSIVE); diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp index c6e09d78c..66edbda08 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp @@ -161,7 +161,7 @@ struct boss_selin_fireheart : public BossAI if (Creature* crystal = SelectNearestCrystal(false)) { Talk(EMOTE_CRYSTAL); - crystal->ReplaceAllUnitFlags(UNIT_FLAG_NONE); + crystal->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); crystal->SetInCombatWithZone(); crystal->AI()->DoCast(me, SPELL_MANA_RAGE, true); DoCast(crystal, SPELL_FEL_CRYSTAL_COSMETIC, true); diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp index 241be9767..a8d515dee 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp @@ -51,24 +51,34 @@ enum Misc struct boss_vexallus : public BossAI { - boss_vexallus(Creature* creature) : BossAI(creature, DATA_VEXALLUS) { } + boss_vexallus(Creature* creature) : BossAI(creature, DATA_VEXALLUS), _energyCooldown(false) { } void Reset() override { _Reset(); + _energyCooldown = false; - ScheduleHealthCheckEvent({ 85, 70, 55, 40 }, [&] + ScheduleHealthCheckEvent({ 85, 70, 55, 40, 25 }, [&] { - Talk(SAY_ENERGY); - Talk(EMOTE_DISCHARGE_ENERGY); - - if (IsHeroic()) + if (!_energyCooldown) { - DoCastSelf(SPELL_SUMMON_PURE_ENERGY_H1); - DoCastSelf(SPELL_SUMMON_PURE_ENERGY_H2); + Talk(SAY_ENERGY); + Talk(EMOTE_DISCHARGE_ENERGY); + + if (IsHeroic()) + { + DoCastSelf(SPELL_SUMMON_PURE_ENERGY_H1); + DoCastSelf(SPELL_SUMMON_PURE_ENERGY_H2); + } + else + DoCastSelf(SPELL_SUMMON_PURE_ENERGY_N); + + _energyCooldown = true; + scheduler.Schedule(5s, [this](TaskContext) + { + _energyCooldown = false; + }); } - else - DoCastSelf(SPELL_SUMMON_PURE_ENERGY_N); }); ScheduleHealthCheckEvent(20, [&] @@ -117,6 +127,9 @@ struct boss_vexallus : public BossAI if (killer) killer->CastSpell(killer, SPELL_ENERGY_FEEDBACK, true, 0, 0, summon->GetGUID()); } + +private: + bool _energyCooldown; }; void AddSC_boss_vexallus() diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp index 6ccc8b13a..69e4a94ac 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp @@ -15,50 +15,63 @@ * with this program. If not, see . */ -#include "CreatureScript.h" #include "InstanceMapScript.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "SmartAI.h" #include "scarletmonastery.h" +#include "ScriptedCreature.h" enum AshbringerEventMisc { - AURA_OF_ASHBRINGER = 28282, - NPC_SCARLET_MYRIDON = 4295, - NPC_SCARLET_DEFENDER = 4298, - NPC_SCARLET_CENTURION = 4301, - NPC_SCARLET_SORCERER = 4294, - NPC_SCARLET_WIZARD = 4300, - NPC_SCARLET_ABBOT = 4303, - NPC_SCARLET_MONK = 4540, - NPC_SCARLET_CHAMPION = 4302, - NPC_SCARLET_CHAPLAIN = 4299, - NPC_FAIRBANKS = 4542, - NPC_COMMANDER_MOGRAINE = 3976, - NPC_INQUISITOR_WHITEMANE = 3977, - DOOR_HIGH_INQUISITOR_ID = 104600, + NPC_COMMANDER_MOGRAINE = 3976, + NPC_INQUISITOR_WHITEMANE = 3977, + NPC_SCARLET_SORCERER = 4294, + NPC_SCARLET_MYRIDON = 4295, + NPC_SCARLET_DEFENDER = 4298, + NPC_SCARLET_CHAPLAIN = 4299, + NPC_SCARLET_WIZARD = 4300, + NPC_SCARLET_CENTURION = 4301, + NPC_SCARLET_CHAMPION = 4302, + NPC_SCARLET_ABBOT = 4303, + NPC_SCARLET_MONK = 4540, + NPC_FAIRBANKS = 4542, + NPC_HIGHLORD_MOGRAINE = 16062, + + GO_CHAPEL_DOOR = 104591, + GO_HIGH_INQUISITOR_DOOR = 104600 +}; + +enum AshbringerSpell +{ + //Highlord Mograine Spells + //Needs Fix: Increased the visual effect of spells on hit + SPELL_FORGIVENESS = 28697, + + //High Inquisitor Fairbanks + //Needs Fix: Increased the visual effect of spells on hit + SPELL_TRANSFORM_GHOST = 28443 }; enum DataTypes { - TYPE_MOGRAINE_AND_WHITE_EVENT = 1, + TYPE_MOGRAINE_AND_WHITE_EVENT = 1, + TYPE_ASHBRINGER_EVENT = 2, - DATA_MOGRAINE = 2, - DATA_WHITEMANE = 3, - DATA_DOOR_WHITEMANE = 4, + DATA_MOGRAINE = 3, + DATA_WHITEMANE = 4, + DATA_DOOR_WHITEMANE = 5, + DATA_HORSEMAN_EVENT = 6, + DATA_VORREL = 7, + DATA_ARCANIST_DOAN = 8, + DATA_DOOR_CHAPEL = 9, - DATA_HORSEMAN_EVENT = 5, - GAMEOBJECT_PUMPKIN_SHRINE = 6, - - DATA_VORREL = 7, - DATA_ARCANIST_DOAN = 8 + GAMEOBJECT_PUMPKIN_SHRINE = 10 }; +float const CATHEDRAL_PULL_RANGE = 80.0f; // Distance from the Cathedral doors to where Mograine is standing + class instance_scarlet_monastery : public InstanceMapScript { public: - instance_scarlet_monastery() : InstanceMapScript("instance_scarlet_monastery", 189) { } + instance_scarlet_monastery() : InstanceMapScript("instance_scarlet_monastery", 189) {} InstanceScript* GetInstanceScript(InstanceMap* map) const override { @@ -72,55 +85,18 @@ public: SetHeaders(DataHeader); } - void OnPlayerEnter(Player* player) override - { - if (player->HasAura(AURA_OF_ASHBRINGER)) - { - std::list ScarletList; - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_MYRIDON, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_DEFENDER, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_CENTURION, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_SORCERER, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_WIZARD, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_ABBOT, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_MONK, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_CHAMPION, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_CHAPLAIN, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_COMMANDER_MOGRAINE, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_FAIRBANKS, 4000.0f); - if (!ScarletList.empty()) - for (std::list::iterator itr = ScarletList.begin(); itr != ScarletList.end(); itr++) (*itr)->SetFaction(FACTION_FRIENDLY); - } - } - - void OnPlayerAreaUpdate(Player* player, uint32 /*oldArea*/, uint32 /*newArea*/) override - { - if (player->HasAura(AURA_OF_ASHBRINGER)) - { - std::list ScarletList; - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_MYRIDON, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_DEFENDER, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_CENTURION, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_SORCERER, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_WIZARD, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_ABBOT, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_MONK, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_CHAMPION, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_SCARLET_CHAPLAIN, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_COMMANDER_MOGRAINE, 4000.0f); - player->GetCreatureListWithEntryInGrid(ScarletList, NPC_FAIRBANKS, 4000.0f); - if (!ScarletList.empty()) - for (std::list::iterator itr = ScarletList.begin(); itr != ScarletList.end(); itr++) (*itr)->SetFaction(FACTION_FRIENDLY); - } - } - void OnGameObjectCreate(GameObject* go) override { switch (go->GetEntry()) { - //case ENTRY_PUMPKIN_SHRINE: PumpkinShrineGUID = go->GetGUID(); break; - case DOOR_HIGH_INQUISITOR_ID: - DoorHighInquisitorGUID = go->GetGUID(); + // case ENTRY_PUMPKIN_SHRINE: PumpkinShrineGUID = go->GetGUID(); break; + case GO_HIGH_INQUISITOR_DOOR: + _doorHighInquisitorGUID = go->GetGUID(); + break; + case GO_CHAPEL_DOOR: + _doorChapelGUID = go->GetGUID(); + break; + default: break; } } @@ -129,11 +105,26 @@ public: { switch (creature->GetEntry()) { + case NPC_SCARLET_MYRIDON: + case NPC_SCARLET_DEFENDER: + case NPC_SCARLET_CENTURION: + case NPC_SCARLET_SORCERER: + case NPC_SCARLET_WIZARD: + case NPC_SCARLET_ABBOT: + case NPC_SCARLET_MONK: + case NPC_SCARLET_CHAMPION: + case NPC_SCARLET_CHAPLAIN: + case NPC_FAIRBANKS: + _ashbringerNpcGUID.emplace(creature->GetGUID()); + break; case NPC_COMMANDER_MOGRAINE: - MograineGUID = creature->GetGUID(); + _mograineGUID = creature->GetGUID(); + _ashbringerNpcGUID.emplace(creature->GetGUID()); break; case NPC_INQUISITOR_WHITEMANE: - WhitemaneGUID = creature->GetGUID(); + _whitemaneGUID = creature->GetGUID(); + break; + default: break; } } @@ -145,19 +136,90 @@ public: case TYPE_MOGRAINE_AND_WHITE_EVENT: if (data == IN_PROGRESS) { - DoUseDoorOrButton(DoorHighInquisitorGUID); - encounter = IN_PROGRESS; + if (Creature* mograine = instance->GetCreature(_mograineGUID)) + { + std::list creatureList; + GetCreatureListWithEntryInGrid(creatureList, mograine, NPC_SCARLET_MONK, CATHEDRAL_PULL_RANGE); + GetCreatureListWithEntryInGrid(creatureList, mograine, NPC_SCARLET_ABBOT, CATHEDRAL_PULL_RANGE); + GetCreatureListWithEntryInGrid(creatureList, mograine, NPC_SCARLET_CHAMPION, CATHEDRAL_PULL_RANGE); + GetCreatureListWithEntryInGrid(creatureList, mograine, NPC_SCARLET_CENTURION, CATHEDRAL_PULL_RANGE); + GetCreatureListWithEntryInGrid(creatureList, mograine, NPC_SCARLET_WIZARD, CATHEDRAL_PULL_RANGE); + GetCreatureListWithEntryInGrid(creatureList, mograine, NPC_SCARLET_CHAPLAIN, CATHEDRAL_PULL_RANGE); + for (std::list::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) + { + if (Creature* creature = *itr) + creature->AI()->AttackStart(mograine->GetVictim()); + } + } + _encounter = IN_PROGRESS; } if (data == FAIL) { - DoUseDoorOrButton(DoorHighInquisitorGUID); - encounter = FAIL; + Creature* whitemane = instance->GetCreature(_whitemaneGUID); + if (!whitemane) + return; + + Creature* mograine = instance->GetCreature(_mograineGUID); + if (!mograine) + return; + + if (whitemane->IsAlive() && mograine->IsAlive()) + { + // When Whitemane emerges from the main gate, Whitemane will stand next to Mograine's corpse and will not reset Whitemane + if (whitemane->IsEngaged()||whitemane->IsInEvadeMode()) + whitemane->DespawnOnEvade(20s); + + mograine->DespawnOnEvade(20s); + _encounter = NOT_STARTED; + return; + } + + // Whitemane will not be able to fight Mograine again when he dies + if (!whitemane->IsAlive()) + { + mograine->DespawnOrUnsummon(); + _encounter = data; + return; + } + + if (whitemane->IsAlive() && !mograine->IsAlive()) + { + whitemane->DespawnOnEvade(20s); + _encounter = data; + return; + } + + _encounter = data; } - if (data == SPECIAL) - encounter = SPECIAL; + if (data == DONE) + _encounter = DONE; + break; + case TYPE_ASHBRINGER_EVENT: + if (data == IN_PROGRESS) + { + // the ashbringer incident did not sniff out any data from whitemane + if (Creature* whitemane = instance->GetCreature(_whitemaneGUID)) + if (whitemane->IsAlive() && !whitemane->IsEngaged()) + whitemane->DespawnOrUnsummon(); + + if (GameObject* go = instance->GetGameObject(_doorChapelGUID)) + { + go->SetGoState(GO_STATE_ACTIVE); + go->SetLootState(GO_ACTIVATED); + go->SetGameObjectFlag(GO_FLAG_IN_USE); + } + + for (auto const& scarletCathedralNpcGuid : _ashbringerNpcGUID) + if (Creature* scarletNpc = instance->GetCreature(scarletCathedralNpcGuid)) + if (scarletNpc->IsAlive() && !scarletNpc->IsEngaged()) + scarletNpc->SetFaction(FACTION_FRIENDLY); + } + _ashencounter = data; break; case DATA_HORSEMAN_EVENT: - encounter = data; + _encounter = data; + break; + default: break; } } @@ -167,528 +229,49 @@ public: switch (type) { case DATA_MOGRAINE: - return MograineGUID; + return _mograineGUID; case DATA_WHITEMANE: - return WhitemaneGUID; + return _whitemaneGUID; case DATA_DOOR_WHITEMANE: - return DoorHighInquisitorGUID; + return _doorHighInquisitorGUID; + case DATA_DOOR_CHAPEL: + return _doorChapelGUID; + default: + return ObjectGuid::Empty; + break; } - - return ObjectGuid::Empty; } uint32 GetData(uint32 type) const override { - if (type == TYPE_MOGRAINE_AND_WHITE_EVENT) - return encounter; - else if (type == DATA_HORSEMAN_EVENT) - return encounter; - return 0; - } - private: - ObjectGuid DoorHighInquisitorGUID; - ObjectGuid MograineGUID; - ObjectGuid WhitemaneGUID; - uint32 encounter; - }; -}; - -enum ScarletMonasteryTrashMisc -{ - SAY_WELCOME = 0, - AURA_ASHBRINGER = 28282, - //FACTION_FRIENDLY_TO_ALL = 35, - NPC_HIGHLORD_MOGRAINE = 16440, - SPELL_COSMETIC_CHAIN = 45537, - SPELL_COSMETIC_EXPLODE = 45935, - SPELL_FORGIVENESS = 28697, -}; - -enum MograineEvents -{ - EVENT_SPELL_CRUSADER_STRIKE = 1, - EVENT_SPELL_HAMMER_OF_JUSTICE = 2, - EVENT_PULL_CATHEDRAL = 3 -}; - -enum WhitemaneEvents -{ - EVENT_SPELL_HOLY_SMITE = 1, - EVENT_SPELL_POWER_WORLD_SHIELD = 2, - EVENT_SPELL_HEAL = 3 -}; - -enum Spells -{ - //Mograine Spells - SPELL_CRUSADER_STRIKE = 14518, - SPELL_HAMMER_OF_JUSTICE = 5589, - SPELL_LAY_ON_HANDS = 9257, - SPELL_RETRIBUTION_AURA = 8990, - SPELL_PERMANENT_FEIGN_DEATH = 29266, - - //Whitemanes Spells - SPELL_SCARLET_RESURRECTION = 9232, - SPELL_DEEP_SLEEP = 9256, - SPELL_DOMINATE_MIND = 14515, - SPELL_HOLY_SMITE = 9481, - SPELL_HEAL = 12039, - SPELL_POWER_WORD_SHIELD = 22187 -}; - -enum Says -{ - //Mograine says - SAY_MO_AGGRO = 0, - SAY_MO_KILL = 1, - SAY_MO_RESURRECTED = 2, - - //Whitemane says - SAY_WH_INTRO = 0, - SAY_WH_KILL = 1, - SAY_WH_RESURRECT = 2, -}; - -float const CATHEDRAL_PULL_RANGE = 80.0f; // Distance from the Cathedral doors to where Mograine is standing - -class npc_mograine : public CreatureScript -{ -public: - npc_mograine() : CreatureScript("npc_scarlet_commander_mograine") { } - - struct npc_mograineAI : public ScriptedAI - { - npc_mograineAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - uint32 AshbringerEvent(uint32 uiSteps) - { - Creature* mograine = me->FindNearestCreature(NPC_HIGHLORD_MOGRAINE, 200.0f); - - switch (uiSteps) + switch (type) { - case 1: - me->GetMotionMaster()->MovePoint(0, 1152.039795f, 1398.405518f, 32.527878f); - return 2 * IN_MILLISECONDS; - case 2: - me->SetSheath(SHEATH_STATE_UNARMED); - me->SetStandState(UNIT_STAND_STATE_KNEEL); - return 2 * IN_MILLISECONDS; - case 3: - Talk(3); - return 10 * IN_MILLISECONDS; - case 4: - me->SummonCreature(NPC_HIGHLORD_MOGRAINE, 1065.130737f, 1399.350586f, 30.763723f, 6.282961f, TEMPSUMMON_TIMED_DESPAWN, 400000)->SetName("Highlord Mograine"); - me->FindNearestCreature(NPC_HIGHLORD_MOGRAINE, 200.0f)->SetFaction(FACTION_FRIENDLY); - return 30 * IN_MILLISECONDS; - case 5: - mograine->StopMovingOnCurrentPos(); - mograine->AI()->Talk(0); - mograine->HandleEmoteCommand(EMOTE_ONESHOT_POINT); - return 4 * IN_MILLISECONDS; - case 6: - me->SetStandState(UNIT_STAND_STATE_STAND); - return 2 * IN_MILLISECONDS; - case 7: - Talk(4); - return 4 * IN_MILLISECONDS; - case 8: - mograine->AI()->Talk(1); - return 11 * IN_MILLISECONDS; - case 9: - mograine->HandleEmoteCommand(EMOTE_ONESHOT_BATTLE_ROAR); - return 4 * IN_MILLISECONDS; - case 10: - me->SetSheath(SHEATH_STATE_UNARMED); - me->SetStandState(UNIT_STAND_STATE_KNEEL); - Talk(5); - return 2 * IN_MILLISECONDS; - case 11: - mograine->CastSpell(me, SPELL_FORGIVENESS, false); - return 1 * IN_MILLISECONDS; - case 12: - mograine->CastSpell(me, SPELL_COSMETIC_CHAIN, true); - return 0.5 * IN_MILLISECONDS; - case 13: - mograine->AI()->Talk(2); - mograine->DespawnOrUnsummon(3 * IN_MILLISECONDS); - mograine->Kill(me, me, true); - return 0; + case TYPE_MOGRAINE_AND_WHITE_EVENT: + return _encounter; + break; + case DATA_HORSEMAN_EVENT: + return _encounter; + break; + case TYPE_ASHBRINGER_EVENT: + return _ashencounter; + break; default: - if (mograine) - mograine->DespawnOrUnsummon(0); return 0; + break; } } - - void PullCathedral() // CallForHelp will ignore any npcs without LOS - { - std::list creatureList; - GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_MONK, CATHEDRAL_PULL_RANGE); - GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_ABBOT, CATHEDRAL_PULL_RANGE); - GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_CHAMPION, CATHEDRAL_PULL_RANGE); - GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_CENTURION, CATHEDRAL_PULL_RANGE); - GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_WIZARD, CATHEDRAL_PULL_RANGE); - GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_CHAPLAIN, CATHEDRAL_PULL_RANGE); - for (std::list::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) - { - if (Creature* creature = *itr) - creature->AI()->AttackStart(me->GetVictim()); - } - } - - void Reset() override - { - //Incase wipe during phase that mograine fake death - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH); - SayAshbringer = false; - timer = 0; - step = 1; - hasDied = false; - heal = false; - fakeDeath = false; - events.Reset(); - } - - void MoveInLineOfSight(Unit* who) override - { - if (who && who->GetDistance2d(me) < 15.0f) - if (Player* player = who->ToPlayer()) - if (player->HasAura(AURA_ASHBRINGER) && !SayAshbringer) - { - me->SetFaction(FACTION_FRIENDLY); - me->SetSheath(SHEATH_STATE_UNARMED); - me->SetStandState(UNIT_STAND_STATE_KNEEL); - me->SetFacingToObject(player); - // me->Yell(12389, LANG_UNIVERSAL, player); // Doesn't exist - SayAshbringer = true; - } - - ScriptedAI::MoveInLineOfSight(who); - } - - void JustEngagedWith(Unit* /*who*/) override - { - Talk(SAY_MO_AGGRO); - me->CastSpell(me, SPELL_RETRIBUTION_AURA, true); - events.ScheduleEvent(EVENT_PULL_CATHEDRAL, 1s); // Has to be done via event, otherwise mob aggroing Mograine DOES NOT aggro the room - events.ScheduleEvent(EVENT_SPELL_CRUSADER_STRIKE, 1s, 5s); - events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, 6s, 11s); - } - - void DamageTaken(Unit* /*doneBy*/, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage < me->GetHealth() || hasDied || fakeDeath) - return; - - //On first death, fake death and open door, as well as initiate whitemane if exist - if (Unit* Whitemane = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_WHITEMANE))) - { - instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, IN_PROGRESS); - Whitemane->GetMotionMaster()->MovePoint(1, 1163.113370f, 1398.856812f, 32.527786f); - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MoveIdle(); - me->SetHealth(0); - if (me->IsNonMeleeSpellCast(false)) - me->InterruptNonMeleeSpells(false); - me->ClearComboPointHolders(); - me->RemoveAllAuras(); - me->ClearAllReactives(); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->CastSpell(me, SPELL_PERMANENT_FEIGN_DEATH, true); - - hasDied = true; - fakeDeath = true; - damage = 0; - ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_WHITEMANE))->SetInCombatWithZone(); - } - } - - void KilledUnit(Unit* /*victim*/) override - { - Talk(SAY_MO_KILL); - } - - void SpellHit(Unit* /*who*/, SpellInfo const* spell) override - { - //When hit with resurrection say text - if (spell->Id == SPELL_SCARLET_RESURRECTION) - { - Talk(SAY_MO_RESURRECTED); - fakeDeath = false; - instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, SPECIAL); - } - } - - void UpdateAI(uint32 diff) override - { - timer = timer - diff; - if (SayAshbringer && step < 15) - { - if (timer <= 0) - { - timer = AshbringerEvent(step); - step++; - } - } - - if (!UpdateVictim()) - return; - - if (hasDied && !heal && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == SPECIAL) - { - //On resurrection, stop fake death and heal whitemane and resume fight - if (Unit* Whitemane = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_WHITEMANE))) - { - //Incase wipe during phase that mograine fake death - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH); - me->CastSpell(me, SPELL_RETRIBUTION_AURA, true); - me->CastSpell(Whitemane, SPELL_LAY_ON_HANDS, true); - events.ScheduleEvent(EVENT_SPELL_CRUSADER_STRIKE, 1s, 5s); - events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, 6s, 11s); - if (me->GetVictim()) - me->GetMotionMaster()->MoveChase(me->GetVictim()); - heal = true; - } - } - - //This if-check to make sure mograine does not attack while fake death - if (fakeDeath) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SPELL_CRUSADER_STRIKE: - me->CastSpell(me->GetVictim(), SPELL_CRUSADER_STRIKE, true); - events.ScheduleEvent(EVENT_SPELL_CRUSADER_STRIKE, 10s); - break; - case EVENT_SPELL_HAMMER_OF_JUSTICE: - me->CastSpell(me->GetVictim(), SPELL_HAMMER_OF_JUSTICE, true); - events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, 60s); - break; - case EVENT_PULL_CATHEDRAL: - PullCathedral(); - break; - } - } - DoMeleeAttackIfReady(); - } - - private: - bool SayAshbringer = false; - int timer = 0; - int step = 1; - bool hasDied; - bool heal; - bool fakeDeath; - EventMap events; - InstanceScript* instance; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetScarletMonasteryAI(creature); - } -}; - -class boss_high_inquisitor_whitemane : public CreatureScript -{ -public: - boss_high_inquisitor_whitemane() : CreatureScript("boss_high_inquisitor_whitemane") { } - - struct boss_high_inquisitor_whitemaneAI : public ScriptedAI - { - boss_high_inquisitor_whitemaneAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - void Reset() override - { - canResurrectCheck = false; - canResurrect = false; - Wait_Timer = 7000; - Heal_Timer = 10000; - } - - void JustReachedHome() override - { - instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, FAIL); - } - - void JustEngagedWith(Unit* /*who*/) override - { - Talk(SAY_WH_INTRO); - events.ScheduleEvent(EVENT_SPELL_HOLY_SMITE, 1s, 3s); - events.ScheduleEvent(EVENT_SPELL_POWER_WORLD_SHIELD, 6s); - events.ScheduleEvent(EVENT_SPELL_HEAL, 9s); - } - - void DamageTaken(Unit* /*doneBy*/, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if ((!canResurrectCheck || canResurrect) && damage >= me->GetHealth()) - damage = me->GetHealth() - 1; - } - - void KilledUnit(Unit* /*victim*/) override - { - Talk(SAY_WH_KILL); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (canResurrect) - { - //When casting resuruction make sure to delay so on rez when reinstate battle deepsleep runs out - if (Wait_Timer <= diff) - { - if (ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MOGRAINE))) - { - DoCast(SPELL_SCARLET_RESURRECTION); - Talk(SAY_WH_RESURRECT); - canResurrect = false; - } - } - else Wait_Timer -= diff; - } - - //Cast Deep sleep when health is less than 50% - if (!canResurrectCheck && !HealthAbovePct(50)) - { - if (me->IsNonMeleeSpellCast(false)) - me->InterruptNonMeleeSpells(false); - - me->CastSpell(me->GetVictim(), SPELL_DEEP_SLEEP, true); - canResurrectCheck = true; - canResurrect = true; - return; - } - - //while in "resurrect-mode", don't do anything - if (canResurrect) - return; - - //If we are <75% hp cast healing spells at self or Mograine - if (Heal_Timer <= diff) - { - Creature* target = nullptr; - - if (!HealthAbovePct(75)) - target = me; - - if (Creature* mograine = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MOGRAINE))) - { - // checking canResurrectCheck prevents her healing Mograine while he is "faking death" - if (canResurrectCheck && mograine->IsAlive() && !mograine->HealthAbovePct(75)) - target = mograine; - } - - if (target) - me->CastSpell(target, SPELL_HEAL, false); - - Heal_Timer = 13000; - } - else Heal_Timer -= diff; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SPELL_POWER_WORLD_SHIELD: - me->CastSpell(me, SPELL_POWER_WORD_SHIELD, false); - events.ScheduleEvent(EVENT_SPELL_POWER_WORLD_SHIELD, 15s); - break; - case EVENT_SPELL_HOLY_SMITE: - me->CastSpell(me->GetVictim(), SPELL_HOLY_SMITE, false); - events.ScheduleEvent(EVENT_SPELL_HOLY_SMITE, 6s); - break; - case EVENT_SPELL_HEAL: - me->CastSpell(me, SPELL_HEAL, false); - break; - } - } - - DoMeleeAttackIfReady(); - } - - private: - InstanceScript* instance; - uint32 Heal_Timer; - uint32 Wait_Timer; - bool canResurrectCheck; - bool canResurrect; - EventMap events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetScarletMonasteryAI(creature); - } -}; - -class npc_fairbanks : public CreatureScript -{ -public: - npc_fairbanks() : CreatureScript("npc_fairbanks") { } - - struct npc_fairbanksAI : public SmartAI - { - npc_fairbanksAI(Creature* creature) : SmartAI(creature) { } - - void Reset() override - { - SayAshbringer = false; - } - - void MoveInLineOfSight(Unit* who) override - { - if (who && who->GetDistance2d(me) < 2.0f) - if (Player* player = who->ToPlayer()) - if (player->HasAura(AURA_ASHBRINGER) && !SayAshbringer) - { - me->SetFaction(FACTION_FRIENDLY); - me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); - me->CastSpell(me, 57767, true); - me->SetDisplayId(16179); - me->SetFacingToObject(player); - SayAshbringer = true; - } - - SmartAI::MoveInLineOfSight(who); - } private: - bool SayAshbringer = false; + ObjectGuid _doorHighInquisitorGUID; + ObjectGuid _doorChapelGUID; + ObjectGuid _mograineGUID; + ObjectGuid _whitemaneGUID; + uint32 _encounter{}; + uint32 _ashencounter{}; + GuidSet _ashbringerNpcGUID; }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetScarletMonasteryAI(creature); - } }; void AddSC_instance_scarlet_monastery() { new instance_scarlet_monastery(); - new npc_fairbanks(); - new npc_mograine(); - new boss_high_inquisitor_whitemane(); } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp index 4ac563b7b..685b749c6 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp @@ -65,7 +65,7 @@ ObjectData const creatureData[] = { NPC_JANALAI, DATA_JANALAI }, { NPC_SPIRIT_LYNX, DATA_SPIRIT_LYNX }, { NPC_HARRISON_JONES, DATA_HARRISON_JONES }, - { NPC_AMINISHI_LOOKOUT, DATA_LOOKOUT }, + { NPC_AMANISHI_LOOKOUT, DATA_LOOKOUT }, { 0, 0 } }; @@ -127,13 +127,18 @@ public: { switch (creature->GetEntry()) { + case NPC_AMANISHI_GUARDIAN: + case NPC_AMANISHI_SAVAGE: + if (creature->GetPositionY() >= 1500.0f) // gate + creature->SetImmuneToAll(true); + break; // Akil'zon gauntlet - case NPC_AMINISHI_TEMPEST: + case NPC_AMANISHI_TEMPEST: if (creature->GetPositionZ() >= 50.0f) // excludes Tempest in Hexlord Malacrass' trash AkilzonTrash.insert(creature->GetGUID()); break; - case NPC_AMINISHI_LOOKOUT: - case NPC_AMINISHI_PROTECTOR: + case NPC_AMANISHI_LOOKOUT: + case NPC_AMANISHI_PROTECTOR: case NPC_EAGLE_TRASH_AGGRO_TRIGGER: AkilzonTrash.insert(creature->GetGUID()); break; @@ -226,8 +231,8 @@ public: case NPC_EAGLE_TRASH_AGGRO_TRIGGER: creature->DisappearAndDie(); break; - case NPC_AMINISHI_LOOKOUT: - case NPC_AMINISHI_TEMPEST: + case NPC_AMANISHI_LOOKOUT: + case NPC_AMANISHI_TEMPEST: creature->AI()->DoAction(ACTION_START_AKILZON_GAUNTLET); break; default: @@ -243,7 +248,7 @@ public: { if (!creature->IsAlive()) creature->Respawn(); - else if (creature->GetEntry() == NPC_AMINISHI_TEMPEST) + else if (creature->GetEntry() == NPC_AMANISHI_TEMPEST) creature->AI()->DoAction(ACTION_RESET_AKILZON_GAUNTLET); } if (Creature* creature = GetCreature(DATA_LOOKOUT)) @@ -259,7 +264,7 @@ public: switch (creature->GetEntry()) { - case NPC_AMINISHI_PROTECTOR: + case NPC_AMANISHI_PROTECTOR: case NPC_AMANISHI_WIND_WALKER: if (_akilzonGauntlet == NOT_STARTED && AkilzonTrash.contains(creature->GetGUID())) creature->DespawnOrUnsummon(30s, 1s); @@ -272,8 +277,8 @@ public: { switch (creature->GetEntry()) { - case NPC_AMINISHI_TEMPEST: - case NPC_AMINISHI_PROTECTOR: + case NPC_AMANISHI_TEMPEST: + case NPC_AMANISHI_PROTECTOR: case NPC_AMANISHI_WIND_WALKER: if (AkilzonTrash.contains(creature->GetGUID())) ResetAkilzonGauntlet(); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp index bbe60ba86..7e1f7465c 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp @@ -358,8 +358,7 @@ enum DisplayIds enum EntryIds { NPC_HARRISON_JONES_1 = 24375, - NPC_HARRISON_JONES_2 = 24365, - NPC_AMANISHI_GUARDIAN = 23597, + NPC_HARRISON_JONES_2 = 24365 }; enum Weapons @@ -417,7 +416,10 @@ struct npc_harrison_jones : public ScriptedAI std::list creatures; me->GetCreatureListWithEntryInGrid(creatures, NPC_AMANISHI_SAVAGE, 100.0f); for (Creature* creature : creatures) + { + creature->SetImmuneToAll(false); creature->SetInCombatWithZone(); + } }); _instance->StorePersistentData(DATA_TIMED_RUN, 21); _instance->DoAction(ACTION_START_TIMED_RUN); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h index 444da72d0..097e4cbde 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h @@ -60,11 +60,12 @@ enum CreatureIds NPC_AMANISHI_MEDICINE_MAN = 23581, NPC_AMANISHI_AXE_THROWER = 23542, NPC_AMANI_HATCHLING = 23598, // 42493 + NPC_AMANISHI_GUARDIAN = 23597, // Akil'zon gauntlet NPC_AMANISHI_WIND_WALKER = 24179, - NPC_AMINISHI_LOOKOUT = 24175, - NPC_AMINISHI_PROTECTOR = 24180, - NPC_AMINISHI_TEMPEST = 24549, + NPC_AMANISHI_LOOKOUT = 24175, + NPC_AMANISHI_PROTECTOR = 24180, + NPC_AMANISHI_TEMPEST = 24549, NPC_EAGLE_TRASH_AGGRO_TRIGGER = 24223 }; diff --git a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp index f11a572ab..b07354ef5 100644 --- a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp +++ b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp @@ -161,136 +161,37 @@ static float PyrewoodSpawnPoints[3][4] = {-397.018219f, 1510.208740f, 18.868748f, 4.731330f}, }; -#define WAIT_SECS 6000 - -class pyrewood_ambush : public CreatureScript +struct npc_deathstalker_fearleia : public ScriptedAI { -public: - pyrewood_ambush() : CreatureScript("pyrewood_ambush") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) override + npc_deathstalker_fearleia(Creature* creature) : ScriptedAI(creature), _summons(me) { - if (quest->GetQuestId() == QUEST_PYREWOOD_AMBUSH && !CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->QuestInProgress) - { - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->QuestInProgress = true; - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->Phase = 0; - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->KillCount = 0; - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->PlayerGUID = player->GetGUID(); - } - - return true; + _questInProgress = false; } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return new pyrewood_ambushAI(creature); + if (!_questInProgress) + { + _playerGUID.Clear(); + _summons.DespawnAll(); + } } - struct pyrewood_ambushAI : public ScriptedAI + void sQuestAccept(Player* player, Quest const* quest) override { - pyrewood_ambushAI(Creature* creature) : ScriptedAI(creature), Summons(me) + if (quest->GetQuestId() == QUEST_PYREWOOD_AMBUSH && !_questInProgress) { - QuestInProgress = false; + _questInProgress = true; + _playerGUID = player->GetGUID(); } - uint32 Phase; - int8 KillCount; - uint32 WaitTimer; - ObjectGuid PlayerGUID; - SummonList Summons; + Talk(NPCSAY_INIT, player); - bool QuestInProgress; - - void Reset() override + scheduler.Schedule(6s, [this](TaskContext context) { - WaitTimer = WAIT_SECS; - - if (!QuestInProgress) //fix reset values (see UpdateVictim) - { - Phase = 0; - KillCount = 0; - PlayerGUID.Clear(); - Summons.DespawnAll(); - } - } - - void JustEngagedWith(Unit* /*who*/) override { } - - void JustSummoned(Creature* summoned) override - { - Summons.Summon(summoned); - ++KillCount; - } - - void SummonedCreatureDespawn(Creature* summoned) override - { - Summons.Despawn(summoned); - --KillCount; - } - - void SummonCreatureWithRandomTarget(uint32 creatureId, int position) - { - if (Creature* summoned = me->SummonCreature(creatureId, PyrewoodSpawnPoints[position][0], PyrewoodSpawnPoints[position][1], PyrewoodSpawnPoints[position][2], PyrewoodSpawnPoints[position][3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000)) - { - Unit* target = nullptr; - if (PlayerGUID) - if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - if (player->IsAlive() && RAND(0, 1)) - target = player; - - if (!target) - target = me; - - summoned->SetFaction(FACTION_STORMWIND); - summoned->AddThreat(target, 32.0f); - summoned->AI()->AttackStart(target); - } - } - - void JustDied(Unit* /*killer*/) override - { - if (PlayerGUID) - if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - if (player->GetQuestStatus(QUEST_PYREWOOD_AMBUSH) == QUEST_STATUS_INCOMPLETE) - player->FailQuest(QUEST_PYREWOOD_AMBUSH); - } - - void UpdateAI(uint32 diff) override - { - //LOG_INFO("scripts", "DEBUG: p({}) k({}) d({}) W({})", Phase, KillCount, diff, WaitTimer); - - if (!QuestInProgress) - return; - - if (KillCount && Phase < 6) - { - if (!UpdateVictim()) //reset() on target Despawn... - return; - - DoMeleeAttackIfReady(); - return; - } - - switch (Phase) + switch (context.GetRepeatCounter()) { case 0: - if (WaitTimer == WAIT_SECS) - { - if (PlayerGUID) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - { - me->AI()->Talk(NPCSAY_INIT, player); - } - } - } - if (WaitTimer <= diff) - { - WaitTimer -= diff; - return; - } - break; - case 1: SummonCreatureWithRandomTarget(2060, 1); break; case 2: @@ -309,21 +210,73 @@ public: SummonCreatureWithRandomTarget(2068, 2); break; case 5: //end - if (PlayerGUID) + if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) { - if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) - { - me->AI()->Talk(NPCSAY_END, player); - player->GroupEventHappens(QUEST_PYREWOOD_AMBUSH, me); - } + Talk(NPCSAY_END, player); + player->GroupEventHappens(QUEST_PYREWOOD_AMBUSH, me); } - QuestInProgress = false; + _questInProgress = false; Reset(); break; } - ++Phase; //prepare next phase + + if (context.GetRepeatCounter() < 5) + context.Repeat(); + }); + } + + void JustEngagedWith(Unit* /*who*/) override {} + + void JustSummoned(Creature* summoned) override + { + _summons.Summon(summoned); + } + + void SummonedCreatureDespawn(Creature* summoned) override + { + _summons.Despawn(summoned); + } + + void SummonCreatureWithRandomTarget(uint32 creatureId, int position) + { + if (Creature* summoned = me->SummonCreature(creatureId, PyrewoodSpawnPoints[position][0], PyrewoodSpawnPoints[position][1], PyrewoodSpawnPoints[position][2], PyrewoodSpawnPoints[position][3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000)) + { + Unit* target = nullptr; + if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) + if (player->IsAlive() && RAND(0, 1)) + target = player; + + if (!target) + target = me; + + summoned->SetFaction(FACTION_STORMWIND); + summoned->AddThreat(target, 32.0f); + summoned->AI()->AttackStart(target); } - }; + } + + void JustDied(Unit* /*killer*/) override + { + if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) + if (player->GetQuestStatus(QUEST_PYREWOOD_AMBUSH) == QUEST_STATUS_INCOMPLETE) + player->FailQuest(QUEST_PYREWOOD_AMBUSH); + } + + void UpdateAI(uint32 diff) override + { + if (_questInProgress && !_summons.IsAnyCreatureAlive()) + scheduler.Update(diff); + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + +private: + ObjectGuid _playerGUID; + SummonList _summons; + bool _questInProgress; }; /** @@ -485,6 +438,6 @@ public: void AddSC_silverpine_forest() { new npc_deathstalker_erland(); - new pyrewood_ambush(); + RegisterCreatureAI(npc_deathstalker_fearleia); new npc_ravenclaw_apparition(); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp index 7de0e534b..b2b286197 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp @@ -57,7 +57,6 @@ public: } bool CLEANED; - TeamId TeamIdInInstance; uint32 InstanceProgress; uint32 m_auiEncounter[MAX_ENCOUNTER]; std::string str_data; @@ -83,7 +82,6 @@ public: void Initialize() override { - TeamIdInInstance = TEAM_NEUTRAL; InstanceProgress = 0; memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); @@ -109,67 +107,49 @@ public: void OnCreatureCreate(Creature* creature) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.IsEmpty()) - if (Player* pPlayer = players.begin()->GetSource()) - { - if (Group* group = pPlayer->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = pPlayer->GetTeamId(); - } - else - TeamIdInInstance = pPlayer->GetTeamId(); - } - } - switch (creature->GetEntry()) { // Grand Champions: case NPC_MOKRA: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_JACOB); break; case NPC_ERESSEA: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_AMBROSE); break; case NPC_RUNOK: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_COLOSOS); break; case NPC_ZULTORE: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_JAELYNE); break; case NPC_VISCERI: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_LANA); break; // Grand Champion Minions: case NPC_ORGRIMMAR_MINION: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_STORMWIND_MINION); break; case NPC_SILVERMOON_MINION: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_GNOMEREGAN_MINION); break; case NPC_THUNDER_BLUFF_MINION: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_EXODAR_MINION); break; case NPC_SENJIN_MINION: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_DARNASSUS_MINION); break; case NPC_UNDERCITY_MINION: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_IRONFORGE_MINION); break; @@ -183,7 +163,7 @@ public: case NPC_JAEREN: case NPC_ARELAS: NPC_AnnouncerGUID = creature->GetGUID(); - //if (TeamIdInInstance == TEAM_ALLIANCE) + //if (GetTeamIdInInstance() == TEAM_ALLIANCE) // creature->UpdateEntry(NPC_ARELAS); creature->SetReactState(REACT_PASSIVE); break; @@ -283,36 +263,14 @@ public: void OnPlayerEnter(Player* player) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = player->GetTeamId(); - } - else - TeamIdInInstance = player->GetTeamId(); - } - - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1); + InstanceScript::OnPlayerEnter(player); if (DoNeedCleanup(player)) - { InstanceCleanup(); - } events.RescheduleEvent(EVENT_CHECK_PLAYERS, CLEANUP_CHECK_INTERVAL); } - void OnPlayerLeave(Player* player) override - { - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFactionForRace(player->getRace()); - } - bool DoNeedCleanup(Player* ignoredPlayer = nullptr) { uint8 aliveCount = 0; @@ -497,7 +455,7 @@ public: case DATA_INSTANCE_PROGRESS: return InstanceProgress; case DATA_TEAMID_IN_INSTANCE: - return TeamIdInInstance; + return GetTeamIdInInstance(); } return 0; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index 0d53492fc..5d2da7425 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -41,7 +41,6 @@ public: uint32 EncounterStatus; uint32 InstanceProgress; uint32 AttemptsLeft; - TeamId TeamIdInInstance; uint8 Counter; uint8 northrendBeastsMask; uint32 AchievementTimer; @@ -168,7 +167,6 @@ public: EncounterStatus = NOT_STARTED; InstanceProgress = INSTANCE_PROGRESS_INITIAL; AttemptsLeft = 50; - TeamIdInInstance = TEAM_NEUTRAL; Counter = 0; northrendBeastsMask = 0; AchievementTimer = 0; @@ -475,7 +473,7 @@ public: case TYPE_FACTION_CHAMPIONS_PLAYER_DIED: if (urand(0, 2) == 0 ) { - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) { if (Creature* pTemp = instance->GetCreature(NPC_VarianGUID)) pTemp->AI()->Talk(SAY_VARIAN_KILL_HORDE_PLAYER_1); @@ -971,16 +969,7 @@ public: } case EVENT_SCENE_202: { - Map::PlayerList const& pl = instance->GetPlayers(); - for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) - if (Player* plr = itr->GetSource()) - if (!plr->IsGameMaster()) - { - TeamIdInInstance = plr->GetTeamId(); - break; - } - - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) { if (Creature* c = instance->GetCreature(NPC_GarroshGUID)) c->AI()->Talk(SAY_STAGE_2_02h); @@ -1004,7 +993,7 @@ public: } case EVENT_SCENE_204: { - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) { if (Creature* c = instance->GetCreature(NPC_GarroshGUID)) c->AI()->Talk(SAY_STAGE_2_04h); @@ -1022,26 +1011,26 @@ public: } case EVENT_SCENE_205: { - if (Creature* c = instance->GetCreature(TeamIdInInstance == TEAM_ALLIANCE ? NPC_VarianGUID : NPC_GarroshGUID)) - c->AI()->Talk(TeamIdInInstance == TEAM_ALLIANCE ? SAY_STAGE_2_05a : SAY_STAGE_2_05h); + if (Creature* c = instance->GetCreature(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_VarianGUID : NPC_GarroshGUID)) + c->AI()->Talk(GetTeamIdInInstance() == TEAM_ALLIANCE ? SAY_STAGE_2_05a : SAY_STAGE_2_05h); break; } case EVENT_SUMMON_CHAMPIONS: { std::vector vHealerEntries; - vHealerEntries.push_back(TeamIdInInstance == TEAM_ALLIANCE ? NPC_HORDE_DRUID_RESTORATION : NPC_ALLIANCE_DRUID_RESTORATION); - vHealerEntries.push_back(TeamIdInInstance == TEAM_ALLIANCE ? NPC_HORDE_PALADIN_HOLY : NPC_ALLIANCE_PALADIN_HOLY); - vHealerEntries.push_back(TeamIdInInstance == TEAM_ALLIANCE ? NPC_HORDE_PRIEST_DISCIPLINE : NPC_ALLIANCE_PRIEST_DISCIPLINE); - vHealerEntries.push_back(TeamIdInInstance == TEAM_ALLIANCE ? NPC_HORDE_SHAMAN_RESTORATION : NPC_ALLIANCE_SHAMAN_RESTORATION); + vHealerEntries.push_back(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_HORDE_DRUID_RESTORATION : NPC_ALLIANCE_DRUID_RESTORATION); + vHealerEntries.push_back(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_HORDE_PALADIN_HOLY : NPC_ALLIANCE_PALADIN_HOLY); + vHealerEntries.push_back(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_HORDE_PRIEST_DISCIPLINE : NPC_ALLIANCE_PRIEST_DISCIPLINE); + vHealerEntries.push_back(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_HORDE_SHAMAN_RESTORATION : NPC_ALLIANCE_SHAMAN_RESTORATION); std::vector vOtherEntries; - vOtherEntries.push_back(TeamIdInInstance == TEAM_ALLIANCE ? NPC_HORDE_DEATH_KNIGHT : NPC_ALLIANCE_DEATH_KNIGHT); - vOtherEntries.push_back(TeamIdInInstance == TEAM_ALLIANCE ? NPC_HORDE_HUNTER : NPC_ALLIANCE_HUNTER); - vOtherEntries.push_back(TeamIdInInstance == TEAM_ALLIANCE ? NPC_HORDE_MAGE : NPC_ALLIANCE_MAGE); - vOtherEntries.push_back(TeamIdInInstance == TEAM_ALLIANCE ? NPC_HORDE_ROGUE : NPC_ALLIANCE_ROGUE); - vOtherEntries.push_back(TeamIdInInstance == TEAM_ALLIANCE ? NPC_HORDE_WARLOCK : NPC_ALLIANCE_WARLOCK); - vOtherEntries.push_back(TeamIdInInstance == TEAM_ALLIANCE ? NPC_HORDE_WARRIOR : NPC_ALLIANCE_WARRIOR); + vOtherEntries.push_back(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_HORDE_DEATH_KNIGHT : NPC_ALLIANCE_DEATH_KNIGHT); + vOtherEntries.push_back(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_HORDE_HUNTER : NPC_ALLIANCE_HUNTER); + vOtherEntries.push_back(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_HORDE_MAGE : NPC_ALLIANCE_MAGE); + vOtherEntries.push_back(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_HORDE_ROGUE : NPC_ALLIANCE_ROGUE); + vOtherEntries.push_back(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_HORDE_WARLOCK : NPC_ALLIANCE_WARLOCK); + vOtherEntries.push_back(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_HORDE_WARRIOR : NPC_ALLIANCE_WARRIOR); uint8 healersSubtracted = 2; if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL || instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC ) @@ -1089,11 +1078,11 @@ public: uint8 pos2 = 10; for( std::vector::iterator itr = vOtherEntries.begin(); itr != vOtherEntries.end(); ++itr ) { - if (Creature* pTemp = instance->SummonCreature(*itr, FactionChampionLoc[urand(0, 4) + (TeamIdInInstance == TEAM_ALLIANCE ? 0 : 5)])) + if (Creature* pTemp = instance->SummonCreature(*itr, FactionChampionLoc[urand(0, 4) + (GetTeamIdInInstance() == TEAM_ALLIANCE ? 0 : 5)])) { NPC_ChampionGUIDs.push_back(pTemp->GetGUID()); - pTemp->SetHomePosition((TeamIdInInstance == TEAM_ALLIANCE ? FactionChampionLoc[pos2].GetPositionX() : (Locs[LOC_CENTER].GetPositionX() * 2 - FactionChampionLoc[pos2].GetPositionX())), FactionChampionLoc[pos2].GetPositionY(), FactionChampionLoc[pos2].GetPositionZ(), 0.0f); - pTemp->GetMotionMaster()->MoveJump((TeamIdInInstance == TEAM_ALLIANCE ? FactionChampionLoc[pos2].GetPositionX() : (Locs[LOC_CENTER].GetPositionX() * 2 - FactionChampionLoc[pos2].GetPositionX())), FactionChampionLoc[pos2].GetPositionY(), FactionChampionLoc[pos2].GetPositionZ(), 20.0f, 20.0f); + pTemp->SetHomePosition((GetTeamIdInInstance() == TEAM_ALLIANCE ? FactionChampionLoc[pos2].GetPositionX() : (Locs[LOC_CENTER].GetPositionX() * 2 - FactionChampionLoc[pos2].GetPositionX())), FactionChampionLoc[pos2].GetPositionY(), FactionChampionLoc[pos2].GetPositionZ(), 0.0f); + pTemp->GetMotionMaster()->MoveJump((GetTeamIdInInstance() == TEAM_ALLIANCE ? FactionChampionLoc[pos2].GetPositionX() : (Locs[LOC_CENTER].GetPositionX() * 2 - FactionChampionLoc[pos2].GetPositionX())), FactionChampionLoc[pos2].GetPositionY(), FactionChampionLoc[pos2].GetPositionZ(), 20.0f, 20.0f); } ++pos2; } @@ -1196,35 +1185,8 @@ public: } case EVENT_SCENE_VALKYR_DEAD: { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& pl = instance->GetPlayers(); - for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) - if (Player* plr = itr->GetSource()) - if (!plr->IsGameMaster()) - { - if (Group* group = plr->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - { - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - break; - } - else - { - TeamIdInInstance = plr->GetTeamId(); - break; - } - } - else - { - TeamIdInInstance = plr->GetTeamId(); - break; - } - } - } - if (Creature* c = instance->GetCreature(TeamIdInInstance == TEAM_ALLIANCE ? NPC_VarianGUID : NPC_GarroshGUID)) - c->AI()->Talk((TeamIdInInstance == TEAM_ALLIANCE ? SAY_STAGE_3_03a : SAY_STAGE_3_03h)); + if (Creature* c = instance->GetCreature(GetTeamIdInInstance() == TEAM_ALLIANCE ? NPC_VarianGUID : NPC_GarroshGUID)) + c->AI()->Talk((GetTeamIdInInstance() == TEAM_ALLIANCE ? SAY_STAGE_3_03a : SAY_STAGE_3_03h)); events.RescheduleEvent(EVENT_SCENE_401, 60000); break; @@ -1413,21 +1375,7 @@ public: void OnPlayerEnter(Player* plr) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - if (Group* group = plr->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = plr->GetTeamId(); - } - else - TeamIdInInstance = plr->GetTeamId(); - } - - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - plr->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1); + InstanceScript::OnPlayerEnter(plr); if (instance->IsHeroic()) { @@ -1448,12 +1396,6 @@ public: events.RescheduleEvent(EVENT_CHECK_PLAYERS, 5s); } - void OnPlayerLeave(Player* player) override - { - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFactionForRace(player->getRace()); - } - bool DoNeedCleanup(Player* ignoredPlayer = nullptr) { uint8 aliveCount = 0; diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp index 382a4c577..c39c3a5e6 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp @@ -96,12 +96,6 @@ public: } } - void OnPlayerLeave(Player* player) override - { - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFactionForRace(player->getRace()); - } - void OnCreatureCreate(Creature* creature) override { if (teamIdInInstance == TEAM_NEUTRAL) diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp index 708ca27c1..7669ed17a 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp @@ -144,7 +144,6 @@ public: }; uint32 EncounterMask; - TeamId TeamIdInInstance; ObjectGuid NPC_FalricGUID; ObjectGuid NPC_MarwynGUID; ObjectGuid NPC_LichKingIntroGUID; @@ -190,7 +189,6 @@ public: void Initialize() override { EncounterMask = 0; - TeamIdInInstance = TEAM_NEUTRAL; memset(&TrashActive, 0, sizeof(TrashActive)); TrashCounter = 0; memset(&chosenComposition, 0, sizeof(chosenComposition)); @@ -214,69 +212,15 @@ public: return (instance->HavePlayers() && WaveNumber) || IsDuringLKFight; // during LK fight npcs are active and will unset this variable } - void OnPlayerEnter(Player* player) override - { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = player->GetTeamId(); - } - else - TeamIdInInstance = player->GetTeamId(); - } - - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1); - } - - void OnPlayerLeave(Player* player) override - { - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFactionForRace(player->getRace()); - } - void OnCreatureCreate(Creature* creature) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.IsEmpty()) - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (Player* p = itr->GetSource()) - if (!p->IsGameMaster()) - { - if (Group* group = p->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - { - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - break; - } - else - { - TeamIdInInstance = p->GetTeamId(); - break; - } - } - else - { - TeamIdInInstance = p->GetTeamId(); - break; - } - } - } - switch (creature->GetEntry()) { case NPC_SYLVANAS_PART1: creature->SetVisible(false); creature->SetSpeed(MOVE_RUN, 1.1); NPC_LeaderIntroGUID = creature->GetGUID(); - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_JAINA_PART1); creature->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); @@ -284,7 +228,7 @@ public: case NPC_DARK_RANGER_LORALEN: creature->SetVisible(false); NPC_GuardGUID = creature->GetGUID(); - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_ARCHMAGE_KORELN); break; case NPC_UTHER: @@ -345,7 +289,7 @@ public: creature->CastSpell(creature, SPELL_SOUL_REAPER, true); } else if (!(EncounterMask & (1 << DATA_LICH_KING))) - creature->AddAura(TeamIdInInstance == TEAM_ALLIANCE ? SPELL_JAINA_ICE_PRISON : SPELL_SYLVANAS_DARK_BINDING, creature); + creature->AddAura(GetTeamIdInInstance() == TEAM_ALLIANCE ? SPELL_JAINA_ICE_PRISON : SPELL_SYLVANAS_DARK_BINDING, creature); else creature->SetVisible(false); @@ -359,7 +303,7 @@ public: NPC_LeaderGUID = creature->GetGUID(); creature->SetWalk(false); creature->SetSheath(SHEATH_STATE_MELEE); - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_JAINA_PART2); creature->SetWalk(false); creature->SetHealth(creature->GetMaxHealth() / 20); @@ -368,9 +312,9 @@ public: if (!(EncounterMask & (1 << DATA_LK_INTRO))) { creature->SetSheath(SHEATH_STATE_MELEE); - creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, TeamIdInInstance == TEAM_ALLIANCE ? EMOTE_ONESHOT_ATTACK2HTIGHT : EMOTE_ONESHOT_ATTACK1H); //the fight cannot be in the form of an emote, it is causing bugs. + creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, GetTeamIdInInstance() == TEAM_ALLIANCE ? EMOTE_ONESHOT_ATTACK2HTIGHT : EMOTE_ONESHOT_ATTACK1H); //the fight cannot be in the form of an emote, it is causing bugs. creature->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); - creature->CastSpell(creature, TeamIdInInstance == TEAM_ALLIANCE ? SPELL_JAINA_ICE_BARRIER : SPELL_SYLVANAS_CLOAK_OF_DARKNESS, true); + creature->CastSpell(creature, GetTeamIdInInstance() == TEAM_ALLIANCE ? SPELL_JAINA_ICE_BARRIER : SPELL_SYLVANAS_CLOAK_OF_DARKNESS, true); } else if (!(EncounterMask & (1 << DATA_LICH_KING))) { @@ -577,7 +521,7 @@ public: if (!c->IsAlive()) { c->Respawn(); - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) c->UpdateEntry(NPC_JAINA_PART2); } c->GetThreatMgr().ClearAllThreat(); @@ -605,7 +549,7 @@ public: c->UpdatePosition(c->GetHomePosition(), true); c->StopMovingOnCurrentPos(); c->RemoveAllAuras(); - c->AddAura(TeamIdInInstance == TEAM_ALLIANCE ? SPELL_JAINA_ICE_PRISON : SPELL_SYLVANAS_DARK_BINDING, c); + c->AddAura(GetTeamIdInInstance() == TEAM_ALLIANCE ? SPELL_JAINA_ICE_PRISON : SPELL_SYLVANAS_DARK_BINDING, c); c->AI()->Reset(); c->setActive(false); c->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); @@ -1126,18 +1070,18 @@ public: break; case 2: { - uint32 entry = TeamIdInInstance == TEAM_ALLIANCE ? GO_THE_SKYBREAKER : GO_ORGRIMS_HAMMER; + uint32 entry = GetTeamIdInInstance() == TEAM_ALLIANCE ? GO_THE_SKYBREAKER : GO_ORGRIMS_HAMMER; T1 = sTransportMgr->CreateTransport(entry, 0, instance); ++outroStep; - outroTimer = TeamIdInInstance == TEAM_ALLIANCE ? 10000 : 10500; + outroTimer = GetTeamIdInInstance() == TEAM_ALLIANCE ? 10000 : 10500; } break; case 3: if (T1) T1->EnableMovement(false); if (Creature* c = instance->GetCreature(NPC_ShipCaptainGUID)) - c->AI()->Talk(TeamIdInInstance == TEAM_ALLIANCE ? SAY_FIRE_ALLY : SAY_FIRE_HORDE); + c->AI()->Talk(GetTeamIdInInstance() == TEAM_ALLIANCE ? SAY_FIRE_ALLY : SAY_FIRE_HORDE); if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) { c->RemoveAllAuras(); @@ -1185,10 +1129,10 @@ public: T1->EnableMovement(false); if (Creature* leader = instance->GetCreature(NPC_LeaderGUID)) { - uint8 index = TeamIdInInstance == TEAM_ALLIANCE ? 0 : 1; + uint8 index = GetTeamIdInInstance() == TEAM_ALLIANCE ? 0 : 1; for (uint8 i = 0; i < 3; ++i) if (StairsPos[index][i].GetPositionX()) - if (GameObject* go = leader->SummonGameObject(TeamIdInInstance == TEAM_ALLIANCE ? GO_STAIRS_ALLIANCE : GO_STAIRS_HORDE, StairsPos[index][i].GetPositionX(), StairsPos[index][i].GetPositionY(), StairsPos[index][i].GetPositionZ(), StairsPos[index][i].GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 86400, false)) + if (GameObject* go = leader->SummonGameObject(GetTeamIdInInstance() == TEAM_ALLIANCE ? GO_STAIRS_ALLIANCE : GO_STAIRS_HORDE, StairsPos[index][i].GetPositionX(), StairsPos[index][i].GetPositionY(), StairsPos[index][i].GetPositionZ(), StairsPos[index][i].GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 86400, false)) go->SetGameObjectFlag(GO_FLAG_INTERACT_COND | GO_FLAG_NOT_SELECTABLE); //Position pos = TeamIdInInstance == TEAM_ALLIANCE ? AllyPortalPos : HordePortalPos; //leader->SummonGameObject(GO_PORTAL_TO_DALARAN, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 86400); @@ -1200,7 +1144,7 @@ public: break; case 8: if (Creature* c = instance->GetCreature(NPC_ShipCaptainGUID)) - c->AI()->Talk(TeamIdInInstance == TEAM_ALLIANCE ? SAY_ONBOARD_ALLY : SAY_ONBOARD_HORDE); + c->AI()->Talk(GetTeamIdInInstance() == TEAM_ALLIANCE ? SAY_ONBOARD_ALLY : SAY_ONBOARD_HORDE); if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) { c->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); @@ -1212,7 +1156,7 @@ public: break; case 9: if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) - c->AI()->Talk(TeamIdInInstance == TEAM_ALLIANCE ? SAY_JAINA_FINAL_1 : SAY_SYLVANA_FINAL); + c->AI()->Talk(GetTeamIdInInstance() == TEAM_ALLIANCE ? SAY_JAINA_FINAL_1 : SAY_SYLVANA_FINAL); HandleGameObject(GO_CaveInGUID, true); ++outroStep; outroTimer = 11000; @@ -1223,7 +1167,7 @@ public: for (Map::PlayerList::const_iterator itr = instance->GetPlayers().begin(); itr != instance->GetPlayers().end(); ++itr) if (Player* p = itr->GetSource()) p->KilledMonsterCredit(NPC_WRATH_OF_THE_LICH_KING_CREDIT); - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) { c->AI()->Talk(SAY_JAINA_FINAL_2); diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp index 9d1e26a90..e91e0b954 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp @@ -35,7 +35,6 @@ public: } uint32 m_auiEncounter[MAX_ENCOUNTER]; - TeamId teamIdInInstance; uint32 InstanceProgress; std::string str_data; @@ -61,7 +60,6 @@ public: void Initialize() override { memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - teamIdInInstance = TEAM_NEUTRAL; InstanceProgress = INSTANCE_PROGRESS_NONE; bAchievEleven = true; @@ -78,62 +76,24 @@ public: void OnPlayerEnter(Player* player) override { - if (teamIdInInstance == TEAM_NEUTRAL) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - teamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - teamIdInInstance = player->GetTeamId(); - } - else - teamIdInInstance = player->GetTeamId(); - } - - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFaction((teamIdInInstance == TEAM_HORDE) ? 1610 : 1); + InstanceScript::OnPlayerEnter(player); instance->LoadGrid(LeaderIntroPos.GetPositionX(), LeaderIntroPos.GetPositionY()); if (Creature* c = instance->GetCreature(GetGuidData(DATA_LEADER_FIRST_GUID))) c->AI()->SetData(DATA_START_INTRO, 0); } - void OnPlayerLeave(Player* player) override - { - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFactionForRace(player->getRace()); - } - uint32 GetCreatureEntry(ObjectGuid::LowType /*guidLow*/, CreatureData const* data) override { - if (teamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.IsEmpty()) - if (Player* player = players.begin()->GetSource()) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - teamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - teamIdInInstance = player->GetTeamId(); - } - else - teamIdInInstance = player->GetTeamId(); - } - } - uint32 entry = data->id1; switch (entry) { case NPC_RESCUED_ALLIANCE_SLAVE: - if (teamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) return 0; break; case NPC_RESCUED_HORDE_SLAVE: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) return 0; break; } @@ -143,28 +103,10 @@ public: void OnCreatureCreate(Creature* creature) override { - if (teamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.IsEmpty()) - if (Player* player = players.begin()->GetSource()) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - teamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - teamIdInInstance = player->GetTeamId(); - } - else - teamIdInInstance = player->GetTeamId(); - } - } - switch (creature->GetEntry()) { case NPC_SYLVANAS_PART1: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_JAINA_PART1); NPC_LeaderFirstGUID = creature->GetGUID(); @@ -183,7 +125,7 @@ public: } break; case NPC_SYLVANAS_PART2: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_JAINA_PART2); NPC_LeaderSecondGUID = creature->GetGUID(); break; @@ -213,50 +155,50 @@ public: } break; case NPC_LORALEN: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_ELANDRA); if (!NPC_GuardFirstGUID) NPC_GuardFirstGUID = creature->GetGUID(); break; case NPC_KALIRA: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_KORELN); if (!NPC_GuardSecondGUID) NPC_GuardSecondGUID = creature->GetGUID(); break; case NPC_HORDE_SLAVE_1: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_ALLIANCE_SLAVE_1); break; case NPC_HORDE_SLAVE_2: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_ALLIANCE_SLAVE_2); break; case NPC_HORDE_SLAVE_3: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_ALLIANCE_SLAVE_3); break; case NPC_HORDE_SLAVE_4: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_ALLIANCE_SLAVE_4); break; case NPC_GORKUN_IRONSKULL_1: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_MARTIN_VICTUS_1); break; case NPC_GARFROST: NPC_GarfrostGUID = creature->GetGUID(); break; case NPC_FREED_SLAVE_1_HORDE: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_FREED_SLAVE_1_ALLIANCE); break; case NPC_FREED_SLAVE_2_HORDE: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_FREED_SLAVE_2_ALLIANCE); break; case NPC_FREED_SLAVE_3_HORDE: - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_FREED_SLAVE_3_ALLIANCE); break; case NPC_GORKUN_IRONSKULL_2: @@ -266,7 +208,7 @@ public: c->AI()->DoAction(1); // despawn summons c->DespawnOrUnsummon(); } - if (teamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_MARTIN_VICTUS_2); NPC_MartinOrGorkunGUID = creature->GetGUID(); break; @@ -370,7 +312,7 @@ public: case DATA_INSTANCE_PROGRESS: return InstanceProgress; case DATA_TEAMID_IN_INSTANCE: - return teamIdInInstance; + return GetTeamIdInInstance(); case DATA_GARFROST: return m_auiEncounter[0]; case DATA_ICK: diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 1fcd8bccf..2887192b6 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -218,7 +218,6 @@ public: LoadBossBoundaries(boundaries); LoadObjectData(creatureData, nullptr); LoadDoorData(doorData); - TeamIdInInstance = TEAM_NEUTRAL; HeroicAttempts = MaxHeroicAttempts; IsBonedEligible = true; IsOozeDanceEligible = true; @@ -261,22 +260,7 @@ public: void OnPlayerEnter(Player* player) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = player->GetTeamId(); - } - else - TeamIdInInstance = player->GetTeamId(); - } - - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1); - + InstanceScript::OnPlayerEnter(player); // for professor putricide hc DoRemoveAurasDueToSpellOnPlayers(SPELL_GAS_VARIABLE); DoRemoveAurasDueToSpellOnPlayers(SPELL_OOZE_VARIABLE); @@ -306,32 +290,8 @@ public: } } - void OnPlayerLeave(Player* player) override - { - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFactionForRace(player->getRace()); - } - void OnCreatureCreate(Creature* creature) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.IsEmpty()) - if (Player* player = players.begin()->GetSource()) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = player->GetTeamId(); - } - else - TeamIdInInstance = player->GetTeamId(); - } - } - // apply ICC buff to pets/summons if (GetData(DATA_BUFF_AVAILABLE) && creature->GetOwnerGUID().IsPlayer() && creature->HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_GUARDIAN | UNIT_MASK_CONTROLABLE_GUARDIAN) && creature->CanHaveThreatList()) if (Unit* owner = creature->GetOwner()) @@ -377,39 +337,39 @@ public: switch (creature->GetEntry()) { case NPC_KOR_KRON_GENERAL: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_ALLIANCE_COMMANDER); break; case NPC_KOR_KRON_LIEUTENANT: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_SKYBREAKER_LIEUTENANT); break; case NPC_TORTUNOK: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_ALANA_MOONSTRIKE); break; case NPC_GERARDO_THE_SUAVE: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_TALAN_MOONSTRIKE); break; case NPC_UVLUS_BANEFIRE: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_MALFUS_GRIMFROST); break; case NPC_IKFIRUS_THE_VILE: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_YILI); break; case NPC_VOL_GUK: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_JEDEBIA); break; case NPC_HARAGG_THE_UNSEEN: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_NIBY_THE_ALMIGHTY); break; case NPC_GARROSH_HELLSCREAM: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_KING_VARIAN_WRYNN); // Xinef: summon in case of instance unload @@ -428,7 +388,7 @@ public: DeathbringerSaurfangGUID = creature->GetGUID(); break; case NPC_SE_HIGH_OVERLORD_SAURFANG: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) { creature->UpdateEntry(NPC_SE_MURADIN_BRONZEBEARD, true); creature->LoadEquipment(); @@ -440,14 +400,14 @@ public: DeathbringerSaurfangEventGUID = creature->GetGUID(); break; case NPC_HIGH_OVERLORD_SAURFANG_DUMMY: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) { creature->UpdateEntry(NPC_MURADIN_BRONZEBEARD_DUMMY, creature->GetCreatureData()); creature->LoadEquipment(); } break; case NPC_SE_KOR_KRON_REAVER: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_SE_SKYBREAKER_MARINE); break; case NPC_FESTERGUT: @@ -579,52 +539,34 @@ public: uint32 GetCreatureEntry(ObjectGuid::LowType /*guidLow*/, CreatureData const* data) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.IsEmpty()) - if (Player* player = players.begin()->GetSource()) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = player->GetTeamId(); - } - else - TeamIdInInstance = player->GetTeamId(); - } - } - uint32 entry = data->id1; switch (entry) { case NPC_HORDE_GUNSHIP_CANNON: case NPC_ORGRIMS_HAMMER_CREW: case NPC_SKY_REAVER_KORM_BLACKSCAR: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) return 0; break; case NPC_ALLIANCE_GUNSHIP_CANNON: case NPC_SKYBREAKER_DECKHAND: case NPC_HIGH_CAPTAIN_JUSTIN_BARTLETT: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) return 0; break; case NPC_ZAFOD_BOOMBOX: if (GameObjectTemplate const* go = sObjectMgr->GetGameObjectTemplate(GO_THE_SKYBREAKER_A)) - if ((TeamIdInInstance == TEAM_ALLIANCE && data->mapid == go->moTransport.mapID) || - (TeamIdInInstance == TEAM_HORDE && data->mapid != go->moTransport.mapID)) + if ((GetTeamIdInInstance() == TEAM_ALLIANCE && data->mapid == go->moTransport.mapID) || + (GetTeamIdInInstance() == TEAM_HORDE && data->mapid != go->moTransport.mapID)) return entry; return 0; case NPC_IGB_MURADIN_BRONZEBEARD: - if ((TeamIdInInstance == TEAM_ALLIANCE && data->posX > 10.0f) || - (TeamIdInInstance == TEAM_HORDE && data->posX < 10.0f)) + if ((GetTeamIdInInstance() == TEAM_ALLIANCE && data->posX > 10.0f) || + (GetTeamIdInInstance() == TEAM_HORDE && data->posX < 10.0f)) return entry; return 0; case NPC_SPIRE_FROSTWYRM: - if ((TeamIdInInstance == TEAM_ALLIANCE && data->posY < 2200.0f) || (TeamIdInInstance == TEAM_HORDE && data->posY > 2200.0f)) + if ((GetTeamIdInInstance() == TEAM_ALLIANCE && data->posY < 2200.0f) || (GetTeamIdInInstance() == TEAM_HORDE && data->posY > 2200.0f)) return 0; break; } @@ -634,38 +576,20 @@ public: uint32 GetGameObjectEntry(ObjectGuid::LowType /*guidLow*/, uint32 entry) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.IsEmpty()) - if (Player* player = players.begin()->GetSource()) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = player->GetTeamId(); - } - else - TeamIdInInstance = player->GetTeamId(); - } - } - switch (entry) { case GO_GUNSHIP_ARMORY_H_10N: case GO_GUNSHIP_ARMORY_H_25N: case GO_GUNSHIP_ARMORY_H_10H: case GO_GUNSHIP_ARMORY_H_25H: - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) return 0; break; case GO_GUNSHIP_ARMORY_A_10N: case GO_GUNSHIP_ARMORY_A_25N: case GO_GUNSHIP_ARMORY_A_10H: case GO_GUNSHIP_ARMORY_A_25H: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) return 0; break; } @@ -748,24 +672,6 @@ public: void OnGameObjectCreate(GameObject* go) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.IsEmpty()) - if (Player* player = players.begin()->GetSource()) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = player->GetTeamId(); - } - else - TeamIdInInstance = player->GetTeamId(); - } - } - switch (go->GetEntry()) { case GO_SPIRIT_ALARM_1: @@ -1021,7 +927,7 @@ public: case DATA_COLDFLAME_JETS: return ColdflameJetsState; case DATA_TEAMID_IN_INSTANCE: - return TeamIdInInstance; + return GetTeamIdInInstance(); case DATA_BLOOD_QUICKENING_STATE: return BloodQuickeningState; case DATA_HEROIC_ATTEMPTS: @@ -1315,7 +1221,7 @@ public: if (!GunshipGUID && instance->HavePlayers()) { SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, NOT_STARTED); - uint32 gunshipEntry = TeamIdInInstance == TEAM_HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A; + uint32 gunshipEntry = GetTeamIdInInstance() == TEAM_HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A; if (MotionTransport* gunship = sTransportMgr->CreateTransport(gunshipEntry, 0, instance)) { GunshipGUID = gunship->GetGUID(); @@ -1880,7 +1786,7 @@ public: } break; case EVENT_ENEMY_GUNSHIP_COMBAT: - if (Creature* captain = source->FindNearestCreature(TeamIdInInstance == TEAM_HORDE ? NPC_IGB_HIGH_OVERLORD_SAURFANG : NPC_IGB_MURADIN_BRONZEBEARD, 200.0f)) + if (Creature* captain = source->FindNearestCreature(GetTeamIdInInstance() == TEAM_HORDE ? NPC_IGB_HIGH_OVERLORD_SAURFANG : NPC_IGB_MURADIN_BRONZEBEARD, 200.0f)) { captain->AI()->DoAction(ACTION_ENEMY_GUNSHIP_TALK); } @@ -1900,7 +1806,7 @@ public: //After movement is stopped remove the backpack RemoveBackPack(); } - if (Creature* captain = source->FindNearestCreature(TeamIdInInstance == TEAM_HORDE ? NPC_IGB_HIGH_OVERLORD_SAURFANG : NPC_IGB_MURADIN_BRONZEBEARD, 200.0f)) + if (Creature* captain = source->FindNearestCreature(GetTeamIdInInstance() == TEAM_HORDE ? NPC_IGB_HIGH_OVERLORD_SAURFANG : NPC_IGB_MURADIN_BRONZEBEARD, 200.0f)) captain->AI()->DoAction(ACTION_EXIT_SHIP); break; @@ -2066,7 +1972,6 @@ public: ObjectGuid FrozenBolvarGUID; ObjectGuid PillarsChainedGUID; ObjectGuid PillarsUnchainedGUID; - TeamId TeamIdInInstance; uint32 ColdflameJetsState; std::set FrostwyrmGUIDs; std::set SpinestalkerTrash; diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index 9a959dfa7..f9b1357e1 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -25,6 +25,8 @@ #include "ScriptedCreature.h" #include "naxxramas.h" +static constexpr uint8 HorsemanCount = 4; + const float HeiganPos[2] = {2796, -3707}; const float HeiganEruptionSlope[3] = { @@ -94,13 +96,12 @@ public: PatchwerkRoomTrash.clear(); // Controls - _horsemanKilled = 0; _speakTimer = 0; _horsemanTimer = 0; _screamTimer = 2 * MINUTE * IN_MILLISECONDS; _hadThaddiusGreet = false; _currentWingTaunt = SAY_FIRST_WING_TAUNT; - _horsemanLoadDoneState = false; + _horsemanLoaded = 0; // Achievements abominationsKilled = 0; @@ -167,14 +168,13 @@ public: ObjectGuid _lichkingGUID; // Controls - uint8 _horsemanKilled; uint32 _speakTimer; uint32 _horsemanTimer; uint32 _screamTimer; bool _hadThaddiusGreet; EventMap events; uint8 _currentWingTaunt; - bool _horsemanLoadDoneState; + uint8 _horsemanLoaded; // Achievements uint8 abominationsKilled; @@ -251,15 +251,19 @@ public: return; case NPC_LADY_BLAUMEUX: _blaumeuxGUID = creature->GetGUID(); + ++_horsemanLoaded; return; case NPC_SIR_ZELIEK: _zeliekGUID = creature->GetGUID(); + ++_horsemanLoaded; return; case NPC_BARON_RIVENDARE: _rivendareGUID = creature->GetGUID(); + ++_horsemanLoaded; return; case NPC_THANE_KORTHAZZ: _korthazzGUID = creature->GetGUID(); + ++_horsemanLoaded; return; case NPC_SAPPHIRON: _sapphironGUID = creature->GetGUID(); @@ -272,6 +276,9 @@ public: return; } + if (_horsemanLoaded == HorsemanCount) + SetBossState(BOSS_HORSEMAN, GetBossState(BOSS_HORSEMAN)); + InstanceScript::OnCreatureCreate(creature); } @@ -681,13 +688,25 @@ public: } // Horseman handling - if (bossId == BOSS_HORSEMAN && !_horsemanLoadDoneState) + if (bossId == BOSS_HORSEMAN && _horsemanLoaded == HorsemanCount) { + uint8 horsemanKilled {}; + if (Creature* cr = instance->GetCreature(_blaumeuxGUID)) + horsemanKilled += !cr->IsAlive(); + + if (Creature* cr = instance->GetCreature(_rivendareGUID)) + horsemanKilled += !cr->IsAlive(); + + if (Creature* cr = instance->GetCreature(_zeliekGUID)) + horsemanKilled += !cr->IsAlive(); + + if (Creature* cr = instance->GetCreature(_korthazzGUID)) + horsemanKilled += !cr->IsAlive(); + if (state == DONE) { _horsemanTimer++; - _horsemanKilled++; - if (_horsemanKilled < 4) + if (horsemanKilled < HorsemanCount) { return false; } @@ -699,10 +718,9 @@ public: } // respawn - else if (state == NOT_STARTED && _horsemanKilled > 0) + else if (state == NOT_STARTED && horsemanKilled > 0) { Creature* cr; - _horsemanKilled = 0; if ((cr = instance->GetCreature(_blaumeuxGUID))) { if (!cr->IsAlive()) diff --git a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp index 28c44cedc..f0dd4c766 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp @@ -49,85 +49,40 @@ public: SetHeaders(DataHeader); SetBossNumber(MAX_ENCOUNTERS); LoadDoorData(doorData); - - TeamIdInInstance = TEAM_NEUTRAL; } void OnCreatureCreate(Creature* creature) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.IsEmpty()) - if (Player* pPlayer = players.begin()->GetSource()) - { - if (Group* group = pPlayer->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = pPlayer->GetTeamId(); - } - else - TeamIdInInstance = pPlayer->GetTeamId(); - } - } - switch (creature->GetEntry()) { case NPC_ALLIANCE_RANGER: creature->SetFaction(FACTION_MONSTER_2); - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_HORDE_RANGER); break; case NPC_ALLIANCE_BERSERKER: creature->SetFaction(FACTION_MONSTER_2); - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_HORDE_BERSERKER); break; case NPC_ALLIANCE_COMMANDER: creature->SetFaction(FACTION_MONSTER_2); - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_HORDE_COMMANDER); break; case NPC_ALLIANCE_CLERIC: creature->SetFaction(FACTION_MONSTER_2); - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_HORDE_CLERIC); break; case NPC_COMMANDER_STOUTBEARD: creature->SetFaction(FACTION_MONSTER_2); - if (TeamIdInInstance == TEAM_ALLIANCE) + if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_COMMANDER_KOLURG); break; } } - void OnPlayerEnter(Player* player) override - { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = player->GetTeamId(); - } - else - TeamIdInInstance = player->GetTeamId(); - } - - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1); - } - - void OnPlayerLeave(Player* player) override - { - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFactionForRace(player->getRace()); - } - void OnGameObjectCreate(GameObject* gameObject) override { switch (gameObject->GetEntry()) @@ -194,8 +149,6 @@ public: (*i)->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); return true; } - protected: - TeamId TeamIdInInstance; }; }; diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h index 5b0056ecb..653491b08 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h @@ -33,12 +33,8 @@ enum bloodFurnace DATA_KELIDAN = 2, MAX_ENCOUNTER = 3, - DATA_DOOR1 = 10, - DATA_DOOR2 = 11, - DATA_DOOR3 = 12, DATA_BROGGOK_REAR_DOOR = 13, DATA_BROGGOK_LEVER = 14, - DATA_DOOR6 = 15, DATA_PRISON_CELL1 = 20, DATA_PRISON_CELL2 = 21, @@ -62,7 +58,11 @@ enum BloodFurnaceGO { GO_BROGGOK_DOOR_FRONT = 181822, GO_BROGGOK_DOOR_REAR = 181819, - GO_BROGGOK_LEVER = 181982 + GO_BROGGOK_LEVER = 181982, + GO_KELIDAN_DOOR_EXIT1 = 181823, + GO_KELIDAN_DOOR_EXIT2 = 181766, + GO_MAKER_DOOR_FRONT = 181811, + GO_MAKER_DOOR_REAR = 181812 }; template diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp index 8c7fe50f3..2c662d46a 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp @@ -101,15 +101,10 @@ public: bool OnGossipHello(Player* /*player*/, GameObject* go) override { if (InstanceScript* instance = go->GetInstanceScript()) - { if (instance->GetBossState(DATA_BROGGOK) == NOT_STARTED) - { if (Creature* broggok = instance->GetCreature(DATA_BROGGOK)) - { broggok->AI()->DoAction(ACTION_PREPARE_BROGGOK); - } - } - } + go->UseDoorOrButton(); return false; } diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp index dd13bb88a..84a4c6656 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp @@ -67,10 +67,6 @@ struct boss_kelidan_the_breaker : public BossAI me->SetReactState(REACT_PASSIVE); me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); DoCastSelf(SPELL_EVOCATION); - if (instance) - { - instance->SetData(DATA_KELIDAN, NOT_STARTED); - } } void JustEngagedWith(Unit* /*who*/) override @@ -78,10 +74,7 @@ struct boss_kelidan_the_breaker : public BossAI Talk(SAY_WAKE); _JustEngagedWith(); me->InterruptNonMeleeSpells(false); - if (instance) - { - instance->SetData(DATA_KELIDAN, IN_PROGRESS); - } + scheduler.Schedule(1s, [this](TaskContext context) { DoCastAOE(SPELL_SHADOW_BOLT_VOLLEY); @@ -97,9 +90,7 @@ struct boss_kelidan_the_breaker : public BossAI me->AddAura(SPELL_BURNING_NOVA, me); ApplyImmunities(true); if (IsHeroic()) - { DoCastAOE(SPELL_VORTEX); - } scheduler.DelayGroup(0, 6s); scheduler.Schedule(5s, [this](TaskContext /*context*/) { @@ -112,41 +103,29 @@ struct boss_kelidan_the_breaker : public BossAI void KilledUnit(Unit* /*victim*/) override { if (urand(0, 1)) - { Talk(SAY_KILL); - } } void DoAction(int32 param) override { if (param == ACTION_CHANNELER_DIED) { - if (me->FindNearestCreature(NPC_SHADOWMOON_CHANNELER, 100.0f)) + if (!me->FindNearestCreature(NPC_SHADOWMOON_CHANNELER, 100.0f)) { - return; + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); } - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_AGGRESSIVE); - me->SetInCombatWithZone(); } - else if (param == ACTION_CHANNELER_AGGRO) - { Talk(SAY_ADD_AGGRO); - } } void JustDied(Unit* /*killer*/) override { Talk(SAY_DIE); _JustDied(); - if (instance) - { - me->GetMap()->LoadGrid(0, -111.0f); - instance->SetData(DATA_KELIDAN, DONE); - instance->HandleGameObject(instance->GetGuidData(DATA_DOOR1), true); - instance->HandleGameObject(instance->GetGuidData(DATA_DOOR6), true); - } + me->GetMap()->LoadGrid(0, -111.0f); } void ApplyImmunities(bool apply) diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_the_maker.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_the_maker.cpp index 8494992f7..125c9c36f 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_the_maker.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_the_maker.cpp @@ -42,22 +42,10 @@ struct boss_the_maker : public BossAI }); } - void Reset() override - { - _Reset(); - if (instance) - { - instance->SetData(DATA_THE_MAKER, NOT_STARTED); - instance->HandleGameObject(instance->GetGuidData(DATA_DOOR2), true); - } - } - void JustEngagedWith(Unit* /*who*/) override { Talk(SAY_AGGRO); _JustEngagedWith(); - instance->SetData(DATA_THE_MAKER, IN_PROGRESS); - instance->HandleGameObject(instance->GetGuidData(DATA_DOOR2), false); scheduler.Schedule(6s, [this](TaskContext context) { DoCastRandomTarget(SPELL_EXPLODING_BEAKER); @@ -72,30 +60,13 @@ struct boss_the_maker : public BossAI void KilledUnit(Unit* victim) override { if (victim->IsPlayer() && urand(0, 1)) - { Talk(SAY_KILL); - } } void JustDied(Unit* /*killer*/) override { Talk(SAY_DIE); _JustDied(); - instance->SetData(DATA_THE_MAKER, DONE); - instance->HandleGameObject(instance->GetGuidData(DATA_DOOR2), true); - instance->HandleGameObject(instance->GetGuidData(DATA_DOOR3), true); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - scheduler.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp index d429e6d84..d036e002a 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp @@ -22,9 +22,13 @@ DoorData const doorData[] = { - { GO_BROGGOK_DOOR_FRONT, DATA_BROGGOK, DOOR_TYPE_ROOM }, - { GO_BROGGOK_DOOR_REAR, DATA_BROGGOK, DOOR_TYPE_PASSAGE }, - { 0, 0, DOOR_TYPE_ROOM } // END + { GO_MAKER_DOOR_FRONT, DATA_THE_MAKER, DOOR_TYPE_ROOM }, + { GO_MAKER_DOOR_REAR, DATA_THE_MAKER, DOOR_TYPE_PASSAGE }, + { GO_BROGGOK_DOOR_FRONT, DATA_BROGGOK, DOOR_TYPE_ROOM }, + { GO_BROGGOK_DOOR_REAR, DATA_BROGGOK, DOOR_TYPE_PASSAGE }, + { GO_KELIDAN_DOOR_EXIT1, DATA_KELIDAN, DOOR_TYPE_PASSAGE }, + { GO_KELIDAN_DOOR_EXIT2, DATA_KELIDAN, DOOR_TYPE_PASSAGE }, + { 0, 0, DOOR_TYPE_ROOM } // END }; ObjectData const gameobjectData[] = @@ -56,26 +60,15 @@ public: LoadObjectData(creatureData, gameobjectData); } - uint32 _auiEncounter[MAX_ENCOUNTER]; - ObjectGuid _doorGUIDs[6]; - ObjectGuid _prisonGUIDs[4]; - - GuidSet _prisonersCell[4]; - - uint8 _prisonerCounter[4]; - void Initialize() override { - memset(&_auiEncounter, 0, sizeof(_auiEncounter)); memset(&_prisonerCounter, 0, sizeof(_prisonerCounter)); } void OnCreatureCreate(Creature* creature) override { if (creature->GetEntry() == NPC_NASCENT_FEL_ORC) - { StorePrisoner(creature); - } InstanceScript::OnCreatureCreate(creature); } @@ -88,20 +81,6 @@ public: void OnGameObjectCreate(GameObject* go) override { - if (go->GetEntry() == 181766) //Final exit door - _doorGUIDs[0] = go->GetGUID(); - if (go->GetEntry() == 181811) //The Maker Front door - _doorGUIDs[1] = go->GetGUID(); - if (go->GetEntry() == 181812) //The Maker Rear door - { - _doorGUIDs[2] = go->GetGUID(); - if (GetData(DATA_THE_MAKER) == DONE) - HandleGameObject(go->GetGUID(), true); - } - - if (go->GetEntry() == 181823) //Kelidan exit door - _doorGUIDs[5] = go->GetGUID(); - if (go->GetEntry() == 181821) //Broggok prison cell front right _prisonGUIDs[0] = go->GetGUID(); if (go->GetEntry() == 181818) //Broggok prison cell back right @@ -118,12 +97,6 @@ public: { switch (data) { - case DATA_DOOR1: - case DATA_DOOR2: - case DATA_DOOR3: - case DATA_DOOR6: - return _doorGUIDs[data - DATA_DOOR1]; - case DATA_PRISON_CELL1: case DATA_PRISON_CELL2: case DATA_PRISON_CELL3: @@ -142,50 +115,17 @@ public: if (type == DATA_BROGGOK) { if (state == IN_PROGRESS) - { ActivateCell(DATA_PRISON_CELL1); - HandleGameObject(_doorGUIDs[3], false); - } else if (state == NOT_STARTED) { ResetPrisons(); - HandleGameObject(_doorGUIDs[4], false); - HandleGameObject(_doorGUIDs[3], true); - if (GameObject* lever = GetGameObject(DATA_BROGGOK_LEVER)) - { - lever->Respawn(); - } + DoRespawnGameObject(DATA_BROGGOK_LEVER); } } return true; } - void SetData(uint32 type, uint32 data) override - { - switch (type) - { - case DATA_THE_MAKER: - case DATA_KELIDAN: - _auiEncounter[type] = data; - break; - } - - if (data == DONE) - SaveToDB(); - } - - uint32 GetData(uint32 type) const override - { - switch (type) - { - case DATA_THE_MAKER: - case DATA_KELIDAN: - return _auiEncounter[type]; - } - return 0; - } - void ResetPrisons() { for (uint8 i = 0; i < 4; ++i) @@ -273,13 +213,9 @@ public: break; case DATA_BROGGOK_REAR_DOOR: if (GameObject* go = GetGameObject(DATA_BROGGOK_REAR_DOOR)) - { HandleGameObject(ObjectGuid::Empty, true, go); - } if (Creature* broggok = GetCreature(DATA_BROGGOK)) - { broggok->AI()->DoAction(ACTION_ACTIVATE_BROGGOK); - } break; } } @@ -294,6 +230,11 @@ public: prisoner->SetInCombatWithZone(); } } + + private: + ObjectGuid _prisonGUIDs[4]; + GuidSet _prisonersCell[4]; + uint8 _prisonerCounter[4]; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp index 1a137d590..2ed91f6f9 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp @@ -59,56 +59,11 @@ public: SetBossNumber(ENCOUNTER_COUNT); LoadObjectData(creatureData, nullptr); LoadDoorData(doorData); - - TeamIdInInstance = TEAM_NEUTRAL; RescueTimer = 100 * MINUTE * IN_MILLISECONDS; } - void OnPlayerEnter(Player* player) override - { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = player->GetTeamId(); - } - else - TeamIdInInstance = player->GetTeamId(); - } - - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1); - } - - void OnPlayerLeave(Player* player) override - { - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - player->SetFactionForRace(player->getRace()); - } - void OnCreatureCreate(Creature* creature) override { - if (TeamIdInInstance == TEAM_NEUTRAL) - { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.IsEmpty()) - if (Player* player = players.begin()->GetSource()) - { - if (Group* group = player->GetGroup()) - { - if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) - TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace()); - else - TeamIdInInstance = player->GetTeamId(); - } - else - TeamIdInInstance = player->GetTeamId(); - } - } - switch (creature->GetEntry()) { case NPC_SHATTERED_EXECUTIONER: @@ -117,22 +72,22 @@ public: ExecutionerGUID = creature->GetGUID(); break; case NPC_RIFLEMAN_BROWNBEARD: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_KORAG_PROUDMANE); PrisonerGUID[0] = creature->GetGUID(); break; case NPC_CAPTAIN_ALINA: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_CAPTAIN_BONESHATTER); PrisonerGUID[1] = creature->GetGUID(); break; case NPC_PRIVATE_JACINT: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_SCOUT_ORGARR); PrisonerGUID[2] = creature->GetGUID(); break; case NPC_RANDY_WHIZZLESPROCKET: - if (TeamIdInInstance == TEAM_HORDE) + if (GetTeamIdInInstance() == TEAM_HORDE) creature->UpdateEntry(NPC_DRISELLA); break; } @@ -147,7 +102,7 @@ public: instance->LoadGrid(230, -80); if (Creature* kargath = GetCreature(DATA_KARGATH)) - sCreatureTextMgr->SendChat(kargath, TeamIdInInstance == TEAM_ALLIANCE ? 3 : 4, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); + sCreatureTextMgr->SendChat(kargath, GetTeamIdInInstance() == TEAM_ALLIANCE ? 3 : 4, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); RescueTimer = 80 * MINUTE * IN_MILLISECONDS; } @@ -213,7 +168,6 @@ public: ObjectGuid ExecutionerGUID; ObjectGuid PrisonerGUID[3]; uint32 RescueTimer; - TeamId TeamIdInInstance; }; };