diff options
Diffstat (limited to 'src/server/scripts')
195 files changed, 6951 insertions, 3346 deletions
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index a15b6f8ad07..31ba073e77d 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -8,138 +8,232 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# Enable precompiled headers when using the GCC compiler. +message("") -if (USE_SCRIPTPCH) - set(scripts_STAT_PCH_HDR PrecompiledHeaders/ScriptPCH.h) - set(scripts_STAT_PCH_SRC PrecompiledHeaders/ScriptPCH.cpp) -endif () +# Make the script module list available in the current scope +GetScriptModuleList(SCRIPT_MODULE_LIST) + +# Make the native install offset available in this scope +GetInstallOffset(INSTALL_OFFSET) -message(STATUS "SCRIPT PREPARATIONS") -include(Spells/CMakeLists.txt) - -include(Commands/CMakeLists.txt) - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - ../game/AI/ScriptedAI/ScriptedEscortAI.cpp - ../game/AI/ScriptedAI/ScriptedCreature.cpp - ../game/AI/ScriptedAI/ScriptedFollowerAI.cpp - ../game/Maps/AreaBoundary.cpp -) - -if(SCRIPTS) - include(Custom/CMakeLists.txt) - include(World/CMakeLists.txt) - include(OutdoorPvP/CMakeLists.txt) - include(EasternKingdoms/CMakeLists.txt) - include(Kalimdor/CMakeLists.txt) - include(Outland/CMakeLists.txt) - include(Northrend/CMakeLists.txt) - include(Events/CMakeLists.txt) - include(Pet/CMakeLists.txt) +# Sets the SCRIPTS_${SCRIPT_MODULE} variables +# when using predefined templates for script building +# like dynamic, static, minimal-static... +# Sets SCRIPTS_DEFAULT_LINKAGE +if (SCRIPTS MATCHES "dynamic") + set(SCRIPTS_DEFAULT_LINKAGE "dynamic") +elseif(SCRIPTS MATCHES "static") + set(SCRIPTS_DEFAULT_LINKAGE "static") +else() + set(SCRIPTS_DEFAULT_LINKAGE "disabled") +endif() +# Sets SCRIPTS_USE_WHITELIST +# Sets SCRIPTS_WHITELIST +if (SCRIPTS MATCHES "minimal") + set(SCRIPTS_USE_WHITELIST ON) + # Whitelist which is used when minimal is selected + list(APPEND SCRIPTS_WHITELIST Commands Spells) endif() -message(STATUS "SCRIPT PREPARATION COMPLETE") -message("") +# Set the SCRIPTS_${SCRIPT_MODULE} variables from the +# variables set above +foreach(SCRIPT_MODULE ${SCRIPT_MODULE_LIST}) + ScriptModuleNameToVariable(${SCRIPT_MODULE} SCRIPT_MODULE_VARIABLE) + if (${SCRIPT_MODULE_VARIABLE} STREQUAL "default") + if(SCRIPTS_USE_WHITELIST) + list(FIND SCRIPTS_WHITELIST "${SCRIPT_MODULE}" INDEX) + if (${INDEX} GREATER -1) + set(${SCRIPT_MODULE_VARIABLE} ${SCRIPTS_DEFAULT_LINKAGE}) + else() + set(${SCRIPT_MODULE_VARIABLE} "disabled") + endif() + else() + set(${SCRIPT_MODULE_VARIABLE} ${SCRIPTS_DEFAULT_LINKAGE}) + endif() + endif() + # Build the Graph values + if (${SCRIPT_MODULE_VARIABLE} MATCHES "dynamic") + GetProjectNameOfScriptModule(${SCRIPT_MODULE} SCRIPT_MODULE_PROJECT_NAME) + GetNativeSharedLibraryName(${SCRIPT_MODULE_PROJECT_NAME} SCRIPT_PROJECT_LIBRARY) + list(APPEND GRAPH_KEYS ${SCRIPT_MODULE_PROJECT_NAME}) + set(GRAPH_VALUE_DISPLAY_${SCRIPT_MODULE_PROJECT_NAME} ${SCRIPT_PROJECT_LIBRARY}) + list(APPEND GRAPH_VALUE_CONTAINS_MODULES_${SCRIPT_MODULE_PROJECT_NAME} ${SCRIPT_MODULE}) + elseif(${SCRIPT_MODULE_VARIABLE} MATCHES "static") + list(APPEND GRAPH_KEYS worldserver) + set(GRAPH_VALUE_DISPLAY_worldserver worldserver) + list(APPEND GRAPH_VALUE_CONTAINS_MODULES_worldserver ${SCRIPT_MODULE}) + else() + list(APPEND GRAPH_KEYS disabled) + set(GRAPH_VALUE_DISPLAY_disabled disabled) + list(APPEND GRAPH_VALUE_CONTAINS_MODULES_disabled ${SCRIPT_MODULE}) + endif() +endforeach() + +list(SORT GRAPH_KEYS) +list(REMOVE_DUPLICATES GRAPH_KEYS) -include_directories( - ${CMAKE_SOURCE_DIR}/dep/cppformat - ${CMAKE_SOURCE_DIR}/dep/g3dlite/include - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include - ${CMAKE_SOURCE_DIR}/src/common/ - ${CMAKE_SOURCE_DIR}/src/common/Collision - ${CMAKE_SOURCE_DIR}/src/common/Collision/Management - ${CMAKE_SOURCE_DIR}/src/common/Collision/Maps - ${CMAKE_SOURCE_DIR}/src/common/Collision/Models - ${CMAKE_SOURCE_DIR}/src/common/Configuration - ${CMAKE_SOURCE_DIR}/src/common/Debugging - ${CMAKE_SOURCE_DIR}/src/common/Logging - ${CMAKE_SOURCE_DIR}/src/common/Threading - ${CMAKE_SOURCE_DIR}/src/common/Utilities - ${CMAKE_SOURCE_DIR}/src/server/database/Database - ${CMAKE_SOURCE_DIR}/src/server/game/Accounts - ${CMAKE_SOURCE_DIR}/src/server/game/Achievements - ${CMAKE_SOURCE_DIR}/src/server/game/Addons - ${CMAKE_SOURCE_DIR}/src/server/game/AI - ${CMAKE_SOURCE_DIR}/src/server/game/AI/CoreAI - ${CMAKE_SOURCE_DIR}/src/server/game/AI/ScriptedAI - ${CMAKE_SOURCE_DIR}/src/server/game/AI/SmartScripts - ${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouse - ${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouseBot - ${CMAKE_SOURCE_DIR}/src/server/game/Battlefield - ${CMAKE_SOURCE_DIR}/src/server/game/Battlefield/Zones - ${CMAKE_SOURCE_DIR}/src/server/game/Battlegrounds - ${CMAKE_SOURCE_DIR}/src/server/game/Battlegrounds/Zones - ${CMAKE_SOURCE_DIR}/src/server/game/Chat - ${CMAKE_SOURCE_DIR}/src/server/game/Chat/Channels - ${CMAKE_SOURCE_DIR}/src/server/game/Combat - ${CMAKE_SOURCE_DIR}/src/server/game/Conditions - ${CMAKE_SOURCE_DIR}/src/server/game/DataStores - ${CMAKE_SOURCE_DIR}/src/server/game/DungeonFinding - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Corpse - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Creature - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/DynamicObject - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/GameObject - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item/Container - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object/Updates - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Pet - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Player - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Transport - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Unit - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Vehicle - ${CMAKE_SOURCE_DIR}/src/server/game/Events - ${CMAKE_SOURCE_DIR}/src/server/game/Globals - ${CMAKE_SOURCE_DIR}/src/server/game/Grids - ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells - ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Notifiers - ${CMAKE_SOURCE_DIR}/src/server/game/Groups - ${CMAKE_SOURCE_DIR}/src/server/game/Guilds - ${CMAKE_SOURCE_DIR}/src/server/game/Handlers - ${CMAKE_SOURCE_DIR}/src/server/game/Instances - ${CMAKE_SOURCE_DIR}/src/server/game/Loot - ${CMAKE_SOURCE_DIR}/src/server/game/Mails - ${CMAKE_SOURCE_DIR}/src/server/game/Maps - ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous - ${CMAKE_SOURCE_DIR}/src/server/game/Movement - ${CMAKE_SOURCE_DIR}/src/server/game/Movement/MovementGenerators - ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Spline - ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints - ${CMAKE_SOURCE_DIR}/src/server/game/OutdoorPvP - ${CMAKE_SOURCE_DIR}/src/server/game/Pools - ${CMAKE_SOURCE_DIR}/src/server/game/Quests - ${CMAKE_SOURCE_DIR}/src/server/game/Reputation - ${CMAKE_SOURCE_DIR}/src/server/game/Scripting - ${CMAKE_SOURCE_DIR}/src/server/game/Server - ${CMAKE_SOURCE_DIR}/src/server/game/Server/Protocol - ${CMAKE_SOURCE_DIR}/src/server/game/Skills - ${CMAKE_SOURCE_DIR}/src/server/game/Spells - ${CMAKE_SOURCE_DIR}/src/server/game/Spells/Auras - ${CMAKE_SOURCE_DIR}/src/server/game/Texts - ${CMAKE_SOURCE_DIR}/src/server/game/Tickets - ${CMAKE_SOURCE_DIR}/src/server/game/Tools - ${CMAKE_SOURCE_DIR}/src/server/game/Warden - ${CMAKE_SOURCE_DIR}/src/server/game/Weather - ${CMAKE_SOURCE_DIR}/src/server/game/World - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/src/server/shared/DataStores - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference - ${CMAKE_SOURCE_DIR}/src/server/shared/Packets - ${MYSQL_INCLUDE_DIR} - ${VALGRIND_INCLUDE_DIR} -) +# Display the script graph +message("* Script configuration (${SCRIPTS}): + |") + +foreach(GRAPH_KEY ${GRAPH_KEYS}) + if (NOT GRAPH_KEY STREQUAL "disabled") + message(" +- ${GRAPH_VALUE_DISPLAY_${GRAPH_KEY}}") + else() + message(" | ${GRAPH_VALUE_DISPLAY_${GRAPH_KEY}}") + endif() + foreach(GRAPH_PROJECT_ENTRY ${GRAPH_VALUE_CONTAINS_MODULES_${GRAPH_KEY}}) + message(" | +- ${GRAPH_PROJECT_ENTRY}") + endforeach() + message(" |") +endforeach() + +# Base sources which are used by every script project +if (USE_SCRIPTPCH) + set(PRIVATE_PCH_HEADER ScriptPCH.h) + set(PRIVATE_PCH_SOURCE ScriptPCH.cpp) +endif () GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) +# Configures the scriptloader with the given name and stores the output in the LOADER_OUT variable. +# It is possible to expose multiple subdirectories from the same scriptloader through passing +# it to the variable arguments +function(ConfigureScriptLoader SCRIPTLOADER_NAME LOADER_OUT IS_DYNAMIC_SCRIPTLOADER) + # Deduces following variables which are referenced by thge template: + # TRINITY_IS_DYNAMIC_SCRIPTLOADER + # TRINITY_SCRIPTS_FORWARD_DECL + # TRINITY_SCRIPTS_INVOKE + # TRINITY_CURRENT_SCRIPT_PROJECT + + # To generate export macros + set(TRINITY_IS_DYNAMIC_SCRIPTLOADER ${IS_DYNAMIC_SCRIPTLOADER}) + # To generate forward declarations of the loading functions + unset(TRINITY_SCRIPTS_FORWARD_DECL) + unset(TRINITY_SCRIPTS_INVOKE) + # The current script project which is built in + set(TRINITY_CURRENT_SCRIPT_PROJECT ${SCRIPTLOADER_NAME}) + foreach(LOCALE_SCRIPT_MODULE ${ARGN}) + # Determine the loader function ("Add##${NameOfDirectory}##Scripts()") + set(LOADER_FUNCTION + "Add${LOCALE_SCRIPT_MODULE}Scripts()") + # Generate the funciton call and the forward declarations + set(TRINITY_SCRIPTS_FORWARD_DECL + "${TRINITY_SCRIPTS_FORWARD_DECL}void ${LOADER_FUNCTION};\n") + set(TRINITY_SCRIPTS_INVOKE + "${TRINITY_SCRIPTS_INVOKE} ${LOADER_FUNCTION};\n") + endforeach() + set(GENERATED_LOADER ${CMAKE_CURRENT_BINARY_DIR}/gen_scriptloader/${SCRIPTLOADER_NAME}/ScriptLoader.cpp) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ScriptLoader.cpp.in.cmake ${GENERATED_LOADER}) + set(${LOADER_OUT} ${GENERATED_LOADER} PARENT_SCOPE) +endfunction() + +# Generates the actual script projects +# Fills the STATIC_SCRIPT_MODULES and DYNAMIC_SCRIPT_MODULE_PROJECTS variables +# which contain the names which scripts are linked statically/dynamically and +# adds the sources of the static modules to the PRIVATE_SOURCES variable. +foreach(SCRIPT_MODULE ${SCRIPT_MODULE_LIST}) + GetPathToScriptModule(${SCRIPT_MODULE} SCRIPT_MODULE_PATH) + ScriptModuleNameToVariable(${SCRIPT_MODULE} SCRIPT_MODULE_VARIABLE) + + if ((${SCRIPT_MODULE_VARIABLE} STREQUAL "disabled") OR + (${SCRIPT_MODULE_VARIABLE} STREQUAL "static")) + # Uninstall disabled modules + GetProjectNameOfScriptModule(${SCRIPT_MODULE} SCRIPT_MODULE_PROJECT_NAME) + GetNativeSharedLibraryName(${SCRIPT_MODULE_PROJECT_NAME} SCRIPT_MODULE_OUTPUT_NAME) + list(APPEND DISABLED_SCRIPT_MODULE_PROJECTS ${INSTALL_OFFSET}/${SCRIPT_MODULE_OUTPUT_NAME}) + if (${SCRIPT_MODULE_VARIABLE} STREQUAL "static") + # Add the module name to STATIC_SCRIPT_MODULES + list(APPEND STATIC_SCRIPT_MODULES ${SCRIPT_MODULE}) + # Add the module content to the whole static module + CollectSourceFiles(${SCRIPT_MODULE_PATH} PRIVATE_SOURCES) + endif() + elseif(${SCRIPT_MODULE_VARIABLE} STREQUAL "dynamic") + # Generate an own dynamic module which is loadable on runtime + # Add the module content to the whole static module + unset(SCRIPT_MODULE_PRIVATE_SOURCES) + CollectSourceFiles(${SCRIPT_MODULE_PATH} SCRIPT_MODULE_PRIVATE_SOURCES) + # Configure the scriptloader + ConfigureScriptLoader(${SCRIPT_MODULE} SCRIPT_MODULE_PRIVATE_SCRIPTLOADER ON ${SCRIPT_MODULE}) + GetProjectNameOfScriptModule(${SCRIPT_MODULE} SCRIPT_MODULE_PROJECT_NAME) + # Add the module name to DYNAMIC_SCRIPT_MODULES + list(APPEND DYNAMIC_SCRIPT_MODULE_PROJECTS ${SCRIPT_MODULE_PROJECT_NAME}) + # Create the script module project + add_library(${SCRIPT_MODULE_PROJECT_NAME} SHARED + ${PRIVATE_PCH_SOURCE} + ${SCRIPT_MODULE_PRIVATE_SOURCES} + ${SCRIPT_MODULE_PRIVATE_SCRIPTLOADER}) + target_link_libraries(${SCRIPT_MODULE_PROJECT_NAME} + PUBLIC + game) + set_target_properties(${SCRIPT_MODULE_PROJECT_NAME} + PROPERTIES + FOLDER + "scripts") + + if(UNIX) + install(TARGETS ${SCRIPT_MODULE_PROJECT_NAME} + DESTINATION ${INSTALL_OFFSET} + COMPONENT ${SCRIPT_MODULE_PROJECT_NAME}) + elseif(WIN32) + install(TARGETS ${SCRIPT_MODULE_PROJECT_NAME} + RUNTIME DESTINATION ${INSTALL_OFFSET} + COMPONENT ${SCRIPT_MODULE_PROJECT_NAME}) + if(MSVC) + # Place the script modules in the script subdirectory + set_target_properties(${SCRIPT_MODULE_PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin/Debug/scripts + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin/Release/scripts + RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}/bin/RelWithDebInfo/scripts + RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_BINARY_DIR}/bin/MinSizeRel/scripts) + endif() + endif() + else() + message(FATAL_ERROR "Unknown value \"${${SCRIPT_MODULE_VARIABLE}}\"!") + endif() +endforeach() + +# Add the dynamic script modules to the worldserver as dependency +set(WORLDSERVER_DYNAMIC_SCRIPT_MODULES_DEPENDENCIES ${DYNAMIC_SCRIPT_MODULE_PROJECTS} PARENT_SCOPE) + +ConfigureScriptLoader("static" SCRIPT_MODULE_PRIVATE_SCRIPTLOADER OFF ${STATIC_SCRIPT_MODULES}) + add_library(scripts STATIC - ${scripts_STAT_SRCS} - ${scripts_STAT_PCH_SRC} -) + ScriptLoader.h + ${PRIVATE_PCH_SOURCE} + ${SCRIPT_MODULE_PRIVATE_SCRIPTLOADER} + ${PRIVATE_SOURCES}) + +target_link_libraries(scripts + PUBLIC + game-interface) + +target_include_directories(scripts + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}) + +set_target_properties(scripts + PROPERTIES + FOLDER + "scripts") # Generate precompiled header if (USE_SCRIPTPCH) - add_cxx_pch(scripts ${scripts_STAT_PCH_HDR} ${scripts_STAT_PCH_SRC}) + list(APPEND ALL_SCRIPT_PROJECTS scripts ${DYNAMIC_SCRIPT_MODULE_PROJECTS}) + add_cxx_pch("${ALL_SCRIPT_PROJECTS}" ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE}) +endif() + +# Remove all shared libraries in the installl directory which +# are contained in the static library already. +if (DISABLED_SCRIPT_MODULE_PROJECTS) + install(CODE " + foreach(SCRIPT_TO_UNINSTALL ${DISABLED_SCRIPT_MODULE_PROJECTS}) + if (EXISTS \"\${SCRIPT_TO_UNINSTALL}\") + message(STATUS \"Uninstalling: \${SCRIPT_TO_UNINSTALL}\") + file(REMOVE \"\${SCRIPT_TO_UNINSTALL}\") + endif() + endforeach() + ") endif() + +message("") diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt deleted file mode 100644 index d4d75cd175f..00000000000 --- a/src/server/scripts/Commands/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -file(GLOB_RECURSE sources_Commands Commands/*.cpp Commands/*.h) - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - ${sources_Commands} -) - -message(" -> Prepared: Commands") diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index f25e91ee3e6..4bce2d168a9 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -121,10 +121,16 @@ public: if (!accountName || !password) return false; - AccountOpResult result = sAccountMgr->CreateAccount(std::string(accountName), std::string(password), email); - switch (result) + if (strchr(accountName, '@')) + { + handler->PSendSysMessage(LANG_ACCOUNT_USE_BNET_COMMANDS); + handler->SetSentErrorMessage(true); + return false; + } + + switch (sAccountMgr->CreateAccount(std::string(accountName), std::string(password), email)) { - case AOR_OK: + case AccountOpResult::AOR_OK: handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName); if (handler->GetSession()) { @@ -134,15 +140,15 @@ public: accountName, email.c_str()); } break; - case AOR_NAME_TOO_LONG: + case AccountOpResult::AOR_NAME_TOO_LONG: handler->SendSysMessage(LANG_ACCOUNT_TOO_LONG); handler->SetSentErrorMessage(true); return false; - case AOR_NAME_ALREADY_EXIST: + case AccountOpResult::AOR_NAME_ALREADY_EXIST: handler->SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); handler->SetSentErrorMessage(true); return false; - case AOR_DB_INTERNAL_ERROR: + case AccountOpResult::AOR_DB_INTERNAL_ERROR: handler->PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR, accountName); handler->SetSentErrorMessage(true); return false; @@ -168,7 +174,7 @@ public: return false; std::string accountName = account; - if (!AccountMgr::normalizeString(accountName)) + if (!Utf8ToUpperOnlyLatin(accountName)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); @@ -192,14 +198,14 @@ public: AccountOpResult result = AccountMgr::DeleteAccount(accountId); switch (result) { - case AOR_OK: + case AccountOpResult::AOR_OK: handler->PSendSysMessage(LANG_ACCOUNT_DELETED, accountName.c_str()); break; - case AOR_NAME_NOT_EXIST: + case AccountOpResult::AOR_NAME_NOT_EXIST: handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); return false; - case AOR_DB_INTERNAL_ERROR: + case AccountOpResult::AOR_DB_INTERNAL_ERROR: handler->PSendSysMessage(LANG_ACCOUNT_NOT_DELETED_SQL_ERROR, accountName.c_str()); handler->SetSentErrorMessage(true); return false; @@ -415,7 +421,7 @@ public: AccountOpResult result = AccountMgr::ChangeEmail(handler->GetSession()->GetAccountId(), std::string(email)); switch (result) { - case AOR_OK: + case AccountOpResult::AOR_OK: handler->SendSysMessage(LANG_COMMAND_EMAIL); sScriptMgr->OnEmailChange(handler->GetSession()->GetAccountId()); TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Changed Email from [%s] to [%s].", @@ -423,7 +429,7 @@ public: handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().GetCounter(), oldEmail, email); break; - case AOR_EMAIL_TOO_LONG: + case AccountOpResult::AOR_EMAIL_TOO_LONG: handler->SendSysMessage(LANG_EMAIL_TOO_LONG); sScriptMgr->OnFailedEmailChange(handler->GetSession()->GetAccountId()); handler->SetSentErrorMessage(true); @@ -505,14 +511,14 @@ public: AccountOpResult result = AccountMgr::ChangePassword(handler->GetSession()->GetAccountId(), std::string(newPassword)); switch (result) { - case AOR_OK: + case AccountOpResult::AOR_OK: handler->SendSysMessage(LANG_COMMAND_PASSWORD); sScriptMgr->OnPasswordChange(handler->GetSession()->GetAccountId()); TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Changed Password.", handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().GetCounter()); break; - case AOR_PASS_TOO_LONG: + case AccountOpResult::AOR_PASS_TOO_LONG: handler->SendSysMessage(LANG_PASSWORD_TOO_LONG); sScriptMgr->OnFailedPasswordChange(handler->GetSession()->GetAccountId()); handler->SetSentErrorMessage(true); @@ -592,7 +598,7 @@ public: { ///- Convert Account name to Upper Format accountName = account; - if (!AccountMgr::normalizeString(accountName)) + if (!Utf8ToUpperOnlyLatin(accountName)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); @@ -662,7 +668,7 @@ public: if (isAccountNameGiven) { targetAccountName = arg1; - if (!AccountMgr::normalizeString(targetAccountName) || !AccountMgr::GetId(targetAccountName)) + if (!Utf8ToUpperOnlyLatin(targetAccountName) || !AccountMgr::GetId(targetAccountName)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, targetAccountName.c_str()); handler->SetSentErrorMessage(true); @@ -750,7 +756,7 @@ public: return false; std::string accountName = account; - if (!AccountMgr::normalizeString(accountName)) + if (!Utf8ToUpperOnlyLatin(accountName)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); @@ -781,14 +787,14 @@ public: switch (result) { - case AOR_OK: + case AccountOpResult::AOR_OK: handler->SendSysMessage(LANG_COMMAND_PASSWORD); break; - case AOR_NAME_NOT_EXIST: + case AccountOpResult::AOR_NAME_NOT_EXIST: handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); return false; - case AOR_PASS_TOO_LONG: + case AccountOpResult::AOR_PASS_TOO_LONG: handler->SendSysMessage(LANG_PASSWORD_TOO_LONG); handler->SetSentErrorMessage(true); return false; @@ -819,7 +825,7 @@ public: } std::string accountName = account; - if (!AccountMgr::normalizeString(accountName)) + if (!Utf8ToUpperOnlyLatin(accountName)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); @@ -849,16 +855,16 @@ public: AccountOpResult result = AccountMgr::ChangeEmail(targetAccountId, email); switch (result) { - case AOR_OK: + case AccountOpResult::AOR_OK: handler->SendSysMessage(LANG_COMMAND_EMAIL); TC_LOG_INFO("entities.player.character", "ChangeEmail: Account %s [Id: %u] had it's email changed to %s.", accountName.c_str(), targetAccountId, email); break; - case AOR_NAME_NOT_EXIST: + case AccountOpResult::AOR_NAME_NOT_EXIST: handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); return false; - case AOR_EMAIL_TOO_LONG: + case AccountOpResult::AOR_EMAIL_TOO_LONG: handler->SendSysMessage(LANG_EMAIL_TOO_LONG); handler->SetSentErrorMessage(true); return false; @@ -895,7 +901,7 @@ public: } std::string accountName = account; - if (!AccountMgr::normalizeString(accountName)) + if (!Utf8ToUpperOnlyLatin(accountName)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); @@ -925,16 +931,16 @@ public: AccountOpResult result = AccountMgr::ChangeRegEmail(targetAccountId, email); switch (result) { - case AOR_OK: + case AccountOpResult::AOR_OK: handler->SendSysMessage(LANG_COMMAND_EMAIL); TC_LOG_INFO("entities.player.character", "ChangeRegEmail: Account %s [Id: %u] had it's Registration Email changed to %s.", accountName.c_str(), targetAccountId, email); break; - case AOR_NAME_NOT_EXIST: + case AccountOpResult::AOR_NAME_NOT_EXIST: handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); return false; - case AOR_EMAIL_TOO_LONG: + case AccountOpResult::AOR_EMAIL_TOO_LONG: handler->SendSysMessage(LANG_EMAIL_TOO_LONG); handler->SetSentErrorMessage(true); return false; diff --git a/src/server/scripts/Commands/cs_ahbot.cpp b/src/server/scripts/Commands/cs_ahbot.cpp index 65e90394261..47553d085b1 100644 --- a/src/server/scripts/Commands/cs_ahbot.cpp +++ b/src/server/scripts/Commands/cs_ahbot.cpp @@ -33,7 +33,7 @@ class ahbot_commandscript : public CommandScript public: ahbot_commandscript(): CommandScript("ahbot_commandscript") {} - std::vector<ChatCommand> GetCommands() const + std::vector<ChatCommand> GetCommands() const override { static std::vector<ChatCommand> ahbotItemsAmountCommandTable = { diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp index 4a1bf71e1d8..ba512dbf8eb 100644 --- a/src/server/scripts/Commands/cs_ban.cpp +++ b/src/server/scripts/Commands/cs_ban.cpp @@ -171,7 +171,7 @@ public: switch (mode) { case BAN_ACCOUNT: - if (!AccountMgr::normalizeString(nameOrIP)) + if (!Utf8ToUpperOnlyLatin(nameOrIP)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, nameOrIP.c_str()); handler->SetSentErrorMessage(true); @@ -244,7 +244,7 @@ public: return false; std::string accountName = nameStr; - if (!AccountMgr::normalizeString(accountName)) + if (!Utf8ToUpperOnlyLatin(accountName)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); @@ -712,7 +712,7 @@ public: switch (mode) { case BAN_ACCOUNT: - if (!AccountMgr::normalizeString(nameOrIP)) + if (!Utf8ToUpperOnlyLatin(nameOrIP)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, nameOrIP.c_str()); handler->SetSentErrorMessage(true); diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index e048aabd4d7..9557d182df1 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -133,7 +133,7 @@ public: info.name = fields[1].GetString(); info.accountId = fields[2].GetUInt32(); - // account name will be empty for not existed account + // account name will be empty for nonexisting account AccountMgr::GetName(info.accountId, info.accountName); info.deleteDate = time_t(fields[3].GetUInt32()); foundList.push_back(info); @@ -169,11 +169,11 @@ public: if (!handler->GetSession()) handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CONSOLE, - itr->guid.GetCounter(), itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(), + itr->guid.GetCounter(), itr->name.c_str(), itr->accountName.empty() ? "<Not existing>" : itr->accountName.c_str(), itr->accountId, dateStr.c_str()); else handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CHAT, - itr->guid.GetCounter(), itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(), + itr->guid.GetCounter(), itr->name.c_str(), itr->accountName.empty() ? "<Not existing>" : itr->accountName.c_str(), itr->accountId, dateStr.c_str()); } @@ -193,7 +193,7 @@ public: */ static void HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo, ChatHandler* handler) { - if (delInfo.accountName.empty()) // account not exist + if (delInfo.accountName.empty()) // account does not exist { handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_ACCOUNT, delInfo.name.c_str(), delInfo.guid.GetCounter(), delInfo.accountId); return; @@ -660,7 +660,7 @@ public: if (newCharName.empty()) { - // Drop not existed account cases + // Drop nonexisting account cases for (DeletedInfoList::iterator itr = foundList.begin(); itr != foundList.end(); ++itr) HandleCharacterDeletedRestoreHelper(*itr, handler); } @@ -810,7 +810,7 @@ public: if (levelStr && isalpha(levelStr[0])) { nameStr = levelStr; - levelStr = NULL; // current level will used + levelStr = NULL; // current level will be used } Player* target; @@ -854,7 +854,7 @@ public: return false; std::string accountName = accountStr; - if (!AccountMgr::normalizeString(accountName)) + if (!Utf8ToUpperOnlyLatin(accountName)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 9902b83ff63..1d8094885d4 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -93,7 +93,8 @@ public: { "moveflags", rbac::RBAC_PERM_COMMAND_DEBUG_MOVEFLAGS, false, &HandleDebugMoveflagsCommand, "" }, { "transport", rbac::RBAC_PERM_COMMAND_DEBUG_TRANSPORT, false, &HandleDebugTransportCommand, "" }, { "loadcells", rbac::RBAC_PERM_COMMAND_DEBUG_LOADCELLS, false, &HandleDebugLoadCellsCommand, "" }, - { "boundary", rbac::RBAC_PERM_COMMAND_DEBUG_BOUNDARY, false, &HandleDebugBoundaryCommand, "" } + { "boundary", rbac::RBAC_PERM_COMMAND_DEBUG_BOUNDARY, false, &HandleDebugBoundaryCommand, "" }, + { "raidreset", rbac::RBAC_PERM_COMMAND_INSTANCE_UNBIND, false, &HandleDebugRaidResetCommand, "" } }; static std::vector<ChatCommand> commandTable = { @@ -123,6 +124,23 @@ public: return false; } + // Dump camera locations + if (CinematicSequencesEntry const* cineSeq = sCinematicSequencesStore.LookupEntry(id)) + { + std::unordered_map<uint32, FlyByCameraCollection>::const_iterator itr = sFlyByCameraStore.find(cineSeq->cinematicCamera); + if (itr != sFlyByCameraStore.end()) + { + handler->PSendSysMessage("Waypoints for sequence %u, camera %u", id, cineSeq->cinematicCamera); + uint32 count = 1 ; + for (FlyByCamera cam : itr->second) + { + handler->PSendSysMessage("%02u - %7ums [%f, %f, %f] Facing %f (%f degrees)", count, cam.timeStamp, cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w, cam.locations.w * (180 / M_PI)); + count++; + } + handler->PSendSysMessage("%u waypoints dumped", itr->second.size()); + } + } + handler->GetSession()->GetPlayer()->SendCinematicStart(id); return true; } @@ -1044,7 +1062,8 @@ public: return false; uint32 animId = atoi((char*)args); - handler->GetSession()->GetPlayer()->HandleEmoteCommand(animId); + if (Unit* unit = handler->getSelectedUnit()) + unit->HandleEmoteCommand(animId); return true; } @@ -1408,10 +1427,7 @@ public: map = player->GetMap(); handler->PSendSysMessage("Loading all cells (mapId: %u). Current next GameObject %u, Creature %u", map->GetId(), map->GetMaxLowGuid<HighGuid::GameObject>(), map->GetMaxLowGuid<HighGuid::Unit>()); - for (uint32 cellX = 0; cellX < TOTAL_NUMBER_OF_CELLS_PER_MAP; cellX++) - for (uint32 cellY = 0; cellY < TOTAL_NUMBER_OF_CELLS_PER_MAP; cellY++) - map->LoadGrid((cellX + 0.5f - CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL, (cellY + 0.5f - CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL); - + map->LoadAllCells(); handler->PSendSysMessage("Cells loaded (mapId: %u) After load - Next GameObject %u, Creature %u", map->GetId(), map->GetMaxLowGuid<HighGuid::GameObject>(), map->GetMaxLowGuid<HighGuid::Unit>()); return true; } @@ -1435,13 +1451,39 @@ public: duration = 3 * MINUTE; bool doFill = fill_str ? (stricmp(fill_str, "FILL") == 0) : false; - + int32 errMsg = target->AI()->VisualizeBoundary(duration, player, doFill); if (errMsg > 0) handler->PSendSysMessage(errMsg); return true; } + + static bool HandleDebugRaidResetCommand(ChatHandler* /*handler*/, char const* args) + { + char* map_str = args ? strtok((char*)args, " ") : nullptr; + char* difficulty_str = args ? strtok(nullptr, " ") : nullptr; + + int32 map = map_str ? atoi(map_str) : -1; + if (map <= 0) + return false; + MapEntry const* mEntry = sMapStore.LookupEntry(map); + if (!mEntry || !mEntry->IsRaid()) + return false; + int32 difficulty = difficulty_str ? atoi(difficulty_str) : -1; + if (difficulty >= MAX_RAID_DIFFICULTY || difficulty < -1) + return false; + + if (difficulty == -1) + for (uint8 diff = 0; diff < MAX_RAID_DIFFICULTY; ++diff) + { + if (GetMapDifficultyData(mEntry->MapID, Difficulty(diff))) + sInstanceSaveMgr->ForceGlobalReset(mEntry->MapID, Difficulty(diff)); + } + else + sInstanceSaveMgr->ForceGlobalReset(mEntry->MapID, Difficulty(difficulty)); + return true; + } }; void AddSC_debug_commandscript() diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index e03942bc247..ffe8ea67816 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -164,7 +164,7 @@ public: ///- Get the accounts with GM Level >0 PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_GM_ACCOUNTS); stmt->setUInt8(0, uint8(SEC_MODERATOR)); - stmt->setInt32(1, int32(realmID)); + stmt->setInt32(1, int32(realm.Id.Realm)); PreparedQueryResult result = LoginDatabase.Query(stmt); if (result) diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index b7acfb85f50..039af61c010 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -424,7 +424,7 @@ public: uint32 areaId = id ? (uint32)atoi(id) : player->GetZoneId(); - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId); if (x < 0 || x > 100 || y < 0 || y > 100 || !areaEntry) { @@ -434,7 +434,7 @@ public: } // update to parent zone if exist (client map show only zones without parents) - AreaTableEntry const* zoneEntry = areaEntry->zone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry; + AreaTableEntry const* zoneEntry = areaEntry->zone ? sAreaTableStore.LookupEntry(areaEntry->zone) : areaEntry; ASSERT(zoneEntry); Map const* map = sMapMgr->CreateBaseMap(zoneEntry->mapid); diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp index 5e8952ce881..9f2bc86f9c0 100644 --- a/src/server/scripts/Commands/cs_group.cpp +++ b/src/server/scripts/Commands/cs_group.cpp @@ -348,10 +348,10 @@ public: phase = (!p->IsGameMaster() ? p->GetPhaseMask() : -1); uint32 locale = handler->GetSessionDbcLocale(); - AreaTableEntry const* area = GetAreaEntryByAreaID(p->GetAreaId()); + AreaTableEntry const* area = sAreaTableStore.LookupEntry(p->GetAreaId()); if (area) { - AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); + AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->zone); if (zone) zoneName = zone->area_name[locale]; } diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp index a53d1f00b54..d0325a317db 100644 --- a/src/server/scripts/Commands/cs_instance.cpp +++ b/src/server/scripts/Commands/cs_instance.cpp @@ -82,7 +82,7 @@ public: { InstanceSave* save = itr->second.save; std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); + handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", itr->second.extendState == EXTEND_STATE_EXPIRED ? "expired" : itr->second.extendState == EXTEND_STATE_EXTENDED ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); counter++; } } @@ -98,7 +98,7 @@ public: { InstanceSave* save = itr->second.save; std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); + handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", "-", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); counter++; } } diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp index 4e749d33fcf..161ade1a30f 100644 --- a/src/server/scripts/Commands/cs_lookup.cpp +++ b/src/server/scripts/Commands/cs_lookup.cpp @@ -97,9 +97,9 @@ public: wstrToLower(wNamePart); // Search in AreaTable.dbc - for (uint32 areaflag = 0; areaflag < sAreaStore.GetNumRows(); ++areaflag) + for (uint32 i = 0; i < sAreaTableStore.GetNumRows(); ++i) { - AreaTableEntry const* areaEntry = sAreaStore.LookupEntry(areaflag); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(i); if (areaEntry) { int locale = handler->GetSessionDbcLocale(); @@ -1343,7 +1343,7 @@ public: char* limitStr = strtok(NULL, " "); int32 limit = limitStr ? atoi(limitStr) : -1; - if (!AccountMgr::normalizeString + if (!Utf8ToUpperOnlyLatin (account)) return false; diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 6ae509af443..3e35a721162 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -36,6 +36,7 @@ #include "MMapFactory.h" #include "DisableMgr.h" #include "SpellHistory.h" +#include "Transport.h" class misc_commandscript : public CommandScript { @@ -198,8 +199,8 @@ public: uint32 mapId = object->GetMapId(); MapEntry const* mapEntry = sMapStore.LookupEntry(mapId); - AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId); - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); + AreaTableEntry const* zoneEntry = sAreaTableStore.LookupEntry(zoneId); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId); float zoneX = object->GetPositionX(); float zoneY = object->GetPositionY(); @@ -237,6 +238,10 @@ public: areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : unknown), object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation()); + if (Transport* transport = object->GetTransport()) + handler->PSendSysMessage(LANG_TRANSPORT_POSITION, + transport->GetGOInfo()->moTransport.mapID, object->GetTransOffsetX(), object->GetTransOffsetY(), object->GetTransOffsetZ(), object->GetTransOffsetO(), + transport->GetEntry(), transport->GetName().c_str()); handler->PSendSysMessage(LANG_GRID_POSITION, cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap, haveMMap); @@ -961,7 +966,7 @@ public: uint32 zoneId = player->GetZoneId(); - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(zoneId); if (!areaEntry || areaEntry->zone !=0) { handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, graveyardId, zoneId); @@ -1052,17 +1057,23 @@ public: return false; } - int32 area = GetAreaFlagByAreaID(atoi((char*)args)); - int32 offset = area / 32; + AreaTableEntry const* area = sAreaTableStore.LookupEntry(atoi(args)); + if (!area) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } - if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) + int32 offset = area->exploreFlag / 32; + if (offset >= PLAYER_EXPLORED_ZONES_SIZE) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } - uint32 val = uint32((1 << (area % 32))); + uint32 val = uint32((1 << (area->exploreFlag % 32))); uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields | val))); @@ -1083,17 +1094,23 @@ public: return false; } - int32 area = GetAreaFlagByAreaID(atoi((char*)args)); - int32 offset = area / 32; + AreaTableEntry const* area = sAreaTableStore.LookupEntry(atoi(args)); + if (!area) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } - if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) + int32 offset = area->exploreFlag / 32; + if (offset >= PLAYER_EXPLORED_ZONES_SIZE) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } - uint32 val = uint32((1 << (area % 32))); + uint32 val = uint32((1 << (area->exploreFlag % 32))); uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields ^ val))); @@ -1576,7 +1593,7 @@ public: // Query the prepared statement for login data stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); - stmt->setInt32(0, int32(realmID)); + stmt->setInt32(0, int32(realm.Id.Realm)); stmt->setUInt32(1, accId); PreparedQueryResult result = LoginDatabase.Query(stmt); @@ -1737,12 +1754,12 @@ public: // Position data MapEntry const* map = sMapStore.LookupEntry(mapId); - AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); + AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId); if (area) { areaName = area->area_name[locale]; - AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); + AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->zone); if (zone) zoneName = zone->area_name[locale]; } @@ -1952,7 +1969,7 @@ public: return false; std::string accountName = nameStr; - if (!AccountMgr::normalizeString(accountName)) + if (!Utf8ToUpperOnlyLatin(accountName)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); handler->SetSentErrorMessage(true); diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 761b4c9e0e6..f1ddb448b35 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -473,15 +473,15 @@ public: return false; } - handler->PSendSysMessage(LANG_YOU_CHANGE_ASPEED, ASpeed, targetNameLink.c_str()); + handler->PSendSysMessage(LANG_YOU_CHANGE_ASPEED, targetNameLink.c_str(), ASpeed); if (handler->needReportToTarget(target)) ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, handler->GetNameLink().c_str(), ASpeed); - target->SetSpeed(MOVE_WALK, ASpeed, true); - target->SetSpeed(MOVE_RUN, ASpeed, true); - target->SetSpeed(MOVE_SWIM, ASpeed, true); - //target->SetSpeed(MOVE_TURN, ASpeed, true); - target->SetSpeed(MOVE_FLIGHT, ASpeed, true); + target->SetSpeedRate(MOVE_WALK, ASpeed); + target->SetSpeedRate(MOVE_RUN, ASpeed); + target->SetSpeedRate(MOVE_SWIM, ASpeed); + //target->SetSpeedRate(MOVE_TURN, ASpeed); + target->SetSpeedRate(MOVE_FLIGHT, ASpeed); return true; } @@ -521,11 +521,11 @@ public: return false; } - handler->PSendSysMessage(LANG_YOU_CHANGE_SPEED, Speed, targetNameLink.c_str()); + handler->PSendSysMessage(LANG_YOU_CHANGE_SPEED, targetNameLink.c_str(), Speed); if (handler->needReportToTarget(target)) ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, handler->GetNameLink().c_str(), Speed); - target->SetSpeed(MOVE_RUN, Speed, true); + target->SetSpeedRate(MOVE_RUN, Speed); return true; } @@ -566,11 +566,11 @@ public: return false; } - handler->PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, Swim, targetNameLink.c_str()); + handler->PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, targetNameLink.c_str(), Swim); if (handler->needReportToTarget(target)) ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, handler->GetNameLink().c_str(), Swim); - target->SetSpeed(MOVE_SWIM, Swim, true); + target->SetSpeedRate(MOVE_SWIM, Swim); return true; } @@ -611,11 +611,11 @@ public: return false; } - handler->PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, BSpeed, targetNameLink.c_str()); + handler->PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, targetNameLink.c_str(), BSpeed); if (handler->needReportToTarget(target)) ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, handler->GetNameLink().c_str(), BSpeed); - target->SetSpeed(MOVE_RUN_BACK, BSpeed, true); + target->SetSpeedRate(MOVE_RUN_BACK, BSpeed); return true; } @@ -647,11 +647,11 @@ public: if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) return false; - handler->PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, FSpeed, handler->GetNameLink(target).c_str()); + handler->PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, handler->GetNameLink(target).c_str(), FSpeed); if (handler->needReportToTarget(target)) ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, handler->GetNameLink().c_str(), FSpeed); - target->SetSpeed(MOVE_FLIGHT, FSpeed, true); + target->SetSpeedRate(MOVE_FLIGHT, FSpeed); return true; } @@ -684,7 +684,7 @@ public: if (handler->HasLowerSecurity(player, ObjectGuid::Empty)) return false; - handler->PSendSysMessage(LANG_YOU_CHANGE_SIZE, Scale, handler->GetNameLink(player).c_str()); + handler->PSendSysMessage(LANG_YOU_CHANGE_SIZE, handler->GetNameLink(player).c_str(), Scale); if (handler->needReportToTarget(player)) ChatHandler(player->GetSession()).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, handler->GetNameLink().c_str(), Scale); } @@ -1339,8 +1339,8 @@ public: } // Set gender - target->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender); - target->SetByteValue(PLAYER_BYTES_3, 0, gender); + target->SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, gender); + target->SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER, gender); // Change display ID target->InitDisplayIds(); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 7580e9a07d3..fbd199b99db 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -43,7 +43,7 @@ struct EnumName #define CREATE_NAMED_ENUM(VALUE) { VALUE, STRINGIZE(VALUE) } #define NPCFLAG_COUNT 24 -#define FLAGS_EXTRA_COUNT 18 +#define FLAGS_EXTRA_COUNT 19 EnumName<NPCFlags, int32> const npcFlagTexts[NPCFLAG_COUNT] = { @@ -164,7 +164,8 @@ EnumName<CreatureFlagsExtra> const flagsExtra[FLAGS_EXTRA_COUNT] = CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_ALL_DIMINISH), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ), CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_DUNGEON_BOSS), - CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING) + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING), + CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK) }; class npc_commandscript : public CommandScript diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp index f7c2d21c12d..64692c4d0ed 100644 --- a/src/server/scripts/Commands/cs_rbac.cpp +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -49,7 +49,7 @@ class rbac_commandscript : public CommandScript public: rbac_commandscript() : CommandScript("rbac_commandscript") { } - std::vector<ChatCommand> GetCommands() const + std::vector<ChatCommand> GetCommands() const override { static std::vector<ChatCommand> rbacAccountCommandTable = { @@ -139,7 +139,7 @@ public: { accountName = param1; - if (AccountMgr::normalizeString(accountName)) + if (Utf8ToUpperOnlyLatin(accountName)) accountId = AccountMgr::GetId(accountName); if (!accountId) @@ -157,7 +157,7 @@ public: if (!rdata) { - data->rbac = new rbac::RBACData(accountId, accountName, realmID, AccountMgr::GetSecurity(accountId, realmID)); + data->rbac = new rbac::RBACData(accountId, accountName, realm.Id.Realm, AccountMgr::GetSecurity(accountId, realm.Id.Realm)); data->rbac->LoadFromDB(); data->needDelete = true; } diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 56b0dbf43d0..eb28a8adae4 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -251,7 +251,7 @@ public: static bool HandleReloadAllScriptsCommand(ChatHandler* handler, const char* /*args*/) { - if (sScriptMgr->IsScriptScheduled()) + if (sMapMgr->IsScriptScheduled()) { handler->PSendSysMessage("DB scripts used currently, please attempt reload later."); handler->SetSentErrorMessage(true); @@ -393,7 +393,7 @@ public: static bool HandleReloadCommandCommand(ChatHandler* handler, const char* /*args*/) { - handler->SetLoadCommandTable(true); + ChatHandler::invalidateCommandTable(); handler->SendGlobalGMSysMessage("DB table `command` will be reloaded at next chat command use."); return true; } @@ -893,7 +893,7 @@ public: static bool HandleReloadEventScriptsCommand(ChatHandler* handler, const char* args) { - if (sScriptMgr->IsScriptScheduled()) + if (sMapMgr->IsScriptScheduled()) { handler->SendSysMessage("DB scripts used currently, please attempt reload later."); handler->SetSentErrorMessage(true); @@ -913,7 +913,7 @@ public: static bool HandleReloadWpScriptsCommand(ChatHandler* handler, const char* args) { - if (sScriptMgr->IsScriptScheduled()) + if (sMapMgr->IsScriptScheduled()) { handler->SendSysMessage("DB scripts used currently, please attempt reload later."); handler->SetSentErrorMessage(true); @@ -946,7 +946,7 @@ public: static bool HandleReloadSpellScriptsCommand(ChatHandler* handler, const char* args) { - if (sScriptMgr->IsScriptScheduled()) + if (sMapMgr->IsScriptScheduled()) { handler->SendSysMessage("DB scripts used currently, please attempt reload later."); handler->SetSentErrorMessage(true); diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp index 05941120423..ba1dab28350 100644 --- a/src/server/scripts/Commands/cs_reset.cpp +++ b/src/server/scripts/Commands/cs_reset.cpp @@ -102,7 +102,7 @@ public: player->setFactionForRace(player->getRace()); - player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powerType << 24))); + player->SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_POWER_TYPE, powerType); // reset only if player not in some form; if (player->GetShapeshiftForm() == FORM_NONE) diff --git a/src/server/scripts/Commands/cs_script_loader.cpp b/src/server/scripts/Commands/cs_script_loader.cpp new file mode 100644 index 00000000000..449e7053942 --- /dev/null +++ b/src/server/scripts/Commands/cs_script_loader.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This is where scripts' loading functions should be declared: +void AddSC_account_commandscript(); +void AddSC_achievement_commandscript(); +void AddSC_ahbot_commandscript(); +void AddSC_arena_commandscript(); +void AddSC_ban_commandscript(); +void AddSC_bf_commandscript(); +void AddSC_cast_commandscript(); +void AddSC_character_commandscript(); +void AddSC_cheat_commandscript(); +void AddSC_debug_commandscript(); +void AddSC_deserter_commandscript(); +void AddSC_disable_commandscript(); +void AddSC_event_commandscript(); +void AddSC_gm_commandscript(); +void AddSC_go_commandscript(); +void AddSC_gobject_commandscript(); +void AddSC_group_commandscript(); +void AddSC_guild_commandscript(); +void AddSC_honor_commandscript(); +void AddSC_instance_commandscript(); +void AddSC_learn_commandscript(); +void AddSC_lfg_commandscript(); +void AddSC_list_commandscript(); +void AddSC_lookup_commandscript(); +void AddSC_message_commandscript(); +void AddSC_misc_commandscript(); +void AddSC_mmaps_commandscript(); +void AddSC_modify_commandscript(); +void AddSC_npc_commandscript(); +void AddSC_pet_commandscript(); +void AddSC_quest_commandscript(); +void AddSC_rbac_commandscript(); +void AddSC_reload_commandscript(); +void AddSC_reset_commandscript(); +void AddSC_send_commandscript(); +void AddSC_server_commandscript(); +void AddSC_tele_commandscript(); +void AddSC_ticket_commandscript(); +void AddSC_titles_commandscript(); +void AddSC_wp_commandscript(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddCommandsScripts() +{ + AddSC_account_commandscript(); + AddSC_achievement_commandscript(); + AddSC_ahbot_commandscript(); + AddSC_arena_commandscript(); + AddSC_ban_commandscript(); + AddSC_bf_commandscript(); + AddSC_cast_commandscript(); + AddSC_character_commandscript(); + AddSC_cheat_commandscript(); + AddSC_debug_commandscript(); + AddSC_deserter_commandscript(); + AddSC_disable_commandscript(); + AddSC_event_commandscript(); + AddSC_gm_commandscript(); + AddSC_go_commandscript(); + AddSC_gobject_commandscript(); + AddSC_group_commandscript(); + AddSC_guild_commandscript(); + AddSC_honor_commandscript(); + AddSC_instance_commandscript(); + AddSC_learn_commandscript(); + AddSC_lookup_commandscript(); + AddSC_lfg_commandscript(); + AddSC_list_commandscript(); + AddSC_message_commandscript(); + AddSC_misc_commandscript(); + AddSC_mmaps_commandscript(); + AddSC_modify_commandscript(); + AddSC_npc_commandscript(); + AddSC_quest_commandscript(); + AddSC_pet_commandscript(); + AddSC_rbac_commandscript(); + AddSC_reload_commandscript(); + AddSC_reset_commandscript(); + AddSC_send_commandscript(); + AddSC_server_commandscript(); + AddSC_tele_commandscript(); + AddSC_ticket_commandscript(); + AddSC_titles_commandscript(); + AddSC_wp_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_send.cpp b/src/server/scripts/Commands/cs_send.cpp index 672db3a3ab0..31544543426 100644 --- a/src/server/scripts/Commands/cs_send.cpp +++ b/src/server/scripts/Commands/cs_send.cpp @@ -74,7 +74,7 @@ public: std::string subject = msgSubject; std::string text = msgText; - // from console show not existed sender + // from console, use non-existing sender MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUID().GetCounter() : 0, MAIL_STATIONERY_GM); /// @todo Fix poor design @@ -173,7 +173,7 @@ public: } } - // from console show not existed sender + // from console show nonexisting sender MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUID().GetCounter() : 0, MAIL_STATIONERY_GM); // fill mail @@ -185,7 +185,7 @@ public: { if (Item* item = Item::CreateItem(itr->first, itr->second, handler->GetSession() ? handler->GetSession()->GetPlayer() : 0)) { - item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted + item->SaveToDB(trans); // Save to prevent being lost at next mail load. If send fails, the item will be deleted. draft.AddItem(item); } } @@ -233,7 +233,7 @@ public: std::string subject = msgSubject; std::string text = msgText; - // from console show not existed sender + // from console show nonexisting sender MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUID().GetCounter() : 0, MAIL_STATIONERY_GM); SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -260,7 +260,7 @@ public: if (!msgStr) return false; - ///- Check that he is not logging out. + /// - Check if player is logging out. if (player->GetSession()->isLogingOut()) { handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp index c5c85f5f3cc..899c5615206 100644 --- a/src/server/scripts/Commands/cs_ticket.cpp +++ b/src/server/scripts/Commands/cs_ticket.cpp @@ -95,7 +95,7 @@ public: ObjectGuid targetGuid = sObjectMgr->GetPlayerGUIDByName(target); uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); // Target must exist and have administrative rights - if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmID)) + if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realm.Id.Realm)) { handler->SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A); return true; @@ -119,7 +119,7 @@ public: // Assign ticket SQLTransaction trans = SQLTransaction(NULL); - ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmID))); + ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realm.Id.Realm))); ticket->SaveToDB(trans); sTicketMgr->UpdateLastChange(); @@ -387,7 +387,7 @@ public: { ObjectGuid guid = ticket->GetAssignedToGUID(); uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(guid); - security = AccountMgr::GetSecurity(accountId, realmID); + security = AccountMgr::GetSecurity(accountId, realm.Id.Realm); } // Check security diff --git a/src/server/scripts/Commands/cs_titles.cpp b/src/server/scripts/Commands/cs_titles.cpp index 2f5d7b8364c..6309e7279c9 100644 --- a/src/server/scripts/Commands/cs_titles.cpp +++ b/src/server/scripts/Commands/cs_titles.cpp @@ -225,7 +225,7 @@ public: if (CharTitlesEntry const* tEntry = sCharTitlesStore.LookupEntry(i)) titles2 &= ~(uint64(1) << tEntry->bit_index); - titles &= ~titles2; // remove not existed titles + titles &= ~titles2; // remove non-existing titles target->SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES, titles); handler->SendSysMessage(LANG_DONE); diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index ef61c231104..424f94f7385 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -561,29 +561,24 @@ public: // -> variable lowguid is filled with the GUID of the NPC uint32 pathid = 0; uint32 point = 0; - uint32 wpGuid = 0; Creature* target = handler->getSelectedCreature(); PreparedStatement* stmt = NULL; + // User did select a visual waypoint? if (!target || target->GetEntry() != VISUAL_WAYPOINT) { handler->SendSysMessage("|cffff33ffERROR: You must select a waypoint.|r"); return false; } - // The visual waypoint - wpGuid = target->GetGUID().GetCounter(); - - // User did select a visual waypoint? - // Check the creature stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_WPGUID); - stmt->setUInt32(0, wpGuid); + stmt->setUInt32(0, target->GetSpawnId()); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { - handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID().GetCounter()); + handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetSpawnId()); // Select waypoint number from database // Since we compare float values, we have to deal with // some difficulties. @@ -599,11 +594,11 @@ public: stmt->setString(3, maxDiff); stmt->setFloat(4, target->GetPositionZ()); stmt->setString(5, maxDiff); - PreparedQueryResult queryResult = WorldDatabase.Query(stmt); + result = WorldDatabase.Query(stmt); - if (!queryResult) + if (!result) { - handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid); + handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetSpawnId()); return true; } } @@ -631,13 +626,8 @@ public: { handler->PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid); - if (wpGuid != 0) - if (Creature* wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(ObjectGuid(HighGuid::Unit, VISUAL_WAYPOINT, wpGuid))) - { - wpCreature->CombatStop(); - wpCreature->DeleteFromDB(); - wpCreature->AddObjectToRemoveList(); - } + target->DeleteFromDB(); + target->AddObjectToRemoveList(); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_DATA); stmt->setUInt32(0, pathid); @@ -659,51 +649,40 @@ public: Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); + // What to do: + // Move the visual spawnpoint + // Respawn the owner of the waypoints + target->DeleteFromDB(); + target->AddObjectToRemoveList(); + + // re-create + Creature* wpCreature = new Creature(); + if (!wpCreature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) { - // What to do: - // Move the visual spawnpoint - // Respawn the owner of the waypoints - if (wpGuid != 0) - { - if (Creature* wpCreature = map->GetCreature(ObjectGuid(HighGuid::Unit, VISUAL_WAYPOINT, wpGuid))) - { - wpCreature->CombatStop(); - wpCreature->DeleteFromDB(); - wpCreature->AddObjectToRemoveList(); - } - // re-create - Creature* wpCreature2 = new Creature(); - if (!wpCreature2->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) - { - handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); - delete wpCreature2; - wpCreature2 = NULL; - return false; - } + handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); + delete wpCreature; + return false; + } - wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); - // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); - /// @todo Should we first use "Create" then use "LoadFromDB"? - if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetSpawnId(), map)) - { - handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); - delete wpCreature2; - wpCreature2 = NULL; - return false; - } - //sMapMgr->GetMap(npcCreature->GetMapId())->Add(wpCreature2); - } + wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); + /// @todo Should we first use "Create" then use "LoadFromDB"? + if (!wpCreature->LoadCreatureFromDB(wpCreature->GetSpawnId(), map)) + { + handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); + delete wpCreature; + return false; + } - stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POSITION); - stmt->setFloat(0, chr->GetPositionX()); - stmt->setFloat(1, chr->GetPositionY()); - stmt->setFloat(2, chr->GetPositionZ()); - stmt->setUInt32(3, pathid); - stmt->setUInt32(4, point); - WorldDatabase.Execute(stmt); + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POSITION); + stmt->setFloat(0, chr->GetPositionX()); + stmt->setFloat(1, chr->GetPositionY()); + stmt->setFloat(2, chr->GetPositionZ()); + stmt->setUInt32(3, pathid); + stmt->setUInt32(4, point); + WorldDatabase.Execute(stmt); - handler->PSendSysMessage(LANG_WAYPOINT_CHANGED); - } + handler->PSendSysMessage(LANG_WAYPOINT_CHANGED); return true; } // move @@ -897,14 +876,15 @@ public: return false; } + wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + // Set "wpguid" column to the visual waypoint stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); - stmt->setInt32(0, int32(wpCreature->GetGUID().GetCounter())); + stmt->setInt32(0, int32(wpCreature->GetSpawnId())); stmt->setUInt32(1, pathid); stmt->setUInt32(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)) { diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt deleted file mode 100644 index 595ff801813..00000000000 --- a/src/server/scripts/Custom/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# file(GLOB_RECURSE sources_Custom Custom/*.cpp Custom/*.h) - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} -# ${sources_Custom} -) - -message(" -> Prepared: Custom") diff --git a/src/server/scripts/Custom/custom_script_loader.cpp b/src/server/scripts/Custom/custom_script_loader.cpp new file mode 100644 index 00000000000..dd4b5e99d77 --- /dev/null +++ b/src/server/scripts/Custom/custom_script_loader.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This is where scripts' loading functions should be declared: + + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddCustomScripts() +{ +} diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp index 9cd724e5596..79709734e18 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp @@ -508,19 +508,11 @@ public: }; // npc_lokhtos_darkbargainer -enum LokhtosItems +enum Lokhtos { + QUEST_A_BINDING_CONTRACT = 7604, + ITEM_SULFURON_INGOT = 17203, ITEM_THRORIUM_BROTHERHOOD_CONTRACT = 18628, - ITEM_SULFURON_INGOT = 17203 -}; - -enum LokhtosQuests -{ - QUEST_A_BINDING_CONTRACT = 7604 -}; - -enum LokhtosSpells -{ SPELL_CREATE_THORIUM_BROTHERHOOD_CONTRACT_DND = 23059 }; @@ -570,67 +562,12 @@ public: } }; -// npc_dughal_stormwing -enum DughalQuests -{ - QUEST_JAIL_BREAK = 4322 -}; - -#define SAY_DUGHAL_FREE "Thank you, $N! I'm free!!!" -#define GOSSIP_DUGHAL "You're free, Dughal! Get out of here!" - -// npc_marshal_windsor -#define SAY_WINDSOR_AGGRO1 "You locked up the wrong Marshal. Prepare to be destroyed!" -#define SAY_WINDSOR_AGGRO2 "I bet you're sorry now, aren't you !?!!" -#define SAY_WINDSOR_AGGRO3 "You better hold me back $N or they are going to feel some prison house beatings." -#define SAY_WINDSOR_1 "Let's get a move on. My gear should be in the storage area up this way..." -#define SAY_WINDSOR_4_1 "Check that cell, $N. If someone is alive in there, we need to get them out." -#define SAY_WINDSOR_4_2 "Get him out of there!" -#define SAY_WINDSOR_4_3 "Good work! We're almost there, $N. This way." -#define SAY_WINDSOR_6 "This is it, $N. My stuff should be in that room. Cover me, I'm going in!" -#define SAY_WINDSOR_9 "Ah, there it is!" - -enum MarshalWindsor -{ - NPC_REGINALD_WINDSOR = 9682 -}; - -// npc_marshal_reginald_windsor -#define SAY_REGINALD_WINDSOR_0_1 "Can you feel the power, $N??? It's time to ROCK!" -#define SAY_REGINALD_WINDSOR_0_2 "Now we just have to free Tobias and we can get out of here. This way!" -#define SAY_REGINALD_WINDSOR_5_1 "Open it." -#define SAY_REGINALD_WINDSOR_5_2 "I never did like those two. Let's get moving." -#define SAY_REGINALD_WINDSOR_7_1 "Open it and be careful this time!" -#define SAY_REGINALD_WINDSOR_7_2 "That intolerant dirtbag finally got what was coming to him. Good riddance!" -#define SAY_REGINALD_WINDSOR_7_3 "Alright, let's go." -#define SAY_REGINALD_WINDSOR_13_1 "Open it. We need to hurry up. I can smell those Dark Irons coming a mile away and I can tell you one thing, they're COMING!" -#define SAY_REGINALD_WINDSOR_13_2 "Administering fists of fury on Crest Killer!" -#define SAY_REGINALD_WINDSOR_13_3 "He has to be in the last cell. Unless... they killed him." -#define SAY_REGINALD_WINDSOR_14_1 "Get him out of there!" -#define SAY_REGINALD_WINDSOR_14_2 "Excellent work, $N. Let's find the exit. I think I know the way. Follow me!" -#define SAY_REGINALD_WINDSOR_20_1 "We made it!" -#define SAY_REGINALD_WINDSOR_20_2 "Meet me at Maxwell's encampment. We'll go over the next stages of the plan there and figure out a way to decode my tablets without the decryption ring." - -enum MarshalReginaldWindor -{ - NPC_SHILL_DINGER = 9678, - NPC_CREST_KILLER = 9680 -}; - // npc_rocknot -enum RocknotSays -{ - SAY_GOT_BEER = 0 -}; - -enum RocknotSpells -{ - SPELL_DRUNKEN_RAGE = 14872 -}; - -enum RocknotQuests +enum Rocknot { - QUEST_ALE = 4295 + SAY_GOT_BEER = 0, + QUEST_ALE = 4295, + SPELL_DRUNKEN_RAGE = 14872 }; class npc_rocknot : public CreatureScript diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp index 51bb314968d..ffec32c0619 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp @@ -27,6 +27,8 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "molten_core.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" enum Emotes { @@ -36,9 +38,10 @@ enum Emotes enum Spells { SPELL_INFERNO = 19695, + SPELL_INFERNO_DMG = 19698, SPELL_IGNITE_MANA = 19659, SPELL_LIVING_BOMB = 20475, - SPELL_ARMAGEDDON = 20479, + SPELL_ARMAGEDDON = 20478, }; enum Events @@ -119,7 +122,36 @@ class boss_baron_geddon : public CreatureScript } }; +class spell_baron_geddon_inferno : public SpellScriptLoader +{ + public: + spell_baron_geddon_inferno() : SpellScriptLoader("spell_baron_geddon_inferno") { } + + class spell_baron_geddon_inferno_AuraScript : public AuraScript + { + PrepareAuraScript(spell_baron_geddon_inferno_AuraScript); + + void OnPeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + int32 damageForTick[8] = { 500, 500, 1000, 1000, 2000, 2000, 3000, 5000 }; + GetTarget()->CastCustomSpell(SPELL_INFERNO_DMG, SPELLVALUE_BASE_POINT0, damageForTick[aurEff->GetTickNumber() - 1], (Unit*)nullptr, TRIGGERED_FULL_MASK, nullptr, aurEff); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_baron_geddon_inferno_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_baron_geddon_inferno_AuraScript(); + } +}; + void AddSC_boss_baron_geddon() { new boss_baron_geddon(); + new spell_baron_geddon_inferno(); } diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt deleted file mode 100644 index 8e6616347f9..00000000000 --- a/src/server/scripts/EasternKingdoms/CMakeLists.txt +++ /dev/null @@ -1,204 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - EasternKingdoms/zone_ghostlands.cpp - EasternKingdoms/AlteracValley/boss_galvangar.cpp - EasternKingdoms/AlteracValley/boss_balinda.cpp - EasternKingdoms/AlteracValley/boss_drekthar.cpp - EasternKingdoms/AlteracValley/boss_vanndar.cpp - EasternKingdoms/AlteracValley/alterac_valley.cpp - EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp - EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp - EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp - EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_general_angerforge.cpp - EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_ambassador_flamelash.cpp - EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp - EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp - EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.h - EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp - EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp - EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp - EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp - EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp - EasternKingdoms/BlackrockMountain/BlackwingLair/boss_broodlord_lashlayer.cpp - EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp - EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp - EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp - EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp - EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp - EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_pyroguard_emberseer.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_drakkisath.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_warmaster_voone.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_mother_smolderweb.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_quartermaster_zigris.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_halycon.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_overlord_wyrmthalak.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_shadow_hunter_voshgajin.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_gyth.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_highlord_omokk.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_the_beast.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_gizrul_the_slavener.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_urok_doomhowl.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_lord_valthalak.cpp - EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h - EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/boss_gehennas.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/boss_lucifron.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/boss_golemagg.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/boss_garr.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/molten_core.h - EasternKingdoms/BlackrockMountain/MoltenCore/instance_molten_core.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/boss_sulfuron_harbinger.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/boss_magmadar.cpp - EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp - EasternKingdoms/Scholomance/boss_the_ravenian.cpp - EasternKingdoms/Scholomance/boss_instructor_malicia.cpp - EasternKingdoms/Scholomance/boss_death_knight_darkreaver.cpp - EasternKingdoms/Scholomance/boss_illucia_barov.cpp - EasternKingdoms/Scholomance/scholomance.h - EasternKingdoms/Scholomance/boss_vectus.cpp - EasternKingdoms/Scholomance/boss_jandice_barov.cpp - EasternKingdoms/Scholomance/boss_kormok.cpp - EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp - EasternKingdoms/Scholomance/boss_doctor_theolen_krastinov.cpp - EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp - EasternKingdoms/Scholomance/instance_scholomance.cpp - EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp - EasternKingdoms/Scholomance/boss_ras_frostwhisper.cpp - EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp - EasternKingdoms/zone_isle_of_queldanas.cpp - EasternKingdoms/ZulGurub/boss_hakkar.cpp - EasternKingdoms/ZulGurub/boss_mandokir.cpp - EasternKingdoms/ZulGurub/boss_marli.cpp - EasternKingdoms/ZulGurub/boss_hazzarah.cpp - EasternKingdoms/ZulGurub/boss_jeklik.cpp - EasternKingdoms/ZulGurub/boss_grilek.cpp - EasternKingdoms/ZulGurub/zulgurub.h - EasternKingdoms/ZulGurub/boss_renataki.cpp - EasternKingdoms/ZulGurub/boss_arlokk.cpp - EasternKingdoms/ZulGurub/boss_gahzranka.cpp - EasternKingdoms/ZulGurub/boss_venoxis.cpp - EasternKingdoms/ZulGurub/instance_zulgurub.cpp - EasternKingdoms/ZulGurub/boss_jindo.cpp - EasternKingdoms/ZulGurub/boss_wushoolay.cpp - EasternKingdoms/ZulGurub/boss_thekal.cpp - EasternKingdoms/zone_wetlands.cpp - EasternKingdoms/zone_arathi_highlands.cpp - EasternKingdoms/Gnomeregan/instance_gnomeregan.cpp - EasternKingdoms/Gnomeregan/gnomeregan.cpp - EasternKingdoms/Gnomeregan/gnomeregan.h - EasternKingdoms/zone_redridge_mountains.cpp - EasternKingdoms/ScarletEnclave/chapter2.cpp - EasternKingdoms/ScarletEnclave/chapter5.cpp - EasternKingdoms/ScarletEnclave/chapter1.cpp - EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp - EasternKingdoms/zone_eastern_plaguelands.cpp - EasternKingdoms/Stratholme/boss_baroness_anastari.cpp - EasternKingdoms/Stratholme/boss_nerubenkan.cpp - EasternKingdoms/Stratholme/instance_stratholme.cpp - EasternKingdoms/Stratholme/boss_dathrohan_balnazzar.cpp - EasternKingdoms/Stratholme/boss_timmy_the_cruel.cpp - EasternKingdoms/Stratholme/boss_baron_rivendare.cpp - EasternKingdoms/Stratholme/boss_magistrate_barthilas.cpp - EasternKingdoms/Stratholme/boss_order_of_silver_hand.cpp - EasternKingdoms/Stratholme/boss_ramstein_the_gorger.cpp - EasternKingdoms/Stratholme/boss_cannon_master_willey.cpp - EasternKingdoms/Stratholme/boss_maleki_the_pallid.cpp - EasternKingdoms/Stratholme/boss_postmaster_malown.cpp - EasternKingdoms/Stratholme/stratholme.h - EasternKingdoms/Stratholme/stratholme.cpp - EasternKingdoms/zone_tirisfal_glades.cpp - EasternKingdoms/SunkenTemple/sunken_temple.cpp - EasternKingdoms/SunkenTemple/sunken_temple.h - EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp - EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp - EasternKingdoms/MagistersTerrace/magisters_terrace.h - EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp - EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp - EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp - EasternKingdoms/MagistersTerrace/boss_vexallus.cpp - EasternKingdoms/MagistersTerrace/magisters_terrace.cpp - EasternKingdoms/Uldaman/uldaman.cpp - EasternKingdoms/Uldaman/boss_ironaya.cpp - EasternKingdoms/Uldaman/uldaman.h - EasternKingdoms/Uldaman/instance_uldaman.cpp - EasternKingdoms/Uldaman/boss_archaedas.cpp - EasternKingdoms/zone_swamp_of_sorrows.cpp - EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp - EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp - EasternKingdoms/SunwellPlateau/sunwell_plateau.h - EasternKingdoms/SunwellPlateau/boss_muru.cpp - EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp - EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp - EasternKingdoms/SunwellPlateau/boss_brutallus.cpp - EasternKingdoms/SunwellPlateau/sunwell_plateau.cpp - EasternKingdoms/SunwellPlateau/boss_felmyst.cpp - EasternKingdoms/zone_stranglethorn_vale.cpp - EasternKingdoms/Deadmines/deadmines.h - EasternKingdoms/Deadmines/deadmines.cpp - EasternKingdoms/Deadmines/boss_mr_smite.cpp - EasternKingdoms/Deadmines/instance_deadmines.cpp - EasternKingdoms/zone_duskwood.cpp - EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp - EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp - EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp - EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp - EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp - EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp - EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp - EasternKingdoms/ScarletMonastery/scarlet_monastery.h - EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp - EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp - EasternKingdoms/ScarletMonastery/boss_herod.cpp - EasternKingdoms/ScarletMonastery/boss_scorn.cpp - EasternKingdoms/zone_undercity.cpp - EasternKingdoms/zone_loch_modan.cpp - EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp - EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp - EasternKingdoms/ShadowfangKeep/shadowfang_keep.h - EasternKingdoms/zone_burning_steppes.cpp - EasternKingdoms/zone_blasted_lands.cpp - EasternKingdoms/zone_stormwind_city.cpp - EasternKingdoms/ZulAman/boss_halazzi.cpp - EasternKingdoms/ZulAman/boss_hexlord.cpp - EasternKingdoms/ZulAman/boss_zuljin.cpp - EasternKingdoms/ZulAman/boss_akilzon.cpp - EasternKingdoms/ZulAman/instance_zulaman.cpp - EasternKingdoms/ZulAman/boss_janalai.cpp - EasternKingdoms/ZulAman/boss_nalorakk.cpp - EasternKingdoms/ZulAman/zulaman.cpp - EasternKingdoms/ZulAman/zulaman.h - EasternKingdoms/zone_hinterlands.cpp - EasternKingdoms/zone_western_plaguelands.cpp - EasternKingdoms/zone_silverpine_forest.cpp - EasternKingdoms/Karazhan/instance_karazhan.cpp - EasternKingdoms/Karazhan/boss_nightbane.cpp - EasternKingdoms/Karazhan/karazhan.cpp - EasternKingdoms/Karazhan/boss_curator.cpp - EasternKingdoms/Karazhan/boss_shade_of_aran.cpp - EasternKingdoms/Karazhan/boss_netherspite.cpp - EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp - EasternKingdoms/Karazhan/boss_midnight.cpp - EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp - EasternKingdoms/Karazhan/bosses_opera.cpp - EasternKingdoms/Karazhan/boss_moroes.cpp - EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp - EasternKingdoms/Karazhan/karazhan.h - EasternKingdoms/TheStockade/instance_the_stockade.cpp -) - -message(" -> Prepared: Eastern Kingdoms") diff --git a/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp b/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp index 541ddc0e1c8..8f246ab9bf0 100644 --- a/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp +++ b/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp @@ -25,17 +25,25 @@ EndScriptData */ #include "ScriptedCreature.h" #include "deadmines.h" -enum Spels +enum Spells { SPELL_TRASH = 3391, SPELL_SMITE_STOMP = 6432, SPELL_SMITE_SLAM = 6435, - SPELL_NIMBLE_REFLEXES = 6264, + SPELL_NIMBLE_REFLEXES = 6264 +}; +enum Equips +{ EQUIP_SWORD = 5191, - EQUIP_MACE = 7230, + EQUIP_AXE = 5196, + EQUIP_MACE = 7230 +}; - SAY_AGGRO = 0, +enum Texts +{ + SAY_PHASE_1 = 2, + SAY_PHASE_2 = 3 }; class boss_mr_smite : public CreatureScript @@ -66,6 +74,8 @@ public: uiPhase = 0; uiTimer = 0; + + uiIsMoving = false; } InstanceScript* instance; @@ -79,16 +89,19 @@ public: uint32 uiPhase; uint32 uiTimer; + bool uiIsMoving; + void Reset() override { Initialize(); SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_UNEQUIP, EQUIP_NO_CHANGE); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetReactState(REACT_AGGRESSIVE); } void EnterCombat(Unit* /*who*/) override { - Talk(SAY_AGGRO); } bool bCheckChances() @@ -105,38 +118,52 @@ public: if (!UpdateVictim()) return; - /*START ACID-AI*/ - if (uiTrashTimer <= uiDiff) + if (!uiIsMoving) // halt abilities in between phases { - if (bCheckChances()) - DoCast(me, SPELL_TRASH); - uiTrashTimer = urand(6000, 15500); - } else uiTrashTimer -= uiDiff; + if (uiTrashTimer <= uiDiff) + { + if (bCheckChances()) + DoCast(me, SPELL_TRASH); + uiTrashTimer = urand(6000, 15500); + } + else uiTrashTimer -= uiDiff; - if (uiSlamTimer <= uiDiff) - { - if (bCheckChances()) - DoCastVictim(SPELL_SMITE_SLAM); - uiSlamTimer = 11000; - } else uiSlamTimer -= uiDiff; + if (uiSlamTimer <= uiDiff) + { + if (bCheckChances()) + DoCastVictim(SPELL_SMITE_SLAM); + uiSlamTimer = 11000; + } + else uiSlamTimer -= uiDiff; - if (uiNimbleReflexesTimer <= uiDiff) - { - if (bCheckChances()) - DoCast(me, SPELL_NIMBLE_REFLEXES); - uiNimbleReflexesTimer = urand(27300, 60100); - } else uiNimbleReflexesTimer -= uiDiff; - /*END ACID-AI*/ + if (uiNimbleReflexesTimer <= uiDiff) + { + if (bCheckChances()) + DoCast(me, SPELL_NIMBLE_REFLEXES); + uiNimbleReflexesTimer = urand(27300, 60100); + } + else uiNimbleReflexesTimer -= uiDiff; + } if ((uiHealth == 0 && !HealthAbovePct(66)) || (uiHealth == 1 && !HealthAbovePct(33))) { ++uiHealth; DoCastAOE(SPELL_SMITE_STOMP, false); SetCombatMovement(false); - if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_SMITE_CHEST))) + me->AttackStop(); + me->InterruptNonMeleeSpells(false); + me->SetReactState(REACT_PASSIVE); + uiTimer = 2500; + uiPhase = 1; + + switch (uiHealth) { - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(1, go->GetPositionX() - 3.0f, go->GetPositionY(), go->GetPositionZ()); + case 1: + Talk(SAY_PHASE_1); + break; + case 2: + Talk(SAY_PHASE_2); + break; } } @@ -147,21 +174,36 @@ public: switch (uiPhase) { case 1: - me->HandleEmoteCommand(EMOTE_STATE_KNEEL); //dosen't work? - uiTimer = 1000; - uiPhase = 2; + { + if (uiIsMoving) + break; + + if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_SMITE_CHEST))) + { + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MovePoint(1, go->GetPositionX() - 1.5f, go->GetPositionY() + 1.4f, go->GetPositionZ()); + uiIsMoving = true; + } break; + } case 2: if (uiHealth == 1) - SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE); + SetEquipmentSlots(false, EQUIP_AXE, EQUIP_AXE, EQUIP_NO_CHANGE); else SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE); uiTimer = 500; uiPhase = 3; break; case 3: + me->SetStandState(UNIT_STAND_STATE_STAND); + uiTimer = 750; + uiPhase = 4; + break; + case 4: + me->SetReactState(REACT_AGGRESSIVE); SetCombatMovement(true); me->GetMotionMaster()->MoveChase(me->GetVictim(), me->m_CombatDistance); + uiIsMoving = false; uiPhase = 0; break; } @@ -176,8 +218,11 @@ public: if (uiType != POINT_MOTION_TYPE) return; - uiTimer = 1500; - uiPhase = 1; + me->SetFacingTo(5.47f); + me->SetStandState(UNIT_STAND_STATE_KNEEL); + + uiTimer = 2000; + uiPhase = 2; } }; }; diff --git a/src/server/scripts/EasternKingdoms/Deadmines/deadmines.h b/src/server/scripts/EasternKingdoms/Deadmines/deadmines.h index dff4243617e..01ebabb160e 100644 --- a/src/server/scripts/EasternKingdoms/Deadmines/deadmines.h +++ b/src/server/scripts/EasternKingdoms/Deadmines/deadmines.h @@ -26,6 +26,7 @@ enum CannonState CANNON_GUNPOWDER_USED, CANNON_BLAST_INITIATED, PIRATES_ATTACK, + SMITE_ALARMED, EVENT_DONE }; @@ -48,4 +49,16 @@ enum GameObjects GO_DOOR_LEVER = 101833, GO_MR_SMITE_CHEST = 144111 }; + +enum CreaturesIds +{ + NPC_MR_SMITE = 646 +}; + +enum InstanceTexts +{ + SAY_ALARM1 = 0, + SAY_ALARM2 = 1 +}; + #endif diff --git a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp index 6714b243765..7599cf38f08 100644 --- a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp +++ b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp @@ -32,18 +32,14 @@ EndScriptData */ enum Sounds { SOUND_CANNONFIRE = 1400, - SOUND_DESTROYDOOR = 3079, - SOUND_MR_SMITE_ALARM1 = 5775, - SOUND_MR_SMITE_ALARM2 = 5777 + SOUND_DESTROYDOOR = 3079 }; -#define SAY_MR_SMITE_ALARM1 "You there, check out that noise!" -#define SAY_MR_SMITE_ALARM2 "We're under attack! A vast, ye swabs! Repel the invaders!" - enum Misc { DATA_CANNON_BLAST_TIMER = 3000, - DATA_PIRATES_DELAY_TIMER = 1000 + DATA_PIRATES_DELAY_TIMER = 1000, + DATA_SMITE_ALARM_DELAY_TIMER = 5000 }; class instance_deadmines : public InstanceMapScript @@ -63,6 +59,7 @@ class instance_deadmines : public InstanceMapScript State = CANNON_NOT_USED; CannonBlast_Timer = 0; PiratesDelay_Timer = 0; + SmiteAlarmDelay_Timer = 0; } ObjectGuid FactoryDoorGUID; @@ -72,10 +69,12 @@ class instance_deadmines : public InstanceMapScript ObjectGuid DefiasPirate1GUID; ObjectGuid DefiasPirate2GUID; ObjectGuid DefiasCompanionGUID; + ObjectGuid MrSmiteGUID; uint32 State; uint32 CannonBlast_Timer; uint32 PiratesDelay_Timer; + uint32 SmiteAlarmDelay_Timer; ObjectGuid uiSmiteChestGUID; virtual void Update(uint32 diff) override @@ -91,22 +90,20 @@ class instance_deadmines : public InstanceMapScript { case CANNON_GUNPOWDER_USED: CannonBlast_Timer = DATA_CANNON_BLAST_TIMER; - // it's a hack - Mr. Smite should do that but his too far away - //pIronCladDoor->SetName("Mr. Smite"); - //pIronCladDoor->MonsterYell(SAY_MR_SMITE_ALARM1, LANG_UNIVERSAL, NULL); - pIronCladDoor->PlayDirectSound(SOUND_MR_SMITE_ALARM1); State = CANNON_BLAST_INITIATED; break; case CANNON_BLAST_INITIATED: PiratesDelay_Timer = DATA_PIRATES_DELAY_TIMER; + SmiteAlarmDelay_Timer = DATA_SMITE_ALARM_DELAY_TIMER; if (CannonBlast_Timer <= diff) { SummonCreatures(); ShootCannon(); BlastOutDoor(); LeverStucked(); - //pIronCladDoor->MonsterYell(SAY_MR_SMITE_ALARM2, LANG_UNIVERSAL, NULL); - pIronCladDoor->PlayDirectSound(SOUND_MR_SMITE_ALARM2); + instance->LoadGrid(-22.8f, -797.24f); // Loads Mr. Smite's grid. + if (Creature* smite = instance->GetCreature(MrSmiteGUID)) // goes off when door blows up + smite->AI()->Talk(SAY_ALARM1); State = PIRATES_ATTACK; } else CannonBlast_Timer -= diff; break; @@ -114,9 +111,17 @@ class instance_deadmines : public InstanceMapScript if (PiratesDelay_Timer <= diff) { MoveCreaturesInside(); - State = EVENT_DONE; + State = SMITE_ALARMED; } else PiratesDelay_Timer -= diff; break; + case SMITE_ALARMED: + if (SmiteAlarmDelay_Timer <= diff) + { + if (Creature* smite = instance->GetCreature(MrSmiteGUID)) + smite->AI()->Talk(SAY_ALARM2); + State = EVENT_DONE; + } else SmiteAlarmDelay_Timer -= diff; + break; } } @@ -180,6 +185,18 @@ class instance_deadmines : public InstanceMapScript pDoorLever->SetUInt32Value(GAMEOBJECT_FLAGS, 4); } + void OnCreatureCreate(Creature* creature) override + { + switch (creature->GetEntry()) + { + case NPC_MR_SMITE: + MrSmiteGUID = creature->GetGUID(); + break; + default: + break; + } + } + void OnGameObjectCreate(GameObject* go) override { switch (go->GetEntry()) diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp index 9f4a31fdbbc..b694c074879 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp @@ -50,19 +50,9 @@ class boss_maiden_of_virtue : public CreatureScript public: boss_maiden_of_virtue() : CreatureScript("boss_maiden_of_virtue") { } - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_maiden_of_virtueAI(creature); - } - struct boss_maiden_of_virtueAI : public BossAI { - boss_maiden_of_virtueAI(Creature* creature) : BossAI(creature, TYPE_MAIDEN) { } - - void Reset() override - { - _Reset(); - } + boss_maiden_of_virtueAI(Creature* creature) : BossAI(creature, DATA_MAIDEN_OF_VIRTUE) { } void KilledUnit(Unit* /*Victim*/) override { @@ -132,6 +122,11 @@ public: DoMeleeAttackIfReady(); } }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new boss_maiden_of_virtueAI(creature); + } }; void AddSC_boss_maiden_of_virtue() diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp index ced8dd8f37e..43ef7e006ef 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp @@ -26,6 +26,7 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "SpellInfo.h" +#include "karazhan.h" enum Midnight { @@ -109,6 +110,9 @@ public: Talk(SAY_DEATH); if (Unit* midnight = ObjectAccessor::GetUnit(*me, Midnight)) midnight->KillSelf(); + + if (InstanceScript* instance = me->GetInstanceScript()) + instance->SetBossState(DATA_ATTUMEN, DONE); } void UpdateAI(uint32 diff) override; @@ -157,7 +161,11 @@ public: me->SetVisible(true); } - void EnterCombat(Unit* /*who*/) override { } + void EnterCombat(Unit* /*who*/) override + { + if (InstanceScript* instance = me->GetInstanceScript()) + instance->SetBossState(DATA_ATTUMEN, IN_PROGRESS); + } void KilledUnit(Unit* /*victim*/) override { diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp index 79e36442f4b..e667141fa29 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp @@ -143,12 +143,12 @@ public: if (me->IsAlive()) SpawnAdds(); - instance->SetData(TYPE_MOROES, NOT_STARTED); + instance->SetBossState(DATA_MOROES, NOT_STARTED); } void StartEvent() { - instance->SetData(TYPE_MOROES, IN_PROGRESS); + instance->SetBossState(DATA_MOROES, IN_PROGRESS); DoZoneInCombat(); } @@ -171,7 +171,7 @@ public: { Talk(SAY_DEATH); - instance->SetData(TYPE_MOROES, DONE); + instance->SetBossState(DATA_MOROES, DONE); DeSpawnAdds(); @@ -257,12 +257,6 @@ public: if (!UpdateVictim()) return; - if (!instance->GetData(TYPE_MOROES)) - { - EnterEvadeMode(); - return; - } - if (!Enrage && HealthBelowPct(30)) { DoCast(me, SPELL_FRENZY); @@ -347,7 +341,7 @@ struct boss_moroes_guestAI : public ScriptedAI void Reset() override { - instance->SetData(TYPE_MOROES, NOT_STARTED); + instance->SetBossState(DATA_MOROES, NOT_STARTED); } void AcquireGUID() @@ -373,7 +367,7 @@ struct boss_moroes_guestAI : public ScriptedAI void UpdateAI(uint32 /*diff*/) override { - if (!instance->GetData(TYPE_MOROES)) + if (instance->GetBossState(DATA_MOROES) != IN_PROGRESS) EnterEvadeMode(); DoMeleeAttackIfReady(); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp index 6f5f2b8f65f..6ff20e66f7f 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp @@ -138,15 +138,15 @@ public: { Initialize(); - me->SetSpeed(MOVE_RUN, 2.0f); + me->SetSpeedRate(MOVE_RUN, 2.0f); me->SetDisableGravity(true); me->SetWalk(false); me->setActive(true); - if (instance->GetData(TYPE_NIGHTBANE) == DONE || instance->GetData(TYPE_NIGHTBANE) == IN_PROGRESS) + if (instance->GetBossState(DATA_NIGHTBANE) == DONE || instance->GetBossState(DATA_NIGHTBANE) == IN_PROGRESS) me->DisappearAndDie(); else - instance->SetData(TYPE_NIGHTBANE, NOT_STARTED); + instance->SetBossState(DATA_NIGHTBANE, NOT_STARTED); HandleTerraceDoors(true); @@ -165,10 +165,10 @@ public: void EnterCombat(Unit* /*who*/) override { - instance->SetData(TYPE_NIGHTBANE, IN_PROGRESS); + instance->SetBossState(DATA_NIGHTBANE, IN_PROGRESS); HandleTerraceDoors(false); - Talk(YELL_AGGRO); + Talk(YELL_AGGRO); } void AttackStart(Unit* who) override @@ -179,7 +179,7 @@ public: void JustDied(Unit* /*killer*/) override { - instance->SetData(TYPE_NIGHTBANE, DONE); + instance->SetBossState(DATA_NIGHTBANE, DONE); HandleTerraceDoors(true); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp index 450678a0f86..17a23a0b2e7 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp @@ -154,7 +154,7 @@ public: Initialize(); // Not in progress - instance->SetData(TYPE_ARAN, NOT_STARTED); + instance->SetBossState(DATA_ARAN, NOT_STARTED); instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), true); } @@ -167,7 +167,7 @@ public: { Talk(SAY_DEATH); - instance->SetData(TYPE_ARAN, DONE); + instance->SetBossState(DATA_ARAN, DONE); instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), true); } @@ -175,7 +175,7 @@ public: { Talk(SAY_AGGRO); - instance->SetData(TYPE_ARAN, IN_PROGRESS); + instance->SetBossState(DATA_ARAN, IN_PROGRESS); instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), false); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp index 7bc835dcced..2e33f0933e3 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp @@ -61,7 +61,6 @@ enum Creatures NPC_DEMONCHAINS = 17248, NPC_FIENDISHIMP = 17267, NPC_PORTAL = 17265, - NPC_KILREK = 17229 }; @@ -316,7 +315,7 @@ public: Initialize(); - instance->SetData(TYPE_TERESTIAN, NOT_STARTED); + instance->SetBossState(DATA_TERESTIAN, NOT_STARTED); me->RemoveAurasDueToSpell(SPELL_BROKEN_PACT); @@ -371,7 +370,7 @@ public: Talk(SAY_DEATH); - instance->SetData(TYPE_TERESTIAN, DONE); + instance->SetBossState(DATA_TERESTIAN, DONE); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp index d4d0e6fa70d..3f236c060d7 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp @@ -674,6 +674,12 @@ public: void Initialize() { + // Hello, developer from the future! It's me again! + // This time, you're fixing Karazhan scripts. Awesome. These are a mess of hacks. An amalgamation of hacks, so to speak. Maybe even a Patchwerk thereof. + // Anyway, I digress. + // @todo This line below is obviously a hack. Duh. I'm just coming in here to hackfix the encounter to actually be completable. + // It needs a rewrite. Badly. Please, take good care of it. + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE); CycloneTimer = 30000; ChainLightningTimer = 10000; } @@ -701,20 +707,12 @@ public: void EnterCombat(Unit* /*who*/) override { Talk(SAY_CRONE_AGGRO); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); } void JustDied(Unit* /*killer*/) override { Talk(SAY_CRONE_DEATH); - - instance->SetData(TYPE_OPERA, DONE); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORLEFT), true); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORRIGHT), true); - - if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_SIDE_ENTRANCE_DOOR))) - pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); + instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE); } void UpdateAI(uint32 diff) override @@ -722,9 +720,6 @@ public: if (!UpdateVictim()) return; - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (CycloneTimer <= diff) { if (Creature* Cyclone = DoSpawnCreature(CREATURE_CYCLONE, float(urand(0, 9)), float(urand(0, 9)), 0, 0, TEMPSUMMON_TIMED_DESPAWN, 15000)) @@ -908,13 +903,7 @@ public: void JustDied(Unit* /*killer*/) override { DoPlaySoundToSet(me, SOUND_WOLF_DEATH); - - instance->SetData(TYPE_OPERA, DONE); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORLEFT), true); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORRIGHT), true); - - if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_SIDE_ENTRANCE_DOOR))) - pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); + instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE); } void UpdateAI(uint32 diff) override @@ -1158,12 +1147,7 @@ public: void JustDied(Unit* /*killer*/) override { Talk(SAY_JULIANNE_DEATH02); - - instance->SetData(TYPE_OPERA, DONE); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORLEFT), true); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORRIGHT), true); - if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_SIDE_ENTRANCE_DOOR))) - pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); + instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE); } void KilledUnit(Unit* /*victim*/) override @@ -1316,13 +1300,7 @@ public: void JustDied(Unit* /*killer*/) override { Talk(SAY_ROMULO_DEATH); - - instance->SetData(TYPE_OPERA, DONE); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORLEFT), true); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORRIGHT), true); - - if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_SIDE_ENTRANCE_DOOR))) - pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); + instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE); } void KilledUnit(Unit* /*victim*/) override diff --git a/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp index b23b9e645d0..ad403e6aeed 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp @@ -27,8 +27,6 @@ EndScriptData */ #include "InstanceScript.h" #include "karazhan.h" -#define MAX_ENCOUNTER 12 - /* 0 - Attumen + Midnight (optional) 1 - Moroes @@ -44,6 +42,13 @@ EndScriptData */ 11 - Nightbane */ +const Position OptionalSpawn[] = +{ + { -10960.981445f, -1940.138428f, 46.178097f, 4.12f }, // Hyakiss the Lurker + { -10945.769531f, -2040.153320f, 49.474438f, 0.077f }, // Shadikith the Glider + { -10899.903320f, -2085.573730f, 49.474449f, 1.38f } // Rokad the Ravager +}; + class instance_karazhan : public InstanceMapScript { public: @@ -59,150 +64,169 @@ public: instance_karazhan_InstanceMapScript(Map* map) : InstanceScript(map) { SetHeaders(DataHeader); - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + SetBossNumber(EncounterCount); // 1 - OZ, 2 - HOOD, 3 - RAJ, this never gets altered. - m_uiOperaEvent = urand(1, 3); - m_uiOzDeathCount = 0; + OperaEvent = urand(EVENT_OZ, EVENT_RAJ); + OzDeathCount = 0; + OptionalBossCount = 0; } - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string strSaveData; - - uint32 m_uiOperaEvent; - uint32 m_uiOzDeathCount; - - ObjectGuid m_uiCurtainGUID; - ObjectGuid m_uiStageDoorLeftGUID; - ObjectGuid m_uiStageDoorRightGUID; - ObjectGuid m_uiKilrekGUID; - ObjectGuid m_uiTerestianGUID; - ObjectGuid m_uiMoroesGUID; - ObjectGuid m_uiLibraryDoor; // Door at Shade of Aran - ObjectGuid m_uiMassiveDoor; // Door at Netherspite - ObjectGuid m_uiSideEntranceDoor; // Side Entrance - ObjectGuid m_uiGamesmansDoor; // Door before Chess - ObjectGuid m_uiGamesmansExitDoor; // Door after Chess - ObjectGuid m_uiNetherspaceDoor; // Door at Malchezaar - ObjectGuid MastersTerraceDoor[2]; - ObjectGuid ImageGUID; - ObjectGuid DustCoveredChest; - - bool IsEncounterInProgress() const override + void OnCreatureCreate(Creature* creature) override { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - return true; - - return false; + switch (creature->GetEntry()) + { + case NPC_KILREK: + KilrekGUID = creature->GetGUID(); + break; + case NPC_TERESTIAN_ILLHOOF: + TerestianGUID = creature->GetGUID(); + break; + case NPC_MOROES: + MoroesGUID = creature->GetGUID(); + break; + } } - void OnCreatureCreate(Creature* creature) override + void OnUnitDeath(Unit* unit) override { + Creature* creature = unit->ToCreature(); + if (!creature) + return; + switch (creature->GetEntry()) { - case 17229: m_uiKilrekGUID = creature->GetGUID(); break; - case 15688: m_uiTerestianGUID = creature->GetGUID(); break; - case 15687: m_uiMoroesGUID = creature->GetGUID(); break; + case NPC_COLDMIST_WIDOW: + case NPC_COLDMIST_STALKER: + case NPC_SHADOWBAT: + case NPC_VAMPIRIC_SHADOWBAT: + case NPC_GREATER_SHADOWBAT: + case NPC_PHASE_HOUND: + case NPC_DREADBEAST: + case NPC_SHADOWBEAST: + if (GetBossState(DATA_OPTIONAL_BOSS) == TO_BE_DECIDED) + { + ++OptionalBossCount; + if (OptionalBossCount == OPTIONAL_BOSS_REQUIRED_DEATH_COUNT) + { + switch (urand(NPC_HYAKISS_THE_LURKER, NPC_ROKAD_THE_RAVAGER)) + { + case NPC_HYAKISS_THE_LURKER: + instance->SummonCreature(NPC_HYAKISS_THE_LURKER, OptionalSpawn[0]); + break; + case NPC_SHADIKITH_THE_GLIDER: + instance->SummonCreature(NPC_SHADIKITH_THE_GLIDER, OptionalSpawn[1]); + break; + case NPC_ROKAD_THE_RAVAGER: + instance->SummonCreature(NPC_ROKAD_THE_RAVAGER, OptionalSpawn[2]); + break; + } + } + } + break; + default: + break; } } - void SetData(uint32 type, uint32 uiData) override + void SetData(uint32 type, uint32 data) override { switch (type) { - case TYPE_ATTUMEN: m_auiEncounter[0] = uiData; break; - case TYPE_MOROES: - if (m_auiEncounter[1] == DONE) - break; - m_auiEncounter[1] = uiData; + case DATA_OPERA_OZ_DEATHCOUNT: + if (data == SPECIAL) + ++OzDeathCount; + else if (data == IN_PROGRESS) + OzDeathCount = 0; break; - case TYPE_MAIDEN: m_auiEncounter[2] = uiData; break; - case TYPE_OPTIONAL_BOSS: m_auiEncounter[3] = uiData; break; - case TYPE_OPERA: - m_auiEncounter[4] = uiData; - if (uiData == DONE) + } + } + + bool SetBossState(uint32 type, EncounterState state) override + { + if (!InstanceScript::SetBossState(type, state)) + return false; + + switch (type) + { + case DATA_OPERA_PERFORMANCE: + if (state == DONE) + { + HandleGameObject(StageDoorLeftGUID, true); + HandleGameObject(StageDoorRightGUID, true); + if (GameObject* sideEntrance = instance->GetGameObject(SideEntranceDoor)) + sideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, 16812, NULL); + } break; - case TYPE_CURATOR: m_auiEncounter[5] = uiData; break; - case TYPE_ARAN: m_auiEncounter[6] = uiData; break; - case TYPE_TERESTIAN: m_auiEncounter[7] = uiData; break; - case TYPE_NETHERSPITE: m_auiEncounter[8] = uiData; break; - case TYPE_CHESS: - if (uiData == DONE) + case DATA_CHESS: + if (state == DONE) DoRespawnGameObject(DustCoveredChest, DAY); - m_auiEncounter[9] = uiData; break; - case TYPE_MALCHEZZAR: m_auiEncounter[10] = uiData; break; - case TYPE_NIGHTBANE: - if (m_auiEncounter[11] != DONE) - m_auiEncounter[11] = uiData; - break; - case DATA_OPERA_OZ_DEATHCOUNT: - if (uiData == SPECIAL) - ++m_uiOzDeathCount; - else if (uiData == IN_PROGRESS) - m_uiOzDeathCount = 0; + default: break; } - if (uiData == DONE) - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' ' - << m_auiEncounter[3] << ' ' << m_auiEncounter[4] << ' ' << m_auiEncounter[5] << ' ' << m_auiEncounter[6] << ' ' - << m_auiEncounter[7] << ' ' << m_auiEncounter[8] << ' ' << m_auiEncounter[9] << ' ' << m_auiEncounter[10] << ' ' << m_auiEncounter[11]; - - strSaveData = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } + return true; } - void SetGuidData(uint32 identifier, ObjectGuid data) override + void SetGuidData(uint32 type, ObjectGuid data) override { - switch (identifier) - { - case DATA_IMAGE_OF_MEDIVH: ImageGUID = data; - } + if (type == DATA_IMAGE_OF_MEDIVH) + ImageGUID = data; } void OnGameObjectCreate(GameObject* go) override { switch (go->GetEntry()) { - case 183932: m_uiCurtainGUID = go->GetGUID(); break; - case 184278: - m_uiStageDoorLeftGUID = go->GetGUID(); - if (m_auiEncounter[4] == DONE) + case GO_STAGE_CURTAIN: + CurtainGUID = go->GetGUID(); + break; + case GO_STAGE_DOOR_LEFT: + StageDoorLeftGUID = go->GetGUID(); + if (GetBossState(DATA_OPERA_PERFORMANCE) == DONE) go->SetGoState(GO_STATE_ACTIVE); break; - case 184279: - m_uiStageDoorRightGUID = go->GetGUID(); - if (m_auiEncounter[4] == DONE) + case GO_STAGE_DOOR_RIGHT: + StageDoorRightGUID = go->GetGUID(); + if (GetBossState(DATA_OPERA_PERFORMANCE) == DONE) go->SetGoState(GO_STATE_ACTIVE); break; - case 184517: m_uiLibraryDoor = go->GetGUID(); break; - case 185521: m_uiMassiveDoor = go->GetGUID(); break; - case 184276: m_uiGamesmansDoor = go->GetGUID(); break; - case 184277: m_uiGamesmansExitDoor = go->GetGUID(); break; - case 185134: m_uiNetherspaceDoor = go->GetGUID(); break; - case 184274: MastersTerraceDoor[0] = go->GetGUID(); break; - case 184280: MastersTerraceDoor[1] = go->GetGUID(); break; - case 184275: - m_uiSideEntranceDoor = go->GetGUID(); - if (m_auiEncounter[4] == DONE) + case GO_PRIVATE_LIBRARY_DOOR: + LibraryDoor = go->GetGUID(); + break; + case GO_MASSIVE_DOOR: + MassiveDoor = go->GetGUID(); + break; + case GO_GAMESMAN_HALL_DOOR: + GamesmansDoor = go->GetGUID(); + break; + case GO_GAMESMAN_HALL_EXIT_DOOR: + GamesmansExitDoor = go->GetGUID(); + break; + case GO_NETHERSPACE_DOOR: + NetherspaceDoor = go->GetGUID(); + break; + case GO_MASTERS_TERRACE_DOOR: + MastersTerraceDoor[0] = go->GetGUID(); + break; + case GO_MASTERS_TERRACE_DOOR2: + MastersTerraceDoor[1] = go->GetGUID(); + break; + case GO_SIDE_ENTRANCE_DOOR: + SideEntranceDoor = go->GetGUID(); + if (GetBossState(DATA_OPERA_PERFORMANCE) == DONE) go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); else go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED); break; - case 185119: DustCoveredChest = go->GetGUID(); break; + case GO_DUST_COVERED_CHEST: + DustCoveredChest = go->GetGUID(); + break; } - switch (m_uiOperaEvent) + switch (OperaEvent) { /// @todo Set Object visibilities for Opera based on performance case EVENT_OZ: @@ -216,77 +240,77 @@ public: } } - std::string GetSaveData() override + uint32 GetData(uint32 type) const override { - return strSaveData; - } - - uint32 GetData(uint32 uiData) const override - { - switch (uiData) + switch (type) { - case TYPE_ATTUMEN: return m_auiEncounter[0]; - case TYPE_MOROES: return m_auiEncounter[1]; - case TYPE_MAIDEN: return m_auiEncounter[2]; - case TYPE_OPTIONAL_BOSS: return m_auiEncounter[3]; - case TYPE_OPERA: return m_auiEncounter[4]; - case TYPE_CURATOR: return m_auiEncounter[5]; - case TYPE_ARAN: return m_auiEncounter[6]; - case TYPE_TERESTIAN: return m_auiEncounter[7]; - case TYPE_NETHERSPITE: return m_auiEncounter[8]; - case TYPE_CHESS: return m_auiEncounter[9]; - case TYPE_MALCHEZZAR: return m_auiEncounter[10]; - case TYPE_NIGHTBANE: return m_auiEncounter[11]; - case DATA_OPERA_PERFORMANCE: return m_uiOperaEvent; - case DATA_OPERA_OZ_DEATHCOUNT: return m_uiOzDeathCount; + case DATA_OPERA_PERFORMANCE: + return OperaEvent; + case DATA_OPERA_OZ_DEATHCOUNT: + return OzDeathCount; } return 0; } - ObjectGuid GetGuidData(uint32 uiData) const override + ObjectGuid GetGuidData(uint32 type) const override { - switch (uiData) + switch (type) { - case DATA_KILREK: return m_uiKilrekGUID; - case DATA_TERESTIAN: return m_uiTerestianGUID; - case DATA_MOROES: return m_uiMoroesGUID; - case DATA_GO_STAGEDOORLEFT: return m_uiStageDoorLeftGUID; - case DATA_GO_STAGEDOORRIGHT: return m_uiStageDoorRightGUID; - case DATA_GO_CURTAINS: return m_uiCurtainGUID; - case DATA_GO_LIBRARY_DOOR: return m_uiLibraryDoor; - case DATA_GO_MASSIVE_DOOR: return m_uiMassiveDoor; - case DATA_GO_SIDE_ENTRANCE_DOOR: return m_uiSideEntranceDoor; - case DATA_GO_GAME_DOOR: return m_uiGamesmansDoor; - case DATA_GO_GAME_EXIT_DOOR: return m_uiGamesmansExitDoor; - case DATA_GO_NETHER_DOOR: return m_uiNetherspaceDoor; - case DATA_MASTERS_TERRACE_DOOR_1: return MastersTerraceDoor[0]; - case DATA_MASTERS_TERRACE_DOOR_2: return MastersTerraceDoor[1]; - case DATA_IMAGE_OF_MEDIVH: return ImageGUID; + case DATA_KILREK: + return KilrekGUID; + case DATA_TERESTIAN: + return TerestianGUID; + case DATA_MOROES: + return MoroesGUID; + case DATA_GO_STAGEDOORLEFT: + return StageDoorLeftGUID; + case DATA_GO_STAGEDOORRIGHT: + return StageDoorRightGUID; + case DATA_GO_CURTAINS: + return CurtainGUID; + case DATA_GO_LIBRARY_DOOR: + return LibraryDoor; + case DATA_GO_MASSIVE_DOOR: + return MassiveDoor; + case DATA_GO_SIDE_ENTRANCE_DOOR: + return SideEntranceDoor; + case DATA_GO_GAME_DOOR: + return GamesmansDoor; + case DATA_GO_GAME_EXIT_DOOR: + return GamesmansExitDoor; + case DATA_GO_NETHER_DOOR: + return NetherspaceDoor; + case DATA_MASTERS_TERRACE_DOOR_1: + return MastersTerraceDoor[0]; + case DATA_MASTERS_TERRACE_DOOR_2: + return MastersTerraceDoor[1]; + case DATA_IMAGE_OF_MEDIVH: + return ImageGUID; } return ObjectGuid::Empty; } - void Load(char const* chrIn) override - { - if (!chrIn) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(chrIn); - std::istringstream loadStream(chrIn); - - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] - >> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6] >> m_auiEncounter[7] - >> m_auiEncounter[8] >> m_auiEncounter[9] >> m_auiEncounter[10] >> m_auiEncounter[11]; - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead. - m_auiEncounter[i] = NOT_STARTED; - OUT_LOAD_INST_DATA_COMPLETE; - } + private: + uint32 OperaEvent; + uint32 OzDeathCount; + uint32 OptionalBossCount; + ObjectGuid CurtainGUID; + ObjectGuid StageDoorLeftGUID; + ObjectGuid StageDoorRightGUID; + ObjectGuid KilrekGUID; + ObjectGuid TerestianGUID; + ObjectGuid MoroesGUID; + ObjectGuid LibraryDoor; // Door at Shade of Aran + ObjectGuid MassiveDoor; // Door at Netherspite + ObjectGuid SideEntranceDoor; // Side Entrance + ObjectGuid GamesmansDoor; // Door before Chess + ObjectGuid GamesmansExitDoor; // Door after Chess + ObjectGuid NetherspaceDoor; // Door at Malchezaar + ObjectGuid MastersTerraceDoor[2]; + ObjectGuid ImageGUID; + ObjectGuid DustCoveredChest; }; }; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp index aa2da8cc391..ace15cc2a7e 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp @@ -168,7 +168,7 @@ public: void StartEvent() { - instance->SetData(TYPE_OPERA, IN_PROGRESS); + instance->SetBossState(DATA_OPERA_PERFORMANCE, IN_PROGRESS); //resets count for this event, in case earlier failed if (m_uiEventId == EVENT_OZ) @@ -377,7 +377,7 @@ public: if (InstanceScript* instance = creature->GetInstanceScript()) { // Check for death of Moroes and if opera event is not done already - if (instance->GetData(TYPE_MOROES) == DONE && instance->GetData(TYPE_OPERA) != DONE) + if (instance->GetBossState(DATA_MOROES) == DONE && instance->GetBossState(DATA_OPERA_PERFORMANCE) != DONE) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, OZ_GOSSIP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); @@ -562,7 +562,7 @@ public: arca->GetMotionMaster()->MovePoint(0, -11010.82f, -1761.18f, 156.47f); arca->setActive(true); arca->InterruptNonMeleeSpells(true); - arca->SetSpeed(MOVE_FLIGHT, 2.0f); + arca->SetSpeedRate(MOVE_FLIGHT, 2.0f); } return 10000; case 13: diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h index db68484c4a8..05de9e43a91 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h @@ -21,27 +21,26 @@ #define DataHeader "KZ" +uint32 const EncounterCount = 12; + enum DataTypes { - TYPE_ATTUMEN = 1, - TYPE_MOROES = 2, - TYPE_MAIDEN = 3, - TYPE_OPTIONAL_BOSS = 4, - TYPE_OPERA = 5, - TYPE_CURATOR = 6, - TYPE_ARAN = 7, - TYPE_TERESTIAN = 8, - TYPE_NETHERSPITE = 9, - TYPE_CHESS = 10, - TYPE_MALCHEZZAR = 11, - TYPE_NIGHTBANE = 12, + DATA_ATTUMEN = 0, + DATA_MOROES = 1, + DATA_MAIDEN_OF_VIRTUE = 2, + DATA_OPTIONAL_BOSS = 3, + DATA_OPERA_PERFORMANCE = 4, + DATA_CURATOR = 5, + DATA_ARAN = 6, + DATA_TERESTIAN = 7, + DATA_NETHERSPITE = 8, + DATA_CHESS = 9, + DATA_MALCHEZZAR = 10, + DATA_NIGHTBANE = 11, - DATA_OPERA_PERFORMANCE = 13, DATA_OPERA_OZ_DEATHCOUNT = 14, DATA_KILREK = 15, - DATA_TERESTIAN = 16, - DATA_MOROES = 17, DATA_GO_CURTAINS = 18, DATA_GO_STAGEDOORLEFT = 19, DATA_GO_STAGEDOORRIGHT = 20, @@ -64,4 +63,45 @@ enum OperaEvents EVENT_RAJ = 3 }; +enum MiscCreatures +{ + NPC_HYAKISS_THE_LURKER = 16179, + NPC_ROKAD_THE_RAVAGER = 16181, + NPC_SHADIKITH_THE_GLIDER = 16180, + NPC_TERESTIAN_ILLHOOF = 15688, + NPC_MOROES = 15687, + + // Trash + NPC_COLDMIST_WIDOW = 16171, + NPC_COLDMIST_STALKER = 16170, + NPC_SHADOWBAT = 16173, + NPC_VAMPIRIC_SHADOWBAT = 16175, + NPC_GREATER_SHADOWBAT = 16174, + NPC_PHASE_HOUND = 16178, + NPC_DREADBEAST = 16177, + NPC_SHADOWBEAST = 16176, + NPC_KILREK = 17229 +}; + +enum GameObjectIds +{ + GO_STAGE_CURTAIN = 183932, + GO_STAGE_DOOR_LEFT = 184278, + GO_STAGE_DOOR_RIGHT = 184279, + GO_PRIVATE_LIBRARY_DOOR = 184517, + GO_MASSIVE_DOOR = 185521, + GO_GAMESMAN_HALL_DOOR = 184276, + GO_GAMESMAN_HALL_EXIT_DOOR = 184277, + GO_NETHERSPACE_DOOR = 185134, + GO_MASTERS_TERRACE_DOOR = 184274, + GO_MASTERS_TERRACE_DOOR2 = 184280, + GO_SIDE_ENTRANCE_DOOR = 184275, + GO_DUST_COVERED_CHEST = 185119 +}; + +enum Misc +{ + OPTIONAL_BOSS_REQUIRED_DEATH_COUNT = 50 +}; + #endif diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index b809128e731..ebe406c8909 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -405,7 +405,7 @@ public: Creature* Orb = DoSpawnCreature(CREATURE_ARCANE_SPHERE, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); if (Orb && target) { - Orb->SetSpeed(MOVE_RUN, 0.5f); + Orb->SetSpeedRate(MOVE_RUN, 0.5f); Orb->AddThreat(target, 1000000.0f); Orb->AI()->AttackStart(target); } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp index b48f0edec25..6386bb50e1a 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp @@ -16,8 +16,10 @@ */ #include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "InstanceScript.h" #include "magisters_terrace.h" +#include "EventMap.h" /* 0 - Selin Fireheart @@ -36,6 +38,8 @@ DoorData const doorData[] = { 0, 0, DOOR_TYPE_ROOM } // END }; +Position const KalecgosSpawnPos = { 164.3747f, -397.1197f, 2.151798f, 1.66219f }; + class instance_magisters_terrace : public InstanceMapScript { public: @@ -93,6 +97,10 @@ class instance_magisters_terrace : public InstanceMapScript case NPC_DELRISSA: DelrissaGUID = creature->GetGUID(); break; + case NPC_KALECGOS: + case NPC_HUMAN_KALECGOS: + KalecgosGUID = creature->GetGUID(); + break; default: break; } @@ -139,6 +147,25 @@ class instance_magisters_terrace : public InstanceMapScript } } + void ProcessEvent(WorldObject* obj, uint32 eventId) override + { + if (eventId == EVENT_SPAWN_KALECGOS) + if (!ObjectAccessor::GetCreature(*obj, KalecgosGUID) && Events.Empty()) + Events.ScheduleEvent(EVENT_SPAWN_KALECGOS, Minutes(1)); + } + + void Update(uint32 diff) override + { + Events.Update(diff); + + if (Events.ExecuteEvent() == EVENT_SPAWN_KALECGOS) + if (Creature* kalecgos = instance->SummonCreature(NPC_KALECGOS, KalecgosSpawnPos)) + { + kalecgos->GetMotionMaster()->MovePath(PATH_KALECGOS_FLIGHT, false); + kalecgos->AI()->Talk(SAY_KALECGOS_SPAWN); + } + } + bool SetBossState(uint32 type, EncounterState state) override { if (!InstanceScript::SetBossState(type, state)) @@ -177,10 +204,12 @@ class instance_magisters_terrace : public InstanceMapScript } protected: + EventMap Events; ObjectGuid SelinGUID; ObjectGuid DelrissaGUID; ObjectGuid KaelStatue[2]; ObjectGuid EscapeOrbGUID; + ObjectGuid KalecgosGUID; uint32 DelrissaDeathCount; }; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp index e216a024468..5b90ac8ccf4 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp @@ -31,7 +31,8 @@ EndContentData */ #include "ScriptedCreature.h" #include "ScriptedGossip.h" #include "Player.h" -#include "SpellInfo.h" +#include "magisters_terrace.h" +#include "EventMap.h" /*###### ## npc_kalecgos @@ -39,30 +40,29 @@ EndContentData */ enum Spells { - SPELL_TRANSFORM_TO_KAEL = 44670, + SPELL_KALECGOS_TRANSFORM = 44670, + SPELL_TRANSFORM_VISUAL = 24085, + SPELL_CAMERA_SHAKE = 44762, SPELL_ORB_KILL_CREDIT = 46307 }; -enum Creatures +enum MovementPoints { - NPC_KAEL = 24848 //human form entry + POINT_ID_PREPARE_LANDING = 6 }; -enum Misc +enum EventIds { - POINT_ID_LAND = 1 + EVENT_KALECGOS_TRANSFORM = 1, + EVENT_KALECGOS_LANDING = 2 }; -const float afKaelLandPoint[] = {225.045f, -276.236f, -5.434f}; - #define GOSSIP_ITEM_KAEL_1 "Who are you?" #define GOSSIP_ITEM_KAEL_2 "What can we do to assist you?" #define GOSSIP_ITEM_KAEL_3 "What brings you to the Sunwell?" #define GOSSIP_ITEM_KAEL_4 "You're not alone here?" #define GOSSIP_ITEM_KAEL_5 "What would Kil'jaeden want with a mortal woman?" -// This is friendly keal that appear after used Orb. -// If we assume DB handle summon, summon appear somewhere outside the platform where Orb is class npc_kalecgos : public CreatureScript { public: @@ -115,52 +115,46 @@ public: struct npc_kalecgosAI : public ScriptedAI { - npc_kalecgosAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } + npc_kalecgosAI(Creature* creature) : ScriptedAI(creature) { } - void Initialize() + void MovementInform(uint32 type, uint32 pointId) override { - m_uiTransformTimer = 0; - } - - uint32 m_uiTransformTimer; - - void Reset() override - { - Initialize(); - - // we must assume he appear as dragon somewhere outside the platform of orb, and then move directly to here - if (me->GetEntry() != NPC_KAEL) - me->GetMotionMaster()->MovePoint(POINT_ID_LAND, afKaelLandPoint[0], afKaelLandPoint[1], afKaelLandPoint[2]); - } - - void MovementInform(uint32 uiType, uint32 uiPointId) override - { - if (uiType != POINT_MOTION_TYPE) + if (type != WAYPOINT_MOTION_TYPE) return; - if (uiPointId == POINT_ID_LAND) - m_uiTransformTimer = MINUTE*IN_MILLISECONDS; + if (pointId == POINT_ID_PREPARE_LANDING) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + me->SetDisableGravity(false); + me->SetHover(false); + events.ScheduleEvent(EVENT_KALECGOS_LANDING, Seconds(2)); + } } - void UpdateAI(uint32 uiDiff) override + void UpdateAI(uint32 diff) override { - if (m_uiTransformTimer) + events.Update(diff); + + switch (events.ExecuteEvent()) { - if (m_uiTransformTimer <= uiDiff) - { + case EVENT_KALECGOS_LANDING: + DoCastAOE(SPELL_CAMERA_SHAKE); + me->SetObjectScale(0.6f); + events.ScheduleEvent(EVENT_KALECGOS_TRANSFORM, Seconds(1)); + break; + case EVENT_KALECGOS_TRANSFORM: DoCast(me, SPELL_ORB_KILL_CREDIT, true); - - // Transform and update entry, now ready for quest/read gossip - DoCast(me, SPELL_TRANSFORM_TO_KAEL, false); - me->UpdateEntry(NPC_KAEL); - - m_uiTransformTimer = 0; - } else m_uiTransformTimer -= uiDiff; + DoCast(me, SPELL_TRANSFORM_VISUAL, false); + DoCast(me, SPELL_KALECGOS_TRANSFORM, false); + me->UpdateEntry(NPC_HUMAN_KALECGOS); + break; + default: + break; } } + + private: + EventMap events; }; }; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h index 917ad0eb50b..05718dfc1dd 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h @@ -42,7 +42,9 @@ enum CreatureIds { NPC_SELIN = 24723, NPC_DELRISSA = 24560, - NPC_FEL_CRYSTAL = 24722 + NPC_FEL_CRYSTAL = 24722, + NPC_KALECGOS = 24844, + NPC_HUMAN_KALECGOS = 24848 }; enum GameObjectIds @@ -57,4 +59,19 @@ enum GameObjectIds GO_ESCAPE_ORB = 188173 }; +enum InstanceEventIds +{ + EVENT_SPAWN_KALECGOS = 16547 +}; + +enum InstanceText +{ + SAY_KALECGOS_SPAWN = 0 +}; + +enum MovementData +{ + PATH_KALECGOS_FLIGHT = 248440 +}; + #endif diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index 81044a0dbb1..3cf78b79f67 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -396,7 +396,7 @@ class npc_eye_of_acherus : public CreatureScript if (Player* owner = me->GetCharmerOrOwner()->ToPlayer()) { for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) - me->SetSpeed(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i)), true); + me->SetSpeedRate(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i))); Talk(TALK_MOVE_START, owner); } me->GetMotionMaster()->MovePath(me->GetEntry() * 100, false); @@ -419,7 +419,7 @@ class npc_eye_of_acherus : public CreatureScript { owner->RemoveAura(SPELL_EYE_FLIGHT_BOOST); for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) - me->SetSpeed(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i)), true); + me->SetSpeedRate(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i))); Talk(TALK_CONTROL, owner); } @@ -703,7 +703,7 @@ class npc_dark_rider_of_acherus : public CreatureScript TargetGUID = who->GetGUID(); me->SetWalk(true); - me->SetSpeed(MOVE_RUN, 0.4f); + me->SetSpeedRate(MOVE_RUN, 0.4f); me->GetMotionMaster()->MoveChase(who); me->SetTarget(TargetGUID); Intro = true; @@ -1050,7 +1050,7 @@ class npc_scarlet_miner_cart : public CreatureScript // Not 100% correct, but movement is smooth. Sometimes miner walks faster // than normal, this speed is fast enough to keep up at those times. - me->SetSpeed(MOVE_RUN, 1.25f); + me->SetSpeedRate(MOVE_RUN, 1.25f); me->GetMotionMaster()->MoveFollow(miner, 1.0f, 0); } diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp index e336ff24382..d25a225717a 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp @@ -923,7 +923,7 @@ public: if (ObjectAccessor::GetCreature(*me, uiLichKingGUID)) DoCast(me, SPELL_MOGRAINE_CHARGE); // jumping charge // doesn't make it looks well, so workarounds, Darion charges, looks better - me->SetSpeed(MOVE_RUN, 3.0f); + me->SetSpeedRate(MOVE_RUN, 3.0f); me->SetWalk(false); SetHoldState(false); JumpToNextStep(0); @@ -935,7 +935,7 @@ public: temp->HandleEmoteCommand(EMOTE_ONESHOT_KICK); temp->AI()->Talk(SAY_LIGHT_OF_DAWN46); } - me->SetSpeed(MOVE_RUN, 6.0f); + me->SetSpeedRate(MOVE_RUN, 6.0f); me->SetStandState(UNIT_STAND_STATE_DEAD); SetHoldState(false); // Darion got kicked by lich king JumpToNextStep(0); @@ -997,7 +997,7 @@ public: Unit* temp = me->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 10), float(rand32() % 10), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); temp->SetWalk(false); - temp->SetSpeed(MOVE_RUN, 2.0f); + temp->SetSpeedRate(MOVE_RUN, 2.0f); temp->setFaction(me->getFaction()); temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); uiDefenderGUID[0] = temp->GetGUID(); @@ -1005,7 +1005,7 @@ public: temp = me->SummonCreature(NPC_RIMBLAT_EARTHSHATTER, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 10), float(rand32() % 10), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); temp->SetWalk(false); - temp->SetSpeed(MOVE_RUN, 2.0f); + temp->SetSpeedRate(MOVE_RUN, 2.0f); temp->setFaction(me->getFaction()); temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); uiEarthshatterGUID[0] = temp->GetGUID(); @@ -1014,7 +1014,7 @@ public: { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); temp->SetWalk(false); - temp->SetSpeed(MOVE_RUN, 2.0f); + temp->SetSpeedRate(MOVE_RUN, 2.0f); temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); temp->AI()->Talk(SAY_LIGHT_OF_DAWN50); } @@ -1022,7 +1022,7 @@ public: { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); temp->SetWalk(false); - temp->SetSpeed(MOVE_RUN, 2.0f); + temp->SetSpeedRate(MOVE_RUN, 2.0f); temp->HandleEmoteCommand(EMOTE_STATE_ATTACK_UNARMED); temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); } @@ -1030,7 +1030,7 @@ public: { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); temp->SetWalk(false); - temp->SetSpeed(MOVE_RUN, 2.0f); + temp->SetSpeedRate(MOVE_RUN, 2.0f); temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); } } @@ -1044,33 +1044,33 @@ public: if (Creature* temp = ObjectAccessor::GetCreature(*me, uiMaxwellGUID)) { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - temp->SetSpeed(MOVE_RUN, 6.0f); + temp->SetSpeedRate(MOVE_RUN, 6.0f); temp->SetStandState(UNIT_STAND_STATE_DEAD); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[14]); } if (Creature* temp = ObjectAccessor::GetCreature(*me, uiKorfaxGUID)) { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - temp->SetSpeed(MOVE_RUN, 6.0f); + temp->SetSpeedRate(MOVE_RUN, 6.0f); temp->SetStandState(UNIT_STAND_STATE_DEAD); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[11]); } if (Creature* temp = ObjectAccessor::GetCreature(*me, uiEligorGUID)) { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - temp->SetSpeed(MOVE_RUN, 6.0f); + temp->SetSpeedRate(MOVE_RUN, 6.0f); temp->SetStandState(UNIT_STAND_STATE_DEAD); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[17]); } if (Creature* temp = ObjectAccessor::GetCreature(*me, uiDefenderGUID[0])) { - temp->SetSpeed(MOVE_RUN, 6.0f); + temp->SetSpeedRate(MOVE_RUN, 6.0f); temp->SetStandState(UNIT_STAND_STATE_DEAD); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 10), float(rand32() % 10), 0.0f, 0.0f })); } if (Creature* temp = ObjectAccessor::GetCreature(*me, uiEarthshatterGUID[0])) { - temp->SetSpeed(MOVE_RUN, 6.0f); + temp->SetSpeedRate(MOVE_RUN, 6.0f); temp->SetStandState(UNIT_STAND_STATE_DEAD); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 10), float(rand32() % 10), 0.0f, 0.0f })); } @@ -1093,7 +1093,7 @@ public: break; case 46: // Darion stand up, "not today" - me->SetSpeed(MOVE_RUN, 1.0f); + me->SetSpeedRate(MOVE_RUN, 1.0f); me->SetWalk(true); me->SetStandState(UNIT_STAND_STATE_STAND); Talk(SAY_LIGHT_OF_DAWN53); @@ -1153,7 +1153,7 @@ public: temp->AI()->Talk(EMOTE_LIGHT_OF_DAWN16); temp->CastSpell(temp, SPELL_TIRION_CHARGE, false); // jumping charge temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); - temp->SetSpeed(MOVE_RUN, 3.0f); // workarounds, make Tirion still running + temp->SetSpeedRate(MOVE_RUN, 3.0f); // workarounds, make Tirion still running temp->SetWalk(false); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[2]); if (Creature* lktemp = ObjectAccessor::GetCreature(*me, uiLichKingGUID)) @@ -1171,7 +1171,7 @@ public: case 54: if (Creature* temp = ObjectAccessor::GetCreature(*me, uiLichKingGUID)) { - temp->SetSpeed(MOVE_RUN, 1.0f); + temp->SetSpeedRate(MOVE_RUN, 1.0f); me->SetWalk(true); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[29]); // 26 } @@ -1208,7 +1208,7 @@ public: if (Creature* temp = ObjectAccessor::GetCreature(*me, uiTirionGUID)) // Tirion runs to Darion { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - temp->SetSpeed(MOVE_RUN, 1.0f); + temp->SetSpeedRate(MOVE_RUN, 1.0f); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[6]); } JumpToNextStep(2500); diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp index 53b6d2be8dd..9abd0c049d8 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp @@ -109,7 +109,7 @@ public: FlyBackTimer = 4500; break; case 2: - if (!player->isResurrectRequested()) + if (!player->IsResurrectRequested()) { me->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_01); DoCast(player, SPELL_REVIVE, true); diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index dff0a66cec0..f7a1c18c234 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -134,8 +134,6 @@ static char const* Text[]= "Now, know demise!" }; -#define EMOTE_LAUGHS "Headless Horseman laughs" // needs assigned to db. - class npc_wisp_invis : public CreatureScript { public: @@ -347,7 +345,6 @@ public: Creature* speaker = DoSpawnCreature(HELPER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 1000); if (speaker) speaker->CastSpell(speaker, SPELL_HEAD_SPEAKS, false); - me->TextEmote(EMOTE_LAUGHS); } else laugh -= diff; } @@ -453,7 +450,7 @@ public: me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetDisableGravity(true); - me->SetSpeed(MOVE_WALK, 5.0f, true); + me->SetSpeedRate(MOVE_WALK, 5.0f); wp_reached = false; count = 0; say_timer = 3000; @@ -724,7 +721,6 @@ public: if (laugh <= diff) { laugh = urand(11000, 22000); - me->TextEmote(EMOTE_LAUGHS); DoPlaySoundToSet(me, RandomLaugh[rand32() % 3]); } else laugh -= diff; diff --git a/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp b/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp index 118d28e2142..6a6a0b0994b 100644 --- a/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp +++ b/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp @@ -35,15 +35,25 @@ enum Gameobject GO_ATALAI_STATUE4 = 148833, GO_ATALAI_STATUE5 = 148834, GO_ATALAI_STATUE6 = 148835, - GO_ATALAI_IDOL = 148836, GO_ATALAI_LIGHT1 = 148883, GO_ATALAI_LIGHT2 = 148937 - }; enum CreatureIds { - NPC_MALFURION_STORMRAGE = 15362 + NPC_ATALALARION = 8580 +}; + +static Position const atalalarianPos = { -466.5134f, 95.19822f, -189.6463f, 0.03490658f }; +static uint8 const nStatues = 6; +static Position const statuePositions[nStatues] +{ + { -515.553f, 95.25821f, -173.707f, 0.0f }, + { -419.8487f, 94.48368f, -173.707f, 0.0f }, + { -491.4003f, 135.9698f, -173.707f, 0.0f }, + { -491.4909f, 53.48179f, -173.707f, 0.0f }, + { -443.8549f, 136.1007f, -173.707f, 0.0f }, + { -443.4171f, 53.83124f, -173.707f, 0.0f } }; class instance_sunken_temple : public InstanceMapScript @@ -77,7 +87,6 @@ public: ObjectGuid GOAtalaiStatue4; ObjectGuid GOAtalaiStatue5; ObjectGuid GOAtalaiStatue6; - ObjectGuid GOAtalaiIdol; uint32 State; @@ -98,7 +107,6 @@ public: case GO_ATALAI_STATUE4: GOAtalaiStatue4 = go->GetGUID(); break; case GO_ATALAI_STATUE5: GOAtalaiStatue5 = go->GetGUID(); break; case GO_ATALAI_STATUE6: GOAtalaiStatue6 = go->GetGUID(); break; - case GO_ATALAI_IDOL: GOAtalaiIdol = go->GetGUID(); break; } } @@ -155,7 +163,10 @@ public: if (s1 && s2 && s3 && s4 && s5 && !s6) { if (GameObject* pAtalaiStatue6 = instance->GetGameObject(GOAtalaiStatue6)) + { UseStatue(pAtalaiStatue6); + UseLastStatue(pAtalaiStatue6); + } s6 = true; State = 0; } @@ -169,18 +180,13 @@ public: go->SetUInt32Value(GAMEOBJECT_FLAGS, 4); } - /* - void UseLastStatue(GameObject* go) - { - AtalaiStatue1->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue1->GetPositionX(), AtalaiStatue1->GetPositionY(), AtalaiStatue1->GetPositionZ(), 0, 0, 0, 0, 0, 100); - AtalaiStatue2->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue2->GetPositionX(), AtalaiStatue2->GetPositionY(), AtalaiStatue2->GetPositionZ(), 0, 0, 0, 0, 0, 100); - AtalaiStatue3->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue3->GetPositionX(), AtalaiStatue3->GetPositionY(), AtalaiStatue3->GetPositionZ(), 0, 0, 0, 0, 0, 100); - AtalaiStatue4->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue4->GetPositionX(), AtalaiStatue4->GetPositionY(), AtalaiStatue4->GetPositionZ(), 0, 0, 0, 0, 0, 100); - AtalaiStatue5->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue5->GetPositionX(), AtalaiStatue5->GetPositionY(), AtalaiStatue5->GetPositionZ(), 0, 0, 0, 0, 0, 100); - AtalaiStatue6->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue6->GetPositionX(), AtalaiStatue6->GetPositionY(), AtalaiStatue6->GetPositionZ(), 0, 0, 0, 0, 0, 100); - go->SummonGameObject(148838, -488.997, 96.61, -189.019, -1.52, 0, 0, 0, 0, 100); - } - */ + void UseLastStatue(GameObject* go) + { + for (uint8 i = 0; i < nStatues; ++i) + go->SummonGameObject(GO_ATALAI_LIGHT2, statuePositions[i].GetPositionX(), statuePositions[i].GetPositionY(), statuePositions[i].GetPositionZ(), statuePositions[i].GetOrientation(), 0, 0, 0, 0, 0); + + go->SummonCreature(NPC_ATALALARION, atalalarianPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200); + } void SetData(uint32 type, uint32 data) override { diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp index d9b481d7b6d..fded249f9ca 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp @@ -249,7 +249,7 @@ public: me->CastStop(SPELL_FOG_BREATH); me->RemoveAurasDueToSpell(SPELL_FOG_BREATH); me->StopMoving(); - me->SetSpeed(MOVE_RUN, 2.0f); + me->SetSpeedRate(MOVE_RUN, 2.0f); events.ScheduleEvent(EVENT_CLEAVE, urand(5000, 10000)); events.ScheduleEvent(EVENT_CORROSION, urand(10000, 20000)); @@ -530,7 +530,7 @@ public: npc_felmyst_vaporAI(Creature* creature) : ScriptedAI(creature) { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetSpeed(MOVE_RUN, 0.8f); + me->SetSpeedRate(MOVE_RUN, 0.8f); } void Reset() override { } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp index 791f68bae31..72e76ba52bf 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp @@ -425,7 +425,7 @@ class npc_akilzon_eagle : public CreatureScript if (Unit* target = ObjectAccessor::GetUnit(*me, TargetGUID)) DoCast(target, SPELL_EAGLE_SWOOP, true); TargetGUID.Clear(); - me->SetSpeed(MOVE_RUN, 1.2f); + me->SetSpeedRate(MOVE_RUN, 1.2f); EagleSwoop_Timer = urand(5000, 10000); } } @@ -454,7 +454,7 @@ class npc_akilzon_eagle : public CreatureScript { target->GetContactPoint(me, x, y, z); z += 2; - me->SetSpeed(MOVE_RUN, 5.0f); + me->SetSpeedRate(MOVE_RUN, 5.0f); TargetGUID = target->GetGUID(); } me->GetMotionMaster()->MovePoint(0, x, y, z); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp index cc55f758a22..5ec57fc44b6 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp @@ -29,109 +29,104 @@ EndScriptData */ #include "SpellAuraEffects.h" #include "zulaman.h" -#define YELL_AGGRO "Da shadow gonna fall on you... " -#define SOUND_YELL_AGGRO 12041 -#define YELL_SPIRIT_BOLTS "Your soul gonna bleed!" -#define SOUND_YELL_SPIRIT_BOLTS 12047 -#define YELL_DRAIN_POWER "Darkness comin\' for you" -#define SOUND_YELL_DRAIN_POWER 12046 -#define YELL_KILL_ONE "Dis a nightmare ya don\' wake up from!" -#define SOUND_YELL_KILL_ONE 12043 -#define YELL_KILL_TWO "Azzaga choogo zinn!" -#define SOUND_YELL_KILL_TWO 12044 -#define YELL_DEATH "Dis not... da end of me..." -#define SOUND_YELL_DEATH 12051 - +enum Yells +{ + YELL_AGGRO = 0, + YELL_KILL_ONE = 1, + YELL_KILL_TWO = 2, + YELL_DRAIN_POWER = 3, + YELL_SPIRIT_BOLTS = 4, + YELL_DEATH = 5 +}; enum Creatures { - NPC_TEMP_TRIGGER = 23920 + NPC_TEMP_TRIGGER = 23920 }; enum Spells { - SPELL_SPIRIT_BOLTS = 43383, - SPELL_DRAIN_POWER = 44131, - SPELL_SIPHON_SOUL = 43501, + SPELL_SPIRIT_BOLTS = 43383, + SPELL_DRAIN_POWER = 44131, + SPELL_SIPHON_SOUL = 43501, // Druid - SPELL_DR_THORNS = 43420, - SPELL_DR_LIFEBLOOM = 43421, - SPELL_DR_MOONFIRE = 43545, + SPELL_DR_THORNS = 43420, + SPELL_DR_LIFEBLOOM = 43421, + SPELL_DR_MOONFIRE = 43545, // Hunter - SPELL_HU_EXPLOSIVE_TRAP = 43444, - SPELL_HU_FREEZING_TRAP = 43447, - SPELL_HU_SNAKE_TRAP = 43449, + SPELL_HU_EXPLOSIVE_TRAP = 43444, + SPELL_HU_FREEZING_TRAP = 43447, + SPELL_HU_SNAKE_TRAP = 43449, // Mage - SPELL_MG_FIREBALL = 41383, - SPELL_MG_FROST_NOVA = 43426, - SPELL_MG_ICE_LANCE = 43427, - SPELL_MG_FROSTBOLT = 43428, + SPELL_MG_FIREBALL = 41383, + SPELL_MG_FROST_NOVA = 43426, + SPELL_MG_ICE_LANCE = 43427, + SPELL_MG_FROSTBOLT = 43428, // Paladin - SPELL_PA_CONSECRATION = 43429, - SPELL_PA_AVENGING_WRATH = 43430, - SPELL_PA_HOLY_LIGHT = 43451, + SPELL_PA_CONSECRATION = 43429, + SPELL_PA_AVENGING_WRATH = 43430, + SPELL_PA_HOLY_LIGHT = 43451, // Priest - SPELL_PR_HEAL = 41372, - SPELL_PR_MIND_BLAST = 41374, - SPELL_PR_SW_DEATH = 41375, - SPELL_PR_PSYCHIC_SCREAM = 43432, - SPELL_PR_MIND_CONTROL = 43550, - SPELL_PR_PAIN_SUPP = 44416, + SPELL_PR_HEAL = 41372, + SPELL_PR_MIND_BLAST = 41374, + SPELL_PR_SW_DEATH = 41375, + SPELL_PR_PSYCHIC_SCREAM = 43432, + SPELL_PR_MIND_CONTROL = 43550, + SPELL_PR_PAIN_SUPP = 44416, // Rogue - SPELL_RO_BLIND = 43433, - SPELL_RO_SLICE_DICE = 43457, - SPELL_RO_WOUND_POISON = 43461, + SPELL_RO_BLIND = 43433, + SPELL_RO_SLICE_DICE = 43457, + SPELL_RO_WOUND_POISON = 43461, // Shaman - SPELL_SH_CHAIN_LIGHT = 43435, - SPELL_SH_FIRE_NOVA = 43436, - SPELL_SH_HEALING_WAVE = 43548, + SPELL_SH_CHAIN_LIGHT = 43435, + SPELL_SH_FIRE_NOVA = 43436, + SPELL_SH_HEALING_WAVE = 43548, // Warlock - SPELL_WL_CURSE_OF_DOOM = 43439, - SPELL_WL_RAIN_OF_FIRE = 43440, - SPELL_WL_UNSTABLE_AFFL = 43522, - SPELL_WL_UNSTABLE_AFFL_DISPEL = 43523, + SPELL_WL_CURSE_OF_DOOM = 43439, + SPELL_WL_RAIN_OF_FIRE = 43440, + SPELL_WL_UNSTABLE_AFFL = 43522, + SPELL_WL_UNSTABLE_AFFL_DISPEL = 43523, // Warrior - SPELL_WR_MORTAL_STRIKE = 43441, - SPELL_WR_WHIRLWIND = 43442, - SPELL_WR_SPELL_REFLECT = 43443, + SPELL_WR_MORTAL_STRIKE = 43441, + SPELL_WR_WHIRLWIND = 43442, + SPELL_WR_SPELL_REFLECT = 43443, // Thurg - SPELL_BLOODLUST = 43578, - SPELL_CLEAVE = 15496, + SPELL_BLOODLUST = 43578, + SPELL_CLEAVE = 15496, // Gazakroth - SPELL_FIREBOLT = 43584, + SPELL_FIREBOLT = 43584, // Alyson Antille - SPELL_FLASH_HEAL = 43575, - SPELL_DISPEL_MAGIC = 43577, + SPELL_FLASH_HEAL = 43575, + SPELL_DISPEL_MAGIC = 43577, // Lord Raadan - SPELL_FLAME_BREATH = 43582, - SPELL_THUNDERCLAP = 43583, + SPELL_FLAME_BREATH = 43582, + SPELL_THUNDERCLAP = 43583, // Darkheart - SPELL_PSYCHIC_WAIL = 43590, + SPELL_PSYCHIC_WAIL = 43590, // Slither - SPELL_VENOM_SPIT = 43579, + SPELL_VENOM_SPIT = 43579, // Fenstalker - SPELL_VOLATILE_INFECTION = 43586, + SPELL_VOLATILE_INFECTION = 43586, // Koragg - SPELL_COLD_STARE = 43593, - SPELL_MIGHTY_BLOW = 43592 - + SPELL_COLD_STARE = 43593, + SPELL_MIGHTY_BLOW = 43592 }; #define ORIENT 1.5696f @@ -306,8 +301,7 @@ class boss_hexlord_malacrass : public CreatureScript instance->SetData(DATA_HEXLORDEVENT, IN_PROGRESS); DoZoneInCombat(); - me->Yell(YELL_AGGRO, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_AGGRO); + Talk(YELL_AGGRO); for (uint8 i = 0; i < 4; ++i) { @@ -327,12 +321,10 @@ class boss_hexlord_malacrass : public CreatureScript switch (urand(0, 1)) { case 0: - me->Yell(YELL_KILL_ONE, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE); + Talk(YELL_KILL_ONE); break; case 1: - me->Yell(YELL_KILL_TWO, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO); + Talk(YELL_KILL_TWO); break; } } @@ -341,8 +333,7 @@ class boss_hexlord_malacrass : public CreatureScript { instance->SetData(DATA_HEXLORDEVENT, DONE); - me->Yell(YELL_DEATH, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_DEATH); + Talk(YELL_DEATH); for (uint8 i = 0; i < 4; ++i) { @@ -415,8 +406,7 @@ class boss_hexlord_malacrass : public CreatureScript if (DrainPower_Timer <= diff) { DoCast(me, SPELL_DRAIN_POWER, true); - me->Yell(YELL_DRAIN_POWER, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_DRAIN_POWER); + Talk(YELL_DRAIN_POWER); DrainPower_Timer = urand(40000, 55000); // must cast in 60 sec, or buff/debuff will disappear } else DrainPower_Timer -= diff; @@ -427,8 +417,7 @@ class boss_hexlord_malacrass : public CreatureScript else { DoCast(me, SPELL_SPIRIT_BOLTS, false); - me->Yell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_SPIRIT_BOLTS); + Talk(YELL_SPIRIT_BOLTS); SpiritBolts_Timer = 40000; SiphonSoul_Timer = 10000; // ready to drain PlayerAbility_Timer = 99999; diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp index 37505a8b74d..188f9d0cc03 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp @@ -30,21 +30,41 @@ EndScriptData */ #include "GridNotifiersImpl.h" #include "CellImpl.h" -enum Spells +enum Yells { - SPELL_BERSERK = 45078, + YELL_NALORAKK_WAVE1 = 0, + YELL_NALORAKK_WAVE2 = 1, + YELL_NALORAKK_WAVE3 = 2, + YELL_NALORAKK_WAVE4 = 3, + YELL_AGGRO = 4, + YELL_SURGE = 5, + YELL_SHIFTEDTOBEAR = 6, + YELL_SHIFTEDTOTROLL = 7, + YELL_BERSERK = 8, + YELL_KILL_ONE = 9, + YELL_KILL_TWO = 10, + YELL_DEATH = 11 + +// Not yet implemented +// YELL_NALORAKK_EVENT1 = 12, +// YELL_NALORAKK_EVENT2 = 13 +}; +enum Spells +{ // Troll form - SPELL_BRUTALSWIPE = 42384, - SPELL_MANGLE = 42389, - SPELL_MANGLEEFFECT = 44955, - SPELL_SURGE = 42402, - SPELL_BEARFORM = 42377, + SPELL_BRUTALSWIPE = 42384, + SPELL_MANGLE = 42389, + SPELL_MANGLEEFFECT = 44955, + SPELL_SURGE = 42402, + SPELL_BEARFORM = 42377, // Bear form - SPELL_LACERATINGSLASH = 42395, - SPELL_RENDFLESH = 42397, - SPELL_DEAFENINGROAR = 42398 + SPELL_LACERATINGSLASH = 42395, + SPELL_RENDFLESH = 42397, + SPELL_DEAFENINGROAR = 42398, + + SPELL_BERSERK = 45078 }; // Trash Waves @@ -57,45 +77,9 @@ float NalorakkWay[8][3] = {-79.929f, 1395.958f, 27.31f}, {-80.072f, 1374.555f, 40.87f}, // waypoint 3 {-80.072f, 1314.398f, 40.87f}, - {-80.072f, 1295.775f, 48.60f} // waypoint 4 + {-80.072f, 1295.775f, 48.60f} // waypoint 4 }; -#define YELL_NALORAKK_WAVE1 "Get da move on, guards! It be killin' time!" -#define SOUND_NALORAKK_WAVE1 12066 -#define YELL_NALORAKK_WAVE2 "Guards, go already! Who you more afraid of, dem... or me?" -#define SOUND_NALORAKK_WAVE2 12067 -#define YELL_NALORAKK_WAVE3 "Ride now! Ride out dere and bring me back some heads!" -#define SOUND_NALORAKK_WAVE3 12068 -#define YELL_NALORAKK_WAVE4 "I be losin' me patience! Go on: make dem wish dey was never born!" -#define SOUND_NALORAKK_WAVE4 12069 - -//Unimplemented SoundIDs -/* -#define SOUND_NALORAKK_EVENT1 12078 -#define SOUND_NALORAKK_EVENT2 12079 -*/ - -//General defines -#define YELL_AGGRO "You be dead soon enough!" -#define SOUND_YELL_AGGRO 12070 -#define YELL_KILL_ONE "Mua-ha-ha! Now whatchoo got to say?" -#define SOUND_YELL_KILL_ONE 12075 -#define YELL_KILL_TWO "Da Amani gonna rule again!" -#define SOUND_YELL_KILL_TWO 12076 -#define YELL_DEATH "I... be waitin' on da udda side...." -#define SOUND_YELL_DEATH 12077 -#define YELL_BERSERK "You had your chance, now it be too late!" //Never seen this being used, so just guessing from what I hear. -#define SOUND_YELL_BERSERK 12074 -#define YELL_SURGE "I bring da pain!" -#define SOUND_YELL_SURGE 12071 - -#define YELL_SHIFTEDTOTROLL "Make way for Nalorakk!" -#define SOUND_YELL_TOTROLL 12073 - - -#define YELL_SHIFTEDTOBEAR "You call on da beast, you gonna get more dan you bargain for!" -#define SOUND_YELL_TOBEAR 12072 - class boss_nalorakk : public CreatureScript { public: @@ -158,7 +142,7 @@ class boss_nalorakk : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); inMove = false; waitTimer = 0; - me->SetSpeed(MOVE_RUN, 2); + me->SetSpeedRate(MOVE_RUN, 2); me->SetWalk(false); }else { @@ -227,8 +211,7 @@ class boss_nalorakk : public CreatureScript case 0: if (me->IsWithinDistInMap(who, 50)) { - me->Yell(YELL_NALORAKK_WAVE1, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE1); + Talk(YELL_NALORAKK_WAVE1); (*me).GetMotionMaster()->MovePoint(1, NalorakkWay[1][0], NalorakkWay[1][1], NalorakkWay[1][2]); MovePhase ++; @@ -240,8 +223,7 @@ class boss_nalorakk : public CreatureScript case 2: if (me->IsWithinDistInMap(who, 40)) { - me->Yell(YELL_NALORAKK_WAVE2, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE2); + Talk(YELL_NALORAKK_WAVE2); (*me).GetMotionMaster()->MovePoint(3, NalorakkWay[3][0], NalorakkWay[3][1], NalorakkWay[3][2]); MovePhase ++; @@ -253,8 +235,7 @@ class boss_nalorakk : public CreatureScript case 5: if (me->IsWithinDistInMap(who, 40)) { - me->Yell(YELL_NALORAKK_WAVE3, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE3); + Talk(YELL_NALORAKK_WAVE3); (*me).GetMotionMaster()->MovePoint(6, NalorakkWay[6][0], NalorakkWay[6][1], NalorakkWay[6][2]); MovePhase ++; @@ -268,8 +249,7 @@ class boss_nalorakk : public CreatureScript { SendAttacker(who); - me->Yell(YELL_NALORAKK_WAVE4, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE4); + Talk(YELL_NALORAKK_WAVE4); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); @@ -287,8 +267,7 @@ class boss_nalorakk : public CreatureScript { instance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS); - me->Yell(YELL_AGGRO, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_AGGRO); + Talk(YELL_AGGRO); DoZoneInCombat(); } @@ -296,8 +275,7 @@ class boss_nalorakk : public CreatureScript { instance->SetData(DATA_NALORAKKEVENT, DONE); - me->Yell(YELL_DEATH, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_DEATH); + Talk(YELL_DEATH); } void KilledUnit(Unit* /*victim*/) override @@ -305,12 +283,10 @@ class boss_nalorakk : public CreatureScript switch (urand(0, 1)) { case 0: - me->Yell(YELL_KILL_ONE, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE); + Talk(YELL_KILL_ONE); break; case 1: - me->Yell(YELL_KILL_TWO, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO); + Talk(YELL_KILL_TWO); break; } } @@ -373,8 +349,7 @@ class boss_nalorakk : public CreatureScript if (Berserk_Timer <= diff) { DoCast(me, SPELL_BERSERK, true); - me->Yell(YELL_BERSERK, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_BERSERK); + Talk(YELL_BERSERK); Berserk_Timer = 600000; } else Berserk_Timer -= diff; @@ -383,8 +358,7 @@ class boss_nalorakk : public CreatureScript if (inBearForm) { // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); - me->Yell(YELL_SHIFTEDTOTROLL, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_TOTROLL); + Talk(YELL_SHIFTEDTOTROLL); me->RemoveAurasDueToSpell(SPELL_BEARFORM); Surge_Timer = urand(15000, 20000); BrutalSwipe_Timer = urand(7000, 12000); @@ -395,8 +369,7 @@ class boss_nalorakk : public CreatureScript else { // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0); - me->Yell(YELL_SHIFTEDTOBEAR, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_TOBEAR); + Talk(YELL_SHIFTEDTOBEAR); DoCast(me, SPELL_BEARFORM, true); LaceratingSlash_Timer = 2000; // dur 18s RendFlesh_Timer = 3000; // dur 5s @@ -426,8 +399,7 @@ class boss_nalorakk : public CreatureScript if (Surge_Timer <= diff) { - me->Yell(YELL_SURGE, LANG_UNIVERSAL); - DoPlaySoundToSet(me, SOUND_YELL_SURGE); + Talk(YELL_SURGE); Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 45, true); if (target) DoCast(target, SPELL_SURGE); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp index 96c0798ae05..a1c2369cf66 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp @@ -347,7 +347,7 @@ class boss_zuljin : public CreatureScript Vortex->CastSpell(Vortex, SPELL_CYCLONE_PASSIVE, true); Vortex->CastSpell(Vortex, SPELL_CYCLONE_VISUAL, true); Vortex->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Vortex->SetSpeed(MOVE_RUN, 1.0f); + Vortex->SetSpeedRate(MOVE_RUN, 1.0f); Vortex->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0)); DoZoneInCombat(Vortex); } @@ -438,7 +438,7 @@ class boss_zuljin : public CreatureScript { if (me->GetVictim()) TankGUID = me->EnsureVictim()->GetGUID(); - me->SetSpeed(MOVE_RUN, 5.0f); + me->SetSpeedRate(MOVE_RUN, 5.0f); AttackStart(target); // change victim Claw_Rage_Timer = 0; Claw_Loop_Timer = 500; @@ -462,7 +462,7 @@ class boss_zuljin : public CreatureScript if (Claw_Counter == 12) { Claw_Rage_Timer = urand(15000, 20000); - me->SetSpeed(MOVE_RUN, 1.2f); + me->SetSpeedRate(MOVE_RUN, 1.2f); AttackStart(ObjectAccessor::GetUnit(*me, TankGUID)); TankGUID.Clear(); return; @@ -487,7 +487,7 @@ class boss_zuljin : public CreatureScript if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { TankGUID = me->EnsureVictim()->GetGUID(); - me->SetSpeed(MOVE_RUN, 5.0f); + me->SetSpeedRate(MOVE_RUN, 5.0f); AttackStart(target); // change victim Lynx_Rush_Timer = 0; Claw_Counter = 0; @@ -510,7 +510,7 @@ class boss_zuljin : public CreatureScript if (Claw_Counter == 9) { Lynx_Rush_Timer = urand(15000, 20000); - me->SetSpeed(MOVE_RUN, 1.2f); + me->SetSpeedRate(MOVE_RUN, 1.2f); AttackStart(ObjectAccessor::GetUnit(*me, TankGUID)); TankGUID.Clear(); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp index 8c179af2adf..3697b0876c8 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -148,6 +148,11 @@ class boss_mandokir : public CreatureScript instance->SaveToDB(); } + void JustReachedHome() override + { + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); + } + void EnterCombat(Unit* /*who*/) override { _EnterCombat(); @@ -194,9 +199,9 @@ class boss_mandokir : public CreatureScript me->SetWalk(false); if (id == POINT_MANDOKIR_END) { - me->SetHomePosition(PosMandokir[0]); + me->SetHomePosition(PosMandokir[1]); + me->GetMotionMaster()->MoveTargetedHome(); instance->SetBossState(DATA_MANDOKIR, NOT_STARTED); - me->DespawnOrUnsummon(6000); // No idea how to respawn on wipe. } } } diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp new file mode 100644 index 00000000000..b794a653791 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This is where scripts' loading functions should be declared: +void AddSC_alterac_valley(); //Alterac Valley +void AddSC_boss_balinda(); +void AddSC_boss_drekthar(); +void AddSC_boss_galvangar(); +void AddSC_boss_vanndar(); +void AddSC_blackrock_depths(); //Blackrock Depths +void AddSC_boss_ambassador_flamelash(); +void AddSC_boss_draganthaurissan(); +void AddSC_boss_general_angerforge(); +void AddSC_boss_high_interrogator_gerstahn(); +void AddSC_boss_magmus(); +void AddSC_boss_moira_bronzebeard(); +void AddSC_boss_tomb_of_seven(); +void AddSC_instance_blackrock_depths(); +void AddSC_boss_drakkisath(); //Blackrock Spire +void AddSC_boss_halycon(); +void AddSC_boss_highlordomokk(); +void AddSC_boss_mothersmolderweb(); +void AddSC_boss_overlordwyrmthalak(); +void AddSC_boss_shadowvosh(); +void AddSC_boss_thebeast(); +void AddSC_boss_warmastervoone(); +void AddSC_boss_quatermasterzigris(); +void AddSC_boss_pyroguard_emberseer(); +void AddSC_boss_gyth(); +void AddSC_boss_rend_blackhand(); +void AddSC_boss_gizrul_the_slavener(); +void AddSC_boss_urok_doomhowl(); +void AddSC_boss_lord_valthalak(); +void AddSC_instance_blackrock_spire(); +void AddSC_boss_razorgore(); //Blackwing lair +void AddSC_boss_vaelastrasz(); +void AddSC_boss_broodlord(); +void AddSC_boss_firemaw(); +void AddSC_boss_ebonroc(); +void AddSC_boss_flamegor(); +void AddSC_boss_chromaggus(); +void AddSC_boss_nefarian(); +void AddSC_instance_blackwing_lair(); +void AddSC_deadmines(); //Deadmines +void AddSC_instance_deadmines(); +void AddSC_boss_mr_smite(); +void AddSC_gnomeregan(); //Gnomeregan +void AddSC_instance_gnomeregan(); +void AddSC_boss_attumen(); //Karazhan +void AddSC_boss_curator(); +void AddSC_boss_maiden_of_virtue(); +void AddSC_boss_shade_of_aran(); +void AddSC_boss_malchezaar(); +void AddSC_boss_terestian_illhoof(); +void AddSC_boss_moroes(); +void AddSC_bosses_opera(); +void AddSC_boss_netherspite(); +void AddSC_instance_karazhan(); +void AddSC_karazhan(); +void AddSC_boss_nightbane(); +void AddSC_boss_felblood_kaelthas(); // Magister's Terrace +void AddSC_boss_selin_fireheart(); +void AddSC_boss_vexallus(); +void AddSC_boss_priestess_delrissa(); +void AddSC_instance_magisters_terrace(); +void AddSC_magisters_terrace(); +void AddSC_boss_lucifron(); //Molten core +void AddSC_boss_magmadar(); +void AddSC_boss_gehennas(); +void AddSC_boss_garr(); +void AddSC_boss_baron_geddon(); +void AddSC_boss_shazzrah(); +void AddSC_boss_golemagg(); +void AddSC_boss_sulfuron(); +void AddSC_boss_majordomo(); +void AddSC_boss_ragnaros(); +void AddSC_instance_molten_core(); +void AddSC_the_scarlet_enclave(); //Scarlet Enclave +void AddSC_the_scarlet_enclave_c1(); +void AddSC_the_scarlet_enclave_c2(); +void AddSC_the_scarlet_enclave_c5(); +void AddSC_boss_arcanist_doan(); //Scarlet Monastery +void AddSC_boss_azshir_the_sleepless(); +void AddSC_boss_bloodmage_thalnos(); +void AddSC_boss_headless_horseman(); +void AddSC_boss_herod(); +void AddSC_boss_high_inquisitor_fairbanks(); +void AddSC_boss_houndmaster_loksey(); +void AddSC_boss_interrogator_vishas(); +void AddSC_boss_scorn(); +void AddSC_instance_scarlet_monastery(); +void AddSC_boss_mograine_and_whitemane(); +void AddSC_boss_darkmaster_gandling(); //Scholomance +void AddSC_boss_death_knight_darkreaver(); +void AddSC_boss_theolenkrastinov(); +void AddSC_boss_illuciabarov(); +void AddSC_boss_instructormalicia(); +void AddSC_boss_jandicebarov(); +void AddSC_boss_kormok(); +void AddSC_boss_lordalexeibarov(); +void AddSC_boss_lorekeeperpolkelt(); +void AddSC_boss_rasfrost(); +void AddSC_boss_theravenian(); +void AddSC_boss_vectus(); +void AddSC_boss_kirtonos_the_herald(); +void AddSC_instance_scholomance(); +void AddSC_shadowfang_keep(); //Shadowfang keep +void AddSC_instance_shadowfang_keep(); +void AddSC_boss_magistrate_barthilas(); //Stratholme +void AddSC_boss_maleki_the_pallid(); +void AddSC_boss_nerubenkan(); +void AddSC_boss_cannon_master_willey(); +void AddSC_boss_baroness_anastari(); +void AddSC_boss_ramstein_the_gorger(); +void AddSC_boss_timmy_the_cruel(); +void AddSC_boss_postmaster_malown(); +void AddSC_boss_baron_rivendare(); +void AddSC_boss_dathrohan_balnazzar(); +void AddSC_boss_order_of_silver_hand(); +void AddSC_instance_stratholme(); +void AddSC_stratholme(); +void AddSC_sunken_temple(); // Sunken Temple +void AddSC_instance_sunken_temple(); +void AddSC_instance_sunwell_plateau(); //Sunwell Plateau +void AddSC_boss_kalecgos(); +void AddSC_boss_brutallus(); +void AddSC_boss_felmyst(); +void AddSC_boss_eredar_twins(); +void AddSC_boss_muru(); +void AddSC_boss_kiljaeden(); +void AddSC_sunwell_plateau(); +void AddSC_boss_archaedas(); //Uldaman +void AddSC_boss_ironaya(); +void AddSC_uldaman(); +void AddSC_instance_uldaman(); +void AddSC_instance_the_stockade(); //The Stockade +void AddSC_boss_akilzon(); //Zul'Aman +void AddSC_boss_halazzi(); +void AddSC_boss_hex_lord_malacrass(); +void AddSC_boss_janalai(); +void AddSC_boss_nalorakk(); +void AddSC_boss_zuljin(); +void AddSC_instance_zulaman(); +void AddSC_zulaman(); +void AddSC_boss_jeklik(); //Zul'Gurub +void AddSC_boss_venoxis(); +void AddSC_boss_marli(); +void AddSC_boss_mandokir(); +void AddSC_boss_gahzranka(); +void AddSC_boss_thekal(); +void AddSC_boss_arlokk(); +void AddSC_boss_jindo(); +void AddSC_boss_hakkar(); +void AddSC_boss_grilek(); +void AddSC_boss_hazzarah(); +void AddSC_boss_renataki(); +void AddSC_boss_wushoolay(); +void AddSC_instance_zulgurub(); +//void AddSC_alterac_mountains(); +void AddSC_arathi_highlands(); +void AddSC_blasted_lands(); +void AddSC_burning_steppes(); +void AddSC_duskwood(); +void AddSC_eastern_plaguelands(); +void AddSC_ghostlands(); +void AddSC_hinterlands(); +void AddSC_isle_of_queldanas(); +void AddSC_loch_modan(); +void AddSC_redridge_mountains(); +void AddSC_silverpine_forest(); +void AddSC_stormwind_city(); +void AddSC_stranglethorn_vale(); +void AddSC_swamp_of_sorrows(); +void AddSC_tirisfal_glades(); +void AddSC_undercity(); +void AddSC_western_plaguelands(); +void AddSC_wetlands(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddEasternKingdomsScripts() +{ + AddSC_alterac_valley(); //Alterac Valley + AddSC_boss_balinda(); + AddSC_boss_drekthar(); + AddSC_boss_galvangar(); + AddSC_boss_vanndar(); + AddSC_blackrock_depths(); //Blackrock Depths + AddSC_boss_ambassador_flamelash(); + AddSC_boss_draganthaurissan(); + AddSC_boss_general_angerforge(); + AddSC_boss_high_interrogator_gerstahn(); + AddSC_boss_magmus(); + AddSC_boss_moira_bronzebeard(); + AddSC_boss_tomb_of_seven(); + AddSC_instance_blackrock_depths(); + AddSC_boss_drakkisath(); //Blackrock Spire + AddSC_boss_halycon(); + AddSC_boss_highlordomokk(); + AddSC_boss_mothersmolderweb(); + AddSC_boss_overlordwyrmthalak(); + AddSC_boss_shadowvosh(); + AddSC_boss_thebeast(); + AddSC_boss_warmastervoone(); + AddSC_boss_quatermasterzigris(); + AddSC_boss_pyroguard_emberseer(); + AddSC_boss_gyth(); + AddSC_boss_rend_blackhand(); + AddSC_boss_gizrul_the_slavener(); + AddSC_boss_urok_doomhowl(); + AddSC_boss_lord_valthalak(); + AddSC_instance_blackrock_spire(); + AddSC_boss_razorgore(); //Blackwing lair + AddSC_boss_vaelastrasz(); + AddSC_boss_broodlord(); + AddSC_boss_firemaw(); + AddSC_boss_ebonroc(); + AddSC_boss_flamegor(); + AddSC_boss_chromaggus(); + AddSC_boss_nefarian(); + AddSC_instance_blackwing_lair(); + AddSC_deadmines(); //Deadmines + AddSC_boss_mr_smite(); + AddSC_instance_deadmines(); + AddSC_gnomeregan(); //Gnomeregan + AddSC_instance_gnomeregan(); + AddSC_boss_attumen(); //Karazhan + AddSC_boss_curator(); + AddSC_boss_maiden_of_virtue(); + AddSC_boss_shade_of_aran(); + AddSC_boss_malchezaar(); + AddSC_boss_terestian_illhoof(); + AddSC_boss_moroes(); + AddSC_bosses_opera(); + AddSC_boss_netherspite(); + AddSC_instance_karazhan(); + AddSC_karazhan(); + AddSC_boss_nightbane(); + AddSC_boss_felblood_kaelthas(); // Magister's Terrace + AddSC_boss_selin_fireheart(); + AddSC_boss_vexallus(); + AddSC_boss_priestess_delrissa(); + AddSC_instance_magisters_terrace(); + AddSC_magisters_terrace(); + AddSC_boss_lucifron(); //Molten core + AddSC_boss_magmadar(); + AddSC_boss_gehennas(); + AddSC_boss_garr(); + AddSC_boss_baron_geddon(); + AddSC_boss_shazzrah(); + AddSC_boss_golemagg(); + AddSC_boss_sulfuron(); + AddSC_boss_majordomo(); + AddSC_boss_ragnaros(); + AddSC_instance_molten_core(); + AddSC_the_scarlet_enclave(); //Scarlet Enclave + AddSC_the_scarlet_enclave_c1(); + AddSC_the_scarlet_enclave_c2(); + AddSC_the_scarlet_enclave_c5(); + AddSC_boss_arcanist_doan(); //Scarlet Monastery + AddSC_boss_azshir_the_sleepless(); + AddSC_boss_bloodmage_thalnos(); + AddSC_boss_headless_horseman(); + AddSC_boss_herod(); + AddSC_boss_high_inquisitor_fairbanks(); + AddSC_boss_houndmaster_loksey(); + AddSC_boss_interrogator_vishas(); + AddSC_boss_scorn(); + AddSC_instance_scarlet_monastery(); + AddSC_boss_mograine_and_whitemane(); + AddSC_boss_darkmaster_gandling(); //Scholomance + AddSC_boss_death_knight_darkreaver(); + AddSC_boss_theolenkrastinov(); + AddSC_boss_illuciabarov(); + AddSC_boss_instructormalicia(); + AddSC_boss_jandicebarov(); + AddSC_boss_kormok(); + AddSC_boss_lordalexeibarov(); + AddSC_boss_lorekeeperpolkelt(); + AddSC_boss_rasfrost(); + AddSC_boss_theravenian(); + AddSC_boss_vectus(); + AddSC_boss_kirtonos_the_herald(); + AddSC_instance_scholomance(); + AddSC_shadowfang_keep(); //Shadowfang keep + AddSC_instance_shadowfang_keep(); + AddSC_boss_magistrate_barthilas(); //Stratholme + AddSC_boss_maleki_the_pallid(); + AddSC_boss_nerubenkan(); + AddSC_boss_cannon_master_willey(); + AddSC_boss_baroness_anastari(); + AddSC_boss_ramstein_the_gorger(); + AddSC_boss_timmy_the_cruel(); + AddSC_boss_postmaster_malown(); + AddSC_boss_baron_rivendare(); + AddSC_boss_dathrohan_balnazzar(); + AddSC_boss_order_of_silver_hand(); + AddSC_instance_stratholme(); + AddSC_stratholme(); + AddSC_sunken_temple(); // Sunken Temple + AddSC_instance_sunken_temple(); + AddSC_instance_sunwell_plateau(); //Sunwell Plateau + AddSC_boss_kalecgos(); + AddSC_boss_brutallus(); + AddSC_boss_felmyst(); + AddSC_boss_eredar_twins(); + AddSC_boss_muru(); + AddSC_boss_kiljaeden(); + AddSC_sunwell_plateau(); + AddSC_instance_the_stockade(); //The Stockade + AddSC_boss_archaedas(); //Uldaman + AddSC_boss_ironaya(); + AddSC_uldaman(); + AddSC_instance_uldaman(); + AddSC_boss_akilzon(); //Zul'Aman + AddSC_boss_halazzi(); + AddSC_boss_hex_lord_malacrass(); + AddSC_boss_janalai(); + AddSC_boss_nalorakk(); + AddSC_boss_zuljin(); + AddSC_instance_zulaman(); + AddSC_zulaman(); + AddSC_boss_jeklik(); //Zul'Gurub + AddSC_boss_venoxis(); + AddSC_boss_marli(); + AddSC_boss_mandokir(); + AddSC_boss_gahzranka(); + AddSC_boss_thekal(); + AddSC_boss_arlokk(); + AddSC_boss_jindo(); + AddSC_boss_hakkar(); + AddSC_boss_grilek(); + AddSC_boss_hazzarah(); + AddSC_boss_renataki(); + AddSC_boss_wushoolay(); + AddSC_instance_zulgurub(); + //AddSC_alterac_mountains(); + AddSC_arathi_highlands(); + AddSC_blasted_lands(); + AddSC_burning_steppes(); + AddSC_duskwood(); + AddSC_eastern_plaguelands(); + AddSC_ghostlands(); + AddSC_hinterlands(); + AddSC_isle_of_queldanas(); + AddSC_loch_modan(); + AddSC_redridge_mountains(); + AddSC_silverpine_forest(); + AddSC_stormwind_city(); + AddSC_stranglethorn_vale(); + AddSC_swamp_of_sorrows(); + AddSC_tirisfal_glades(); + AddSC_undercity(); + AddSC_western_plaguelands(); + AddSC_wetlands(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp index df61a010f84..73b397553a5 100644 --- a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp +++ b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp @@ -19,7 +19,7 @@ /* ScriptData SDName: Burning_Steppes SD%Complete: 100 -SDComment: Quest support: 4224, 4866 +SDComment: Quest support: 4866 SDCategory: Burning Steppes EndScriptData */ @@ -36,25 +36,11 @@ EndContentData */ ## npc_ragged_john ######*/ -#define GOSSIP_HELLO "Official buisness, John. I need some information about Marsha Windsor. Tell me about the last time you saw him." -#define GOSSIP_SELECT1 "So what did you do?" -#define GOSSIP_SELECT2 "Start making sense, dwarf. I don't want to have anything to do with your cracker, your pappy, or any sort of 'discreditin'." -#define GOSSIP_SELECT3 "Ironfoe?" -#define GOSSIP_SELECT4 "Interesting... continue John." -#define GOSSIP_SELECT5 "So that's how Windsor died..." -#define GOSSIP_SELECT6 "So how did he die?" -#define GOSSIP_SELECT7 "Ok so where the hell is he? Wait a minute! Are you drunk?" -#define GOSSIP_SELECT8 "WHY is he in Blackrock Depths?" -#define GOSSIP_SELECT9 "300? So the Dark Irons killed him and dragged him into the Depths?" -#define GOSSIP_SELECT10 "Ahh... Ironfoe" -#define GOSSIP_SELECT11 "Thanks, Ragged John. Your story was very uplifting and informative" - enum RaggedJohn { - QUEST_THE_TRUE_MASTERS = 4224, - QUEST_MOTHERS_MILK = 4866, - SPELL_MOTHERS_MILK = 16468, - SPELL_WICKED_MILKING = 16472 + QUEST_MOTHERS_MILK = 4866, + SPELL_MOTHERS_MILK = 16468, + SPELL_WICKED_MILKING = 16472 }; class npc_ragged_john : public CreatureScript @@ -86,72 +72,13 @@ public: void EnterCombat(Unit* /*who*/) override { } }; - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(2714, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(2715, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(2716, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(2717, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - player->SEND_GOSSIP_MENU(2718, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - player->SEND_GOSSIP_MENU(2719, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); - player->SEND_GOSSIP_MENU(2720, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+7: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT8, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8); - player->SEND_GOSSIP_MENU(2721, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+8: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT9, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); - player->SEND_GOSSIP_MENU(2722, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+9: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT10, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10); - player->SEND_GOSSIP_MENU(2723, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+10: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT11, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); - player->SEND_GOSSIP_MENU(2725, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+11: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(QUEST_THE_TRUE_MASTERS); - break; - } - return true; - } - bool OnGossipHello(Player* player, Creature* creature) override { if (creature->IsQuestGiver()) + { player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_THE_TRUE_MASTERS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(2713, creature->GetGUID()); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + } return true; } diff --git a/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp index ce0ebf4d129..4cc72715868 100644 --- a/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp @@ -19,7 +19,7 @@ /* ScriptData SDName: Eastern_Plaguelands SD%Complete: 100 -SDComment: Quest support: 5211, 5742. Special vendor Augustus the Touched +SDComment: Quest support: 5211. Special vendor Augustus the Touched SDCategory: Eastern Plaguelands EndScriptData */ @@ -27,7 +27,6 @@ EndScriptData */ npc_ghoul_flayer npc_augustus_the_touched npc_darrowshire_spirit -npc_tirion_fordring EndContentData */ #include "ScriptMgr.h" @@ -133,63 +132,9 @@ public: }; }; -/*###### -## npc_tirion_fordring -######*/ - -#define GOSSIP_HELLO "I am ready to hear your tale, Tirion." -#define GOSSIP_SELECT1 "Thank you, Tirion. What of your identity?" -#define GOSSIP_SELECT2 "That is terrible." -#define GOSSIP_SELECT3 "I will, Tirion." - -class npc_tirion_fordring : public CreatureScript -{ -public: - npc_tirion_fordring() : CreatureScript("npc_tirion_fordring") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(4493, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(4494, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(4495, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(5742); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(5742) == QUEST_STATUS_INCOMPLETE && player->getStandState() == UNIT_STAND_STATE_SIT) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - void AddSC_eastern_plaguelands() { new npc_ghoul_flayer(); new npc_augustus_the_touched(); new npc_darrowshire_spirit(); - new npc_tirion_fordring(); } diff --git a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp index 2d6d4da5aef..4a585bcb267 100644 --- a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp +++ b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp @@ -19,14 +19,12 @@ /* ScriptData SDName: Stormwind_City SD%Complete: 100 -SDComment: Quest support: 1640, 1447, 4185, 11223, 434. +SDComment: Quest support: 1640, 1447, 434. SDCategory: Stormwind City EndScriptData */ /* ContentData -npc_archmage_malin npc_bartleby -npc_lady_katrana_prestor npc_tyrion npc_tyrion_spybot npc_marzon_silent_blade @@ -40,50 +38,13 @@ EndContentData */ #include "Player.h" /*###### -## npc_archmage_malin -######*/ - -#define GOSSIP_ITEM_MALIN "Can you send me to Theramore? I have an urgent message for Lady Jaina from Highlord Bolvar." - -class npc_archmage_malin : public CreatureScript -{ -public: - npc_archmage_malin() : CreatureScript("npc_archmage_malin") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, 42711, true); - } - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(11223) == QUEST_STATUS_COMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MALIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### ## npc_bartleby ######*/ enum Bartleby { - FACTION_ENEMY = 168, - QUEST_BEAT = 1640 + FACTION_ENEMY = 168, + QUEST_BEAT = 1640 }; class npc_bartleby : public CreatureScript @@ -148,71 +109,18 @@ public: }; /*###### -## npc_lady_katrana_prestor -######*/ - -#define GOSSIP_ITEM_KAT_1 "Pardon the intrusion, Lady Prestor, but Highlord Bolvar suggested that I seek your advice." -#define GOSSIP_ITEM_KAT_2 "My apologies, Lady Prestor." -#define GOSSIP_ITEM_KAT_3 "Begging your pardon, Lady Prestor. That was not my intent." -#define GOSSIP_ITEM_KAT_4 "Thank you for your time, Lady Prestor." - -class npc_lady_katrana_prestor : public CreatureScript -{ -public: - npc_lady_katrana_prestor() : CreatureScript("npc_lady_katrana_prestor") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(2694, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(2695, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(2696, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(4185); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(4185) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(2693, creature->GetGUID()); - - return true; - } -}; - -/*###### ## npc_lord_gregor_lescovar ######*/ enum LordGregorLescovar { - SAY_GUARD_2 = 0, - SAY_LESCOVAR_2 = 0, - SAY_LESCOVAR_3 = 1, - SAY_LESCOVAR_4 = 2, - SAY_MARZON_1 = 0, - SAY_MARZON_2 = 1, - SAY_TYRION_2 = 1, + SAY_GUARD_2 = 0, + SAY_LESCOVAR_2 = 0, + SAY_LESCOVAR_3 = 1, + SAY_LESCOVAR_4 = 2, + SAY_MARZON_1 = 0, + SAY_MARZON_2 = 1, + SAY_TYRION_2 = 1, NPC_STORMWIND_ROYAL = 1756, NPC_MARZON_BLADE = 1755, @@ -650,9 +558,7 @@ public: void AddSC_stormwind_city() { - new npc_archmage_malin(); new npc_bartleby(); - new npc_lady_katrana_prestor(); new npc_tyrion(); new npc_tyrion_spybot(); new npc_lord_gregor_lescovar(); diff --git a/src/server/scripts/EasternKingdoms/zone_undercity.cpp b/src/server/scripts/EasternKingdoms/zone_undercity.cpp index c0b4e06cfff..99556587e65 100644 --- a/src/server/scripts/EasternKingdoms/zone_undercity.cpp +++ b/src/server/scripts/EasternKingdoms/zone_undercity.cpp @@ -157,7 +157,7 @@ public: { if (Creature* target = ObjectAccessor::GetCreature(*summoned, targetGUID)) { - target->GetMotionMaster()->MoveJump(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ() + 15.0f, 0); + target->GetMotionMaster()->MoveJump(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ() + 15.0f, me->GetOrientation(), 0); target->SetPosition(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0.0f); summoned->CastSpell(target, SPELL_RIBBON_OF_SOULS, false); } diff --git a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp index b1a00f35bb5..a01b93a140b 100644 --- a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp @@ -25,7 +25,6 @@ EndScriptData */ /* ContentData npcs_dithers_and_arbington -npc_myranda_the_hag npc_the_scourge_cauldron npc_andorhal_tower EndContentData */ @@ -33,7 +32,6 @@ EndContentData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" #include "Player.h" #include "WorldSession.h" @@ -120,54 +118,6 @@ public: }; /*###### -## npc_myranda_the_hag -######*/ - -enum Myranda -{ - ILLUSION_GOSSIP = 4773, - QUEST_SUBTERFUGE = 5862, - QUEST_IN_DREAMS = 5944, - SPELL_SCARLET_ILLUSION = 17961 -}; - -class npc_myranda_the_hag : public CreatureScript -{ -public: - npc_myranda_the_hag() : CreatureScript("npc_myranda_the_hag") { } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF + 1) - { - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_SCARLET_ILLUSION, false); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_SUBTERFUGE) == QUEST_STATUS_COMPLETE && - player->GetQuestStatus(QUEST_IN_DREAMS) != QUEST_STATUS_COMPLETE && - !player->HasAura(SPELL_SCARLET_ILLUSION)) - { - player->ADD_GOSSIP_ITEM_DB(Player::GetDefaultGossipMenuForSource(creature), 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(ILLUSION_GOSSIP, creature->GetGUID()); - return true; - } - else - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### ## npc_the_scourge_cauldron ######*/ @@ -195,7 +145,7 @@ public: me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); //override any database `spawntimesecs` to prevent duplicated summons uint32 rTime = me->GetRespawnDelay(); - if (rTime<600) + if (rTime < 600) me->SetRespawnDelay(600); } @@ -274,7 +224,6 @@ public: } void MoveInLineOfSight(Unit* who) override - { if (!who || who->GetTypeId() != TYPEID_PLAYER) return; @@ -286,14 +235,9 @@ public: }; }; -/*###### -## -######*/ - void AddSC_western_plaguelands() { new npcs_dithers_and_arbington(); - new npc_myranda_the_hag(); new npc_the_scourge_cauldron(); new npc_andorhal_tower(); } diff --git a/src/server/scripts/Events/CMakeLists.txt b/src/server/scripts/Events/CMakeLists.txt deleted file mode 100644 index 1c9e5cfe8e1..00000000000 --- a/src/server/scripts/Events/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -file(GLOB_RECURSE sources_Events Events/*.cpp Events/*.h) - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - ${sources_Events} -) - -message(" -> Prepared: Events") diff --git a/src/server/scripts/Events/events_script_loader.cpp b/src/server/scripts/Events/events_script_loader.cpp new file mode 100644 index 00000000000..625c08f5389 --- /dev/null +++ b/src/server/scripts/Events/events_script_loader.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This is where scripts' loading functions should be declared: +void AddSC_event_childrens_week(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddEventsScripts() +{ + AddSC_event_childrens_week(); +} diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt deleted file mode 100644 index 2d1b4b49649..00000000000 --- a/src/server/scripts/Kalimdor/CMakeLists.txt +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - Kalimdor/zone_stonetalon_mountains.cpp - Kalimdor/zone_silithus.cpp - Kalimdor/zone_moonglade.cpp - Kalimdor/RazorfenDowns/razorfen_downs.cpp - Kalimdor/RazorfenDowns/instance_razorfen_downs.cpp - Kalimdor/RazorfenDowns/boss_tuten_kash.cpp - Kalimdor/RazorfenDowns/boss_mordresh_fire_eye.cpp - Kalimdor/RazorfenDowns/boss_glutton.cpp - Kalimdor/RazorfenDowns/boss_amnennar_the_coldbringer.cpp - Kalimdor/RazorfenDowns/razorfen_downs.h - Kalimdor/ZulFarrak/zulfarrak.cpp - Kalimdor/ZulFarrak/instance_zulfarrak.cpp - Kalimdor/ZulFarrak/boss_zum_rah.cpp - Kalimdor/ZulFarrak/zulfarrak.h - Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp - Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h - Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp - Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp - Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp - Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp - Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp - Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h - Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h - Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp - Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp - Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp - Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp - Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp - Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp - Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h - Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp - Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite_corruptor.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm_the_fleshcrafter.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/boss_meathook.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h - Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h - Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp - Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp - Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp - Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp - Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp - Kalimdor/BlackfathomDeeps/boss_kelris.cpp - Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp - Kalimdor/BlackfathomDeeps/boss_gelihast.cpp - Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp - Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp - Kalimdor/BlackfathomDeeps/blackfathom_deeps.h - Kalimdor/zone_azuremyst_isle.cpp - Kalimdor/zone_orgrimmar.cpp - Kalimdor/zone_desolace.cpp - Kalimdor/zone_feralas.cpp - Kalimdor/Maraudon/boss_princess_theradras.cpp - Kalimdor/Maraudon/boss_landslide.cpp - Kalimdor/Maraudon/boss_celebras_the_cursed.cpp - Kalimdor/Maraudon/boss_noxxion.cpp - Kalimdor/Maraudon/instance_maraudon.cpp - Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp - Kalimdor/TempleOfAhnQiraj/boss_huhuran.cpp - Kalimdor/TempleOfAhnQiraj/instance_temple_of_ahnqiraj.cpp - Kalimdor/TempleOfAhnQiraj/mob_anubisath_sentinel.cpp - Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp - Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp - Kalimdor/TempleOfAhnQiraj/boss_sartura.cpp - Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp - Kalimdor/TempleOfAhnQiraj/temple_of_ahnqiraj.h - Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp - Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp - Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp - Kalimdor/zone_darkshore.cpp - Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp - Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp - Kalimdor/RuinsOfAhnQiraj/boss_rajaxx.cpp - Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp - Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp - Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp - Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h - Kalimdor/RuinsOfAhnQiraj/boss_kurinnaxx.cpp - Kalimdor/zone_bloodmyst_isle.cpp - Kalimdor/zone_thunder_bluff.cpp - Kalimdor/zone_azshara.cpp - Kalimdor/RazorfenKraul/razorfen_kraul.h - Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp - Kalimdor/RazorfenKraul/razorfen_kraul.cpp - Kalimdor/zone_the_barrens.cpp - Kalimdor/zone_ungoro_crater.cpp - Kalimdor/WailingCaverns/wailing_caverns.h - Kalimdor/WailingCaverns/instance_wailing_caverns.cpp - Kalimdor/WailingCaverns/wailing_caverns.cpp - Kalimdor/zone_durotar.cpp - Kalimdor/zone_felwood.cpp - Kalimdor/boss_azuregos.cpp - Kalimdor/zone_tanaris.cpp - Kalimdor/zone_dustwallow_marsh.cpp - Kalimdor/zone_winterspring.cpp - Kalimdor/zone_thousand_needles.cpp - Kalimdor/zone_ashenvale.cpp - Kalimdor/OnyxiasLair/boss_onyxia.cpp - Kalimdor/OnyxiasLair/onyxias_lair.h - Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp - Kalimdor/RagefireChasm/instance_ragefire_chasm.cpp - Kalimdor/DireMaul/instance_dire_maul.cpp -) - -message(" -> Prepared: Kalimdor") diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h index 55b85801652..54d3c53039e 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h @@ -121,15 +121,15 @@ struct hyjalAI : public npc_escortAI void Initialize(); - void Reset(); // Generically used to reset our variables. Do *not* call in EnterEvadeMode as this may make problems if the raid is still in combat + void Reset() override; // Generically used to reset our variables. Do *not* call in EnterEvadeMode as this may make problems if the raid is still in combat - void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER); // Send creature back to spawn location and evade. + void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override; // Send creature back to spawn location and evade. - void EnterCombat(Unit* /*who*/); // Used to reset cooldowns for our spells and to inform the raid that we're under attack + void EnterCombat(Unit* /*who*/) override; // Used to reset cooldowns for our spells and to inform the raid that we're under attack - void UpdateAI(uint32 diff); // Called to summon waves, check for boss deaths and to cast our spells. + void UpdateAI(uint32 diff) override; // Called to summon waves, check for boss deaths and to cast our spells. - void JustDied(Unit* /*killer*/); // Called on death, informs the raid that they have failed. + void JustDied(Unit* /*killer*/) override; // Called on death, informs the raid that they have failed. void SetFaction(uint32 _faction) // Set the faction to either Alliance or Horde in Hyjal { @@ -140,13 +140,13 @@ struct hyjalAI : public npc_escortAI void SpawnVeins(); void DeSpawnVeins(); - void JustSummoned(Creature* summoned); - void SummonedCreatureDespawn(Creature* summoned); + void JustSummoned(Creature* summoned) override; + void SummonedCreatureDespawn(Creature* summoned) override; void HideNearPos(float x, float y); void RespawnNearPos(float x, float y); - void WaypointReached(uint32 waypointId); + void WaypointReached(uint32 waypointId) override; void DoOverrun(uint32 faction, const uint32 diff); - void MoveInLineOfSight(Unit* who); + void MoveInLineOfSight(Unit* who) override; void SummonCreature(uint32 entry, float Base[4][3]); // Summons a creature for that wave in that base diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h index 5275c07f63a..f29851e7cea 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h @@ -25,11 +25,11 @@ struct hyjal_trashAI : public npc_escortAI { hyjal_trashAI(Creature* creature); - void UpdateAI(uint32 diff); + void UpdateAI(uint32 diff) override; - void JustDied(Unit* /*killer*/); + void JustDied(Unit* /*killer*/) override; - void DamageTaken(Unit* done_by, uint32 &damage); + void DamageTaken(Unit* done_by, uint32 &damage) override; public: InstanceScript* instance; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp index 44cbdec2cb5..0526dcfa630 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -479,12 +479,12 @@ public: void DoMount() { me->Mount(SKARLOC_MOUNT_MODEL); - me->SetSpeed(MOVE_RUN, SPEED_MOUNT); + me->SetSpeedRate(MOVE_RUN, SPEED_MOUNT); } void DoUnmount() { me->Dismount(); - me->SetSpeed(MOVE_RUN, SPEED_RUN); + me->SetSpeedRate(MOVE_RUN, SPEED_RUN); } void EnterCombat(Unit* /*who*/) override { diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp index 7da15b1fdce..71ebe870e3d 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp +++ b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp @@ -205,7 +205,7 @@ public: PointData = GetMoveData(); MovePoint = PointData->LocIdEnd; - me->SetSpeed(MOVE_FLIGHT, 1.5f); + me->SetSpeedRate(MOVE_FLIGHT, 1.5f); me->GetMotionMaster()->MovePoint(8, MiddleRoomLocation); } } @@ -220,7 +220,7 @@ public: PointData = GetMoveData(); if (PointData) { - me->SetSpeed(MOVE_FLIGHT, 1.0f); + me->SetSpeedRate(MOVE_FLIGHT, 1.0f); me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); } break; @@ -250,7 +250,7 @@ public: if (Creature * trigger = me->SummonCreature(NPC_TRIGGER, MiddleRoomLocation, TEMPSUMMON_CORPSE_DESPAWN)) triggerGUID = trigger->GetGUID(); me->GetMotionMaster()->MoveTakeoff(11, Phase2Floating); - me->SetSpeed(MOVE_FLIGHT, 1.0f); + me->SetSpeedRate(MOVE_FLIGHT, 1.0f); Talk(SAY_PHASE_2_TRANS); instance->SetData(DATA_ONYXIA_PHASE, Phase); events.ScheduleEvent(EVENT_WHELP_SPAWN, 5000); diff --git a/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp b/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp new file mode 100644 index 00000000000..87edf4781d4 --- /dev/null +++ b/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This is where scripts' loading functions should be declared: +void AddSC_blackfathom_deeps(); //Blackfathom Depths +void AddSC_boss_gelihast(); +void AddSC_boss_kelris(); +void AddSC_boss_aku_mai(); +void AddSC_instance_blackfathom_deeps(); +void AddSC_hyjal(); //CoT Battle for Mt. Hyjal +void AddSC_boss_archimonde(); +void AddSC_instance_mount_hyjal(); +void AddSC_hyjal_trash(); +void AddSC_boss_rage_winterchill(); +void AddSC_boss_anetheron(); +void AddSC_boss_kazrogal(); +void AddSC_boss_azgalor(); +void AddSC_boss_captain_skarloc(); //CoT Old Hillsbrad +void AddSC_boss_epoch_hunter(); +void AddSC_boss_lieutenant_drake(); +void AddSC_instance_old_hillsbrad(); +void AddSC_old_hillsbrad(); +void AddSC_boss_aeonus(); //CoT The Black Morass +void AddSC_boss_chrono_lord_deja(); +void AddSC_boss_temporus(); +void AddSC_the_black_morass(); +void AddSC_instance_the_black_morass(); +void AddSC_boss_epoch(); //CoT Culling Of Stratholme +void AddSC_boss_infinite_corruptor(); +void AddSC_boss_salramm(); +void AddSC_boss_mal_ganis(); +void AddSC_boss_meathook(); +void AddSC_culling_of_stratholme(); +void AddSC_instance_culling_of_stratholme(); +void AddSC_instance_dire_maul(); //Dire Maul +void AddSC_instance_ragefire_chasm(); //Ragefire Chasm +void AddSC_boss_celebras_the_cursed(); //Maraudon +void AddSC_boss_landslide(); +void AddSC_boss_noxxion(); +void AddSC_boss_ptheradras(); +void AddSC_instance_maraudon(); +void AddSC_boss_onyxia(); //Onyxia's Lair +void AddSC_instance_onyxias_lair(); +void AddSC_boss_tuten_kash(); //Razorfen Downs +void AddSC_boss_mordresh_fire_eye(); +void AddSC_boss_glutton(); +void AddSC_boss_amnennar_the_coldbringer(); +void AddSC_razorfen_downs(); +void AddSC_instance_razorfen_downs(); +void AddSC_razorfen_kraul(); //Razorfen Kraul +void AddSC_instance_razorfen_kraul(); +void AddSC_boss_kurinnaxx(); //Ruins of ahn'qiraj +void AddSC_boss_rajaxx(); +void AddSC_boss_moam(); +void AddSC_boss_buru(); +void AddSC_boss_ayamiss(); +void AddSC_boss_ossirian(); +void AddSC_instance_ruins_of_ahnqiraj(); +void AddSC_boss_cthun(); //Temple of ahn'qiraj +void AddSC_boss_viscidus(); +void AddSC_boss_fankriss(); +void AddSC_boss_huhuran(); +void AddSC_bug_trio(); +void AddSC_boss_sartura(); +void AddSC_boss_skeram(); +void AddSC_boss_twinemperors(); +void AddSC_boss_ouro(); +void AddSC_npc_anubisath_sentinel(); +void AddSC_instance_temple_of_ahnqiraj(); +void AddSC_wailing_caverns(); //Wailing caverns +void AddSC_instance_wailing_caverns(); +void AddSC_boss_zum_rah(); //Zul'Farrak +void AddSC_zulfarrak(); +void AddSC_instance_zulfarrak(); + +void AddSC_ashenvale(); +void AddSC_azshara(); +void AddSC_azuremyst_isle(); +void AddSC_bloodmyst_isle(); +void AddSC_boss_azuregos(); +void AddSC_darkshore(); +void AddSC_desolace(); +void AddSC_durotar(); +void AddSC_dustwallow_marsh(); +void AddSC_felwood(); +void AddSC_feralas(); +void AddSC_moonglade(); +void AddSC_orgrimmar(); +void AddSC_silithus(); +void AddSC_stonetalon_mountains(); +void AddSC_tanaris(); +void AddSC_the_barrens(); +void AddSC_thousand_needles(); +void AddSC_thunder_bluff(); +void AddSC_ungoro_crater(); +void AddSC_winterspring(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddKalimdorScripts() +{ + AddSC_blackfathom_deeps(); //Blackfathom Depths + AddSC_boss_gelihast(); + AddSC_boss_kelris(); + AddSC_boss_aku_mai(); + AddSC_instance_blackfathom_deeps(); + AddSC_hyjal(); //CoT Battle for Mt. Hyjal + AddSC_boss_archimonde(); + AddSC_instance_mount_hyjal(); + AddSC_hyjal_trash(); + AddSC_boss_rage_winterchill(); + AddSC_boss_anetheron(); + AddSC_boss_kazrogal(); + AddSC_boss_azgalor(); + AddSC_boss_captain_skarloc(); //CoT Old Hillsbrad + AddSC_boss_epoch_hunter(); + AddSC_boss_lieutenant_drake(); + AddSC_instance_old_hillsbrad(); + AddSC_old_hillsbrad(); + AddSC_boss_aeonus(); //CoT The Black Morass + AddSC_boss_chrono_lord_deja(); + AddSC_boss_temporus(); + AddSC_the_black_morass(); + AddSC_instance_the_black_morass(); + AddSC_boss_epoch(); //CoT Culling Of Stratholme + AddSC_boss_infinite_corruptor(); + AddSC_boss_salramm(); + AddSC_boss_mal_ganis(); + AddSC_boss_meathook(); + AddSC_culling_of_stratholme(); + AddSC_instance_culling_of_stratholme(); + AddSC_instance_dire_maul(); //Dire Maul + AddSC_instance_ragefire_chasm(); //Ragefire Chasm + AddSC_boss_celebras_the_cursed(); //Maraudon + AddSC_boss_landslide(); + AddSC_boss_noxxion(); + AddSC_boss_ptheradras(); + AddSC_instance_maraudon(); + AddSC_boss_onyxia(); //Onyxia's Lair + AddSC_instance_onyxias_lair(); + AddSC_boss_tuten_kash(); //Razorfen Downs + AddSC_boss_mordresh_fire_eye(); + AddSC_boss_glutton(); + AddSC_boss_amnennar_the_coldbringer(); + AddSC_razorfen_downs(); + AddSC_instance_razorfen_downs(); + AddSC_razorfen_kraul(); //Razorfen Kraul + AddSC_instance_razorfen_kraul(); + AddSC_boss_kurinnaxx(); //Ruins of ahn'qiraj + AddSC_boss_rajaxx(); + AddSC_boss_moam(); + AddSC_boss_buru(); + AddSC_boss_ayamiss(); + AddSC_boss_ossirian(); + AddSC_instance_ruins_of_ahnqiraj(); + AddSC_boss_cthun(); //Temple of ahn'qiraj + AddSC_boss_viscidus(); + AddSC_boss_fankriss(); + AddSC_boss_huhuran(); + AddSC_bug_trio(); + AddSC_boss_sartura(); + AddSC_boss_skeram(); + AddSC_boss_twinemperors(); + AddSC_boss_ouro(); + AddSC_npc_anubisath_sentinel(); + AddSC_instance_temple_of_ahnqiraj(); + AddSC_wailing_caverns(); //Wailing caverns + AddSC_instance_wailing_caverns(); + AddSC_boss_zum_rah(); //Zul'Farrak + AddSC_zulfarrak(); + AddSC_instance_zulfarrak(); + + AddSC_ashenvale(); + AddSC_azshara(); + AddSC_azuremyst_isle(); + AddSC_bloodmyst_isle(); + AddSC_boss_azuregos(); + AddSC_darkshore(); + AddSC_desolace(); + AddSC_durotar(); + AddSC_dustwallow_marsh(); + AddSC_felwood(); + AddSC_feralas(); + AddSC_moonglade(); + AddSC_orgrimmar(); + AddSC_silithus(); + AddSC_stonetalon_mountains(); + AddSC_tanaris(); + AddSC_the_barrens(); + AddSC_thousand_needles(); + AddSC_thunder_bluff(); + AddSC_ungoro_crater(); + AddSC_winterspring(); +} diff --git a/src/server/scripts/Kalimdor/zone_ashenvale.cpp b/src/server/scripts/Kalimdor/zone_ashenvale.cpp index 52a83c02a8a..50730507b8f 100644 --- a/src/server/scripts/Kalimdor/zone_ashenvale.cpp +++ b/src/server/scripts/Kalimdor/zone_ashenvale.cpp @@ -31,6 +31,7 @@ EndContentData */ #include "ScriptedCreature.h" #include "ScriptedEscortAI.h" #include "Player.h" +#include "SpellScript.h" /*#### # npc_ruul_snowhoof @@ -344,9 +345,42 @@ class go_naga_brazier : public GameObjectScript } }; +enum KingoftheFoulwealdMisc +{ + GO_BANNER = 178205 +}; + +class spell_destroy_karangs_banner : public SpellScriptLoader +{ + public: + spell_destroy_karangs_banner() : SpellScriptLoader("spell_destroy_karangs_banner") { } + + class spell_destroy_karangs_banner_SpellScript : public SpellScript + { + PrepareSpellScript(spell_destroy_karangs_banner_SpellScript); + + void HandleAfterCast() + { + if (GameObject* banner = GetCaster()->FindNearestGameObject(GO_BANNER, GetSpellInfo()->GetMaxRange(true))) + banner->Delete(); + } + + void Register() override + { + AfterCast += SpellCastFn(spell_destroy_karangs_banner_SpellScript::HandleAfterCast); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_destroy_karangs_banner_SpellScript(); + } +}; + void AddSC_ashenvale() { new npc_ruul_snowhoof(); new npc_muglash(); new go_naga_brazier(); + new spell_destroy_karangs_banner(); } diff --git a/src/server/scripts/Kalimdor/zone_azshara.cpp b/src/server/scripts/Kalimdor/zone_azshara.cpp index 1ed95c16a0d..4847ac46542 100644 --- a/src/server/scripts/Kalimdor/zone_azshara.cpp +++ b/src/server/scripts/Kalimdor/zone_azshara.cpp @@ -404,7 +404,7 @@ public: DoCast(me, SPELL_PERIODIC_DEPTH_CHARGE); me->SetHover(true); me->SetSwim(true); - me->SetSpeed(MOVE_RUN, 0.85f, true); + me->SetSpeedRate(MOVE_RUN, 0.85f); me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]); Escape = true; diff --git a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp index 273e81d83c0..6063b9fe5c6 100644 --- a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp +++ b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp @@ -240,11 +240,6 @@ class npc_sironas : public CreatureScript public: npc_sironas() : CreatureScript("npc_sironas") { } - CreatureAI* GetAI(Creature* creature) const - { - return new npc_sironasAI(creature); - } - struct npc_sironasAI : public ScriptedAI { npc_sironasAI(Creature* creature) : ScriptedAI(creature) { } @@ -343,6 +338,11 @@ public: GuidList _beamGuidList; EventMap _events; }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_sironasAI(creature); + } }; /*###### @@ -354,11 +354,6 @@ class npc_demolitionist_legoso : public CreatureScript public: npc_demolitionist_legoso() : CreatureScript("npc_demolitionist_legoso") { } - CreatureAI* GetAI(Creature* creature) const - { - return new npc_demolitionist_legosoAI(creature); - } - struct npc_demolitionist_legosoAI : public npc_escortAI { npc_demolitionist_legosoAI(Creature* creature) : npc_escortAI(creature) @@ -812,6 +807,11 @@ public: GuidList _explosivesGuids; EventMap _events; }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_demolitionist_legosoAI(creature); + } }; void AddSC_bloodmyst_isle() diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp index 621e0b0a585..3f4a905147f 100644 --- a/src/server/scripts/Kalimdor/zone_desolace.cpp +++ b/src/server/scripts/Kalimdor/zone_desolace.cpp @@ -66,7 +66,6 @@ public: npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) { } void MoveInLineOfSight(Unit* who) override - { if (who->GetEntry() == NPC_SMEED && me->IsWithinDistInMap(who, 10.0f) && !me->HasAura(SPELL_KODO_KOMBO_GOSSIP)) { @@ -90,7 +89,7 @@ public: me->UpdateEntry(NPC_TAMED_KODO); me->CombatStop(); me->DeleteThreatList(); - me->SetSpeed(MOVE_RUN, 0.6f, true); + me->SetSpeedRate(MOVE_RUN, 0.6f); me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle()); me->setActive(true); } @@ -226,37 +225,9 @@ public: } }; -/*###### -## go_demon_portal -######*/ - -enum DemonPortal -{ - NPC_DEMON_GUARDIAN = 11937, - QUEST_PORTAL_OF_THE_LEGION = 5581 -}; - -class go_demon_portal : public GameObjectScript -{ - public: - go_demon_portal() : GameObjectScript("go_demon_portal") { } - - bool OnGossipHello(Player* player, GameObject* go) override - { - if (player->GetQuestStatus(QUEST_PORTAL_OF_THE_LEGION) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_GUARDIAN, 5.0f, true)) - { - if (Creature* guardian = player->SummonCreature(NPC_DEMON_GUARDIAN, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0)) - guardian->AI()->AttackStart(player); - } - - return true; - } -}; - void AddSC_desolace() { new npc_aged_dying_ancient_kodo(); new go_iruxos(); new npc_dalinda(); - new go_demon_portal(); } diff --git a/src/server/scripts/Kalimdor/zone_durotar.cpp b/src/server/scripts/Kalimdor/zone_durotar.cpp index 05caf9cca3a..62a041e7798 100644 --- a/src/server/scripts/Kalimdor/zone_durotar.cpp +++ b/src/server/scripts/Kalimdor/zone_durotar.cpp @@ -483,8 +483,8 @@ class spell_mount_check : public SpellScriptLoader else if (!owner->IsMounted() && target->IsMounted()) target->Dismount(); - target->SetSpeed(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); - target->SetSpeed(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK)); + target->SetSpeedRate(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); + target->SetSpeedRate(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK)); } void Register() override diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp index 9df9f0b604a..be49778ee4a 100644 --- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp +++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp @@ -24,7 +24,6 @@ SDCategory: Dustwallow Marsh EndScriptData */ /* ContentData -npc_lady_jaina_proudmoore npc_nat_pagle npc_private_hendel npc_cassa_crimsonwing - handled by npc_taxi @@ -39,49 +38,6 @@ EndContentData */ #include "WorldSession.h" /*###### -## npc_lady_jaina_proudmoore -######*/ - -enum LadyJaina -{ - QUEST_JAINAS_AUTOGRAPH = 558, - SPELL_JAINAS_AUTOGRAPH = 23122 -}; - -#define GOSSIP_ITEM_JAINA "I know this is rather silly but i have a young ward who is a bit shy and would like your autograph." - -class npc_lady_jaina_proudmoore : public CreatureScript -{ -public: - npc_lady_jaina_proudmoore() : CreatureScript("npc_lady_jaina_proudmoore") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_SENDER_INFO) - { - player->SEND_GOSSIP_MENU(7012, creature->GetGUID()); - player->CastSpell(player, SPELL_JAINAS_AUTOGRAPH, false); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_JAINAS_AUTOGRAPH) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_JAINA, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - -}; - -/*###### ## npc_nat_pagle ######*/ @@ -417,7 +373,6 @@ class spell_energize_aoe : public SpellScriptLoader void AddSC_dustwallow_marsh() { - new npc_lady_jaina_proudmoore(); new npc_nat_pagle(); new npc_private_hendel(); new npc_zelfrax(); diff --git a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp index ac26aa1f811..adb6439272a 100644 --- a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp +++ b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp @@ -143,20 +143,30 @@ public: enum ThrallWarchief { - QUEST_6566 = 6566, - - SPELL_CHAIN_LIGHTNING = 16033, - SPELL_SHOCK = 16034 + GOSSIP_MENU_OPTION_ID_ALL = 0, + + OPTION_PLEASE_SHARE_YOUR = 3664, + OPTION_WHAT_DISCOVERIES = 3665, + OPTION_USURPER = 3666, + OPTION_WITH_ALL_DUE_RESPECT = 3667, + OPTION_I_I_DID_NOT_THINK_OF = 3668, + OPTION_I_LIVE_ONLY_TO_SERVE = 3669, + OPTION_OF_COURSE_WARCHIEF = 3670, + + GOSSIP_MEMBERS_OF_THE_HORDE = 4477, + GOSSIP_THE_SHATTERED_HAND = 5733, + GOSSIP_IT_WOULD_APPEAR_AS = 5734, + GOSSIP_THE_BROOD_MOTHER = 5735, + GOSSIP_SO_MUCH_TO_LEARN = 5736, + GOSSIP_I_DO_NOT_FAULT_YOU = 5737, + GOSSIP_NOW_PAY_ATTENTION = 5738, + + QUEST_WHAT_THE_WIND_CARRIES = 6566, + + SPELL_CHAIN_LIGHTNING = 16033, + SPELL_SHOCK = 16034 }; -#define GOSSIP_HTW "Please share your wisdom with me, Warchief." -#define GOSSIP_STW1 "What discoveries?" -#define GOSSIP_STW2 "Usurper?" -#define GOSSIP_STW3 "With all due respect, Warchief - why not allow them to be destroyed? Does this not strengthen our position?" -#define GOSSIP_STW4 "I... I did not think of it that way, Warchief." -#define GOSSIP_STW5 "I live only to serve, Warchief! My life is empty and meaningless without your guidance." -#define GOSSIP_STW6 "Of course, Warchief!" - /// @todo verify abilities/timers class npc_thrall_warchief : public CreatureScript { @@ -169,32 +179,32 @@ public: switch (action) { case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(5733, creature->GetGUID()); + player->ADD_GOSSIP_ITEM_DB(OPTION_WHAT_DISCOVERIES, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(GOSSIP_THE_SHATTERED_HAND, creature->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(5734, creature->GetGUID()); + player->ADD_GOSSIP_ITEM_DB(OPTION_USURPER, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->SEND_GOSSIP_MENU(GOSSIP_IT_WOULD_APPEAR_AS, creature->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(5735, creature->GetGUID()); + player->ADD_GOSSIP_ITEM_DB(OPTION_WITH_ALL_DUE_RESPECT, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + player->SEND_GOSSIP_MENU(GOSSIP_THE_BROOD_MOTHER, creature->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(5736, creature->GetGUID()); + player->ADD_GOSSIP_ITEM_DB(OPTION_I_I_DID_NOT_THINK_OF, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(GOSSIP_SO_MUCH_TO_LEARN, creature->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); - player->SEND_GOSSIP_MENU(5737, creature->GetGUID()); + player->ADD_GOSSIP_ITEM_DB(OPTION_I_LIVE_ONLY_TO_SERVE, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); + player->SEND_GOSSIP_MENU(GOSSIP_I_DO_NOT_FAULT_YOU, creature->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF+6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7); - player->SEND_GOSSIP_MENU(5738, creature->GetGUID()); + player->ADD_GOSSIP_ITEM_DB(OPTION_OF_COURSE_WARCHIEF, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7); + player->SEND_GOSSIP_MENU(GOSSIP_NOW_PAY_ATTENTION, creature->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF+7: player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(QUEST_6566); + player->AreaExploredOrEventHappens(QUEST_WHAT_THE_WIND_CARRIES); break; } return true; @@ -205,10 +215,10 @@ public: if (creature->IsQuestGiver()) player->PrepareQuestMenu(creature->GetGUID()); - if (player->GetQuestStatus(QUEST_6566) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HTW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + if (player->GetQuestStatus(QUEST_WHAT_THE_WIND_CARRIES) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM_DB(OPTION_PLEASE_SHARE_YOUR, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + player->SEND_GOSSIP_MENU(GOSSIP_MEMBERS_OF_THE_HORDE, creature->GetGUID()); return true; } diff --git a/src/server/scripts/Kalimdor/zone_the_barrens.cpp b/src/server/scripts/Kalimdor/zone_the_barrens.cpp index 852cd62c277..b113615ca50 100644 --- a/src/server/scripts/Kalimdor/zone_the_barrens.cpp +++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp @@ -552,7 +552,7 @@ public: { if (!HasEscortState(STATE_ESCORT_ESCORTING)) { - if (me->getStandState() == UNIT_STAND_STATE_DEAD) + if (me->GetStandState() == UNIT_STAND_STATE_DEAD) me->SetStandState(UNIT_STAND_STATE_STAND); IsPostEvent = false; diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp index ab09dd45710..3c11fd5d9a6 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp @@ -454,11 +454,11 @@ public: float distance = me->GetDistance(JedogaPosition[1]); if (distance < 9.0f) - me->SetSpeed(MOVE_WALK, 0.5f, true); + me->SetSpeedRate(MOVE_WALK, 0.5f); else if (distance < 15.0f) - me->SetSpeed(MOVE_WALK, 0.75f, true); + me->SetSpeedRate(MOVE_WALK, 0.75f); else if (distance < 20.0f) - me->SetSpeed(MOVE_WALK, 1.0f, true); + me->SetSpeedRate(MOVE_WALK, 1.0f); me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MovePoint(1, JedogaPosition[1]); diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp index e25f64f61aa..04b62f77e9a 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -178,7 +178,7 @@ class boss_prince_taldaram : public CreatureScript if (Unit* embraceTarget = GetEmbraceTarget()) { me->GetMotionMaster()->Clear(); - me->SetSpeed(MOVE_WALK, 2.0f, true); + me->SetSpeedRate(MOVE_WALK, 2.0f); me->GetMotionMaster()->MoveChase(embraceTarget); } events.ScheduleEvent(EVENT_VANISHED, 1300); @@ -188,7 +188,7 @@ class boss_prince_taldaram : public CreatureScript DoCast(embraceTarget, SPELL_EMBRACE_OF_THE_VAMPYR); Talk(SAY_FEED); me->GetMotionMaster()->Clear(); - me->SetSpeed(MOVE_WALK, 1.0f, true); + me->SetSpeedRate(MOVE_WALK, 1.0f); me->GetMotionMaster()->MoveChase(me->GetVictim()); events.ScheduleEvent(EVENT_FEEDING, 20000); break; diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt deleted file mode 100644 index 1dc453ad416..00000000000 --- a/src/server/scripts/Northrend/CMakeLists.txt +++ /dev/null @@ -1,199 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - Northrend/zone_wintergrasp.cpp - Northrend/isle_of_conquest.cpp - Northrend/zone_storm_peaks.cpp - Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp - Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp - Northrend/Ulduar/HallsOfLightning/halls_of_lightning.h - Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp - Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp - Northrend/Ulduar/HallsOfLightning/boss_loken.cpp - Northrend/Ulduar/Ulduar/boss_general_vezax.cpp - Northrend/Ulduar/Ulduar/boss_thorim.cpp - Northrend/Ulduar/Ulduar/boss_ignis.cpp - Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp - Northrend/Ulduar/Ulduar/instance_ulduar.cpp - Northrend/Ulduar/Ulduar/boss_auriaya.cpp - Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp - Northrend/Ulduar/Ulduar/boss_hodir.cpp - Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp - Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp - Northrend/Ulduar/Ulduar/boss_xt002.cpp - Northrend/Ulduar/Ulduar/boss_mimiron.cpp - Northrend/Ulduar/Ulduar/ulduar.h - Northrend/Ulduar/Ulduar/boss_freya.cpp - Northrend/Ulduar/Ulduar/boss_razorscale.cpp - Northrend/Ulduar/Ulduar/boss_kologarn.cpp - Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp - Northrend/Ulduar/HallsOfStone/halls_of_stone.h - Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp - Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp - Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp - Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp - Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp - Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h - Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp - Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp - Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp - Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.h - Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp - Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp - Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp - Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp - Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp - Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h - Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp - Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp - Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp - Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp - Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp - Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp - Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp - Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp - Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h - Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp - Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.cpp - Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp - Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp - Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp - Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h - Northrend/Nexus/EyeOfEternity/boss_malygos.cpp - Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp - Northrend/Nexus/EyeOfEternity/eye_of_eternity.h - Northrend/Nexus/Oculus/boss_eregos.cpp - Northrend/Nexus/Oculus/boss_drakos.cpp - Northrend/Nexus/Oculus/oculus.h - Northrend/Nexus/Oculus/boss_varos.cpp - Northrend/Nexus/Oculus/boss_urom.cpp - Northrend/Nexus/Oculus/oculus.cpp - Northrend/Nexus/Oculus/instance_oculus.cpp - Northrend/Nexus/Nexus/boss_nexus_commanders.cpp - Northrend/Nexus/Nexus/boss_ormorok.cpp - Northrend/Nexus/Nexus/boss_magus_telestra.cpp - Northrend/Nexus/Nexus/instance_nexus.cpp - Northrend/Nexus/Nexus/boss_keristrasza.cpp - Northrend/Nexus/Nexus/boss_anomalus.cpp - Northrend/Nexus/Nexus/nexus.h - Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp - Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp - Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp - Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h - Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp - Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp - Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp - Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp - Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h - Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp - Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp - Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp - Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp - Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp - Northrend/Naxxramas/boss_loatheb.cpp - Northrend/Naxxramas/boss_anubrekhan.cpp - Northrend/Naxxramas/boss_maexxna.cpp - Northrend/Naxxramas/boss_patchwerk.cpp - Northrend/Naxxramas/boss_gothik.cpp - Northrend/Naxxramas/boss_faerlina.cpp - Northrend/Naxxramas/boss_gluth.cpp - Northrend/Naxxramas/boss_four_horsemen.cpp - Northrend/Naxxramas/naxxramas.h - Northrend/Naxxramas/boss_kelthuzad.cpp - Northrend/Naxxramas/boss_heigan.cpp - Northrend/Naxxramas/boss_thaddius.cpp - Northrend/Naxxramas/boss_razuvious.cpp - Northrend/Naxxramas/boss_sapphiron.cpp - Northrend/Naxxramas/instance_naxxramas.cpp - Northrend/Naxxramas/boss_grobbulus.cpp - Northrend/Naxxramas/boss_noth.cpp - Northrend/zone_crystalsong_forest.cpp - Northrend/VaultOfArchavon/boss_archavon.cpp - Northrend/VaultOfArchavon/boss_koralon.cpp - Northrend/VaultOfArchavon/vault_of_archavon.h - Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp - Northrend/VaultOfArchavon/boss_emalon.cpp - Northrend/VaultOfArchavon/boss_toravon.cpp - Northrend/zone_sholazar_basin.cpp - Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp - Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp - Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp - Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp - Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp - Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h - Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp - Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp - Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.h - Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp - Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp - Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp - Northrend/zone_dragonblight.cpp - Northrend/zone_grizzly_hills.cpp - Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h - Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp - Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp - Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp - Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp - Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp - Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp - Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp - Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp - Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp - Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp - Northrend/AzjolNerub/Ahnkahet/ahnkahet.h - Northrend/VioletHold/boss_zuramat.cpp - Northrend/VioletHold/instance_violet_hold.cpp - Northrend/VioletHold/boss_lavanthor.cpp - Northrend/VioletHold/boss_cyanigosa.cpp - Northrend/VioletHold/violet_hold.h - Northrend/VioletHold/boss_ichoron.cpp - Northrend/VioletHold/boss_moragg.cpp - Northrend/VioletHold/boss_xevozz.cpp - Northrend/VioletHold/boss_erekem.cpp - Northrend/VioletHold/violet_hold.cpp - Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp - Northrend/IcecrownCitadel/icecrown_citadel.cpp - Northrend/IcecrownCitadel/icecrown_citadel.h - Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp - Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp - Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp - Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp - Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp - Northrend/IcecrownCitadel/boss_festergut.cpp - Northrend/IcecrownCitadel/boss_rotface.cpp - Northrend/IcecrownCitadel/boss_professor_putricide.cpp - Northrend/IcecrownCitadel/boss_blood_prince_council.cpp - Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp - Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp - Northrend/IcecrownCitadel/boss_sindragosa.cpp - Northrend/IcecrownCitadel/boss_the_lich_king.cpp - Northrend/zone_zuldrak.cpp - Northrend/zone_icecrown.cpp - Northrend/Gundrak/boss_slad_ran.cpp - Northrend/Gundrak/instance_gundrak.cpp - Northrend/Gundrak/boss_drakkari_colossus.cpp - Northrend/Gundrak/gundrak.h - Northrend/Gundrak/boss_gal_darah.cpp - Northrend/Gundrak/boss_moorabi.cpp - Northrend/Gundrak/boss_eck.cpp - Northrend/zone_borean_tundra.cpp - Northrend/zone_howling_fjord.cpp - Northrend/zone_dalaran.cpp - Northrend/DraktharonKeep/boss_trollgore.cpp - Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp - Northrend/DraktharonKeep/boss_novos.cpp - Northrend/DraktharonKeep/drak_tharon_keep.h - Northrend/DraktharonKeep/boss_tharon_ja.cpp - Northrend/DraktharonKeep/boss_king_dred.cpp -) - -message(" -> Prepared: Northrend") diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp index fb5642c6f3b..84d7d92acfe 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp @@ -135,9 +135,9 @@ class boss_general_zarithrian : public CreatureScript Talk(SAY_KILL); } - bool CanAIAttack(Unit const* /*target*/) const override + bool CanAIAttack(Unit const* target) const override { - return (instance->GetBossState(DATA_SAVIANA_RAGEFIRE) == DONE && instance->GetBossState(DATA_BALTHARUS_THE_WARBORN) == DONE); + return (instance->GetBossState(DATA_SAVIANA_RAGEFIRE) == DONE && instance->GetBossState(DATA_BALTHARUS_THE_WARBORN) == DONE && BossAI::CanAIAttack(target)); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp index a6cd8362db3..739c3602f44 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp @@ -23,7 +23,7 @@ #include "WorldPacket.h" #include "ruby_sanctum.h" -BossBoundaryData const boundaries = +BossBoundaryData const boundaries = { { DATA_GENERAL_ZARITHRIAN, new EllipseBoundary(Position(3013.409f, 529.492f), 45.0, 100.0) }, { DATA_HALION, new CircleBoundary(Position(3156.037f, 533.2656f), 48.5) } diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp index ae4a5e2a69a..9235b75d53e 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp @@ -18,6 +18,7 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" +#include "SpellScript.h" #include "ruby_sanctum.h" #include "Player.h" @@ -45,6 +46,11 @@ enum Events EVENT_XERESTRASZA_EVENT_7 = 7, }; +enum Spells +{ + SPELL_RALLY = 75416 +}; + Position const xerestraszaMovePos = {3151.236f, 379.8733f, 86.31996f, 0.0f}; class npc_xerestrasza : public CreatureScript @@ -165,8 +171,53 @@ class at_baltharus_plateau : public AreaTriggerScript } }; +// 75415 - Rallying Shout +class spell_ruby_sanctum_rallying_shout : public SpellScriptLoader +{ + public: + spell_ruby_sanctum_rallying_shout() : SpellScriptLoader("spell_ruby_sanctum_rallying_shout") { } + + class spell_ruby_sanctum_rallying_shout_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ruby_sanctum_rallying_shout_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_RALLY)) + return false; + return true; + } + + void CountTargets(std::list<WorldObject*>& targets) + { + _targetCount = targets.size(); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (_targetCount && !GetCaster()->HasAura(SPELL_RALLY)) + GetCaster()->CastCustomSpell(SPELL_RALLY, SPELLVALUE_AURA_STACK, _targetCount, GetCaster(), TRIGGERED_FULL_MASK); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ruby_sanctum_rallying_shout_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + OnEffectHit += SpellEffectFn(spell_ruby_sanctum_rallying_shout_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + + private: + uint32 _targetCount = 0; + }; + + SpellScript* GetSpellScript() const override + { + return new spell_ruby_sanctum_rallying_shout_SpellScript(); + } +}; + void AddSC_ruby_sanctum() { new npc_xerestrasza(); new at_baltharus_plateau(); + new spell_ruby_sanctum_rallying_shout(); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index c89510211b9..7440984d7c5 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -804,7 +804,7 @@ class npc_anubarak_spike : public CreatureScript void StartChase(Unit* who) { DoCast(who, SPELL_MARK); - me->SetSpeed(MOVE_RUN, 0.5f); + me->SetSpeedRate(MOVE_RUN, 0.5f); // make sure the Spine will really follow the one he should me->getThreatManager().clearReferences(); me->SetInCombatWithZone(); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp index 1e860fb6ec5..6c1b516c7de 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp @@ -461,13 +461,13 @@ class boss_toc_champion_controller : public CreatureScript if (playerTeam == ALLIANCE) { temp->SetHomePosition(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 0); - temp->GetMotionMaster()->MoveJump(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 20.0f, 20.0f); + temp->GetMotionMaster()->MoveJump(vChampionJumpTarget[pos], 20.0f, 20.0f); temp->SetOrientation(0); } else { temp->SetHomePosition((ToCCommonLoc[1].GetPositionX()*2)-vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 3); - temp->GetMotionMaster()->MoveJump((ToCCommonLoc[1].GetPositionX()*2)-vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 20.0f, 20.0f); + temp->GetMotionMaster()->MoveJump((ToCCommonLoc[1].GetPositionX() * 2) - vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), vChampionJumpTarget[pos].GetOrientation(), 20.0f, 20.0f); temp->SetOrientation(3); } } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp index 83daa6e35a2..e3720503d0a 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp @@ -390,7 +390,7 @@ class npc_snobold_vassal : public CreatureScript else if (Unit* target2 = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { _targetGUID = target2->GetGUID(); - me->GetMotionMaster()->MoveJump(target2->GetPositionX(), target2->GetPositionY(), target2->GetPositionZ(), 15.0f, 15.0f); + me->GetMotionMaster()->MoveJump(*target2, 15.0f, 15.0f); } } } @@ -981,7 +981,7 @@ class boss_icehowl : public CreatureScript events.ScheduleEvent(EVENT_WHIRL, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS)); return; case EVENT_MASSIVE_CRASH: - me->GetMotionMaster()->MoveJump(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 20.0f, 20.0f, 0); // 1: Middle of the room + me->GetMotionMaster()->MoveJump(ToCCommonLoc[1], 20.0f, 20.0f, 0); // 1: Middle of the room SetCombatMovement(false); me->AttackStop(); _stage = 7; //Invalid (Do nothing more than move) @@ -1034,7 +1034,7 @@ class boss_icehowl : public CreatureScript _trampleTargetY = target->GetPositionY(); _trampleTargetZ = target->GetPositionZ(); // 2: Hop Backwards - me->GetMotionMaster()->MoveJump(2*me->GetPositionX() - _trampleTargetX, 2*me->GetPositionY() - _trampleTargetY, me->GetPositionZ(), 30.0f, 20.0f, 0); + me->GetMotionMaster()->MoveJump(2*me->GetPositionX() - _trampleTargetX, 2*me->GetPositionY() - _trampleTargetY, me->GetPositionZ(), me->GetOrientation(), 30.0f, 20.0f, 0); _stage = 7; //Invalid (Do nothing more than move) } else diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index eb1e769c07e..278f6a7ab4f 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -132,7 +132,7 @@ class OrbsDespawner : public BasicEvent { } - bool Execute(uint64 /*currTime*/, uint32 /*diff*/) + bool Execute(uint64 /*currTime*/, uint32 /*diff*/) override { Trinity::CreatureWorker<OrbsDespawner> worker(_creature, *this); _creature->VisitNearbyGridObject(5000.0f, worker); diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 4c2b92da0ea..3ac85809fa2 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -2580,7 +2580,7 @@ class npc_quel_delar_sword : public CreatureScript void Reset() override { _events.Reset(); - me->SetSpeed(MOVE_FLIGHT, 4.5f, true); + me->SetSpeedRate(MOVE_FLIGHT, 4.5f); DoCast(SPELL_WHIRLWIND_VISUAL); if (_intro) _events.ScheduleEvent(EVENT_QUEL_DELAR_INIT, 0); diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp index 03f12e46bc3..b24a36da3fb 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp @@ -418,7 +418,7 @@ class boss_krick : public CreatureScript case EVENT_OUTRO_6: if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _instanceScript->GetGuidData(DATA_TYRANNUS_EVENT))) { - tyrannus->SetSpeed(MOVE_FLIGHT, 3.5f, true); + tyrannus->SetSpeedRate(MOVE_FLIGHT, 3.5f); tyrannus->GetMotionMaster()->MovePoint(1, outroPos[4]); _tyrannusGUID = tyrannus->GetGUID(); } diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp index 96bd0aaa35e..5410f403ab9 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp @@ -22,6 +22,7 @@ #include "pit_of_saron.h" #include "Vehicle.h" #include "Player.h" +#include "PlayerAI.h" enum Yells { @@ -438,9 +439,10 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader if (GetTarget()->GetTypeId() != TYPEID_PLAYER) return; - oldAI = GetTarget()->GetAI(); - oldAIState = GetTarget()->IsAIEnabled; - GetTarget()->SetAI(new player_overlord_brandAI(GetTarget()->ToPlayer(), GetCasterGUID())); + Player* pTarget = GetTarget()->ToPlayer(); + oldAI = pTarget->AI(); + oldAIState = pTarget->IsAIEnabled; + GetTarget()->SetAI(new player_overlord_brandAI(pTarget, GetCasterGUID())); GetTarget()->IsAIEnabled = true; } @@ -450,7 +452,7 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader return; GetTarget()->IsAIEnabled = oldAIState; - UnitAI* thisAI = GetTarget()->GetAI(); + PlayerAI* thisAI = GetTarget()->ToPlayer()->AI(); GetTarget()->SetAI(oldAI); delete thisAI; } @@ -461,7 +463,7 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader AfterEffectRemove += AuraEffectRemoveFn(spell_tyrannus_overlord_brand_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } - UnitAI* oldAI; + PlayerAI* oldAI; bool oldAIState; }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index b8e7dcc91d5..51711f9ded5 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -160,7 +160,7 @@ class StandUpEvent : public BasicEvent public: StandUpEvent(Creature& owner) : BasicEvent(), _owner(owner) { } - bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) + bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override { _owner.HandleEmoteCommand(EMOTE_ONESHOT_ROAR); _owner.SetReactState(REACT_AGGRESSIVE); @@ -1069,7 +1069,7 @@ class npc_blood_queen_lana_thel : public CreatureScript if (Creature* summon = DoSummon(NPC_FLOATING_TRIGGER, triggerPos, 15000, TEMPSUMMON_TIMED_DESPAWN)) { summon->CastSpell(summon, SPELL_OOC_INVOCATION_VISUAL, true); - summon->SetSpeed(MOVE_FLIGHT, 0.15f, true); // todo: creature is swimming, check if this is blizzlike or not. + summon->SetSpeedRate(MOVE_FLIGHT, 0.15f); // todo: creature is swimming, check if this is blizzlike or not. summon->GetMotionMaster()->MovePoint(0, triggerEndPos); } } @@ -1222,7 +1222,6 @@ class npc_kinetic_bomb : public CreatureScript _x = 0.f; _y = 0.f; _groundZ = 0.f; - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); } void Reset() override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index bc8c7f877a9..3d21388ca11 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -809,7 +809,7 @@ class spell_blood_queen_pact_of_the_darkfallen_dmg : public SpellScriptLoader // this is an additional effect to be executed void PeriodicTick(AuraEffect const* aurEff) { - SpellInfo const* damageSpell = sSpellMgr->EnsureSpellInfo(SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE); + SpellInfo const* damageSpell = sSpellMgr->AssertSpellInfo(SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE); int32 damage = damageSpell->Effects[EFFECT_0].CalcValue(); float multiplier = 0.3375f + 0.1f * uint32(aurEff->GetTickNumber()/10); // do not convert to 0.01f - we need tick number/10 as INT (damage increases every 10 ticks) damage = int32(damage * multiplier); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 7e9083115b8..3ea0de31764 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -598,7 +598,7 @@ class boss_deathbringer_saurfang : public CreatureScript if (target->GetTransport()) return false; - return true; + return BossAI::CanAIAttack(target); } static uint32 const FightWonValue; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp index 9b0693ec95e..d77842fff0a 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -1843,7 +1843,7 @@ class spell_igb_rocket_pack : public SpellScriptLoader void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { - SpellInfo const* damageInfo = sSpellMgr->EnsureSpellInfo(SPELL_ROCKET_PACK_DAMAGE); + SpellInfo const* damageInfo = sSpellMgr->AssertSpellInfo(SPELL_ROCKET_PACK_DAMAGE); GetTarget()->CastCustomSpell(SPELL_ROCKET_PACK_DAMAGE, SPELLVALUE_BASE_POINT0, 2 * (damageInfo->Effects[EFFECT_0].CalcValue() + aurEff->GetTickNumber() * aurEff->GetAmplitude()), NULL, TRIGGERED_FULL_MASK); GetTarget()->CastSpell(NULL, SPELL_ROCKET_BURST, TRIGGERED_FULL_MASK); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index d3cf6495aa7..b3a11b8eb31 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -203,7 +203,7 @@ class DaranavanMoveEvent : public BasicEvent public: DaranavanMoveEvent(Creature& darnavan) : _darnavan(darnavan) { } - bool Execute(uint64 /*time*/, uint32 /*diff*/) + bool Execute(uint64 /*time*/, uint32 /*diff*/) override { _darnavan.GetMotionMaster()->MovePoint(POINT_DESPAWN, SummonPositions[6]); return true; @@ -421,7 +421,7 @@ class boss_lady_deathwhisper : public CreatureScript void UpdateAI(uint32 diff) override { - if ((!UpdateVictim() && !events.IsInPhase(PHASE_INTRO))) + if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) return; events.Update(diff); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 056231285e2..9f20799df82 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -142,7 +142,7 @@ class boss_lord_marrowgar : public CreatureScript void Reset() override { _Reset(); - me->SetSpeed(MOVE_RUN, _baseSpeed, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); me->RemoveAurasDueToSpell(SPELL_BONE_STORM); me->RemoveAurasDueToSpell(SPELL_BERSERK); events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000); @@ -224,7 +224,7 @@ class boss_lord_marrowgar : public CreatureScript case EVENT_BONE_STORM_BEGIN: if (Aura* pStorm = me->GetAura(SPELL_BONE_STORM)) pStorm->SetDuration(int32(_boneStormDuration)); - me->SetSpeed(MOVE_RUN, _baseSpeed*3.0f, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed*3.0f); Talk(SAY_BONE_STORM); events.ScheduleEvent(EVENT_BONE_STORM_END, _boneStormDuration+1); // no break here @@ -242,7 +242,7 @@ class boss_lord_marrowgar : public CreatureScript if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->MoveChase(me->GetVictim()); - me->SetSpeed(MOVE_RUN, _baseSpeed, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); events.CancelEvent(EVENT_BONE_STORM_MOVE); events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000); if (!IsHeroic()) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 0f721148b72..fe6e4081326 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -317,14 +317,12 @@ class boss_professor_putricide : public CreatureScript // no possible aura seen in sniff adding the aurastate summon->ModifyAuraState(AURA_STATE_UNKNOWN22, true); summon->CastSpell(summon, SPELL_GASEOUS_BLOAT_PROC, true); - summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); summon->SetReactState(REACT_PASSIVE); break; case NPC_VOLATILE_OOZE: // no possible aura seen in sniff adding the aurastate summon->ModifyAuraState(AURA_STATE_UNKNOWN19, true); summon->CastSpell(summon, SPELL_OOZE_ERUPTION_SEARCH_PERIODIC, true); - summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); summon->SetReactState(REACT_PASSIVE); break; case NPC_CHOKING_GAS_BOMB: @@ -371,21 +369,21 @@ class boss_professor_putricide : public CreatureScript { case POINT_FESTERGUT: instance->SetBossState(DATA_FESTERGUT, IN_PROGRESS); // needed here for delayed gate close - me->SetSpeed(MOVE_RUN, _baseSpeed, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); DoAction(ACTION_FESTERGUT_GAS); if (Creature* festergut = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FESTERGUT))) festergut->CastSpell(festergut, SPELL_GASEOUS_BLIGHT_LARGE, false, NULL, NULL, festergut->GetGUID()); break; case POINT_ROTFACE: instance->SetBossState(DATA_ROTFACE, IN_PROGRESS); // needed here for delayed gate close - me->SetSpeed(MOVE_RUN, _baseSpeed, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); DoAction(ACTION_ROTFACE_OOZE); events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25000, 0, PHASE_ROTFACE); break; case POINT_TABLE: // stop attack me->GetMotionMaster()->MoveIdle(); - me->SetSpeed(MOVE_RUN, _baseSpeed, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); if (GameObject* table = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_PUTRICIDE_TABLE))) me->SetFacingToObject(table); // operating on new phase already @@ -420,7 +418,7 @@ class boss_professor_putricide : public CreatureScript { case ACTION_FESTERGUT_COMBAT: SetPhase(PHASE_FESTERGUT); - me->SetSpeed(MOVE_RUN, _baseSpeed*2.0f, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); me->GetMotionMaster()->MovePoint(POINT_FESTERGUT, festergutWatchPos); me->SetReactState(REACT_PASSIVE); DoZoneInCombat(me); @@ -437,7 +435,7 @@ class boss_professor_putricide : public CreatureScript case ACTION_ROTFACE_COMBAT: { SetPhase(PHASE_ROTFACE); - me->SetSpeed(MOVE_RUN, _baseSpeed*2.0f, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); me->GetMotionMaster()->MovePoint(POINT_ROTFACE, rotfaceWatchPos); me->SetReactState(REACT_PASSIVE); _oozeFloodStage = 0; @@ -479,7 +477,7 @@ class boss_professor_putricide : public CreatureScript events.ScheduleEvent(EVENT_ROTFACE_DIES, 4500, 0, PHASE_ROTFACE); break; case ACTION_CHANGE_PHASE: - me->SetSpeed(MOVE_RUN, _baseSpeed*2.0f, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); events.DelayEvents(30000); me->AttackStop(); if (!IsHeroic()) @@ -564,7 +562,7 @@ class boss_professor_putricide : public CreatureScript void UpdateAI(uint32 diff) override { - if ((!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) && !UpdateVictim())) + if (!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) && !UpdateVictim()) return; events.Update(diff); @@ -778,7 +776,7 @@ class npc_volatile_ooze : public CreatureScript { } - void CastMainSpell() + void CastMainSpell() override { me->CastSpell(me, SPELL_VOLATILE_OOZE_ADHESIVE, false); } @@ -802,7 +800,7 @@ class npc_gas_cloud : public CreatureScript _newTargetSelectTimer = 0; } - void CastMainSpell() + void CastMainSpell() override { me->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, me, false); } @@ -1259,7 +1257,7 @@ class spell_putricide_mutated_plague : public SpellScriptLoader return; uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; - SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(triggerSpell); + SpellInfo const* spell = sSpellMgr->AssertSpellInfo(triggerSpell); spell = sSpellMgr->GetSpellForDifficultyFromSpell(spell, caster); int32 damage = spell->Effects[EFFECT_0].CalcValue(caster); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index 683dd976b7a..bf69a49055c 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -856,14 +856,14 @@ class spell_rotface_vile_gas_trigger : public SpellScriptLoader GetCaster()->CastSpell(GetHitUnit(), SPELL_VILE_GAS_TRIGGER_SUMMON); } - void Register() + void Register() override { OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_vile_gas_trigger_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); OnEffectHitTarget += SpellEffectFn(spell_rotface_vile_gas_trigger_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; - SpellScript* GetSpellScript() const + SpellScript* GetSpellScript() const override { return new spell_rotface_vile_gas_trigger_SpellScript(); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index ac094588d35..caa37465165 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -134,6 +134,7 @@ enum FrostwingData DATA_WHELP_MARKER = 2, DATA_LINKED_GAMEOBJECT = 3, DATA_TRAPPED_PLAYER = 4, + DATA_IS_THIRD_PHASE = 5 }; enum MovementPoints @@ -168,7 +169,7 @@ class FrostwyrmLandEvent : public BasicEvent public: FrostwyrmLandEvent(Creature& owner, Position const& dest) : _owner(owner), _dest(dest) { } - bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) + bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override { _owner.GetMotionMaster()->MoveLand(POINT_FROSTWYRM_LAND, _dest); return true; @@ -184,7 +185,7 @@ class FrostBombExplosion : public BasicEvent public: FrostBombExplosion(Creature* owner, ObjectGuid sindragosaGUID) : _owner(owner), _sindragosaGUID(sindragosaGUID) { } - bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) + bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override { _owner->CastSpell((Unit*)NULL, SPELL_FROST_BOMB, false, NULL, NULL, _sindragosaGUID); _owner->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL); @@ -196,20 +197,19 @@ class FrostBombExplosion : public BasicEvent ObjectGuid _sindragosaGUID; }; -class FrostBeaconSelector +class FrostBeaconSelector : NonTankTargetSelector { public: - FrostBeaconSelector(Unit* source) : _source(source) { } + FrostBeaconSelector(Unit* source) : NonTankTargetSelector(source, true) { } - bool operator()(Unit* target) const + bool operator()(WorldObject* target) const { - return target->GetTypeId() == TYPEID_PLAYER && - target != _source->GetVictim() && - !target->HasAura(SPELL_ICE_TOMB_UNTARGETABLE); - } + if (Unit* unitTarget = target->ToUnit()) + return !NonTankTargetSelector::operator()(unitTarget) || + unitTarget->HasAura(SPELL_ICE_TOMB_UNTARGETABLE); - private: - Unit* _source; + return false; + } }; class boss_sindragosa : public CreatureScript @@ -315,7 +315,7 @@ class boss_sindragosa : public CreatureScript me->SetCanFly(true); me->SetDisableGravity(true); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); - me->SetSpeed(MOVE_FLIGHT, 4.0f); + me->SetSpeedRate(MOVE_FLIGHT, 4.0f); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); float moveTime = me->GetExactDist(&SindragosaFlyPos) / (me->GetSpeed(MOVE_FLIGHT) * 0.001f); me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, SindragosaLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250)); @@ -326,9 +326,15 @@ class boss_sindragosa : public CreatureScript uint32 GetData(uint32 type) const override { - if (type == DATA_MYSTIC_BUFFET_STACK) - return _mysticBuffetStack; - return 0xFFFFFFFF; + switch (type) + { + case DATA_MYSTIC_BUFFET_STACK: + return _mysticBuffetStack; + case DATA_IS_THIRD_PHASE: + return _isThirdPhase; + default: + return 0xFFFFFFFF; + } } void MovementInform(uint32 type, uint32 point) override @@ -345,7 +351,7 @@ class boss_sindragosa : public CreatureScript me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); me->SetHomePosition(SindragosaLandPos); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetSpeed(MOVE_FLIGHT, 2.5f); + me->SetSpeedRate(MOVE_FLIGHT, 2.5f); // Sindragosa enters combat as soon as she lands DoZoneInCombat(); @@ -419,7 +425,6 @@ class boss_sindragosa : public CreatureScript if (spellId == spell->Id) if (Aura const* mysticBuffet = target->GetAura(spell->Id)) _mysticBuffetStack = std::max<uint8>(_mysticBuffetStack, mysticBuffet->GetStackAmount()); - } void UpdateAI(uint32 diff) override @@ -494,11 +499,7 @@ class boss_sindragosa : public CreatureScript me->GetMotionMaster()->MovePoint(POINT_AIR_PHASE_FAR, SindragosaAirPosFar); break; case EVENT_ICE_TOMB: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, FrostBeaconSelector(me))) - { - Talk(EMOTE_WARN_FROZEN_ORB, target); - me->CastCustomSpell(SPELL_ICE_TOMB_TARGET, SPELLVALUE_MAX_TARGETS, 1, nullptr, TRIGGERED_FULL_MASK); - } + me->CastCustomSpell(SPELL_ICE_TOMB_TARGET, SPELLVALUE_MAX_TARGETS, 1, nullptr, TRIGGERED_FULL_MASK); events.ScheduleEvent(EVENT_ICE_TOMB, urand(16000, 23000)); break; case EVENT_FROST_BOMB: @@ -696,7 +697,7 @@ class npc_spinestalker : public CreatureScript return; me->setActive(true); - me->SetSpeed(MOVE_FLIGHT, 2.0f); + me->SetSpeedRate(MOVE_FLIGHT, 2.0f); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); float moveTime = me->GetExactDist(&SpinestalkerFlyPos) / (me->GetSpeed(MOVE_FLIGHT) * 0.001f); me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, SpinestalkerLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250)); @@ -833,7 +834,7 @@ class npc_rimefang : public CreatureScript return; me->setActive(true); - me->SetSpeed(MOVE_FLIGHT, 2.0f); + me->SetSpeedRate(MOVE_FLIGHT, 2.0f); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); float moveTime = me->GetExactDist(&RimefangFlyPos) / (me->GetSpeed(MOVE_FLIGHT) * 0.001f); me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, RimefangLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250)); @@ -1576,6 +1577,41 @@ class spell_frostwarden_handler_focus_fire : public SpellScriptLoader } }; +class spell_sindragosa_ice_tomb_target : public SpellScriptLoader +{ +public: + spell_sindragosa_ice_tomb_target() : SpellScriptLoader("spell_sindragosa_ice_tomb_target") { } + + class spell_sindragosa_ice_tomb_target_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sindragosa_ice_tomb_target_SpellScript); + + void FilterTargets(std::list<WorldObject*>& unitList) + { + Unit* caster = GetCaster(); + unitList.remove_if(FrostBeaconSelector(caster)); + } + + void HandleSindragosaTalk(SpellEffIndex /*effIndex*/) + { + if (Creature* creatureCaster = GetCaster()->ToCreature()) + if (creatureCaster->GetAI()->GetData(DATA_IS_THIRD_PHASE)) + creatureCaster->AI()->Talk(EMOTE_WARN_FROZEN_ORB, GetHitUnit()); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_ice_tomb_target_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectLaunchTarget += SpellEffectFn(spell_sindragosa_ice_tomb_target_SpellScript::HandleSindragosaTalk, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_sindragosa_ice_tomb_target_SpellScript(); + } +}; + class at_sindragosa_lair : public AreaTriggerScript { public: @@ -1641,6 +1677,7 @@ void AddSC_boss_sindragosa() new spell_frostwarden_handler_focus_fire(); new spell_trigger_spell_from_caster("spell_sindragosa_ice_tomb", SPELL_ICE_TOMB_DUMMY, TRIGGERED_IGNORE_SET_FACING); new spell_trigger_spell_from_caster("spell_sindragosa_ice_tomb_dummy", SPELL_FROST_BEACON); + new spell_sindragosa_ice_tomb_target(); new at_sindragosa_lair(); new achievement_all_you_can_eat(); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index 755bbd759e7..4a0a8217af8 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -285,6 +285,7 @@ enum Phases #define PHASE_TWO_THREE (events.IsInPhase(PHASE_TWO) ? PHASE_TWO : PHASE_THREE) Position const CenterPosition = {503.6282f, -2124.655f, 840.8569f, 0.0f}; +Position const TirionSpawn = {505.2118f, -2124.353f, 840.9403f, 3.141593f}; Position const TirionIntro = {489.2970f, -2124.840f, 840.8569f, 0.0f}; Position const TirionCharge = {482.9019f, -2124.479f, 840.8570f, 0.0f}; Position const LichKingIntro[3] = @@ -436,7 +437,7 @@ class StartMovementEvent : public BasicEvent { } - bool Execute(uint64 /*time*/, uint32 /*diff*/) + bool Execute(uint64 /*time*/, uint32 /*diff*/) override { _owner->SetReactState(REACT_AGGRESSIVE); if (Creature* _summoner = ObjectAccessor::GetCreature(*_owner, _summonerGuid)) @@ -458,7 +459,7 @@ class VileSpiritActivateEvent : public BasicEvent { } - bool Execute(uint64 /*time*/, uint32 /*diff*/) + bool Execute(uint64 /*time*/, uint32 /*diff*/) override { _owner->SetReactState(REACT_AGGRESSIVE); _owner->CastSpell(_owner, SPELL_VILE_SPIRIT_MOVE_SEARCH, true); @@ -478,7 +479,7 @@ class TriggerWickedSpirit : public BasicEvent { } - bool Execute(uint64 /*time*/, uint32 /*diff*/) + bool Execute(uint64 /*time*/, uint32 /*diff*/) override { _owner->CastCustomSpell(SPELL_TRIGGER_VILE_SPIRIT_HEROIC, SPELLVALUE_MAX_TARGETS, 1, NULL, true); @@ -514,13 +515,33 @@ class boss_the_lich_king : public CreatureScript _vileSpiritExplosions = 0; } - void Reset() override + void InitializeAI() override + { + SetupEncounter(); + } + + void JustRespawned() override + { + SetupEncounter(); + } + + void SetupEncounter() { _Reset(); me->SetReactState(REACT_PASSIVE); events.SetPhase(PHASE_INTRO); Initialize(); SetEquipmentSlots(true); + + // Reset The Frozen Throne gameobjects + FrozenThroneResetWorker reset; + Trinity::GameObjectWorker<FrozenThroneResetWorker> worker(me, reset); + me->VisitNearbyGridObject(333.0f, worker); + + // Reset any light override + me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, 0, 5000); + + me->SummonCreature(NPC_HIGHLORD_TIRION_FORDRING_LK, TirionSpawn, TEMPSUMMON_MANUAL_DESPAWN); } void JustDied(Unit* /*killer*/) override @@ -556,40 +577,21 @@ class boss_the_lich_king : public CreatureScript events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500, 0, PHASE_ONE); } - void JustReachedHome() override - { - _JustReachedHome(); - instance->SetBossState(DATA_THE_LICH_KING, NOT_STARTED); - - // Reset The Frozen Throne gameobjects - FrozenThroneResetWorker reset; - Trinity::GameObjectWorker<FrozenThroneResetWorker> worker(me, reset); - me->VisitNearbyGridObject(333.0f, worker); - - // Restore Tirion's gossip only after The Lich King fully resets to prevent - // restarting the encounter while LK still runs back to spawn point - if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING))) - tirion->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - - // Reset any light override - me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, 0, 5000); - } - bool CanAIAttack(Unit const* target) const override { // The Lich King must not select targets in frostmourne room if he killed everyone outside - return !target->HasAura(SPELL_IN_FROSTMOURNE_ROOM); + return !target->HasAura(SPELL_IN_FROSTMOURNE_ROOM) && BossAI::CanAIAttack(target); } - void EnterEvadeMode(EvadeReason why) override + void EnterEvadeMode(EvadeReason /*why*/) override { - instance->SetBossState(DATA_THE_LICH_KING, FAIL); - BossAI::EnterEvadeMode(why); if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING))) - tirion->AI()->EnterEvadeMode(); + tirion->DespawnOrUnsummon(); DoCastAOE(SPELL_KILL_FROSTMOURNE_PLAYERS); EntryCheckPredicate pred(NPC_STRANGULATE_VEHICLE); summons.DoAction(ACTION_TELEPORT_BACK, pred); + summons.DespawnAll(); + _DespawnAtEvade(); } void KilledUnit(Unit* victim) override @@ -761,7 +763,7 @@ class boss_the_lich_king : public CreatureScript { summons.Summon(summon); summon->SetReactState(REACT_PASSIVE); - summon->SetSpeed(MOVE_FLIGHT, 0.5f); + summon->SetSpeedRate(MOVE_FLIGHT, 0.5f); summon->GetMotionMaster()->MoveRandom(10.0f); if (!events.IsInPhase(PHASE_FROSTMOURNE)) summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000)); @@ -770,6 +772,8 @@ class boss_the_lich_king : public CreatureScript case NPC_STRANGULATE_VEHICLE: summons.Summon(summon); return; + case NPC_HIGHLORD_TIRION_FORDRING_LK: + return; default: break; } @@ -1153,6 +1157,7 @@ class npc_tirion_fordring_tft : public CreatureScript _events.Reset(); if (_instance->GetBossState(DATA_THE_LICH_KING) == DONE) me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->LoadEquipment(1); } void MovementInform(uint32 type, uint32 id) override @@ -1443,7 +1448,7 @@ class npc_valkyr_shadowguard : public CreatureScript _events.Reset(); me->SetReactState(REACT_PASSIVE); DoCast(me, SPELL_WINGS_OF_THE_DAMNED, false); - me->SetSpeed(MOVE_FLIGHT, 0.642857f, true); + me->SetSpeedRate(MOVE_FLIGHT, 0.642857f); } void IsSummonedBy(Unit* /*summoner*/) override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index 4f35f848927..b07de3457bd 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -179,7 +179,7 @@ class DelayedCastEvent : public BasicEvent { } - bool Execute(uint64 /*time*/, uint32 /*diff*/) + bool Execute(uint64 /*time*/, uint32 /*diff*/) override { _trigger->CastSpell(_trigger, _spellId, false, NULL, NULL, _originalCaster); if (_despawnTime) @@ -201,7 +201,7 @@ class AuraRemoveEvent : public BasicEvent { } - bool Execute(uint64 /*time*/, uint32 /*diff*/) + bool Execute(uint64 /*time*/, uint32 /*diff*/) override { _trigger->RemoveAurasDueToSpell(_spellId); return true; @@ -219,7 +219,7 @@ class ValithriaDespawner : public BasicEvent { } - bool Execute(uint64 /*currTime*/, uint32 /*diff*/) + bool Execute(uint64 /*currTime*/, uint32 /*diff*/) override { Trinity::CreatureWorker<ValithriaDespawner> worker(_creature, *this); _creature->VisitNearbyGridObject(333.0f, worker); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 25ca99f6a20..abb9c025771 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -365,7 +365,7 @@ class CaptainSurviveTalk : public BasicEvent public: explicit CaptainSurviveTalk(Creature const& owner) : _owner(owner) { } - bool Execute(uint64 /*currTime*/, uint32 /*diff*/) + bool Execute(uint64 /*currTime*/, uint32 /*diff*/) override { _owner.AI()->Talk(SAY_CAPTAIN_SURVIVE_TALK); return true; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp index e8c4216b00e..60c60640c04 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp @@ -162,13 +162,13 @@ public: summons.DoZoneInCombat(); events.SetPhase(PHASE_NORMAL); - events.ScheduleEvent(EVENT_IMPALE, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_NORMAL); - events.ScheduleEvent(EVENT_SCARABS, urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS), 0, PHASE_NORMAL); - events.ScheduleEvent(EVENT_LOCUST, urand(80,120) * IN_MILLISECONDS, 0, PHASE_NORMAL); - events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_IMPALE, randtime(Seconds(10), Seconds(20)), 0, PHASE_NORMAL); + events.ScheduleEvent(EVENT_SCARABS, randtime(Seconds(20), Seconds(30)), 0, PHASE_NORMAL); + events.ScheduleEvent(EVENT_LOCUST, Minutes(1)+randtime(Seconds(40), Seconds(60)), 0, PHASE_NORMAL); + events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); if (!Is25ManRaid()) - events.ScheduleEvent(EVENT_SPAWN_GUARD, urand(15, 20) * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_SPAWN_GUARD, randtime(Seconds(15), Seconds(20))); } void UpdateAI(uint32 diff) override @@ -189,11 +189,9 @@ public: else EnterEvadeMode(); - events.ScheduleEvent(EVENT_IMPALE, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_NORMAL); + events.Repeat(randtime(Seconds(10), Seconds(20))); break; case EVENT_SCARABS: - events.ScheduleEvent(EVENT_SCARABS, urand(40 * IN_MILLISECONDS, 60 * IN_MILLISECONDS), 0, PHASE_NORMAL); - if (!guardCorpses.empty()) { if (ObjectGuid target = Trinity::Containers::SelectRandomContainerElement(guardCorpses)) @@ -204,27 +202,28 @@ public: creatureTarget->DespawnOrUnsummon(); } } + events.Repeat(randtime(Seconds(40), Seconds(60))); break; case EVENT_LOCUST: Talk(EMOTE_LOCUST); + events.SetPhase(PHASE_SWARM); DoCast(me, SPELL_LOCUST_SWARM); - events.ScheduleEvent(EVENT_SPAWN_GUARD, 3 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_LOCUST_ENDS, RAID_MODE(19, 23) * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_LOCUST, 90000); - events.SetPhase(PHASE_SWARM); + events.ScheduleEvent(EVENT_SPAWN_GUARD, Seconds(3)); + events.ScheduleEvent(EVENT_LOCUST_ENDS, RAID_MODE(Seconds(19), Seconds(23))); + events.Repeat(Minutes(1)+Seconds(30)); break; case EVENT_LOCUST_ENDS: - events.ScheduleEvent(EVENT_IMPALE, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_NORMAL); - events.ScheduleEvent(EVENT_SCARABS, urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS), 0, PHASE_NORMAL); events.SetPhase(PHASE_NORMAL); + events.ScheduleEvent(EVENT_IMPALE, randtime(Seconds(10), Seconds(20)), 0, PHASE_NORMAL); + events.ScheduleEvent(EVENT_SCARABS, randtime(Seconds(20), Seconds(30)), 0, PHASE_NORMAL); break; case EVENT_SPAWN_GUARD: me->SummonCreatureGroup(GROUP_SINGLE_SPAWN); break; case EVENT_BERSERK: DoCast(me, SPELL_BERSERK, true); - events.ScheduleEvent(EVENT_BERSERK, 600000); + events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); break; } } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp index 39c41c935bf..8a7bdd293ba 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp @@ -100,9 +100,9 @@ class boss_faerlina : public CreatureScript _EnterCombat(); Talk(SAY_AGGRO); summons.DoZoneInCombat(); - events.ScheduleEvent(EVENT_POISON, urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS)); - events.ScheduleEvent(EVENT_FIRE, urand(6 * IN_MILLISECONDS, 18 * IN_MILLISECONDS)); - events.ScheduleEvent(EVENT_FRENZY, urand(60 * IN_MILLISECONDS, 80 * IN_MILLISECONDS)); + events.ScheduleEvent(EVENT_POISON, randtime(Seconds(10), Seconds(15))); + events.ScheduleEvent(EVENT_FIRE, randtime(Seconds(6), Seconds(18))); + events.ScheduleEvent(EVENT_FRENZY, Minutes(1)+randtime(Seconds(0), Seconds(20))); } void Reset() override @@ -111,9 +111,9 @@ class boss_faerlina : public CreatureScript _frenzyDispels = 0; } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* victim) override { - if (!urand(0, 2)) + if (victim->GetTypeId() == TYPEID_PLAYER) Talk(SAY_SLAY); } @@ -158,21 +158,21 @@ class boss_faerlina : public CreatureScript case EVENT_POISON: if (!me->HasAura(SPELL_WIDOWS_EMBRACE_HELPER)) DoCastAOE(SPELL_POISON_BOLT_VOLLEY); - events.ScheduleEvent(EVENT_POISON, urand(8000, 15000)); + events.Repeat(randtime(Seconds(8), Seconds(15))); break; case EVENT_FIRE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_RAIN_OF_FIRE); - events.ScheduleEvent(EVENT_FIRE, urand(6000, 18000)); + events.Repeat(randtime(Seconds(6), Seconds(18))); break; case EVENT_FRENZY: if (Aura* widowsEmbrace = me->GetAura(SPELL_WIDOWS_EMBRACE_HELPER)) - events.ScheduleEvent(EVENT_FRENZY, widowsEmbrace->GetDuration()+1 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_FRENZY, Milliseconds(widowsEmbrace->GetDuration()+1)); else { DoCast(SPELL_FRENZY); Talk(EMOTE_FRENZY); - events.ScheduleEvent(EVENT_FRENZY, urand(60 * IN_MILLISECONDS, 80 * IN_MILLISECONDS)); + events.Repeat(Minutes(1) + randtime(Seconds(0), Seconds(20))); } break; } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index a7a89f44d81..0de1c4785b8 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -285,7 +285,7 @@ struct boss_four_horsemen_baseAI : public BossAI void EnterCombat(Unit* /*who*/) override { - if (instance->GetBossState(BOSS_HORSEMEN) != NOT_STARTED) // another horseman already did it + if (instance->GetBossState(BOSS_HORSEMEN) == IN_PROGRESS || instance->GetBossState(BOSS_HORSEMEN) == DONE) // another horseman already did it return; Talk(SAY_AGGRO); BeginEncounter(); @@ -411,9 +411,9 @@ class boss_four_horsemen_baron : public CreatureScript else AttackStart(threat.getHostilTarget()); - events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_MARK, 24 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_UNHOLYSHADOW, urandms(3,7)); + events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); + events.ScheduleEvent(EVENT_MARK, Seconds(24)); + events.ScheduleEvent(EVENT_UNHOLYSHADOW, randtime(Seconds(3), Seconds(7))); } void _UpdateAI(uint32 diff) override @@ -431,11 +431,11 @@ class boss_four_horsemen_baron : public CreatureScript break; case EVENT_MARK: DoCastAOE(SPELL_BARON_MARK, true); - events.ScheduleEvent(EVENT_MARK, 12 * IN_MILLISECONDS); + events.Repeat(Seconds(12)); break; case EVENT_UNHOLYSHADOW: DoCastVictim(SPELL_UNHOLY_SHADOW); - events.ScheduleEvent(EVENT_UNHOLYSHADOW, urandms(10,30)); + events.Repeat(randtime(Seconds(10), Seconds(30))); break; } } @@ -484,9 +484,9 @@ class boss_four_horsemen_thane : public CreatureScript else AttackStart(threat.getHostilTarget()); - events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_MARK, 24 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_METEOR, urandms(10,15)); + events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); + events.ScheduleEvent(EVENT_MARK, Seconds(24)); + events.ScheduleEvent(EVENT_METEOR, randtime(Seconds(10), Seconds(25))); } void _UpdateAI(uint32 diff) override { @@ -503,7 +503,7 @@ class boss_four_horsemen_thane : public CreatureScript break; case EVENT_MARK: DoCastAOE(SPELL_THANE_MARK, true); - events.ScheduleEvent(EVENT_MARK, 12 * IN_MILLISECONDS); + events.Repeat(Seconds(12)); break; case EVENT_METEOR: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20.0f, true)) @@ -511,7 +511,7 @@ class boss_four_horsemen_thane : public CreatureScript DoCast(target, SPELL_METEOR); _shouldSay = true; } - events.ScheduleEvent(EVENT_METEOR, urandms(13,17)); + events.Repeat(randtime(Seconds(13), Seconds(17))); break; } } @@ -550,9 +550,9 @@ class boss_four_horsemen_lady : public CreatureScript boss_four_horsemen_ladyAI(Creature* creature) : boss_four_horsemen_baseAI(creature, LADY, ladyPath) { } void BeginFighting() override { - events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_MARK, 24 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_VOIDZONE, urandms(5,10)); + events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); + events.ScheduleEvent(EVENT_MARK, Seconds(24)); + events.ScheduleEvent(EVENT_VOIDZONE, randtime(Seconds(5), Seconds(10))); } void _UpdateAI(uint32 diff) override @@ -578,7 +578,7 @@ class boss_four_horsemen_lady : public CreatureScript break; case EVENT_MARK: DoCastAOE(SPELL_LADY_MARK, true); - events.ScheduleEvent(EVENT_MARK, 15 * IN_MILLISECONDS); + events.Repeat(Seconds(15)); break; case EVENT_VOIDZONE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true)) @@ -586,7 +586,7 @@ class boss_four_horsemen_lady : public CreatureScript DoCast(target, SPELL_VOID_ZONE, true); Talk(SAY_SPECIAL); } - events.ScheduleEvent(EVENT_VOIDZONE, urandms(12, 18)); + events.Repeat(randtime(Seconds(12), Seconds(18))); break; } } @@ -620,9 +620,9 @@ class boss_four_horsemen_sir : public CreatureScript boss_four_horsemen_sirAI(Creature* creature) : boss_four_horsemen_baseAI(creature, SIR, sirPath), _shouldSay(true) { } void BeginFighting() override { - events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_MARK, 24 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_HOLYWRATH, urandms(13,18)); + events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); + events.ScheduleEvent(EVENT_MARK, Seconds(24)); + events.ScheduleEvent(EVENT_HOLYWRATH, randtime(Seconds(13), Seconds(18))); } void _UpdateAI(uint32 diff) override @@ -648,7 +648,7 @@ class boss_four_horsemen_sir : public CreatureScript break; case EVENT_MARK: DoCastAOE(SPELL_SIR_MARK, true); - events.ScheduleEvent(EVENT_MARK, 15 * IN_MILLISECONDS); + events.Repeat(Seconds(15)); break; case EVENT_HOLYWRATH: if (Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0, 45.0f, true)) @@ -656,7 +656,7 @@ class boss_four_horsemen_sir : public CreatureScript DoCast(target, SPELL_HOLY_WRATH, true); _shouldSay = true; } - events.ScheduleEvent(EVENT_HOLYWRATH, urandms(10,18)); + events.Repeat(randtime(Seconds(10), Seconds(18))); break; } } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp index ec47b0db101..ef6ccf5bf4b 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp @@ -18,38 +18,74 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "naxxramas.h" +#include "SpellScript.h" +#include <math.h> -enum Spells +enum Texts { - SPELL_MORTAL_WOUND = 25646, - SPELL_ENRAGE = 28371, - SPELL_DECIMATE = 28374, - SPELL_BERSERK = 26662, - SPELL_INFECTED_WOUND = 29306 + EMOTE_SPOTS_ONE = 0, + EMOTE_DECIMATE = 1, + EMOTE_ENRAGE = 2, + EMOTE_DEVOURS_ALL = 3, + EMOTE_BERSERKER = 4 }; -enum Creatures +enum Spells { - NPC_ZOMBIE = 16360 + // Gluth + SPELL_MORTAL_WOUND = 54378, // spell effect dummy unused. what its supposed to do is unkown. + SPELL_ENRAGE = 28371, // 54427 in 25 man. + SPELL_DECIMATE = 28374, // 54426 in 25 man. Effect0 is handled by SpellScript (see below) and 2 rows in conditions table. Effect2 is handled by SpellScript (see below). + SPELL_DECIMATE_DMG = 28375, + SPELL_BERSERK = 26662, + SPELL_ZOMBIE_CHOW_SEARCH_SINGLE = 28239, // Insta kill spell. Single target. See spell script below. + SPELL_ZOMBIE_CHOW_SEARCH_MULTI = 28404, // Insta kill spell. Affect all zombies 10 yards around Gluth's center. See one row conditions table + spell script below. + + // Zombies + SPELL_INFECTED_WOUND = 29307 // Used by the zombies on self. }; Position const PosSummon[3] = { - {3267.9f, -3172.1f, 297.42f, 0.94f}, - {3253.2f, -3132.3f, 297.42f, 0}, - {3308.3f, -3185.8f, 297.42f, 1.58f}, + { 3270.132f, -3169.948f, 297.5891f, 5.88176f }, + { 3307.298f, -3183.449f, 297.5891f, 5.742133f }, + { 3255.708f, -3135.677f, 297.5891f, 1.867502f } }; enum Events { - EVENT_WOUND = 1, + EVENT_WOUND = 1, EVENT_ENRAGE, EVENT_DECIMATE, EVENT_BERSERK, EVENT_SUMMON, + EVENT_SEARCH_ZOMBIE_SINGLE, + EVENT_KILL_ZOMBIE_SINGLE, + EVENT_SEARCH_ZOMBIE_MULTI }; -#define EMOTE_NEARBY " spots a nearby zombie to devour!" +enum States +{ + STATE_GLUTH_NORMAL = 1, + STATE_GLUTH_EATING = 2, + + STATE_ZOMBIE_NORMAL = 1, + STATE_ZOMBIE_DECIMATED = 2, + STATE_ZOMBIE_TOBE_EATEN = 3 +}; + +enum SummonGroups +{ + SUMMON_GROUP_CHOW_10MAN = 1, + SUMMON_GROUP_CHOW_25MAN = 2 +}; + +enum Misc +{ + EVENT_GLUTH_ZOMBIE_BEHAVIOR = 10495, // unused. event handled by spell_gluth_decimate_SpellScript::HandleEvent + DATA_ZOMBIE_STATE = 1, + ACTION_DECIMATE_EVENT = 2, +}; class boss_gluth : public CreatureScript { @@ -58,99 +94,388 @@ public: CreatureAI* GetAI(Creature* creature) const override { - return new boss_gluthAI(creature); + return GetInstanceAI<boss_gluthAI>(creature); } struct boss_gluthAI : public BossAI { - boss_gluthAI(Creature* creature) : BossAI(creature, BOSS_GLUTH) - { - // Do not let Gluth be affected by zombies' debuff - me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_INFECTED_WOUND, true); - } - void MoveInLineOfSight(Unit* who) override + boss_gluthAI(Creature* creature) : BossAI(creature, BOSS_GLUTH), state(STATE_GLUTH_NORMAL) {} + + void Reset() override { - if (who->GetEntry() == NPC_ZOMBIE && me->IsWithinDistInMap(who, 7)) - { - SetGazeOn(who); - /// @todo use a script text - me->TextEmote(EMOTE_NEARBY, nullptr, true); - } - else - BossAI::MoveInLineOfSight(who); + _Reset(); + zombieToBeEatenGUID.Clear(); + state = STATE_GLUTH_NORMAL; + me->SetReactState(REACT_AGGRESSIVE); + me->SetSpeed(UnitMoveType::MOVE_RUN, 12.0f); } void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - events.ScheduleEvent(EVENT_WOUND, 10000); - events.ScheduleEvent(EVENT_ENRAGE, 15000); - events.ScheduleEvent(EVENT_DECIMATE, 105000); - events.ScheduleEvent(EVENT_BERSERK, 8*60000); - events.ScheduleEvent(EVENT_SUMMON, 15000); + events.ScheduleEvent(EVENT_WOUND, Seconds(10)); + events.ScheduleEvent(EVENT_ENRAGE, randtime(Seconds(16), Seconds(22))); + events.ScheduleEvent(EVENT_DECIMATE, randtime(Minutes(1)+Seconds(50), Minutes(2))); + events.ScheduleEvent(EVENT_BERSERK, Minutes(8)); + events.ScheduleEvent(EVENT_SUMMON, Seconds(15)); + events.ScheduleEvent(EVENT_SEARCH_ZOMBIE_SINGLE, Seconds(12)); } - void JustSummoned(Creature* summon) override + void SummonedCreatureDies(Creature* summoned, Unit* /* who */) override { - if (summon->GetEntry() == NPC_ZOMBIE) - summon->AI()->AttackStart(me); - summons.Summon(summon); + summons.Despawn(summoned); // needed or else dead zombies not despawned yet will still be in the list } void UpdateAI(uint32 diff) override { - if (!UpdateVictimWithGaze()) + if (!UpdateVictim() || !CheckInRoom()) return; events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_WOUND: + if (state == STATE_GLUTH_EATING) + { + events.Repeat(Seconds(3)); + break; + } + DoCastVictim(SPELL_MORTAL_WOUND); - events.ScheduleEvent(EVENT_WOUND, 10000); + events.Repeat(Seconds(10)); break; case EVENT_ENRAGE: - /// @todo Add missing text + if (state == STATE_GLUTH_EATING) + { + events.Repeat(Seconds(5)); + break; + } + + Talk(EMOTE_ENRAGE); DoCast(me, SPELL_ENRAGE); - events.ScheduleEvent(EVENT_ENRAGE, 15000); + events.Repeat(randtime(Seconds(16), Seconds(22))); break; case EVENT_DECIMATE: - /// @todo Add missing text + if (state == STATE_GLUTH_EATING) + { + events.Repeat(Seconds(4)); + break; + } + + Talk(EMOTE_DECIMATE); DoCastAOE(SPELL_DECIMATE); - events.ScheduleEvent(EVENT_DECIMATE, 105000); + for (int i = 1; i <= 20; i++) + events.ScheduleEvent(EVENT_SEARCH_ZOMBIE_MULTI, Seconds(3*i)); + events.ScheduleEvent(EVENT_DECIMATE, randtime(Minutes(1)+Seconds(50), Minutes(2))); break; case EVENT_BERSERK: + Talk(EMOTE_BERSERKER); DoCast(me, SPELL_BERSERK); - events.ScheduleEvent(EVENT_BERSERK, 5*60000); + events.Repeat(Minutes(5)); //refresh the hard enrage buff break; case EVENT_SUMMON: - for (int32 i = 0; i < RAID_MODE(1, 2); ++i) - DoSummon(NPC_ZOMBIE, PosSummon[rand32() % RAID_MODE(1, 3)]); - events.ScheduleEvent(EVENT_SUMMON, 10000); + if (Is25ManRaid()) // one wave each 10s. one wave=1 zombie in 10man and 2 zombies in 25man. + me->SummonCreatureGroup(SUMMON_GROUP_CHOW_25MAN); + else + me->SummonCreatureGroup(SUMMON_GROUP_CHOW_10MAN); + events.Repeat(Seconds(10)); + break; + case EVENT_SEARCH_ZOMBIE_SINGLE: + { + Creature* zombie = nullptr; + for (SummonList::const_iterator itr = summons.begin(); !zombie && itr != summons.end(); ++itr) + { + zombie=ObjectAccessor::GetCreature(*me, *itr); + if (!zombie || !zombie->IsAlive() || !zombie->IsWithinDistInMap(me, 10.0)) + zombie = nullptr; + } + + if (zombie) + { + zombieToBeEatenGUID = zombie->GetGUID(); // save for later use + + // the soon-to-be-eaten zombie should stop moving and stop attacking + zombie->AI()->SetData(DATA_ZOMBIE_STATE, STATE_ZOMBIE_TOBE_EATEN); + + // gluth should stop AAs on his primary target and turn toward the zombie (2 yards away). He then pauses for a few seconds. + me->SetSpeed(MOVE_RUN, 36.0f); + + me->SetReactState(ReactStates::REACT_PASSIVE); + me->AttackStop(); + + Talk(EMOTE_SPOTS_ONE); + + //me->SetTarget(ObjectGuid::Empty); + + me->GetMotionMaster()->MoveCloserAndStop(1, zombie, 2.0f); + + state = STATE_GLUTH_EATING; + } + + events.Repeat(RAID_MODE(Seconds(7), Seconds(5))); + break; + } + case EVENT_KILL_ZOMBIE_SINGLE: + { + Creature* zombieToBeEaten = ObjectAccessor::GetCreature(*me, zombieToBeEatenGUID); + if (zombieToBeEaten && zombieToBeEaten->IsAlive() && zombieToBeEaten->IsWithinDistInMap(me, 10.0)) + DoCast(zombieToBeEaten, SPELL_ZOMBIE_CHOW_SEARCH_SINGLE); // do the killing + healing in done inside by spell script see below. + + zombieToBeEatenGUID = ObjectGuid::Empty; + state = STATE_GLUTH_NORMAL; + me->SetSpeed(UnitMoveType::MOVE_RUN, 12.0f); + + // and then return on primary target + me->SetReactState(REACT_AGGRESSIVE); + + break; + } + case EVENT_SEARCH_ZOMBIE_MULTI: + { + if (state == STATE_GLUTH_EATING) // skip and simply wait for the next occurence + break; + + Creature* zombie = nullptr; + for (SummonList::const_iterator itr = summons.begin(); !zombie && itr != summons.end(); ++itr) + { + zombie = ObjectAccessor::GetCreature(*me, *itr); + if (zombie && zombie->IsAlive() && zombie->GetExactDist2d(me) > 18.0) + zombie = nullptr; + } + + if (zombie) // cast the aoe spell only if at least one zombie is found nearby + { + Talk(EMOTE_DEVOURS_ALL); + DoCastAOE(SPELL_ZOMBIE_CHOW_SEARCH_MULTI); + } break; + } } } - if (me->GetVictim() && me->EnsureVictim()->GetEntry() == NPC_ZOMBIE) + DoMeleeAttackIfReady(); + } + + void MovementInform(uint32 /*type*/, uint32 id) override + { + if (id == 1){ + me->GetMotionMaster()->MoveIdle(); + events.ScheduleEvent(EVENT_KILL_ZOMBIE_SINGLE, Seconds(1)); + } + + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_DECIMATE_EVENT: + for (ObjectGuid zombieGuid : summons) + { + Creature* zombie = ObjectAccessor::GetCreature(*me, zombieGuid); + if (zombie && zombie->IsAlive()) + zombie->AI()->SetData(DATA_ZOMBIE_STATE, STATE_ZOMBIE_DECIMATED); + } + break; + } + } + + private: + ObjectGuid zombieToBeEatenGUID; + uint8 state; + }; + +}; + +// spell 28374 (10man) / 54426 (25man) - Decimate +class spell_gluth_decimate : public SpellScriptLoader +{ +public: + spell_gluth_decimate() : SpellScriptLoader("spell_gluth_decimate") { } + + class spell_gluth_decimate_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gluth_decimate_SpellScript); + + // handles the damaging effect of the decimate spell. + void HandleScriptEffect(SpellEffIndex /* index */) + { + if (Unit *unit = GetHitUnit()) { - if (me->IsWithinMeleeRange(me->GetVictim())) + int32 damage = int32(unit->GetHealth()) - int32(unit->CountPctFromMaxHealth(5)); + if (damage > 0) + GetCaster()->CastCustomSpell(SPELL_DECIMATE_DMG, SPELLVALUE_BASE_POINT0, damage, unit); + } + } + + // handles the change of zombies behavior after the decimate spell + void HandleEvent(SpellEffIndex /* index */) + { + GetCaster()->GetAI()->DoAction(ACTION_DECIMATE_EVENT); + } + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return (sSpellMgr->GetSpellInfo(SPELL_DECIMATE_DMG) != nullptr); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gluth_decimate_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHit += SpellEffectFn(spell_gluth_decimate_SpellScript::HandleEvent, EFFECT_2, SPELL_EFFECT_SEND_EVENT); + } + + bool Load() override + { + return GetCaster() && GetCaster()->GetEntry() == NPC_GLUTH; + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gluth_decimate_SpellScript(); + } + +}; + +// used by both 28239 & 28404 (single target and aoe zombie-kill spell) to heal Gluth on each target hit. + +class spell_gluth_zombiechow_search : public SpellScriptLoader +{ +public: + spell_gluth_zombiechow_search() : SpellScriptLoader("spell_gluth_zombiechow_search") { } + + class spell_gluth_zombiechow_search_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gluth_zombiechow_search_SpellScript); + + void HealForEachTargetHit() + { + GetCaster()->ModifyHealth(int32(GetCaster()->CountPctFromMaxHealth(5))); + } + + void Register() override + { + AfterHit += SpellHitFn(spell_gluth_zombiechow_search_SpellScript::HealForEachTargetHit); + } + + bool Load() override + { + return GetCaster() && GetCaster()->GetEntry() == NPC_GLUTH; + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gluth_zombiechow_search_SpellScript(); + } + +}; + +// creature 16360 (10man) / 30303 (25man) +class npc_zombie_chow : public CreatureScript +{ +public: + + npc_zombie_chow() : CreatureScript("npc_zombie_chow") { } + + struct npc_zombie_chowAI : public ScriptedAI + { + npc_zombie_chowAI(Creature* creature) : ScriptedAI(creature) + { + GluthGUID = creature->GetInstanceScript()->GetGuidData(DATA_GLUTH); + + DoCast(me, SPELL_INFECTED_WOUND); + timer = 0; + state = STATE_ZOMBIE_NORMAL; + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (state == STATE_ZOMBIE_DECIMATED) + { + timer += diff; + Creature* gluth = ObjectAccessor::GetCreature(*me, GluthGUID); + // Putting this in the UpdateAI loop fixes an issue where death gripping a decimated zombie would make the zombie stand still until the rest of the fight. + // Also fix the issue where if one or more zombie is rooted when decimates hits (and MovePoint() is called), the zombie teleport to the boss. pretty weird behavior. + if (gluth && timer>1600 && me->GetExactDist2d(gluth) > 10.0 && me->CanFreeMove()) // it takes about 1600 ms for the animation to cycle. This way, the animation looks relatively smooth. { - me->Kill(me->GetVictim()); - me->ModifyHealth(int32(me->CountPctFromMaxHealth(5))); + me->GetMotionMaster()->MovePoint(0, gluth->GetPosition()); // isn't dynamic. So, to take into account Gluth's movement, it must be called periodicly. + timer = 0; } + + if (me->GetExactDist2d(gluth) <= 10.0) + me->StopMoving(); } - else + else if (state == STATE_ZOMBIE_NORMAL) DoMeleeAttackIfReady(); } + + void SetData(uint32 id, uint32 value) override + { + if (id == DATA_ZOMBIE_STATE) // change of state + { + state = value; + if (value == STATE_ZOMBIE_DECIMATED) + { + me->SetReactState(ReactStates::REACT_PASSIVE); + me->AttackStop(); + me->SetTarget(ObjectGuid::Empty); + // at this point, the zombie should be non attacking and non moving. + + me->SetWalk(true); // it doesnt seem to work with MoveFollow() (but it does work with MovePoint()). + + timer = 1000; + } + else if (value == STATE_ZOMBIE_TOBE_EATEN) + { + // forced to stand still + me->GetMotionMaster()->Clear(); + me->StopMoving(); + + // and loose aggro behavior + me->SetReactState(ReactStates::REACT_PASSIVE); + me->AttackStop(); + me->SetTarget(ObjectGuid::Empty); + + me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true); // not sure if this is blizz-like but this is very convenient + } + } + } + + uint32 GetData(uint32 index) const override + { + if (index == DATA_ZOMBIE_STATE) + return state; + return 0; + } + + private: + uint32 timer; + uint8 state; + ObjectGuid GluthGUID; }; + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<npc_zombie_chowAI>(creature); + } }; void AddSC_boss_gluth() { new boss_gluth(); + new spell_gluth_decimate(); + new spell_gluth_zombiechow_search(); + new npc_zombie_chow(); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp index 81f1e071da0..30c05c9dca9 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp @@ -65,7 +65,7 @@ enum Spells /* gothik phase two spells */ SPELL_HARVEST_SOUL = 28679, SPELL_SHADOW_BOLT = 29317, - + /* visual spells */ SPELL_ANCHOR_1_TRAINEE = 27892, SPELL_ANCHOR_1_DK = 27928, @@ -324,13 +324,13 @@ class boss_gothik : public CreatureScript { _EnterCombat(); events.SetPhase(PHASE_ONE); - events.ScheduleEvent(EVENT_SUMMON, 25 * IN_MILLISECONDS, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_DOORS_UNLOCK, 205 * IN_MILLISECONDS, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_PHASE_TWO, 270 * IN_MILLISECONDS, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SUMMON, Seconds(25), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_DOORS_UNLOCK, Minutes(3) + Seconds(25), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_PHASE_TWO, Minutes(4) + Seconds(30), 0, PHASE_ONE); Talk(SAY_INTRO_1); - events.ScheduleEvent(EVENT_INTRO_2, 4 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_INTRO_3, 9 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_INTRO_4, 14 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_INTRO_2, Seconds(4)); + events.ScheduleEvent(EVENT_INTRO_3, Seconds(9)); + events.ScheduleEvent(EVENT_INTRO_4, Seconds(14)); instance->SetData(DATA_GOTHIK_GATE, GO_STATE_READY); _gateIsOpen = false; } @@ -373,10 +373,14 @@ class boss_gothik : public CreatureScript instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE); Talk(EMOTE_GATE_OPENED); _gateIsOpen = true; - + for (ObjectGuid summonGuid : summons) + { if (Creature* summon = ObjectAccessor::GetCreature(*me, summonGuid)) summon->AI()->DoAction(ACTION_GATE_OPENED); + if (summons.empty()) // ACTION_GATE_OPENED may cause an evade, despawning summons and invalidating our iterator + break; + } } void DamageTaken(Unit* /*who*/, uint32& damage) override @@ -440,7 +444,7 @@ class boss_gothik : public CreatureScript TC_LOG_INFO("scripts", "GothikAI: Wave count %d is out of range for difficulty %d.", _waveCount, GetDifficulty()); break; } - + std::list<Creature*> triggers; me->GetCreatureListWithEntryInGrid(triggers, NPC_TRIGGER, 150.0f); for (GothikWaveEntry entry : RAID_MODE(waves10, waves25)[_waveCount].first) @@ -466,7 +470,7 @@ class boss_gothik : public CreatureScript default: targetDBGuid = 0; } - + for (Creature* trigger : triggers) if (trigger && trigger->GetSpawnId() == targetDBGuid) { @@ -476,7 +480,7 @@ class boss_gothik : public CreatureScript } if (uint8 timeToNext = RAID_MODE(waves10, waves25)[_waveCount].second) - events.ScheduleEvent(EVENT_SUMMON, timeToNext * IN_MILLISECONDS, 0, PHASE_ONE); + events.Repeat(Seconds(timeToNext)); ++_waveCount; break; @@ -493,9 +497,9 @@ class boss_gothik : public CreatureScript break; case EVENT_PHASE_TWO: events.SetPhase(PHASE_TWO); - events.ScheduleEvent(EVENT_TELEPORT, 20 * IN_MILLISECONDS, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_HARVEST, 15 * IN_MILLISECONDS, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_RESUME_ATTACK, 2 * IN_MILLISECONDS, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_TELEPORT, Seconds(20), 0, PHASE_TWO); + events.ScheduleEvent(EVENT_HARVEST, Seconds(15), 0, PHASE_TWO); + events.ScheduleEvent(EVENT_RESUME_ATTACK, Seconds(2), 0, PHASE_TWO); Talk(SAY_PHASE_TWO); Talk(EMOTE_PHASE_TWO); me->SetReactState(REACT_PASSIVE); @@ -514,23 +518,23 @@ class boss_gothik : public CreatureScript _lastTeleportDead = !_lastTeleportDead; events.CancelEvent(EVENT_BOLT); - events.ScheduleEvent(EVENT_TELEPORT, 20 * IN_MILLISECONDS, 0, PHASE_TWO); events.ScheduleEvent(EVENT_RESUME_ATTACK, 2 * IN_MILLISECONDS, 0, PHASE_TWO); + events.Repeat(Seconds(20)); } break; case EVENT_HARVEST: DoCastAOE(SPELL_HARVEST_SOUL, true); // triggered allows this to go "through" shadow bolt - events.ScheduleEvent(EVENT_HARVEST, 15 * IN_MILLISECONDS, 0, PHASE_TWO); + events.Repeat(Seconds(15)); break; case EVENT_RESUME_ATTACK: me->SetReactState(REACT_AGGRESSIVE); - events.ScheduleEvent(EVENT_BOLT, 0, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_BOLT, Seconds(0), 0, PHASE_TWO); // return to the start of this method so victim side etc is re-evaluated return UpdateAI(0u); // tail recursion for efficiency case EVENT_BOLT: DoCastVictim(SPELL_SHADOW_BOLT); - events.ScheduleEvent(EVENT_BOLT, 1 * IN_MILLISECONDS, 0, PHASE_TWO); + events.Repeat(Seconds(2)); break; case EVENT_INTRO_2: Talk(SAY_INTRO_2); @@ -544,7 +548,7 @@ class boss_gothik : public CreatureScript } } } - + private: uint32 _waveCount; bool _gateCanOpen; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp index a1d8f6e5e02..cf38d659d40 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp @@ -57,10 +57,10 @@ class boss_grobbulus : public CreatureScript void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - events.ScheduleEvent(EVENT_CLOUD, 15000); - events.ScheduleEvent(EVENT_INJECT, 20000); - events.ScheduleEvent(EVENT_SPRAY, urand(15000, 30000)); // not sure - events.ScheduleEvent(EVENT_BERSERK, 12 * 60000); + events.ScheduleEvent(EVENT_CLOUD, Seconds(15)); + events.ScheduleEvent(EVENT_INJECT, Seconds(20)); + events.ScheduleEvent(EVENT_SPRAY, randtime(Seconds(15), Seconds(30))); // not sure + events.ScheduleEvent(EVENT_BERSERK, Minutes(12)); } void SpellHitTarget(Unit* target, SpellInfo const* spell) override @@ -82,19 +82,19 @@ class boss_grobbulus : public CreatureScript { case EVENT_CLOUD: DoCastAOE(SPELL_POISON_CLOUD); - events.ScheduleEvent(EVENT_CLOUD, 15000); + events.Repeat(Seconds(15)); return; case EVENT_BERSERK: DoCastAOE(SPELL_BERSERK, true); return; case EVENT_SPRAY: DoCastAOE(SPELL_SLIME_SPRAY); - events.ScheduleEvent(EVENT_SPRAY, urand(15000, 30000)); + events.Repeat(randtime(Seconds(15), Seconds(30))); return; case EVENT_INJECT: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_MUTATING_INJECTION)) DoCast(target, SPELL_MUTATING_INJECTION); - events.ScheduleEvent(EVENT_INJECT, 8000 + uint32(120 * me->GetHealthPct())); + events.Repeat(Seconds(8) + Milliseconds(uint32(std::round(120 * me->GetHealthPct())))); return; default: break; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp index 9b9619fe5b9..41d718d188d 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp @@ -27,6 +27,7 @@ enum Spells SPELL_SPELL_DISRUPTION = 29310, SPELL_PLAGUE_CLOUD = 29350, SPELL_TELEPORT_SELF = 30211, + SPELL_ERUPTION = 29371 }; enum Yells @@ -60,6 +61,15 @@ enum Misc DATA_SAFETY_DANCE = 19962139 }; +static const uint32 firstEruptionDBGUID = 84980; +static const uint8 numSections = 4; +static const uint8 numEruptions[numSections] = { // count of sequential GO DBGUIDs in the respective section of the room + 15, + 25, + 23, + 13 +}; + class boss_heigan : public CreatureScript { public: @@ -72,7 +82,7 @@ public: struct boss_heiganAI : public BossAI { - boss_heiganAI(Creature* creature) : BossAI(creature, BOSS_HEIGAN), eruptSection(0), eruptDirection(false), safetyDance(false) { } + boss_heiganAI(Creature* creature) : BossAI(creature, BOSS_HEIGAN), _safeSection(0), _danceDirection(false), _safetyDance(false) { } void Reset() override { @@ -82,15 +92,16 @@ public: void KilledUnit(Unit* who) override { - Talk(SAY_SLAY); - if (who->GetTypeId() == TYPEID_PLAYER) - safetyDance = false; + { + Talk(SAY_SLAY); + _safetyDance = false; + } } uint32 GetData(uint32 type) const override { - return (type == DATA_SAFETY_DANCE && safetyDance) ? 1u : 0u; + return (type == DATA_SAFETY_DANCE && _safetyDance) ? 1u : 0u; } void JustDied(Unit* /*killer*/) override @@ -104,13 +115,27 @@ public: _EnterCombat(); Talk(SAY_AGGRO); - eruptSection = 3; - events.ScheduleEvent(EVENT_DISRUPT, urand(15 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_FIGHT); - events.ScheduleEvent(EVENT_FEVER, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_FIGHT); - events.ScheduleEvent(EVENT_DANCE, 90 * IN_MILLISECONDS, 0, PHASE_FIGHT); - events.ScheduleEvent(EVENT_ERUPT, 15 * IN_MILLISECONDS, 0, PHASE_FIGHT); + _safeSection = 0; + events.ScheduleEvent(EVENT_DISRUPT, randtime(Seconds(15), Seconds(20)), 0, PHASE_FIGHT); + events.ScheduleEvent(EVENT_FEVER, randtime(Seconds(10), Seconds(20)), 0, PHASE_FIGHT); + events.ScheduleEvent(EVENT_DANCE, Minutes(1) + Seconds(30), 0, PHASE_FIGHT); + events.ScheduleEvent(EVENT_ERUPT, Seconds(15), 0, PHASE_FIGHT); + + _safetyDance = true; - safetyDance = true; + // figure out the current GUIDs of our eruption tiles and which segment they belong in + std::unordered_multimap<uint32, GameObject*> const& mapGOs = me->GetMap()->GetGameObjectBySpawnIdStore(); + uint32 spawnId = firstEruptionDBGUID; + for (uint8 section = 0; section < numSections; ++section) + { + _eruptTiles[section].clear(); + for (uint8 i = 0; i < numEruptions[section]; ++i) + { + std::pair<std::unordered_multimap<uint32, GameObject*>::const_iterator, std::unordered_multimap<uint32, GameObject*>::const_iterator> tileIt = mapGOs.equal_range(spawnId++); + for (std::unordered_multimap<uint32, GameObject*>::const_iterator it = tileIt.first; it != tileIt.second; ++it) + _eruptTiles[section].push_back(it->second->GetGUID()); + } + } } void UpdateAI(uint32 diff) override @@ -126,52 +151,56 @@ public: { case EVENT_DISRUPT: DoCastAOE(SPELL_SPELL_DISRUPTION); - events.ScheduleEvent(EVENT_DISRUPT, 11 * IN_MILLISECONDS); + events.Repeat(Seconds(11)); break; case EVENT_FEVER: DoCastAOE(SPELL_DECREPIT_FEVER); - events.ScheduleEvent(EVENT_FEVER, urand(20 * IN_MILLISECONDS, 25 * IN_MILLISECONDS)); + events.Repeat(randtime(Seconds(20), Seconds(25))); break; case EVENT_DANCE: events.SetPhase(PHASE_DANCE); Talk(SAY_TAUNT); Talk(EMOTE_DANCE); - eruptSection = 3; + _safeSection = 0; me->SetReactState(REACT_PASSIVE); me->AttackStop(); me->StopMoving(); DoCast(SPELL_TELEPORT_SELF); DoCastAOE(SPELL_PLAGUE_CLOUD); - events.ScheduleEvent(EVENT_DANCE_END, 45 * IN_MILLISECONDS, 0, PHASE_DANCE); - events.ScheduleEvent(EVENT_ERUPT, 10 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_DANCE_END, Seconds(45), 0, PHASE_DANCE); + events.ScheduleEvent(EVENT_ERUPT, Seconds(10)); break; case EVENT_DANCE_END: events.SetPhase(PHASE_FIGHT); Talk(EMOTE_DANCE_END); - eruptSection = 3; - events.ScheduleEvent(EVENT_DISRUPT, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_FIGHT); - events.ScheduleEvent(EVENT_FEVER, urand(15, 20) * IN_MILLISECONDS, 0, PHASE_FIGHT); - events.ScheduleEvent(EVENT_DANCE, 90 * IN_MILLISECONDS, 0, PHASE_FIGHT); - events.ScheduleEvent(EVENT_ERUPT, 15 * IN_MILLISECONDS, 0, PHASE_FIGHT); + _safeSection = 0; + events.ScheduleEvent(EVENT_DISRUPT, randtime(Seconds(10), Seconds(25)), 0, PHASE_FIGHT); + events.ScheduleEvent(EVENT_FEVER, randtime(Seconds(15), Seconds(20)), 0, PHASE_FIGHT); + events.ScheduleEvent(EVENT_DANCE, Minutes(1) + Seconds(30), 0, PHASE_FIGHT); + events.ScheduleEvent(EVENT_ERUPT, Seconds(15), 0, PHASE_FIGHT); me->CastStop(); me->SetReactState(REACT_AGGRESSIVE); DoZoneInCombat(); break; case EVENT_ERUPT: - instance->SetData(DATA_HEIGAN_ERUPT, eruptSection); TeleportCheaters(); - - if (eruptSection == 0) - eruptDirection = true; - else if (eruptSection == 3) - eruptDirection = false; - - eruptDirection ? ++eruptSection : --eruptSection; - - if (events.IsInPhase(PHASE_DANCE)) - events.ScheduleEvent(EVENT_ERUPT, 3 * IN_MILLISECONDS, 0, PHASE_DANCE); - else - events.ScheduleEvent(EVENT_ERUPT, 10 * IN_MILLISECONDS, 0, PHASE_FIGHT); + for (uint8 section = 0; section < numSections; ++section) + if (section != _safeSection) + for (ObjectGuid tileGUID : _eruptTiles[section]) + if (GameObject* tile = ObjectAccessor::GetGameObject(*me, tileGUID)) + { + tile->SendCustomAnim(0); + tile->CastSpell(nullptr, SPELL_ERUPTION); + } + + if (_safeSection == 0) + _danceDirection = true; + else if (_safeSection == numSections-1) + _danceDirection = false; + + _danceDirection ? ++_safeSection : --_safeSection; + + events.Repeat(events.IsInPhase(PHASE_DANCE) ? Seconds(3) : Seconds(10)); break; } } @@ -180,10 +209,11 @@ public: } private: - uint32 eruptSection; - bool eruptDirection; + std::vector<ObjectGuid> _eruptTiles[numSections]; // populated on encounter start - bool safetyDance; // is achievement still possible? (= no player deaths yet) + uint32 _safeSection; // 0 is next to the entrance + bool _danceDirection; // true is counter-clockwise, false is clock-wise + bool _safetyDance; // is achievement still possible? (= no player deaths yet) }; }; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp index 086d21120e8..c6c9c76bed4 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp @@ -24,7 +24,6 @@ enum Spells { SPELL_NECROTIC_AURA = 55593, - SPELL_WARN_NECROTIC_AURA = 59481, SPELL_SUMMON_SPORE = 29234, SPELL_DEATHBLOOM = 29865, SPELL_INEVITABLE_DOOM = 29204, @@ -42,11 +41,12 @@ enum Texts enum Events { - EVENT_NECROTIC_AURA = 1, - EVENT_DEATHBLOOM = 2, - EVENT_INEVITABLE_DOOM = 3, - EVENT_SPORE = 4, - EVENT_NECROTIC_AURA_FADING = 5, + EVENT_NECROTIC_AURA = 1, + EVENT_DEATHBLOOM, + EVENT_INEVITABLE_DOOM, + EVENT_SPORE, + EVENT_NECROTIC_AURA_FADING, + EVENT_NECROTIC_AURA_FADED }; enum Achievement @@ -82,10 +82,10 @@ class boss_loatheb : public CreatureScript void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - events.ScheduleEvent(EVENT_NECROTIC_AURA, 17 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_DEATHBLOOM, 5 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_SPORE, RAID_MODE(36,18) * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 2 * MINUTE * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_NECROTIC_AURA, Seconds(17)); + events.ScheduleEvent(EVENT_DEATHBLOOM, Seconds(5)); + events.ScheduleEvent(EVENT_SPORE, Seconds(18)); + events.ScheduleEvent(EVENT_INEVITABLE_DOOM, Minutes(2)); } void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override @@ -94,13 +94,6 @@ class boss_loatheb : public CreatureScript summon->CastSpell(summon,SPELL_FUNGAL_CREEP,true); } - void SummonedCreatureDespawn(Creature* summon) override - { - summons.Despawn(summon); - if (summon->IsAlive()) - summon->CastSpell(summon,SPELL_FUNGAL_CREEP,true); - } - uint32 GetData(uint32 id) const override { return (_sporeLoserData && id == DATA_ACHIEVEMENT_SPORE_LOSER) ? 1u : 0u; @@ -119,34 +112,33 @@ class boss_loatheb : public CreatureScript { case EVENT_NECROTIC_AURA: DoCastAOE(SPELL_NECROTIC_AURA); - DoCast(me, SPELL_WARN_NECROTIC_AURA); - events.ScheduleEvent(EVENT_NECROTIC_AURA, 20 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_NECROTIC_AURA_FADING, 14 * IN_MILLISECONDS); + Talk(SAY_NECROTIC_AURA_APPLIED); + events.ScheduleEvent(EVENT_NECROTIC_AURA_FADING, Seconds(14)); + events.ScheduleEvent(EVENT_NECROTIC_AURA_FADED, Seconds(17)); + events.Repeat(Seconds(20)); break; case EVENT_DEATHBLOOM: DoCastAOE(SPELL_DEATHBLOOM); - events.ScheduleEvent(EVENT_DEATHBLOOM, 30 * IN_MILLISECONDS); + events.Repeat(Seconds(30)); break; case EVENT_INEVITABLE_DOOM: _doomCounter++; DoCastAOE(SPELL_INEVITABLE_DOOM); if (_doomCounter > 6) - { - if (_doomCounter & 1) // odd - events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 14 * IN_MILLISECONDS); - else - events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 17 * IN_MILLISECONDS); - } + events.Repeat((_doomCounter & 1) ? Seconds(14) : Seconds(17)); else - events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 30 * IN_MILLISECONDS); + events.Repeat(30); break; case EVENT_SPORE: DoCast(me, SPELL_SUMMON_SPORE, false); - events.ScheduleEvent(EVENT_SPORE, RAID_MODE(36,18) * IN_MILLISECONDS); + events.Repeat(RAID_MODE(Seconds(36), Seconds(15))); break; case EVENT_NECROTIC_AURA_FADING: Talk(SAY_NECROTIC_AURA_FADING); break; + case EVENT_NECROTIC_AURA_FADED: + Talk(SAY_NECROTIC_AURA_REMOVED); + break; default: break; } @@ -177,49 +169,6 @@ class achievement_spore_loser : public AchievementCriteriaScript } }; -typedef boss_loatheb::boss_loathebAI LoathebAI; - -class spell_loatheb_necrotic_aura_warning : public SpellScriptLoader -{ - public: - spell_loatheb_necrotic_aura_warning() : SpellScriptLoader("spell_loatheb_necrotic_aura_warning") { } - - class spell_loatheb_necrotic_aura_warning_AuraScript : public AuraScript - { - PrepareAuraScript(spell_loatheb_necrotic_aura_warning_AuraScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - if (!sSpellStore.LookupEntry(SPELL_WARN_NECROTIC_AURA)) - return false; - return true; - } - - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTarget()->IsAIEnabled) - ENSURE_AI(LoathebAI, GetTarget()->GetAI())->Talk(SAY_NECROTIC_AURA_APPLIED); - } - - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTarget()->IsAIEnabled) - ENSURE_AI(LoathebAI, GetTarget()->GetAI())->Talk(SAY_NECROTIC_AURA_REMOVED); - } - - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_loatheb_necrotic_aura_warning_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_loatheb_necrotic_aura_warning_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_loatheb_necrotic_aura_warning_AuraScript(); - } -}; - class spell_loatheb_deathbloom : public SpellScriptLoader { public: @@ -260,6 +209,5 @@ void AddSC_boss_loatheb() { new boss_loatheb(); new achievement_spore_loser(); - new spell_loatheb_necrotic_aura_warning(); new spell_loatheb_deathbloom(); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp index 9d8f1365afb..9502193884a 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp @@ -73,6 +73,8 @@ struct WebTargetSelector : public std::unary_function<Unit*, bool> WebTargetSelector(Unit* maexxna) : _maexxna(maexxna) {} bool operator()(Unit const* target) const { + if (target->GetTypeId() != TYPEID_PLAYER) // never web nonplayers (pets, guardians, etc.) + return false; if (_maexxna->GetVictim() == target) // never target tank return false; if (target->HasAura(SPELL_WEB_WRAP)) // never target targets that are already webbed @@ -101,11 +103,11 @@ public: void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - events.ScheduleEvent(EVENT_WRAP, 20 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_SPRAY, 40 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_SHOCK, urandms(5, 10)); - events.ScheduleEvent(EVENT_POISON, urandms(10, 15)); - events.ScheduleEvent(EVENT_SUMMON, 30 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_WRAP, Seconds(20)); + events.ScheduleEvent(EVENT_SPRAY, Seconds(40)); + events.ScheduleEvent(EVENT_SHOCK, randtime(Seconds(5), Seconds(10))); + events.ScheduleEvent(EVENT_POISON, randtime(Seconds(10), Seconds(15))); + events.ScheduleEvent(EVENT_SUMMON, Seconds(30)); } void Reset() override @@ -153,28 +155,28 @@ public: } } } - events.ScheduleEvent(EVENT_WRAP, 40000); + events.Repeat(Seconds(40)); break; } case EVENT_SPRAY: Talk(EMOTE_WEB_SPRAY); DoCastAOE(SPELL_WEB_SPRAY); - events.ScheduleEvent(EVENT_SPRAY, 40000); + events.Repeat(Seconds(40)); break; case EVENT_SHOCK: DoCastAOE(SPELL_POISON_SHOCK); - events.ScheduleEvent(EVENT_SHOCK, urandms(10, 20)); + events.Repeat(randtime(Seconds(10), Seconds(20))); break; case EVENT_POISON: DoCastVictim(SPELL_NECROTIC_POISON); - events.ScheduleEvent(EVENT_POISON, urandms(10, 20)); + events.Repeat(randtime(Seconds(10), Seconds(20))); break; case EVENT_SUMMON: Talk(EMOTE_SPIDERS); uint8 amount = urand(8, 10); for (uint8 i = 0; i < amount; ++i) DoSummon(NPC_SPIDERLING, me, 4.0f, 5 * IN_MILLISECONDS, TEMPSUMMON_CORPSE_TIMED_DESPAWN); - events.ScheduleEvent(EVENT_SUMMON, 40000); + events.Repeat(Seconds(40)); break; } } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp index 8ee3936dee3..2108b4ce102 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp @@ -131,25 +131,25 @@ public: Reset(); else { - uint8 secondsGround; + uint8 timeGround; switch (balconyCount) { case 0: - secondsGround = 90; + timeGround = 90; break; case 1: - secondsGround = 110; + timeGround = 110; break; case 2: default: - secondsGround = 180; + timeGround = 180; } - events.ScheduleEvent(EVENT_GROUND_ATTACKABLE, 2 * IN_MILLISECONDS, 0, PHASE_GROUND); - events.ScheduleEvent(EVENT_BALCONY, secondsGround * IN_MILLISECONDS, 0, PHASE_GROUND); - events.ScheduleEvent(EVENT_CURSE, urand(10,25) * IN_MILLISECONDS, 0, PHASE_GROUND); - events.ScheduleEvent(EVENT_WARRIOR, urand(20,30) * IN_MILLISECONDS, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_GROUND_ATTACKABLE, Seconds(2), 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_BALCONY, Seconds(timeGround), 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_CURSE, randtime(Seconds(10), Seconds(25)), 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_WARRIOR, randtime(Seconds(20), Seconds(30)), 0, PHASE_GROUND); if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) - events.ScheduleEvent(EVENT_BLINK, urand(20,30) * IN_MILLISECONDS, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_BLINK, randtime(Seconds(20), Seconds(30)), 0, PHASE_GROUND); } } @@ -220,7 +220,7 @@ public: case EVENT_CURSE: { DoCastAOE(SPELL_CURSE); - events.ScheduleEvent(EVENT_CURSE, urand(50, 70) * IN_MILLISECONDS, 0, PHASE_GROUND); + events.Repeat(randtime(Seconds(50), Seconds(70))); break; } case EVENT_WARRIOR: @@ -229,7 +229,7 @@ public: CastSummon(RAID_MODE(2, 3), 0, 0); - events.ScheduleEvent(EVENT_WARRIOR, 40 * IN_MILLISECONDS, 0, PHASE_GROUND); + events.Repeat(Seconds(40)); break; case EVENT_BLINK: DoCastAOE(SPELL_CRIPPLE, true); @@ -237,7 +237,7 @@ public: DoResetThreat(); justBlinked = true; - events.ScheduleEvent(EVENT_BLINK, 40000, 0, PHASE_GROUND); + events.Repeat(Seconds(40)); break; case EVENT_BALCONY: events.SetPhase(PHASE_BALCONY); @@ -247,24 +247,24 @@ public: me->StopMoving(); me->RemoveAllAuras(); - events.ScheduleEvent(EVENT_BALCONY_TELEPORT, 3 * IN_MILLISECONDS, 0, PHASE_BALCONY); - events.ScheduleEvent(EVENT_WAVE, urand(5 * IN_MILLISECONDS, 8 * IN_MILLISECONDS), 0, PHASE_BALCONY); + events.ScheduleEvent(EVENT_BALCONY_TELEPORT, Seconds(3), 0, PHASE_BALCONY); + events.ScheduleEvent(EVENT_WAVE, randtime(Seconds(5), Seconds(8)), 0, PHASE_BALCONY); - uint8 secondsBalcony; + uint8 timeBalcony; switch (balconyCount) { case 0: - secondsBalcony = 70; + timeBalcony = 70; break; case 1: - secondsBalcony = 97; + timeBalcony = 97; break; case 2: default: - secondsBalcony = 120; + timeBalcony = 120; break; } - events.ScheduleEvent(EVENT_GROUND, secondsBalcony * IN_MILLISECONDS, 0, PHASE_BALCONY); + events.ScheduleEvent(EVENT_GROUND, Seconds(timeBalcony), 0, PHASE_BALCONY); break; case EVENT_BALCONY_TELEPORT: Talk(EMOTE_TELEPORT_1); @@ -287,7 +287,7 @@ public: CastSummon(0, RAID_MODE(5, 10), RAID_MODE(5, 10)); break; } - events.ScheduleEvent(EVENT_WAVE, urand(30, 45) * IN_MILLISECONDS, 0, PHASE_BALCONY); + events.Repeat(randtime(Seconds(30), Seconds(45))); break; case EVENT_GROUND: ++balconyCount; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp b/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp index b8ce402a939..cfa6e2e9f30 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp @@ -97,8 +97,8 @@ public: _EnterCombat(); Enraged = false; Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_HATEFUL, 1 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_BERSERK, 6 * MINUTE * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_HATEFUL, Seconds(1)); + events.ScheduleEvent(EVENT_BERSERK, Minutes(6)); instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_MAKE_QUICK_WERK_OF_HIM_STARTING_EVENT); } @@ -167,17 +167,17 @@ public: if (thirdThreatTarget) me->getThreatManager().addThreat(thirdThreatTarget, HATEFUL_THREAT_AMT); // this will only ever be used in 25m - events.ScheduleEvent(EVENT_HATEFUL, 1 * IN_MILLISECONDS); + events.Repeat(Seconds(1)); break; } case EVENT_BERSERK: DoCast(me, SPELL_BERSERK, true); Talk(EMOTE_BERSERK); - events.ScheduleEvent(EVENT_SLIME, 2 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_SLIME, Seconds(2)); break; case EVENT_SLIME: - DoCastVictim(SPELL_SLIME_BOLT, true); - events.ScheduleEvent(EVENT_SLIME, 2 * IN_MILLISECONDS); + DoCastAOE(SPELL_SLIME_BOLT, true); + events.Repeat(Seconds(2)); break; } } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp index 1d12f64a949..548f8086eb8 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp @@ -104,6 +104,9 @@ public: void JustDied(Unit* /*killer*/) override { + for (ObjectGuid summonGuid : summons) + if (Creature* summon = ObjectAccessor::GetCreature(*me, summonGuid)) + summon->RemoveCharmAuras(); Talk(SAY_DEATH); DoCastAOE(SPELL_HOPELESS, true); @@ -117,10 +120,10 @@ public: me->StopMoving(); summons.DoZoneInCombat(); Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_ATTACK, 7 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_STRIKE, 21 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_SHOUT, 16 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_KNIFE, 10 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_ATTACK, Seconds(7)); + events.ScheduleEvent(EVENT_STRIKE, Seconds(21)); + events.ScheduleEvent(EVENT_SHOUT, Seconds(16)); + events.ScheduleEvent(EVENT_KNIFE, Seconds(10)); } void UpdateAI(uint32 diff) override @@ -141,16 +144,16 @@ public: break; case EVENT_STRIKE: DoCastVictim(SPELL_UNBALANCING_STRIKE); - events.ScheduleEvent(EVENT_STRIKE, 6 * IN_MILLISECONDS); + events.Repeat(Seconds(6)); return; case EVENT_SHOUT: DoCastAOE(SPELL_DISRUPTING_SHOUT); - events.ScheduleEvent(EVENT_SHOUT, 16 * IN_MILLISECONDS); + events.Repeat(Seconds(16)); return; case EVENT_KNIFE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f)) DoCast(target, SPELL_JAGGED_KNIFE); - events.ScheduleEvent(EVENT_KNIFE, urandms(10,15)); + events.Repeat(randtime(Seconds(10), Seconds(15))); return; } } @@ -174,7 +177,10 @@ class npc_dk_understudy : public CreatureScript struct npc_dk_understudyAI : public ScriptedAI { - npc_dk_understudyAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), bloodStrikeTimer(0) { } + npc_dk_understudyAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), bloodStrikeTimer(0) + { + creature->LoadEquipment(1); + } void EnterCombat(Unit* /*who*/) override { diff --git a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp index 68b9e252150..4596b17bc23 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp @@ -16,7 +16,9 @@ */ #include "ScriptMgr.h" +#include "GameObjectAI.h" #include "ScriptedCreature.h" +#include "SpellScript.h" #include "Player.h" #include "SpellInfo.h" #include "naxxramas.h" @@ -31,25 +33,24 @@ enum Yells enum Spells { - SPELL_FROST_AURA = 28531, - SPELL_CLEAVE = 19983, - SPELL_TAIL_SWEEP = 55697, - SPELL_SUMMON_BLIZZARD = 28560, - SPELL_LIFE_DRAIN = 28542, - SPELL_ICEBOLT = 28522, - SPELL_FROST_BREATH = 29318, - SPELL_FROST_EXPLOSION = 28524, - SPELL_FROST_MISSILE = 30101, - SPELL_BERSERK = 26662, - SPELL_DIES = 29357, - SPELL_CHILL = 28547, - SPELL_CHECK_RESISTS = 60539, + SPELL_FROST_AURA = 28531, + SPELL_CLEAVE = 19983, + SPELL_TAIL_SWEEP = 55697, + SPELL_SUMMON_BLIZZARD = 28560, + SPELL_LIFE_DRAIN = 28542, + SPELL_ICEBOLT = 28522, + SPELL_FROST_BREATH_ANTICHEAT = 29318, // damage effect ignoring LoS on the entrance platform to prevent cheese + SPELL_FROST_BREATH = 28524, // damage effect below sapphiron + SPELL_FROST_MISSILE = 30101, // visual only + SPELL_BERSERK = 26662, + SPELL_DIES = 29357, + SPELL_CHECK_RESISTS = 60539, + SPELL_SAPPHIRON_WING_BUFFET = 29328 }; enum Phases { - PHASE_NULL = 0, - PHASE_BIRTH, + PHASE_BIRTH = 1, PHASE_GROUND, PHASE_FLIGHT }; @@ -72,9 +73,15 @@ enum Events EVENT_CHECK_RESISTS }; +enum Actions +{ + ACTION_BIRTH = 1 +}; + enum Misc { NPC_BLIZZARD = 16474, + NPC_WING_BUFFET = 17025, GO_ICEBLOCK = 181247, // The Hundred Club @@ -92,77 +99,74 @@ class boss_sapphiron : public CreatureScript struct boss_sapphironAI : public BossAI { boss_sapphironAI(Creature* creature) : - BossAI(creature, BOSS_SAPPHIRON), _iceboltCount(0), _map(me->GetMap()) + BossAI(creature, BOSS_SAPPHIRON) { Initialize(); } void Initialize() { - _phase = PHASE_NULL; - + _delayedDrain = false; _canTheHundredClub = true; } void InitializeAI() override { + if (instance->GetBossState(BOSS_SAPPHIRON) == DONE) + return; + _canTheHundredClub = true; - float x, y, z; - me->GetPosition(x, y, z); - me->SummonGameObject(GO_BIRTH, x, y, z, 0, 0, 0, 0, 0, 0); - me->SetVisible(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_PASSIVE); + if (!instance->GetData(DATA_HAD_SAPPHIRON_BIRTH)) + { + me->SetVisible(false); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_PASSIVE); + } BossAI::InitializeAI(); } void Reset() override { - _Reset(); - - if (_phase == PHASE_FLIGHT) + if (events.IsInPhase(PHASE_FLIGHT)) { - ClearIceBlock(); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ICEBOLT); me->SetReactState(REACT_AGGRESSIVE); if (me->IsHovering()) { me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->SetHover(false); } - me->SetDisableGravity(false); } + _Reset(); Initialize(); } + void DamageTaken(Unit* /*who*/, uint32& damage) override + { + if (damage < me->GetHealth() || !events.IsInPhase(PHASE_FLIGHT)) + return; + damage = me->GetHealth()-1; // don't die during air phase + } + void EnterCombat(Unit* /*who*/) override { _EnterCombat(); me->CastSpell(me, SPELL_FROST_AURA, true); - DoCast(me, SPELL_CHECK_RESISTS); - events.ScheduleEvent(EVENT_CHECK_RESISTS, 30 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_BERSERK, 15 * MINUTE * IN_MILLISECONDS); - EnterPhaseGround(); + events.SetPhase(PHASE_GROUND); + events.ScheduleEvent(EVENT_CHECK_RESISTS, Seconds(0)); + events.ScheduleEvent(EVENT_BERSERK, Minutes(15)); + EnterPhaseGround(true); } void SpellHitTarget(Unit* target, SpellInfo const* spell) override { switch(spell->Id) { - case SPELL_ICEBOLT: - { - IceBlockMap::iterator itr = _iceblocks.find(target->GetGUID()); - if (itr != _iceblocks.end() && !itr->second) - { - if (GameObject* iceblock = me->SummonGameObject(GO_ICEBLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, 0, 0, 0, 0, 25)) - itr->second = iceblock->GetGUID(); - } - break; - } case SPELL_CHECK_RESISTS: if (target && target->GetResistance(SPELL_SCHOOL_FROST) > MAX_FROST_RESISTANCE) _canTheHundredClub = false; @@ -179,41 +183,37 @@ class boss_sapphiron : public CreatureScript void MovementInform(uint32 /*type*/, uint32 id) override { if (id == 1) - events.ScheduleEvent(EVENT_LIFTOFF, 0); + events.ScheduleEvent(EVENT_LIFTOFF, Seconds(0), 0, PHASE_FLIGHT); } void DoAction(int32 param) override { - if (param == DATA_SAPPHIRON_BIRTH) + if (param == ACTION_BIRTH) { - _phase = PHASE_BIRTH; - events.ScheduleEvent(EVENT_BIRTH, 23 * IN_MILLISECONDS); + events.SetPhase(PHASE_BIRTH); + events.ScheduleEvent(EVENT_BIRTH, Seconds(23)); } } - void EnterPhaseGround() + void EnterPhaseGround(bool initial) { - _phase = PHASE_GROUND; me->SetReactState(REACT_AGGRESSIVE); - events.SetPhase(PHASE_GROUND); - events.ScheduleEvent(EVENT_CLEAVE, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND); - events.ScheduleEvent(EVENT_TAIL, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND); - events.ScheduleEvent(EVENT_DRAIN, 24 * IN_MILLISECONDS, 0, PHASE_GROUND); - events.ScheduleEvent(EVENT_BLIZZARD, urand(5, 10) * IN_MILLISECONDS, 0, PHASE_GROUND); - events.ScheduleEvent(EVENT_FLIGHT, 45 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_CLEAVE, randtime(Seconds(5), Seconds(15)), 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_TAIL, randtime(Seconds(7), Seconds(10)), 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_BLIZZARD, randtime(Seconds(5), Seconds(10)), 0, PHASE_GROUND); + if (initial) + { + events.ScheduleEvent(EVENT_DRAIN, randtime(Seconds(22), Seconds(28))); + events.ScheduleEvent(EVENT_FLIGHT, Seconds(48) + Milliseconds(500), 0, PHASE_GROUND); + } + else + events.ScheduleEvent(EVENT_FLIGHT, Minutes(1), 0, PHASE_GROUND); } - void ClearIceBlock() + inline void CastDrain() { - for (IceBlockMap::const_iterator itr = _iceblocks.begin(); itr != _iceblocks.end(); ++itr) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, itr->first)) - player->RemoveAura(SPELL_ICEBOLT); - - if (GameObject* go = ObjectAccessor::GetGameObject(*me, itr->second)) - go->Delete(); - } - _iceblocks.clear(); + DoCastAOE(SPELL_LIFE_DRAIN); + events.ScheduleEvent(EVENT_DRAIN, randtime(Seconds(22), Seconds(28))); } uint32 GetData(uint32 data) const override @@ -226,15 +226,12 @@ class boss_sapphiron : public CreatureScript void UpdateAI(uint32 diff) override { - if (!_phase) - return; - events.Update(diff); - if (_phase != PHASE_BIRTH && !UpdateVictim()) + if (!events.IsInPhase(PHASE_BIRTH) && !UpdateVictim()) return; - if (_phase == PHASE_GROUND) + if (events.IsInPhase(PHASE_GROUND)) { while (uint32 eventId = events.ExecuteEvent()) { @@ -242,7 +239,10 @@ class boss_sapphiron : public CreatureScript { case EVENT_CHECK_RESISTS: DoCast(me, SPELL_CHECK_RESISTS); - events.ScheduleEvent(EVENT_CHECK_RESISTS, 30 * IN_MILLISECONDS); + events.Repeat(Seconds(30)); + return; + case EVENT_GROUND: + EnterPhaseGround(false); return; case EVENT_BERSERK: Talk(EMOTE_ENRAGE); @@ -250,27 +250,26 @@ class boss_sapphiron : public CreatureScript return; case EVENT_CLEAVE: DoCastVictim(SPELL_CLEAVE); - events.ScheduleEvent(EVENT_CLEAVE, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_CLEAVE, randtime(Seconds(5), Seconds(15)), 0, PHASE_GROUND); return; case EVENT_TAIL: DoCastAOE(SPELL_TAIL_SWEEP); - events.ScheduleEvent(EVENT_TAIL, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_TAIL, randtime(Seconds(7), Seconds(10)), 0, PHASE_GROUND); return; case EVENT_DRAIN: - DoCastAOE(SPELL_LIFE_DRAIN); - events.ScheduleEvent(EVENT_DRAIN, 24 * IN_MILLISECONDS, 0, PHASE_GROUND); + if (events.IsInPhase(PHASE_FLIGHT)) + _delayedDrain = true; + else + CastDrain(); return; case EVENT_BLIZZARD: - { - if (Creature* summon = DoSummon(NPC_BLIZZARD, me, 0.0f, urand(25, 30) * IN_MILLISECONDS, TEMPSUMMON_TIMED_DESPAWN)) - summon->GetMotionMaster()->MoveRandom(40); - events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(20, 7) * IN_MILLISECONDS, 0, PHASE_GROUND); + DoCastAOE(SPELL_SUMMON_BLIZZARD); + events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(Seconds(20), Seconds(7)), 0, PHASE_GROUND); break; - } case EVENT_FLIGHT: if (HealthAbovePct(10)) { - _phase = PHASE_FLIGHT; + _delayedDrain = false; events.SetPhase(PHASE_FLIGHT); me->SetReactState(REACT_PASSIVE); me->AttackStop(); @@ -293,61 +292,69 @@ class boss_sapphiron : public CreatureScript { case EVENT_CHECK_RESISTS: DoCast(me, SPELL_CHECK_RESISTS); - events.ScheduleEvent(EVENT_CHECK_RESISTS, 30 * IN_MILLISECONDS); + events.Repeat(Seconds(30)); return; case EVENT_LIFTOFF: + { Talk(EMOTE_AIR_PHASE); - me->SetDisableGravity(true); + if (Creature* buffet = DoSummon(NPC_WING_BUFFET, me, 0.0f, 0, TEMPSUMMON_MANUAL_DESPAWN)) + _buffet = buffet->GetGUID(); + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); me->SetHover(true); - events.ScheduleEvent(EVENT_ICEBOLT, 1500); - _iceboltCount = RAID_MODE(2, 3); + events.ScheduleEvent(EVENT_ICEBOLT, Seconds(7), 0, PHASE_FLIGHT); + + _iceboltTargets.clear(); + std::list<Unit*> targets; + SelectTargetList(targets, RAID_MODE(2, 3), SELECT_TARGET_RANDOM, 200.0f, true); + for (Unit* target : targets) + if (target) + _iceboltTargets.push_back(target->GetGUID()); return; + } case EVENT_ICEBOLT: { - std::vector<Unit*> targets; - std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); - for (; i != me->getThreatManager().getThreatList().end(); ++i) - if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER && !(*i)->getTarget()->HasAura(SPELL_ICEBOLT)) - targets.push_back((*i)->getTarget()); - - if (targets.empty()) - _iceboltCount = 0; - else + if (_iceboltTargets.empty()) { - std::vector<Unit*>::const_iterator itr = targets.begin(); - advance(itr, rand32() % targets.size()); - _iceblocks.insert(std::make_pair((*itr)->GetGUID(), ObjectGuid::Empty)); - DoCast(*itr, SPELL_ICEBOLT); - --_iceboltCount; + events.ScheduleEvent(EVENT_BREATH, Seconds(2), 0, PHASE_FLIGHT); + return; } - - if (_iceboltCount) - events.ScheduleEvent(EVENT_ICEBOLT, 1 * IN_MILLISECONDS); + ObjectGuid target = _iceboltTargets.back(); + if (Player* pTarget = ObjectAccessor::GetPlayer(*me, target)) + if (pTarget->IsAlive()) + DoCast(pTarget, SPELL_ICEBOLT); + _iceboltTargets.pop_back(); + + if (_iceboltTargets.empty()) + events.ScheduleEvent(EVENT_BREATH, Seconds(2), 0, PHASE_FLIGHT); else - events.ScheduleEvent(EVENT_BREATH, 1 * IN_MILLISECONDS); + events.Repeat(Seconds(3)); return; } case EVENT_BREATH: { Talk(EMOTE_BREATH); DoCastAOE(SPELL_FROST_MISSILE); - events.ScheduleEvent(EVENT_EXPLOSION, 8 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_EXPLOSION, Seconds(8), 0, PHASE_FLIGHT); return; } case EVENT_EXPLOSION: - CastExplosion(); - ClearIceBlock(); - events.ScheduleEvent(EVENT_LAND, 3 * IN_MILLISECONDS); + DoCastAOE(SPELL_FROST_BREATH); + DoCastAOE(SPELL_FROST_BREATH_ANTICHEAT); + events.ScheduleEvent(EVENT_LAND, Seconds(3) + Milliseconds(500), 0, PHASE_FLIGHT); return; case EVENT_LAND: + if (_delayedDrain) + CastDrain(); + if (Creature* cBuffet = ObjectAccessor::GetCreature(*me, _buffet)) + { + cBuffet->DespawnOrUnsummon(1 * IN_MILLISECONDS); + _buffet.Clear(); + } me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); Talk(EMOTE_GROUND_PHASE); me->SetHover(false); - me->SetDisableGravity(false); - events.ScheduleEvent(EVENT_GROUND, 1500); - return; - case EVENT_GROUND: - EnterPhaseGround(); + events.SetPhase(PHASE_GROUND); + events.ScheduleEvent(EVENT_GROUND, Seconds(3) + Milliseconds(500), 0, PHASE_GROUND); return; case EVENT_BIRTH: me->SetVisible(true); @@ -359,56 +366,261 @@ class boss_sapphiron : public CreatureScript } } - void CastExplosion() + private: + std::vector<ObjectGuid> _iceboltTargets; + ObjectGuid _buffet; + bool _delayedDrain; + bool _canTheHundredClub; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new boss_sapphironAI(creature); + } +}; + +class go_sapphiron_birth : public GameObjectScript +{ + public: + go_sapphiron_birth() : GameObjectScript("go_sapphiron_birth") { } + + struct go_sapphiron_birthAI : public GameObjectAI + { + go_sapphiron_birthAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { } + + void OnStateChanged(uint32 state, Unit* who) override + { + if (state == GO_ACTIVATED) + { + if (who) + { + if (Creature* sapphiron = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_SAPPHIRON))) + sapphiron->AI()->DoAction(ACTION_BIRTH); + instance->SetData(DATA_HAD_SAPPHIRON_BIRTH, 1u); + } + } + else if (state == GO_JUST_DEACTIVATED) + { // prevent ourselves from going back to _READY and resetting the client anim + go->SetRespawnTime(0); + go->Delete(); + } + } + + InstanceScript* instance; + }; + + GameObjectAI* GetAI(GameObject* go) const override + { + return GetInstanceAI<go_sapphiron_birthAI>(go); + } +}; + + +class spell_sapphiron_change_blizzard_target : public SpellScriptLoader +{ + public: + spell_sapphiron_change_blizzard_target() : SpellScriptLoader("spell_sapphiron_change_blizzard_target") { } + + class spell_sapphiron_change_blizzard_target_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sapphiron_change_blizzard_target_AuraScript); + + void HandlePeriodic(AuraEffect const* /*eff*/) + { + TempSummon* me = GetTarget()->ToTempSummon(); + if (Creature* owner = me ? me->GetSummonerCreatureBase() : nullptr) + { + Unit* newTarget = owner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true); + if (!newTarget) + newTarget = owner->getAttackerForHelper(); + if (newTarget) + me->GetMotionMaster()->MoveFollow(newTarget, 0.1f, 0.0f); + else + { + me->StopMoving(); + me->GetMotionMaster()->Clear(); + } + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_sapphiron_change_blizzard_target_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sapphiron_change_blizzard_target_AuraScript(); + } +}; + +class spell_sapphiron_icebolt : public SpellScriptLoader +{ + public: + spell_sapphiron_icebolt() : SpellScriptLoader("spell_sapphiron_icebolt") { } + + class spell_sapphiron_icebolt_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sapphiron_icebolt_AuraScript); + + void HandleApply(AuraEffect const* /*eff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->ApplySpellImmune(SPELL_ICEBOLT, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_FROST, true); + } + + void HandleRemove(AuraEffect const* /*eff*/, AuraEffectHandleModes /*mode*/) + { + if (_block) + if (GameObject* oBlock = ObjectAccessor::GetGameObject(*GetTarget(), _block)) + oBlock->Delete(); + GetTarget()->ApplySpellImmune(SPELL_ICEBOLT, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_FROST, false); + } + + void HandlePeriodic(AuraEffect const* /*eff*/) + { + if (_block) + return; + if (GetTarget()->isMoving()) + return; + float x, y, z; + GetTarget()->GetPosition(x, y, z); + if (GameObject* block = GetTarget()->SummonGameObject(GO_ICEBLOCK, x, y, z, 0, 0, 0, 0, 0, 25)) + _block = block->GetGUID(); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_sapphiron_icebolt_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_sapphiron_icebolt_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_sapphiron_icebolt_AuraScript::HandlePeriodic, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + + ObjectGuid _block; + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sapphiron_icebolt_AuraScript(); + } +}; + +// @hack Hello, developer from the future! How has your day been? +// Anyway, this is, as you can undoubtedly see, a hack to emulate line of sight checks on a spell that abides line of sight anyway. +// In the current core, line of sight is not properly checked for people standing behind an ice block. This is not a good thing and kills people. +// Thus, we have this hack to check for ice block LoS in a "safe" way. Kind of. It's inaccurate, but in a good way (tends to save people when it shouldn't in edge cases). +// If LoS handling is better in whatever the current revision is when you read this, please get rid of the hack. Thanks! +class spell_sapphiron_frost_breath : public SpellScriptLoader +{ + public: + spell_sapphiron_frost_breath() : SpellScriptLoader("spell_sapphiron_frost_breath") { } + + class spell_sapphiron_frost_breath_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sapphiron_frost_breath_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + return !!sSpellMgr->GetSpellInfo(SPELL_FROST_BREATH); + } + + void HandleTargets(std::list<WorldObject*>& targetList) { - DoZoneInCombat(); // make sure everyone is in threatlist - std::vector<Unit*> targets; - std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); - for (; i != me->getThreatManager().getThreatList().end(); ++i) + std::list<GameObject*> blocks; + if (GetCaster()) + GetCaster()->GetGameObjectListWithEntryInGrid(blocks, GO_ICEBLOCK, 200.0f); + + std::vector<Unit*> toRemove; + toRemove.reserve(3); + std::list<WorldObject*>::iterator it = targetList.begin(); + while (it != targetList.end()) { - Unit* target = (*i)->getTarget(); - if (target->GetTypeId() != TYPEID_PLAYER) + Unit* target = (*it)->ToUnit(); + if (!target) + { + it = targetList.erase(it); continue; + } if (target->HasAura(SPELL_ICEBOLT)) { - target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); - targets.push_back(target); + it = targetList.erase(it); + toRemove.push_back(target); + continue; + } + + bool found = false; + for (GameObject* block : blocks) + if (block->IsInBetween(GetCaster(), target, 2.0f) && GetCaster()->GetExactDist2d(block) + 5 >= GetCaster()->GetExactDist2d(target)) + { + found = true; + break; + } + if (found) + { + it = targetList.erase(it); continue; } + ++it; + } + + for (Unit* block : toRemove) + block->RemoveAura(SPELL_ICEBOLT); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sapphiron_frost_breath_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + } + }; - for (IceBlockMap::const_iterator itr = _iceblocks.begin(); itr != _iceblocks.end(); ++itr) + SpellScript* GetSpellScript() const override + { + return new spell_sapphiron_frost_breath_SpellScript(); + } +}; + +class spell_sapphiron_summon_blizzard : public SpellScriptLoader +{ + public: + spell_sapphiron_summon_blizzard() : SpellScriptLoader("spell_sapphiron_summon_blizzard") { } + + class spell_sapphiron_summon_blizzard_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sapphiron_summon_blizzard_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + return !!sSpellMgr->GetSpellInfo(SPELL_SUMMON_BLIZZARD); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + if (Creature* blizzard = GetCaster()->SummonCreature(NPC_BLIZZARD, *target, TEMPSUMMON_TIMED_DESPAWN, urandms(25, 30))) { - if (GameObject* go = ObjectAccessor::GetGameObject(*me, itr->second)) + blizzard->CastSpell(nullptr, blizzard->m_spells[0], TRIGGERED_NONE); + if (Creature* creatureCaster = GetCaster()->ToCreature()) { - if (go->IsInBetween(me, target, 2.0f) - && me->GetExactDist2d(target->GetPositionX(), target->GetPositionY()) - me->GetExactDist2d(go->GetPositionX(), go->GetPositionY()) < 5.0f) + if (Unit* newTarget = creatureCaster->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) { - target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); - targets.push_back(target); - break; + blizzard->GetMotionMaster()->MoveFollow(newTarget, 0.1f, 0.0f); + return; } } + blizzard->GetMotionMaster()->MoveFollow(target, 0.1f, 0.0f); } - } - - me->CastSpell(me, SPELL_FROST_EXPLOSION, true); - - for (std::vector<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) - (*itr)->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, false); } - private: - Phases _phase; - uint32 _iceboltCount; - IceBlockMap _iceblocks; - bool _canTheHundredClub; - Map* _map; + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_sapphiron_summon_blizzard_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; - CreatureAI* GetAI(Creature* creature) const override + SpellScript* GetSpellScript() const override { - return new boss_sapphironAI(creature); + return new spell_sapphiron_summon_blizzard_SpellScript(); } }; @@ -426,5 +638,10 @@ class achievement_the_hundred_club : public AchievementCriteriaScript void AddSC_boss_sapphiron() { new boss_sapphiron(); + new go_sapphiron_birth(); + new spell_sapphiron_change_blizzard_target(); + new spell_sapphiron_icebolt(); + new spell_sapphiron_frost_breath(); + new spell_sapphiron_summon_blizzard(); new achievement_the_hundred_club(); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp index 7330f90e585..2cf3a4664dd 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp @@ -109,6 +109,10 @@ enum PetSpells SPELL_MAGNETIC_PULL = 54517, SPELL_MAGNETIC_PULL_EFFECT = 28337, + // @hack feugen/stalagg use this in P1 after gripping tanks to prevent mmaps from pathing them off the platform once they approach the ramp + // developer from the future, if you read this and mmaps in the room has been fixed, then get rid of the hackfix, please + SPELL_ROOT_SELF = 75215, + SPELL_TESLA_SHOCK = 28099 }; @@ -166,10 +170,12 @@ public: struct boss_thaddiusAI : public BossAI { public: - boss_thaddiusAI(Creature* creature) : BossAI(creature, BOSS_THADDIUS), stalaggAlive(true), feugenAlive(true), ballLightningEnabled(false), shockingEligibility(true) + boss_thaddiusAI(Creature* creature) : BossAI(creature, BOSS_THADDIUS), stalaggAlive(true), feugenAlive(true), ballLightningUnlocked(false), ballLightningEnabled(false), shockingEligibility(true) {} + + void InitializeAI() override { if (instance->GetBossState(BOSS_THADDIUS) != DONE) - { + { events.SetPhase(PHASE_NOT_ENGAGED); SetCombatMovement(false); @@ -184,12 +190,33 @@ public: Talk(SAY_SLAY); } - void Reset() override + void Reset() override { } + + void EnterEvadeMode(EvadeReason why) override { + if (!ballLightningEnabled && why == EVADE_REASON_NO_HOSTILES) + { + ballLightningEnabled = true; + return; // try again + } if (events.IsInPhase(PHASE_TRANSITION) || (events.IsInPhase(PHASE_THADDIUS) && me->IsAlive())) BeginResetEncounter(); } + bool CanAIAttack(Unit const* who) const override + { + if (ballLightningEnabled || me->IsWithinMeleeRange(who)) + return BossAI::CanAIAttack(who); + else + return false; + } + + void JustRespawned() override + { + if (events.IsInPhase(PHASE_RESETTING)) + ResetEncounter(); + } + void JustDied(Unit* /*killer*/) override { _JustDied(); @@ -217,18 +244,25 @@ public: case ACTION_FEUGEN_AGGRO: case ACTION_STALAGG_AGGRO: if (events.IsInPhase(PHASE_RESETTING)) - return BeginResetEncounter(); + { + BeginResetEncounter(); + return; + } if (!events.IsInPhase(PHASE_NOT_ENGAGED)) return; events.SetPhase(PHASE_PETS); shockingEligibility = true; - + if (!instance->CheckRequiredBosses(BOSS_THADDIUS)) - return BeginResetEncounter(); + { + BeginResetEncounter(); + return; + } instance->SetBossState(BOSS_THADDIUS, IN_PROGRESS); me->setActive(true); + DoZoneInCombat(); if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) stalagg->setActive(true); if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) @@ -239,7 +273,7 @@ public: feugen->AI()->DoAction(ACTION_FEUGEN_REVIVING_FX); feugenAlive = false; if (stalaggAlive) - events.ScheduleEvent(EVENT_REVIVE_FEUGEN, 5 * IN_MILLISECONDS, 0, PHASE_PETS); + events.ScheduleEvent(EVENT_REVIVE_FEUGEN, Seconds(5), 0, PHASE_PETS); else Transition(); @@ -249,7 +283,7 @@ public: stalagg->AI()->DoAction(ACTION_STALAGG_REVIVING_FX); stalaggAlive = false; if (feugenAlive) - events.ScheduleEvent(EVENT_REVIVE_STALAGG, 5 * IN_MILLISECONDS, 0, PHASE_PETS); + events.ScheduleEvent(EVENT_REVIVE_STALAGG, Seconds(5), 0, PHASE_PETS); else Transition(); @@ -274,9 +308,9 @@ public: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - events.ScheduleEvent(EVENT_TRANSITION_1, 10 * IN_MILLISECONDS, 0, PHASE_TRANSITION); - events.ScheduleEvent(EVENT_TRANSITION_2, 12 * IN_MILLISECONDS, 0, PHASE_TRANSITION); - events.ScheduleEvent(EVENT_TRANSITION_3, 14 * IN_MILLISECONDS, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_TRANSITION_1, Seconds(10), 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_TRANSITION_2, Seconds(12), 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_TRANSITION_3, Seconds(14), 0, PHASE_TRANSITION); } void BeginResetEncounter(bool initial = false) @@ -286,16 +320,12 @@ public: if (events.IsInPhase(PHASE_RESETTING)) return; - if (initial) // signal shorter spawn timer to instance script - instance->SetBossState(BOSS_THADDIUS, SPECIAL); - instance->ProcessEvent(me, EVENT_THADDIUS_BEGIN_RESET); - instance->SetBossState(BOSS_THADDIUS, NOT_STARTED); - // remove polarity shift debuffs on reset instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_APPLY); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_APPLY); me->DespawnOrUnsummon(); + me->SetRespawnTime(initial ? 5 : 30); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED); events.SetPhase(PHASE_RESETTING); @@ -312,11 +342,9 @@ public: feugenAlive = true; stalaggAlive = true; - me->Respawn(true); _Reset(); events.SetPhase(PHASE_NOT_ENGAGED); - - me->CastSpell(me, SPELL_THADDIUS_INACTIVE_VISUAL, true); + me->SetReactState(REACT_PASSIVE); if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) feugen->AI()->DoAction(ACTION_RESET_ENCOUNTER); @@ -361,16 +389,20 @@ public: break; case EVENT_TRANSITION_3: // thaddius becomes active me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true); - ballLightningEnabled = false; + ballLightningUnlocked = false; me->RemoveAura(SPELL_THADDIUS_INACTIVE_VISUAL); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - + me->SetReactState(REACT_AGGRESSIVE); + DoZoneInCombat(); if (Unit* closest = SelectTarget(SELECT_TARGET_NEAREST, 0, 500.0f)) AttackStart(closest); else // if there is no nearest target, then there is no target, meaning we should reset - return BeginResetEncounter(); + { + BeginResetEncounter(); + return; + } if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) feugen->AI()->DoAction(ACTION_TRANSITION_3); @@ -381,20 +413,20 @@ public: Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_ENABLE_BALL_LIGHTNING, 5 * IN_MILLISECONDS, 0, PHASE_THADDIUS); - events.ScheduleEvent(EVENT_SHIFT, 10 * IN_MILLISECONDS, 0, PHASE_THADDIUS); - events.ScheduleEvent(EVENT_CHAIN, urand(10, 20) * IN_MILLISECONDS, 0, PHASE_THADDIUS); - events.ScheduleEvent(EVENT_BERSERK, 6 * MINUTE * IN_MILLISECONDS, 0, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_ENABLE_BALL_LIGHTNING, Seconds(5), 0, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_SHIFT, Seconds(10), 0, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_CHAIN, randtime(Seconds(10), Seconds(20)), 0, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_BERSERK, Minutes(6), 0, PHASE_THADDIUS); break; case EVENT_ENABLE_BALL_LIGHTNING: - ballLightningEnabled = true; + ballLightningUnlocked = true; break; case EVENT_SHIFT: me->CastStop(); // shift overrides all other spells DoCastAOE(SPELL_POLARITY_SHIFT); - events.ScheduleEvent(EVENT_SHIFT_TALK, 3 * IN_MILLISECONDS, PHASE_THADDIUS); - events.ScheduleEvent(EVENT_SHIFT, 30 * IN_MILLISECONDS, PHASE_THADDIUS); + events.ScheduleEvent(EVENT_SHIFT_TALK, Seconds(3), PHASE_THADDIUS); + events.ScheduleEvent(EVENT_SHIFT, Seconds(30), PHASE_THADDIUS); break; case EVENT_SHIFT_TALK: Talk(SAY_ELECT); @@ -402,12 +434,12 @@ public: break; case EVENT_CHAIN: if (me->FindCurrentSpellBySpellId(SPELL_POLARITY_SHIFT)) // delay until shift is over - events.ScheduleEvent(EVENT_CHAIN, 3 * IN_MILLISECONDS, 0, PHASE_THADDIUS); + events.Repeat(Seconds(3)); else { me->CastStop(); DoCastVictim(SPELL_CHAIN_LIGHTNING); - events.ScheduleEvent(EVENT_CHAIN, urand(10, 20) * IN_MILLISECONDS, PHASE_THADDIUS); + events.Repeat(randtime(Seconds(10), Seconds(20))); } break; case EVENT_BERSERK: @@ -418,22 +450,24 @@ public: break; } } - - if (events.IsInPhase(PHASE_THADDIUS)) + if (events.IsInPhase(PHASE_THADDIUS) && !me->HasUnitState(UNIT_STATE_CASTING) && me->isAttackReady()) { if (me->IsWithinMeleeRange(me->GetVictim())) + { + ballLightningEnabled = false; DoMeleeAttackIfReady(); - else - if (ballLightningEnabled) - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_BALL_LIGHTNING); + } + else if (ballLightningUnlocked) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_BALL_LIGHTNING); } } private: bool stalaggAlive; bool feugenAlive; - bool ballLightningEnabled; + bool ballLightningUnlocked; // whether the initial ball lightning grace period has expired and we should proceed to exterminate with extreme prejudice + bool ballLightningEnabled; // switch that is flipped to true if we try to evade due to no eligible targets in melee range bool shockingEligibility; }; @@ -521,7 +555,7 @@ public: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Talk(EMOTE_FEIGN_REVIVE); isFeignDeath = false; - + refreshBeam = true; // force beam refresh if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN))) @@ -586,7 +620,7 @@ public: damage = 0; return; } - + isFeignDeath = true; isOverloading = false; @@ -652,7 +686,7 @@ public: else { DoCast(me, SPELL_STALAGG_POWERSURGE); - powerSurgeTimer = urand(25, 30) * IN_MILLISECONDS; + powerSurgeTimer = urandms(25, 30); } } else @@ -790,7 +824,7 @@ public: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Talk(EMOTE_FEIGN_REVIVE); isFeignDeath = false; - + refreshBeam = true; // force beam refresh if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) @@ -836,7 +870,7 @@ public: Talk(SAY_FEUGEN_AGGRO); if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS))) - thaddius->AI()->DoAction(ACTION_STALAGG_AGGRO); + thaddius->AI()->DoAction(ACTION_FEUGEN_AGGRO); if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG))) if (!stalagg->IsInCombat()) @@ -922,7 +956,7 @@ public: magneticPullTimer = 20 * IN_MILLISECONDS; } else magneticPullTimer -= uiDiff; - + if (staticFieldTimer <= uiDiff) { DoCast(me, SPELL_FEUGEN_STATICFIELD); @@ -971,7 +1005,7 @@ public: ObjectGuid _myCoil; ObjectGuid _myCoilGO; - + bool isOverloading; bool refreshBeam; bool isFeignDeath; @@ -1094,7 +1128,7 @@ class spell_thaddius_polarity_charge : public SpellScriptLoader SpellScript* GetSpellScript() const override { - return new spell_thaddius_polarity_charge_SpellScript; + return new spell_thaddius_polarity_charge_SpellScript(); } }; @@ -1169,7 +1203,7 @@ class spell_thaddius_magnetic_pull : public SpellScriptLoader Unit* feugen = GetCaster(); if (!feugen || feugen->GetEntry() != NPC_FEUGEN) return; - + Unit* stalagg = ObjectAccessor::GetCreature(*feugen, feugen->GetInstanceScript()->GetGuidData(DATA_STALAGG)); if (!stalagg) return; @@ -1212,6 +1246,10 @@ class spell_thaddius_magnetic_pull : public SpellScriptLoader feugenTank->CastSpell(stalaggTank, SPELL_MAGNETIC_PULL_EFFECT, true); stalaggTank->CastSpell(feugenTank, SPELL_MAGNETIC_PULL_EFFECT, true); + // @hack prevent mmaps clusterfucks from breaking tesla while tanks are midair + feugen->AddAura(SPELL_ROOT_SELF, feugen); + stalagg->AddAura(SPELL_ROOT_SELF, stalagg); + // and make both attack their respective new tanks if (feugen->GetAI()) feugen->GetAI()->AttackStart(stalaggTank); diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index c8a4eb7fbc8..e3971248513 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -20,7 +20,7 @@ #include "InstanceScript.h" #include "naxxramas.h" -BossBoundaryData const boundaries = +BossBoundaryData const boundaries = { /* Arachnid Quarter */ { BOSS_ANUBREKHAN, new CircleBoundary(Position(3273.376709f, -3475.876709f), Position(3195.668213f, -3475.930176f)) }, @@ -100,36 +100,6 @@ ObjectData const objectData[] = { 0, 0, } }; -// from P2 teleport spell stored target -float const HeiganPos[2] = { 2793.86f, -3707.38f }; -float const HeiganEruptionSlope[3] = -{ - (-3703.303223f - HeiganPos[1]) / (2777.494141f - HeiganPos[0]), // between right center and far right - (-3696.948242f - HeiganPos[1]) / (2785.624268f - HeiganPos[0]), // between left and right halves - (-3691.880615f - HeiganPos[1]) / (2790.280029f - HeiganPos[0]) // between far left and left center -}; - -// 0 H x -// 1 ^ -// 2 | -// 3 y<--o -inline uint32 GetEruptionSection(float x, float y) -{ - y -= HeiganPos[1]; - if (y < 1.0f) - return 0; - - x -= HeiganPos[0]; - if (x > -1.0f) - return 3; - - float slope = y/x; - for (uint32 i = 0; i < 3; ++i) - if (slope > HeiganEruptionSlope[i]) - return i; - return 3; -} - class instance_naxxramas : public InstanceMapScript { public: @@ -149,6 +119,7 @@ class instance_naxxramas : public InstanceMapScript hadAnubRekhanGreet = false; hadFaerlinaGreet = false; hadThaddiusGreet = false; + hadSapphironBirth = false; CurrentWingTaunt = SAY_KELTHUZAD_FIRST_WING_TAUNT; playerDied = 0; @@ -182,6 +153,9 @@ class instance_naxxramas : public InstanceMapScript case NPC_SIR: SirGUID = creature->GetGUID(); break; + case NPC_GLUTH: + GluthGUID = creature->GetGUID(); + break; case NPC_HEIGAN: HeiganGUID = creature->GetGUID(); break; @@ -208,28 +182,8 @@ class instance_naxxramas : public InstanceMapScript } } - void ProcessEvent(WorldObject* /*source*/, uint32 eventId) override - { - switch (eventId) - { - case EVENT_THADDIUS_BEGIN_RESET: - if (GetBossState(BOSS_THADDIUS) == SPECIAL) // this is the initial spawn, we want a shorter spawn time - events.ScheduleEvent(EVENT_THADDIUS_RESET, 5 * IN_MILLISECONDS); - else - events.ScheduleEvent(EVENT_THADDIUS_RESET, 30 * IN_MILLISECONDS); - break; - } - } - void OnGameObjectCreate(GameObject* go) override { - if (go->GetGOInfo()->displayId == 6785 || go->GetGOInfo()->displayId == 1287) - { - uint32 section = GetEruptionSection(go->GetPositionX(), go->GetPositionY()); - HeiganEruptionGUID[section].insert(go->GetGUID()); - return; - } - switch (go->GetEntry()) { case GO_GOTHIK_GATE: @@ -273,37 +227,18 @@ class instance_naxxramas : public InstanceMapScript if (GetBossState(BOSS_HORSEMEN) == DONE) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); break; - default: - break; - } - - InstanceScript::OnGameObjectCreate(go); - } - - void OnGameObjectRemove(GameObject* go) override - { - if (go->GetGOInfo()->displayId == 6785 || go->GetGOInfo()->displayId == 1287) - { - uint32 section = GetEruptionSection(go->GetPositionX(), go->GetPositionY()); - HeiganEruptionGUID[section].erase(go->GetGUID()); - return; - } - - switch (go->GetEntry()) - { case GO_BIRTH: - if (SapphironGUID) + if (hadSapphironBirth || GetBossState(BOSS_SAPPHIRON) == DONE) { - if (Creature* sapphiron = instance->GetCreature(SapphironGUID)) - sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); - return; + hadSapphironBirth = true; + go->Delete(); } break; default: break; } - InstanceScript::OnGameObjectRemove(go); + InstanceScript::OnGameObjectCreate(go); } void OnUnitDeath(Unit* unit) override @@ -328,9 +263,6 @@ class instance_naxxramas : public InstanceMapScript { switch (id) { - case DATA_HEIGAN_ERUPT: - HeiganErupt(value); - break; case DATA_GOTHIK_GATE: if (GameObject* gate = instance->GetGameObject(GothikGateGUID)) gate->SetGoState(GOState(value)); @@ -347,6 +279,9 @@ class instance_naxxramas : public InstanceMapScript case DATA_HAD_THADDIUS_GREET: hadThaddiusGreet = (value == 1u); break; + case DATA_HAD_SAPPHIRON_BIRTH: + hadSapphironBirth = (value == 1u); + break; default: break; } @@ -364,6 +299,8 @@ class instance_naxxramas : public InstanceMapScript return hadFaerlinaGreet ? 1u : 0u; case DATA_HAD_THADDIUS_GREET: return hadThaddiusGreet ? 1u : 0u; + case DATA_HAD_SAPPHIRON_BIRTH: + return hadSapphironBirth ? 1u : 0u; default: break; } @@ -393,12 +330,16 @@ class instance_naxxramas : public InstanceMapScript return SirGUID; case DATA_HEIGAN: return HeiganGUID; + case DATA_GLUTH: + return GluthGUID; case DATA_FEUGEN: return FeugenGUID; case DATA_STALAGG: return StalaggGUID; case DATA_THADDIUS: return ThaddiusGUID; + case DATA_SAPPHIRON: + return SapphironGUID; case DATA_KELTHUZAD: return KelthuzadGUID; case DATA_KELTHUZAD_PORTAL01: @@ -431,7 +372,7 @@ class instance_naxxramas : public InstanceMapScript if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_ARACHNID)) teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000); + events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, Seconds(6)); } break; case BOSS_LOATHEB: @@ -440,7 +381,7 @@ class instance_naxxramas : public InstanceMapScript if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_PLAGUE)) teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000); + events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, Seconds(6)); } break; case BOSS_THADDIUS: @@ -449,12 +390,12 @@ class instance_naxxramas : public InstanceMapScript if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_CONSTRUCT)) teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000); + events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, Seconds(6)); } break; case BOSS_GOTHIK: if (state == DONE) - events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ, 10000); + events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ, Seconds(10)); break; case BOSS_HORSEMEN: if (state == DONE) @@ -468,12 +409,12 @@ class instance_naxxramas : public InstanceMapScript if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_MILITARY)) teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000); + events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, Seconds(6)); } break; case BOSS_SAPPHIRON: if (state == DONE) - events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD, 6000); + events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD, Seconds(6)); break; default: break; @@ -493,37 +434,37 @@ class instance_naxxramas : public InstanceMapScript case EVENT_DIALOGUE_GOTHIK_KORTHAZZ: if (Creature* korthazz = instance->GetCreature(ThaneGUID)) korthazz->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN); - events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK, 5000); + events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK, Seconds(5)); break; case EVENT_DIALOGUE_GOTHIK_ZELIEK: if (Creature* zeliek = instance->GetCreature(SirGUID)) zeliek->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN); - events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX, 6000); + events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX, Seconds(6)); break; case EVENT_DIALOGUE_GOTHIK_BLAUMEUX: if (Creature* blaumeux = instance->GetCreature(LadyGUID)) blaumeux->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN); - events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE, 6000); + events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE, Seconds(6)); break; case EVENT_DIALOGUE_GOTHIK_RIVENDARE: if (Creature* rivendare = instance->GetCreature(BaronGUID)) rivendare->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN); - events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX2, 6000); + events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX2, Seconds(6)); break; case EVENT_DIALOGUE_GOTHIK_BLAUMEUX2: if (Creature* blaumeux = instance->GetCreature(LadyGUID)) blaumeux->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2); - events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK2, 6000); + events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK2, Seconds(6)); break; case EVENT_DIALOGUE_GOTHIK_ZELIEK2: if (Creature* zeliek = instance->GetCreature(SirGUID)) zeliek->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2); - events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ2, 6000); + events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ2, Seconds(6)); break; case EVENT_DIALOGUE_GOTHIK_KORTHAZZ2: if (Creature* korthazz = instance->GetCreature(ThaneGUID)) korthazz->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2); - events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE2, 6000); + events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE2, Seconds(6)); break; case EVENT_DIALOGUE_GOTHIK_RIVENDARE2: if (Creature* rivendare = instance->GetCreature(BaronGUID)) @@ -540,62 +481,39 @@ class instance_naxxramas : public InstanceMapScript if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID)) kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD); HandleGameObject(KelthuzadDoorGUID, false); - events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING, 6000); + events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING, Seconds(6)); break; case EVENT_DIALOGUE_SAPPHIRON_LICHKING: if (Creature* lichKing = instance->GetCreature(LichKingGUID)) lichKing->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_LICH_KING); - events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2, 16000); + events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2, Seconds(16)); break; case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2: if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID)) kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD2); - events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING2, 9000); + events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING2, Seconds(9)); break; case EVENT_DIALOGUE_SAPPHIRON_LICHKING2: if (Creature* lichKing = instance->GetCreature(LichKingGUID)) lichKing->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_LICH_KING2); - events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3, 12000); + events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3, Seconds(12)); break; case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3: if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID)) kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD3); - events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4, 6000); + events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4, Seconds(6)); break; case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4: if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID)) kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD4); HandleGameObject(KelthuzadDoorGUID, true); break; - case EVENT_THADDIUS_RESET: - if (GetBossState(BOSS_THADDIUS) != DONE) - if (Creature* thaddius = instance->GetCreature(ThaddiusGUID)) - thaddius->AI()->DoAction(-1); - break; default: break; } } } - void HeiganErupt(uint32 section) - { - for (uint32 i = 0; i < 4; ++i) - { - if (i == section) - continue; - - for (ObjectGuid guid : HeiganEruptionGUID[i]) - { - if (GameObject* heiganEruption = instance->GetGameObject(guid)) - { - heiganEruption->SendCustomAnim(heiganEruption->GetGoAnimProgress()); - heiganEruption->CastSpell(NULL, SPELL_ERUPTION); - } - } - } - } - // This Function is called in CheckAchievementCriteriaMeet and CheckAchievementCriteriaMeet is called before SetBossState(bossId, DONE), // so to check if all bosses are done the checker must exclude 1 boss, the last done, if there is at most 1 encouter in progress when is // called this function then all bosses are done. The one boss that check is the boss that calls this function, so it is dead. @@ -653,7 +571,6 @@ class instance_naxxramas : public InstanceMapScript /* The Plague Quarter */ // Heigan the Unclean - GuidSet HeiganEruptionGUID[4]; ObjectGuid HeiganGUID; /* The Military Quarter */ @@ -670,6 +587,8 @@ class instance_naxxramas : public InstanceMapScript ObjectGuid HorsemenChestGUID; /* The Construct Quarter */ + // Gluth + ObjectGuid GluthGUID; // Thaddius ObjectGuid ThaddiusGUID; ObjectGuid FeugenGUID; @@ -688,6 +607,7 @@ class instance_naxxramas : public InstanceMapScript bool hadAnubRekhanGreet; bool hadFaerlinaGreet; bool hadThaddiusGreet; + bool hadSapphironBirth; uint8 CurrentWingTaunt; /* The Immortal / The Undying */ diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h index c0caa86e93f..a3fedf5aa40 100644 --- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h +++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h @@ -43,12 +43,11 @@ enum Encounter enum Data { - DATA_HEIGAN_ERUPT, DATA_GOTHIK_GATE, - DATA_SAPPHIRON_BIRTH, DATA_HAD_ANUBREKHAN_GREET, DATA_HAD_FAERLINA_GREET, DATA_HAD_THADDIUS_GREET, + DATA_HAD_SAPPHIRON_BIRTH, DATA_HORSEMEN_CHECK_ACHIEVEMENT_CREDIT, DATA_ABOMINATION_KILLED, @@ -69,10 +68,12 @@ enum Data64 DATA_LADY, DATA_BARON, DATA_SIR, + DATA_GLUTH, DATA_THADDIUS, DATA_HEIGAN, DATA_FEUGEN, DATA_STALAGG, + DATA_SAPPHIRON, DATA_KELTHUZAD, DATA_KELTHUZAD_PORTAL01, DATA_KELTHUZAD_PORTAL02, @@ -92,6 +93,7 @@ enum CreaturesIds NPC_LADY = 16065, NPC_BARON = 30549, NPC_SIR = 16063, + NPC_GLUTH = 15932, NPC_HEIGAN = 15936, NPC_THADDIUS = 15928, NPC_FEUGEN = 15930, @@ -158,12 +160,6 @@ enum GameObjectsIds GO_NAXX_PORTAL_MILITARY = 181578 }; -enum SpellIds -{ - SPELL_ERUPTION = 29371, - SPELL_SLIME = 28801 -}; - enum InstanceEvents { // Dialogue that happens after Gothik's death. @@ -176,10 +172,6 @@ enum InstanceEvents EVENT_DIALOGUE_GOTHIK_KORTHAZZ2, EVENT_DIALOGUE_GOTHIK_RIVENDARE2, - // Thaddius AI requesting timed encounter (re-)spawn - EVENT_THADDIUS_BEGIN_RESET, - EVENT_THADDIUS_RESET, - // Dialogue that happens after each wing. EVENT_KELTHUZAD_WING_TAUNT, diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 277ca793a8f..f000d7a3ef7 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -377,7 +377,7 @@ public: me->SetDisableGravity(true); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); // TO DO: find what in core is making boss slower than in retail (when correct speed data) or find missing movement flag update or forced spline change - me->SetSpeed(MOVE_FLIGHT, _flySpeed * 0.25f); + me->SetSpeedRate(MOVE_FLIGHT, _flySpeed * 0.25f); if (_despawned) DoAction(ACTION_HANDLE_RESPAWN); @@ -603,7 +603,7 @@ public: me->SetRespawnDelay(respawnDelay); // Set speed to normal value - me->SetSpeed(MOVE_FLIGHT, _flySpeed); + me->SetSpeedRate(MOVE_FLIGHT, _flySpeed); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->RemoveAllAuras(); @@ -1165,7 +1165,7 @@ public: _instance = creature->GetInstanceScript(); me->SetReactState(REACT_PASSIVE); // TO DO: These were a bit faster than what they should be. Not sure what is the reason. - me->SetSpeed(MOVE_FLIGHT, 1.25f); + me->SetSpeedRate(MOVE_FLIGHT, 1.25f); } void Initialize() @@ -1274,7 +1274,7 @@ public: me->SetReactState(REACT_PASSIVE); // TO DO: Something is wrong with calculations for flying creatures that are on WP/Cyclic path. // They should get the same difference as to when at ground from run creature switch to walk. - me->SetSpeed(MOVE_FLIGHT, 0.45f); + me->SetSpeedRate(MOVE_FLIGHT, 0.45f); } void Reset() override @@ -1566,7 +1566,7 @@ public: { me->DespawnOrUnsummon(2050); me->SetOrientation(2.5f); - me->SetSpeed(MOVE_FLIGHT, 1.0f, true); + me->SetSpeedRate(MOVE_FLIGHT, 1.0f); Position pos = me->GetPosition(); pos.m_positionX += 10.0f; pos.m_positionY += 10.0f; diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp index e1a4a6ed7b8..3d9ea97b136 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp @@ -375,7 +375,7 @@ class npc_ruby_emerald_amber_drake : public CreatureScript { me->DespawnOrUnsummon(2050); me->SetOrientation(2.5f); - me->SetSpeed(MOVE_FLIGHT, 1.0f, true); + me->SetSpeedRate(MOVE_FLIGHT, 1.0f); Talk(SAY_DRAKES_TAKEOFF); Position pos = me->GetPosition(); Position offset = { 10.0f, 10.0f, 12.0f, 0.0f }; diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp index a98da2c6e3d..8f7687d0fca 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp @@ -174,7 +174,7 @@ public: { if (pSpark->IsAlive()) { - pSpark->SetSpeed(MOVE_RUN, 2.0f); + pSpark->SetSpeedRate(MOVE_RUN, 2.0f); pSpark->GetMotionMaster()->Clear(); pSpark->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); } @@ -355,7 +355,7 @@ public: { Position pos = ionar->GetPosition(); - me->SetSpeed(MOVE_RUN, 2.0f); + me->SetSpeedRate(MOVE_RUN, 2.0f); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index dbb00fa252e..b2a1bb70077 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -979,6 +979,9 @@ class go_celestial_planetarium_access : public GameObjectScript bool GossipHello(Player* player) override { + if (go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE)) + return true; + bool hasKey = true; if (LockEntry const* lock = sLockStore.LookupEntry(go->GetGOInfo()->goober.lockId)) { @@ -1161,6 +1164,7 @@ class spell_algalon_trigger_3_adds : public SpellScriptLoader void Register() override { OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_trigger_3_adds_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_algalon_trigger_3_adds_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index c77f5b2bce3..98827fb3e00 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -334,7 +334,8 @@ class boss_flame_leviathan : public CreatureScript void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override { if (spell->Id == SPELL_START_THE_ENGINE) - ASSERT_NOTNULL(me->GetVehicleKit())->InstallAllAccessories(false); + if (Vehicle* vehicleKit = me->GetVehicleKit()) + vehicleKit->InstallAllAccessories(false); if (spell->Id == SPELL_ELECTROSHOCK) me->InterruptSpell(CURRENT_CHANNELED_SPELL); @@ -1186,6 +1187,7 @@ class npc_brann_bronzebeard_ulduar_intro : public CreatureScript { if (menuId == GOSSIP_MENU_BRANN_BRONZEBEARD && gossipListId == GOSSIP_OPTION_BRANN_BRONZEBEARD) { + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); player->PlayerTalkClass->SendCloseGossip(); if (Creature* loreKeeper = _instance->GetCreature(DATA_LORE_KEEPER_OF_NORGANNON)) loreKeeper->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); @@ -1238,6 +1240,7 @@ class npc_lorekeeper : public CreatureScript { if (menuId == GOSSIP_MENU_LORE_KEEPER && gossipListId == GOSSIP_OPTION_LORE_KEEPER) { + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); player->PlayerTalkClass->SendCloseGossip(); _instance->instance->LoadGrid(364, -16); // make sure leviathan is loaded @@ -1250,6 +1253,7 @@ class npc_lorekeeper : public CreatureScript { if (Creature* brann = _instance->GetCreature(DATA_BRANN_BRONZEBEARD_INTRO)) { + brann->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); delorah->GetMotionMaster()->MovePoint(0, brann->GetPositionX() - 4, brann->GetPositionY(), brann->GetPositionZ()); /// @todo delorah->AI()->Talk(xxxx, brann->GetGUID()); when reached at branz } @@ -1765,9 +1769,7 @@ class spell_vehicle_throw_passenger : public SpellScriptLoader else { passenger->ExitVehicle(); - float x, y, z; - targets.GetDstPos()->GetPosition(x, y, z); - passenger->GetMotionMaster()->MoveJump(x, y, z, targets.GetSpeedXY(), targets.GetSpeedZ()); + passenger->GetMotionMaster()->MoveJump(*targets.GetDstPos(), targets.GetSpeedXY(), targets.GetSpeedZ()); } } } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index df5877d9220..05beacca638 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -222,7 +222,6 @@ class npc_iron_roots : public CreatureScript { SetCombatMovement(false); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip me->setFaction(14); me->SetReactState(REACT_PASSIVE); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp index 385f7d6a69d..09d95b34521 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp @@ -380,7 +380,6 @@ class npc_saronite_vapors : public CreatureScript { Talk(EMOTE_VAPORS); instance = me->GetInstanceScript(); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip jump effect me->SetReactState(REACT_PASSIVE); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 820332791c8..8aa443cba3f 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -359,9 +359,9 @@ static bool IsEncounterFinished(Unit* who) if (!mkii || !vx001 || !aerial) return false; - if (mkii->getStandState() == UNIT_STAND_STATE_DEAD && - vx001->getStandState() == UNIT_STAND_STATE_DEAD && - aerial->getStandState() == UNIT_STAND_STATE_DEAD) + if (mkii->GetStandState() == UNIT_STAND_STATE_DEAD && + vx001->GetStandState() == UNIT_STAND_STATE_DEAD && + aerial->GetStandState() == UNIT_STAND_STATE_DEAD) { who->Kill(mkii); who->Kill(vx001); @@ -444,7 +444,7 @@ class boss_mimiron : public CreatureScript DoCastAOE(SPELL_DESPAWN_ASSAULT_BOTS); me->ExitVehicle(); // ExitVehicle() offset position is not implemented, so we make up for that with MoveJump()... - me->GetMotionMaster()->MoveJump(me->GetPositionX() + (10.f * std::cos(me->GetOrientation())), me->GetPositionY() + (10.f * std::sin(me->GetOrientation())), me->GetPositionZ(), 10.f, 5.f); + me->GetMotionMaster()->MoveJump(me->GetPositionX() + (10.f * std::cos(me->GetOrientation())), me->GetPositionY() + (10.f * std::sin(me->GetOrientation())), me->GetPositionZ(), me->GetOrientation(), 10.f, 5.f); events.ScheduleEvent(EVENT_OUTTRO_1, 7000); } @@ -703,7 +703,7 @@ class boss_leviathan_mk_ii : public CreatureScript if (Unit* turret = me->GetVehicleKit()->GetPassenger(3)) turret->KillSelf(); - me->SetSpeed(MOVE_RUN, 1.5f, true); + me->SetSpeedRate(MOVE_RUN, 1.5f); me->GetMotionMaster()->MovePoint(WP_MKII_P1_IDLE, VehicleRelocation[WP_MKII_P1_IDLE]); } else if (events.IsInPhase(PHASE_VOL7RON)) @@ -1634,8 +1634,11 @@ class go_mimiron_hardmode_button : public GameObjectScript public: go_mimiron_hardmode_button() : GameObjectScript("go_mimiron_hardmode_button") { } - bool OnGossipHello(Player* /*player*/, GameObject* go) + bool OnGossipHello(Player* /*player*/, GameObject* go) override { + if (go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE)) + return true; + InstanceScript* instance = go->GetInstanceScript(); if (!instance) return false; @@ -2756,7 +2759,7 @@ class achievement_setup_boom : public AchievementCriteriaScript public: achievement_setup_boom() : AchievementCriteriaScript("achievement_setup_boom") { } - bool OnCheck(Player* /*source*/, Unit* target) + bool OnCheck(Player* /*source*/, Unit* target) override { return target && target->GetAI()->GetData(DATA_SETUP_BOMB); } @@ -2767,7 +2770,7 @@ class achievement_setup_mine : public AchievementCriteriaScript public: achievement_setup_mine() : AchievementCriteriaScript("achievement_setup_mine") { } - bool OnCheck(Player* /*source*/, Unit* target) + bool OnCheck(Player* /*source*/, Unit* target) override { return target && target->GetAI()->GetData(DATA_SETUP_MINE); } @@ -2778,7 +2781,7 @@ class achievement_setup_rocket : public AchievementCriteriaScript public: achievement_setup_rocket() : AchievementCriteriaScript("achievement_setup_rocket") { } - bool OnCheck(Player* /*source*/, Unit* target) + bool OnCheck(Player* /*source*/, Unit* target) override { return target && target->GetAI()->GetData(DATA_SETUP_ROCKET); } @@ -2789,7 +2792,7 @@ class achievement_firefighter : public AchievementCriteriaScript public: achievement_firefighter() : AchievementCriteriaScript("achievement_firefighter") { } - bool OnCheck(Player* /*source*/, Unit* target) + bool OnCheck(Player* /*source*/, Unit* target) override { return target && target->GetAI()->GetData(DATA_FIREFIGHTER); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index f5337b2dca5..363f5907048 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -366,7 +366,7 @@ class boss_razorscale : public CreatureScript _EnterCombat(); if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RAZORSCALE_CONTROL))) controller->AI()->DoAction(ACTION_HARPOON_BUILD); - me->SetSpeed(MOVE_FLIGHT, 3.0f, true); + me->SetSpeedRate(MOVE_FLIGHT, 3.0f); me->SetReactState(REACT_PASSIVE); phase = PHASE_GROUND; events.SetPhase(PHASE_GROUND); @@ -550,7 +550,7 @@ class boss_razorscale : public CreatureScript me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); me->SetReactState(REACT_AGGRESSIVE); me->RemoveAurasDueToSpell(SPELL_HARPOON_TRIGGER); - me->SetSpeed(MOVE_FLIGHT, 1.0f, true); + me->SetSpeedRate(MOVE_FLIGHT, 1.0f); PermaGround = true; DoCastAOE(SPELL_FLAMEBREATH); events.ScheduleEvent(EVENT_FLAME, 15000, 0, PHASE_PERMAGROUND); @@ -677,7 +677,7 @@ class npc_expedition_commander : public CreatureScript if (Creature* summonedEngineer = me->SummonCreature(NPC_ENGINEER, PosEngSpawn, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000)) { summonedEngineer->SetWalk(false); - summonedEngineer->SetSpeed(MOVE_RUN, 0.5f); + summonedEngineer->SetSpeedRate(MOVE_RUN, 0.5f); summonedEngineer->SetHomePosition(PosEngRepair[n]); summonedEngineer->GetMotionMaster()->MoveTargetedHome(); Engineer[n] = summonedEngineer->GetGUID(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp index 8cb20eadc9f..f3aeec85af2 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp @@ -637,7 +637,7 @@ class BoomEvent : public BasicEvent { } - bool Execute(uint64 /*time*/, uint32 /*diff*/) + bool Execute(uint64 /*time*/, uint32 /*diff*/) override { // This hack is here because we suspect our implementation of spell effect execution on targets // is done in the wrong order. We suspect that EFFECT_0 needs to be applied on all targets, diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp index 7da67171b5c..675268b4e93 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp @@ -230,6 +230,9 @@ enum Spells // Descend Into Madness SPELL_TELEPORT_PORTAL_VISUAL = 64416, + SPELL_TELEPORT_TO_STORMWIND_ILLUSION = 63989, + SPELL_TELEPORT_TO_CHAMBER_ILLUSION = 63997, + SPELL_TELEPORT_TO_ICECROWN_ILLUSION = 63998, // Illusions SPELL_GRIM_REPRISAL = 63305, @@ -395,6 +398,14 @@ enum MiscData { ACHIEV_TIMED_START_EVENT = 21001, SOUND_LUNATIC_GAZE = 15757, + MAX_ILLUSION_ROOMS = 3 +}; + +uint32 const IllusionSpells[MAX_ILLUSION_ROOMS] +{ + SPELL_TELEPORT_TO_CHAMBER_ILLUSION, + SPELL_TELEPORT_TO_ICECROWN_ILLUSION, + SPELL_TELEPORT_TO_STORMWIND_ILLUSION }; class StartAttackEvent : public BasicEvent @@ -405,7 +416,7 @@ class StartAttackEvent : public BasicEvent { } - bool Execute(uint64 /*time*/, uint32 /*diff*/) + bool Execute(uint64 /*time*/, uint32 /*diff*/) override { _owner->SetReactState(REACT_AGGRESSIVE); if (Creature* _summoner = ObjectAccessor::GetCreature(*_owner, _summonerGuid)) @@ -1419,7 +1430,11 @@ class npc_descend_into_madness : public CreatureScript { if (!result) return; + clicker->RemoveAurasDueToSpell(SPELL_BRAIN_LINK); + uint32 illusion = _instance->GetData(DATA_ILLUSION); + if (illusion < MAX_ILLUSION_ROOMS) + DoCast(clicker, IllusionSpells[illusion], true); me->DespawnOrUnsummon(); } diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp index 1af45f3031a..3dec0c60991 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp @@ -102,7 +102,7 @@ public: Sequence[i] = Phase(i); /// This ensures a random order and only executes each phase once. - std::random_shuffle(Sequence, Sequence + PHASE_GORTOK_PALEHOOF); + Trinity::Containers::RandomShuffle(Sequence); uiArcingSmashTimer = 15000; uiImpaleTimer = 12000; @@ -118,7 +118,7 @@ public: uint32 uiWhiteringRoarTimer; Phase currentPhase; uint8 AddCount; - Phase Sequence[4]; + std::array<Phase, 4> Sequence; void Reset() override { @@ -746,7 +746,7 @@ public: //! HACK: Creature's can't have MOVEMENTFLAG_FLYING me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING); me->RemoveAurasDueToSpell(SPELL_ORB_VISUAL); - me->SetSpeed(MOVE_FLIGHT, 0.5f); + me->SetSpeedRate(MOVE_FLIGHT, 0.5f); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp index 77b376bf7d5..7615217a794 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp @@ -209,7 +209,7 @@ public: Initialize(); Summons.DespawnAll(); - me->SetSpeed(MOVE_FLIGHT, 3.0f); + me->SetSpeedRate(MOVE_FLIGHT, 3.0f); if ((ObjectAccessor::GetCreature(*me, m_uiGraufGUID) == NULL) && !me->IsMounted()) me->SummonCreature(NPC_GRAUF, Location[0].GetPositionX(), Location[0].GetPositionY(), Location[0].GetPositionZ(), 3.0f); instance->SetBossState(DATA_SKADI_THE_RUTHLESS, NOT_STARTED); @@ -238,7 +238,7 @@ public: me->SetInCombatWithZone(); instance->SetBossState(DATA_SKADI_THE_RUTHLESS, IN_PROGRESS); instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT); - me->GetMotionMaster()->MoveJump(Location[0].GetPositionX(), Location[0].GetPositionY(), Location[0].GetPositionZ(), 5.0f, 10.0f); + me->GetMotionMaster()->MoveJump(Location[0], 5.0f, 10.0f); me->SetWalk(false); m_uiMountTimer = 1000; Summons.DespawnEntry(NPC_GRAUF); @@ -289,7 +289,7 @@ public: pGrauf->GetMotionMaster()->MoveFall(); pGrauf->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH); } - me->GetMotionMaster()->MoveJump(Location[4].GetPositionX(), Location[4].GetPositionY(), Location[4].GetPositionZ(), 5.0f, 10.0f); + me->GetMotionMaster()->MoveJump(Location[4], 5.0f, 10.0f); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); Talk(SAY_DRAKE_DEATH); m_uiCrushTimer = 8000; diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp index 8f2d5a61770..547dc681ac6 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp @@ -19,7 +19,7 @@ #include "InstanceScript.h" #include "utgarde_pinnacle.h" -BossBoundaryData const boundaries = +BossBoundaryData const boundaries = { { DATA_KING_YMIRON, new RectangleBoundary(340.0f, 450.0f, -412.0f, -275.0f) } }; diff --git a/src/server/scripts/Northrend/isle_of_conquest.cpp b/src/server/scripts/Northrend/isle_of_conquest.cpp index 14d862eca39..11cc645f0cb 100644 --- a/src/server/scripts/Northrend/isle_of_conquest.cpp +++ b/src/server/scripts/Northrend/isle_of_conquest.cpp @@ -206,11 +206,11 @@ class spell_ioc_parachute_ic : public SpellScriptLoader class StartLaunchEvent : public BasicEvent { public: - StartLaunchEvent(float x, float y, float z, ObjectGuid::LowType lowGuid) : _x(x), _y(y), _z(z), _lowGuid(lowGuid) + StartLaunchEvent(Position const& pos, ObjectGuid::LowType lowGuid) : _pos(pos), _lowGuid(lowGuid) { } - bool Execute(uint64 /*time*/, uint32 /*diff*/) + bool Execute(uint64 /*time*/, uint32 /*diff*/) override { Player* player = sObjectMgr->GetPlayerByLowGUID(_lowGuid); if (!player || !player->GetVehicle()) @@ -218,15 +218,15 @@ class StartLaunchEvent : public BasicEvent player->AddAura(SPELL_LAUNCH_NO_FALLING_DAMAGE, player); // prevents falling damage float speedZ = 10.0f; - float dist = player->GetExactDist2d(_x, _y); + float dist = player->GetExactDist2d(&_pos); player->ExitVehicle(); - player->GetMotionMaster()->MoveJump(_x, _y, _z, dist, speedZ); + player->GetMotionMaster()->MoveJump(_pos, dist, speedZ, EVENT_JUMP, true); return true; } private: - float _x, _y, _z; + Position _pos; ObjectGuid::LowType _lowGuid; }; @@ -244,11 +244,7 @@ class spell_ioc_launch : public SpellScriptLoader if (!GetCaster()->ToCreature() || !GetExplTargetDest()) return; - float x, y, z; - x = GetExplTargetDest()->GetPositionX(); - y = GetExplTargetDest()->GetPositionY(); - z = GetExplTargetDest()->GetPositionZ(); - GetCaster()->ToCreature()->m_Events.AddEvent(new StartLaunchEvent(x, y, z, GetHitPlayer()->GetGUID().GetCounter()), GetCaster()->ToCreature()->m_Events.CalculateTime(2500)); + GetCaster()->ToCreature()->m_Events.AddEvent(new StartLaunchEvent(*GetExplTargetDest(), GetHitPlayer()->GetGUID().GetCounter()), GetCaster()->ToCreature()->m_Events.CalculateTime(2500)); } void Register() override diff --git a/src/server/scripts/Northrend/northrend_script_loader.cpp b/src/server/scripts/Northrend/northrend_script_loader.cpp new file mode 100644 index 00000000000..7d104b85f6d --- /dev/null +++ b/src/server/scripts/Northrend/northrend_script_loader.cpp @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This is where scripts' loading functions should be declared: +void AddSC_boss_slad_ran(); +void AddSC_boss_moorabi(); +void AddSC_boss_drakkari_colossus(); +void AddSC_boss_gal_darah(); +void AddSC_boss_eck(); +void AddSC_instance_gundrak(); + +// Azjol-Nerub - Azjol-Nerub +void AddSC_boss_krik_thir(); +void AddSC_boss_hadronox(); +void AddSC_boss_anub_arak(); +void AddSC_instance_azjol_nerub(); + +// Azjol-Nerub - Ahn'kahet +void AddSC_boss_elder_nadox(); +void AddSC_boss_taldaram(); +void AddSC_boss_amanitar(); +void AddSC_boss_jedoga_shadowseeker(); +void AddSC_boss_volazj(); +void AddSC_instance_ahnkahet(); + +// Drak'Tharon Keep +void AddSC_boss_trollgore(); +void AddSC_boss_novos(); +void AddSC_boss_king_dred(); +void AddSC_boss_tharon_ja(); +void AddSC_instance_drak_tharon_keep(); + +void AddSC_boss_argent_challenge(); //Trial of the Champion +void AddSC_boss_black_knight(); +void AddSC_boss_grand_champions(); +void AddSC_instance_trial_of_the_champion(); +void AddSC_trial_of_the_champion(); +void AddSC_boss_anubarak_trial(); //Trial of the Crusader +void AddSC_boss_faction_champions(); +void AddSC_boss_jaraxxus(); +void AddSC_boss_northrend_beasts(); +void AddSC_boss_twin_valkyr(); +void AddSC_trial_of_the_crusader(); +void AddSC_instance_trial_of_the_crusader(); +void AddSC_boss_anubrekhan(); //Naxxramas +void AddSC_boss_maexxna(); +void AddSC_boss_patchwerk(); +void AddSC_boss_grobbulus(); +void AddSC_boss_razuvious(); +void AddSC_boss_kelthuzad(); +void AddSC_boss_loatheb(); +void AddSC_boss_noth(); +void AddSC_boss_gluth(); +void AddSC_boss_sapphiron(); +void AddSC_boss_four_horsemen(); +void AddSC_boss_faerlina(); +void AddSC_boss_heigan(); +void AddSC_boss_gothik(); +void AddSC_boss_thaddius(); +void AddSC_instance_naxxramas(); +void AddSC_boss_nexus_commanders(); // The Nexus Nexus +void AddSC_boss_magus_telestra(); +void AddSC_boss_anomalus(); +void AddSC_boss_ormorok(); +void AddSC_boss_keristrasza(); +void AddSC_instance_nexus(); +void AddSC_boss_drakos(); //The Nexus The Oculus +void AddSC_boss_urom(); +void AddSC_boss_varos(); +void AddSC_boss_eregos(); +void AddSC_instance_oculus(); +void AddSC_oculus(); +void AddSC_boss_malygos(); // The Nexus: Eye of Eternity +void AddSC_instance_eye_of_eternity(); +void AddSC_boss_sartharion(); //Obsidian Sanctum +void AddSC_obsidian_sanctum(); +void AddSC_instance_obsidian_sanctum(); +void AddSC_boss_bjarngrim(); //Ulduar Halls of Lightning +void AddSC_boss_loken(); +void AddSC_boss_ionar(); +void AddSC_boss_volkhan(); +void AddSC_instance_halls_of_lightning(); +void AddSC_boss_maiden_of_grief(); //Ulduar Halls of Stone +void AddSC_boss_krystallus(); +void AddSC_boss_sjonnir(); +void AddSC_instance_halls_of_stone(); +void AddSC_halls_of_stone(); +void AddSC_boss_auriaya(); //Ulduar Ulduar +void AddSC_boss_flame_leviathan(); +void AddSC_boss_ignis(); +void AddSC_boss_razorscale(); +void AddSC_boss_xt002(); +void AddSC_boss_kologarn(); +void AddSC_boss_assembly_of_iron(); +void AddSC_boss_general_vezax(); +void AddSC_boss_mimiron(); +void AddSC_boss_hodir(); +void AddSC_boss_freya(); +void AddSC_boss_yogg_saron(); +void AddSC_boss_algalon_the_observer(); +void AddSC_instance_ulduar(); + +// Utgarde Keep - Utgarde Keep +void AddSC_boss_keleseth(); +void AddSC_boss_skarvald_dalronn(); +void AddSC_boss_ingvar_the_plunderer(); +void AddSC_instance_utgarde_keep(); +void AddSC_utgarde_keep(); + +// Utgarde Keep - Utgarde Pinnacle +void AddSC_boss_svala(); +void AddSC_boss_palehoof(); +void AddSC_boss_skadi(); +void AddSC_boss_ymiron(); +void AddSC_instance_utgarde_pinnacle(); + +// Vault of Archavon +void AddSC_boss_archavon(); +void AddSC_boss_emalon(); +void AddSC_boss_koralon(); +void AddSC_boss_toravon(); +void AddSC_instance_vault_of_archavon(); + +void AddSC_boss_cyanigosa(); //Violet Hold +void AddSC_boss_erekem(); +void AddSC_boss_ichoron(); +void AddSC_boss_lavanthor(); +void AddSC_boss_moragg(); +void AddSC_boss_xevozz(); +void AddSC_boss_zuramat(); +void AddSC_instance_violet_hold(); +void AddSC_violet_hold(); +void AddSC_instance_forge_of_souls(); //Forge of Souls +void AddSC_forge_of_souls(); +void AddSC_boss_bronjahm(); +void AddSC_boss_devourer_of_souls(); +void AddSC_instance_pit_of_saron(); //Pit of Saron +void AddSC_pit_of_saron(); +void AddSC_boss_garfrost(); +void AddSC_boss_ick(); +void AddSC_boss_tyrannus(); +void AddSC_instance_halls_of_reflection(); // Halls of Reflection +void AddSC_halls_of_reflection(); +void AddSC_boss_falric(); +void AddSC_boss_marwyn(); +void AddSC_boss_lord_marrowgar(); // Icecrown Citadel +void AddSC_boss_lady_deathwhisper(); +void AddSC_boss_icecrown_gunship_battle(); +void AddSC_boss_deathbringer_saurfang(); +void AddSC_boss_festergut(); +void AddSC_boss_rotface(); +void AddSC_boss_professor_putricide(); +void AddSC_boss_blood_prince_council(); +void AddSC_boss_blood_queen_lana_thel(); +void AddSC_boss_valithria_dreamwalker(); +void AddSC_boss_sindragosa(); +void AddSC_boss_the_lich_king(); +void AddSC_icecrown_citadel_teleport(); +void AddSC_instance_icecrown_citadel(); +void AddSC_icecrown_citadel(); +void AddSC_instance_ruby_sanctum(); // Ruby Sanctum +void AddSC_ruby_sanctum(); +void AddSC_boss_baltharus_the_warborn(); +void AddSC_boss_saviana_ragefire(); +void AddSC_boss_general_zarithrian(); +void AddSC_boss_halion(); + +void AddSC_dalaran(); +void AddSC_borean_tundra(); +void AddSC_dragonblight(); +void AddSC_grizzly_hills(); +void AddSC_howling_fjord(); +void AddSC_icecrown(); +void AddSC_sholazar_basin(); +void AddSC_storm_peaks(); +void AddSC_wintergrasp(); +void AddSC_zuldrak(); +void AddSC_crystalsong_forest(); +void AddSC_isle_of_conquest(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddNorthrendScripts() +{ + AddSC_boss_slad_ran(); //Gundrak + AddSC_boss_moorabi(); + AddSC_boss_drakkari_colossus(); + AddSC_boss_gal_darah(); + AddSC_boss_eck(); + AddSC_instance_gundrak(); + + // Azjol-Nerub - Ahn'kahet + AddSC_boss_elder_nadox(); + AddSC_boss_taldaram(); + AddSC_boss_amanitar(); + AddSC_boss_jedoga_shadowseeker(); + AddSC_boss_volazj(); + AddSC_instance_ahnkahet(); + + // Azjol-Nerub - Azjol-Nerub + AddSC_boss_krik_thir(); + AddSC_boss_hadronox(); + AddSC_boss_anub_arak(); + AddSC_instance_azjol_nerub(); + + // Drak'Tharon Keep + AddSC_boss_trollgore(); + AddSC_boss_novos(); + AddSC_boss_king_dred(); + AddSC_boss_tharon_ja(); + AddSC_instance_drak_tharon_keep(); + + AddSC_boss_argent_challenge(); //Trial of the Champion + AddSC_boss_black_knight(); + AddSC_boss_grand_champions(); + AddSC_instance_trial_of_the_champion(); + AddSC_trial_of_the_champion(); + AddSC_boss_anubarak_trial(); //Trial of the Crusader + AddSC_boss_faction_champions(); + AddSC_boss_jaraxxus(); + AddSC_trial_of_the_crusader(); + AddSC_boss_twin_valkyr(); + AddSC_boss_northrend_beasts(); + AddSC_instance_trial_of_the_crusader(); + AddSC_boss_anubrekhan(); //Naxxramas + AddSC_boss_maexxna(); + AddSC_boss_patchwerk(); + AddSC_boss_grobbulus(); + AddSC_boss_razuvious(); + AddSC_boss_kelthuzad(); + AddSC_boss_loatheb(); + AddSC_boss_noth(); + AddSC_boss_gluth(); + AddSC_boss_sapphiron(); + AddSC_boss_four_horsemen(); + AddSC_boss_faerlina(); + AddSC_boss_heigan(); + AddSC_boss_gothik(); + AddSC_boss_thaddius(); + AddSC_instance_naxxramas(); + AddSC_boss_nexus_commanders(); // The Nexus Nexus + AddSC_boss_magus_telestra(); + AddSC_boss_anomalus(); + AddSC_boss_ormorok(); + AddSC_boss_keristrasza(); + AddSC_instance_nexus(); + AddSC_boss_drakos(); //The Nexus The Oculus + AddSC_boss_urom(); + AddSC_boss_varos(); + AddSC_boss_eregos(); + AddSC_instance_oculus(); + AddSC_oculus(); + AddSC_boss_malygos(); // The Nexus: Eye of Eternity + AddSC_instance_eye_of_eternity(); + AddSC_boss_sartharion(); //Obsidian Sanctum + AddSC_obsidian_sanctum(); + AddSC_instance_obsidian_sanctum(); + AddSC_boss_bjarngrim(); //Ulduar Halls of Lightning + AddSC_boss_loken(); + AddSC_boss_ionar(); + AddSC_boss_volkhan(); + AddSC_instance_halls_of_lightning(); + AddSC_boss_maiden_of_grief(); //Ulduar Halls of Stone + AddSC_boss_krystallus(); + AddSC_boss_sjonnir(); + AddSC_instance_halls_of_stone(); + AddSC_halls_of_stone(); + AddSC_boss_auriaya(); //Ulduar Ulduar + AddSC_boss_flame_leviathan(); + AddSC_boss_ignis(); + AddSC_boss_razorscale(); + AddSC_boss_xt002(); + AddSC_boss_general_vezax(); + AddSC_boss_assembly_of_iron(); + AddSC_boss_kologarn(); + AddSC_boss_mimiron(); + AddSC_boss_hodir(); + AddSC_boss_freya(); + AddSC_boss_yogg_saron(); + AddSC_boss_algalon_the_observer(); + AddSC_instance_ulduar(); + + // Utgarde Keep - Utgarde Keep + AddSC_boss_keleseth(); + AddSC_boss_skarvald_dalronn(); + AddSC_boss_ingvar_the_plunderer(); + AddSC_instance_utgarde_keep(); + AddSC_utgarde_keep(); + + // Utgarde Keep - Utgarde Pinnacle + AddSC_boss_svala(); + AddSC_boss_palehoof(); + AddSC_boss_skadi(); + AddSC_boss_ymiron(); + AddSC_instance_utgarde_pinnacle(); + + // Vault of Archavon + AddSC_boss_archavon(); + AddSC_boss_emalon(); + AddSC_boss_koralon(); + AddSC_boss_toravon(); + AddSC_instance_vault_of_archavon(); + + AddSC_boss_cyanigosa(); //Violet Hold + AddSC_boss_erekem(); + AddSC_boss_ichoron(); + AddSC_boss_lavanthor(); + AddSC_boss_moragg(); + AddSC_boss_xevozz(); + AddSC_boss_zuramat(); + AddSC_instance_violet_hold(); + AddSC_violet_hold(); + AddSC_instance_forge_of_souls(); //Forge of Souls + AddSC_forge_of_souls(); + AddSC_boss_bronjahm(); + AddSC_boss_devourer_of_souls(); + AddSC_instance_pit_of_saron(); //Pit of Saron + AddSC_pit_of_saron(); + AddSC_boss_garfrost(); + AddSC_boss_ick(); + AddSC_boss_tyrannus(); + AddSC_instance_halls_of_reflection(); // Halls of Reflection + AddSC_halls_of_reflection(); + AddSC_boss_falric(); + AddSC_boss_marwyn(); + AddSC_boss_lord_marrowgar(); // Icecrown Citadel + AddSC_boss_lady_deathwhisper(); + AddSC_boss_icecrown_gunship_battle(); + AddSC_boss_deathbringer_saurfang(); + AddSC_boss_festergut(); + AddSC_boss_rotface(); + AddSC_boss_professor_putricide(); + AddSC_boss_blood_prince_council(); + AddSC_boss_blood_queen_lana_thel(); + AddSC_boss_valithria_dreamwalker(); + AddSC_boss_sindragosa(); + AddSC_boss_the_lich_king(); + AddSC_icecrown_citadel_teleport(); + AddSC_instance_icecrown_citadel(); + AddSC_icecrown_citadel(); + AddSC_instance_ruby_sanctum(); // Ruby Sanctum + AddSC_ruby_sanctum(); + AddSC_boss_baltharus_the_warborn(); + AddSC_boss_saviana_ragefire(); + AddSC_boss_general_zarithrian(); + AddSC_boss_halion(); + + AddSC_dalaran(); + AddSC_borean_tundra(); + AddSC_dragonblight(); + AddSC_grizzly_hills(); + AddSC_howling_fjord(); + AddSC_icecrown(); + AddSC_sholazar_basin(); + AddSC_storm_peaks(); + AddSC_wintergrasp(); + AddSC_zuldrak(); + AddSC_crystalsong_forest(); + AddSC_isle_of_conquest(); +} diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp index 2ec2af80624..d7ff1e5cb4d 100644 --- a/src/server/scripts/Northrend/zone_dragonblight.cpp +++ b/src/server/scripts/Northrend/zone_dragonblight.cpp @@ -360,7 +360,7 @@ class npc_commander_eligor_dawnbringer : public CreatureScript uint8 talkWing; }; - CreatureAI* GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const override { return new npc_commander_eligor_dawnbringerAI(creature); } @@ -695,7 +695,7 @@ class npc_torturer_lecraft : public CreatureScript ObjectGuid _playerGUID; }; - CreatureAI* GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const override { return new npc_torturer_lecraftAI(creature); } diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp index 88217cb384e..3d801cc2fbb 100644 --- a/src/server/scripts/Northrend/zone_icecrown.cpp +++ b/src/server/scripts/Northrend/zone_icecrown.cpp @@ -213,7 +213,6 @@ class npc_tournament_training_dummy : public CreatureScript void Reset() override { me->SetControlled(true, UNIT_STATE_STUNNED); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); Initialize(); // Cast Defend spells to max stack size @@ -713,7 +712,7 @@ enum BorrowedTechnologyAndVolatility SPELL_PING_BUNNY = 59375, SPELL_IMMOLATION = 54690, SPELL_EXPLOSION = 59335, - SPELL_RIDE = 56687, + SPELL_RIDE = 59319, // Points POINT_GRAB_DECOY = 1, diff --git a/src/server/scripts/OutdoorPvP/CMakeLists.txt b/src/server/scripts/OutdoorPvP/CMakeLists.txt deleted file mode 100644 index 91ce4ce4186..00000000000 --- a/src/server/scripts/OutdoorPvP/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - OutdoorPvP/OutdoorPvPTF.cpp - OutdoorPvP/OutdoorPvPSI.cpp - OutdoorPvP/OutdoorPvPSI.h - OutdoorPvP/OutdoorPvPZM.cpp - OutdoorPvP/OutdoorPvPNA.cpp - OutdoorPvP/OutdoorPvPHP.cpp - OutdoorPvP/OutdoorPvPTF.h - OutdoorPvP/OutdoorPvPEP.h - OutdoorPvP/OutdoorPvPEP.cpp - OutdoorPvP/OutdoorPvPHP.h - OutdoorPvP/OutdoorPvPZM.h - OutdoorPvP/OutdoorPvPNA.h -) - -message(" -> Prepared: Outdoor PVP Zones") diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPHP.h b/src/server/scripts/OutdoorPvP/OutdoorPvPHP.h index 71dbd139ea0..4fd608ccd1c 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPHP.h +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPHP.h @@ -96,9 +96,9 @@ class OPvPCapturePointHP : public OPvPCapturePoint public: OPvPCapturePointHP(OutdoorPvP* pvp, OutdoorPvPHPTowerType type); - void ChangeState(); + void ChangeState() override; - void FillInitialWorldStates(WorldPacket & data); + void FillInitialWorldStates(WorldPacket & data) override; private: OutdoorPvPHPTowerType m_TowerType; @@ -109,18 +109,18 @@ class OutdoorPvPHP : public OutdoorPvP public: OutdoorPvPHP(); - bool SetupOutdoorPvP(); + bool SetupOutdoorPvP() override; - void HandlePlayerEnterZone(Player* player, uint32 zone); - void HandlePlayerLeaveZone(Player* player, uint32 zone); + void HandlePlayerEnterZone(Player* player, uint32 zone) override; + void HandlePlayerLeaveZone(Player* player, uint32 zone) override; - bool Update(uint32 diff); + bool Update(uint32 diff) override; - void FillInitialWorldStates(WorldPacket &data); + void FillInitialWorldStates(WorldPacket &data) override; - void SendRemoveWorldStates(Player* player); + void SendRemoveWorldStates(Player* player) override; - void HandleKillImpl(Player* player, Unit* killed); + void HandleKillImpl(Player* player, Unit* killed) override; uint32 GetAllianceTowersControlled() const; void SetAllianceTowersControlled(uint32 count); diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h index 4ed47c42206..80878828d44 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h @@ -311,18 +311,18 @@ class OutdoorPvPNA : public OutdoorPvP public: OutdoorPvPNA(); - bool SetupOutdoorPvP(); + bool SetupOutdoorPvP() override; - void HandlePlayerEnterZone(Player* player, uint32 zone); - void HandlePlayerLeaveZone(Player* player, uint32 zone); + void HandlePlayerEnterZone(Player* player, uint32 zone) override; + void HandlePlayerLeaveZone(Player* player, uint32 zone) override; - bool Update(uint32 diff); + bool Update(uint32 diff) override; - void FillInitialWorldStates(WorldPacket &data); + void FillInitialWorldStates(WorldPacket &data) override; - void SendRemoveWorldStates(Player* player); + void SendRemoveWorldStates(Player* player) override; - void HandleKillImpl(Player* player, Unit* killed); + void HandleKillImpl(Player* player, Unit* killed) override; private: OPvPCapturePointNA * m_obj; diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.h b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.h index f28fea926fc..fae2ea9738e 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.h +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.h @@ -56,22 +56,22 @@ class OutdoorPvPSI : public OutdoorPvP public: OutdoorPvPSI(); - bool SetupOutdoorPvP(); + bool SetupOutdoorPvP() override; - void HandlePlayerEnterZone(Player* player, uint32 zone); - void HandlePlayerLeaveZone(Player* player, uint32 zone); + void HandlePlayerEnterZone(Player* player, uint32 zone) override; + void HandlePlayerLeaveZone(Player* player, uint32 zone) override; - bool Update(uint32 diff); + bool Update(uint32 diff) override; - void FillInitialWorldStates(WorldPacket &data); + void FillInitialWorldStates(WorldPacket &data) override; - void SendRemoveWorldStates(Player* player); + void SendRemoveWorldStates(Player* player) override; - bool HandleAreaTrigger(Player* player, uint32 trigger); + bool HandleAreaTrigger(Player* player, uint32 trigger) override; - bool HandleDropFlag(Player* player, uint32 spellId); + bool HandleDropFlag(Player* player, uint32 spellId) override; - bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go); + bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go) override; void UpdateWorldState(); diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPScriptLoader.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPScriptLoader.cpp new file mode 100644 index 00000000000..ebf29910046 --- /dev/null +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPScriptLoader.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This is where scripts' loading functions should be declared: +void AddSC_outdoorpvp_ep(); +void AddSC_outdoorpvp_hp(); +void AddSC_outdoorpvp_na(); +void AddSC_outdoorpvp_si(); +void AddSC_outdoorpvp_tf(); +void AddSC_outdoorpvp_zm(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddOutdoorPvPScripts() +{ + AddSC_outdoorpvp_ep(); + AddSC_outdoorpvp_hp(); + AddSC_outdoorpvp_na(); + AddSC_outdoorpvp_si(); + AddSC_outdoorpvp_tf(); + AddSC_outdoorpvp_zm(); +} diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.h b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.h index 237fee3283b..ebbccfd63cb 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.h +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.h @@ -132,11 +132,11 @@ class OPvPCapturePointTF : public OPvPCapturePoint public: OPvPCapturePointTF(OutdoorPvP* pvp, OutdoorPvPTF_TowerType type); - bool Update(uint32 diff); + bool Update(uint32 diff) override; - void ChangeState(); + void ChangeState() override; - void FillInitialWorldStates(WorldPacket & data); + void FillInitialWorldStates(WorldPacket & data) override; void UpdateTowerState(); @@ -151,16 +151,16 @@ class OutdoorPvPTF : public OutdoorPvP public: OutdoorPvPTF(); - bool SetupOutdoorPvP(); + bool SetupOutdoorPvP() override; - void HandlePlayerEnterZone(Player* player, uint32 zone); - void HandlePlayerLeaveZone(Player* player, uint32 zone); + void HandlePlayerEnterZone(Player* player, uint32 zone) override; + void HandlePlayerLeaveZone(Player* player, uint32 zone) override; - bool Update(uint32 diff); + bool Update(uint32 diff) override; - void FillInitialWorldStates(WorldPacket &data); + void FillInitialWorldStates(WorldPacket &data) override; - void SendRemoveWorldStates(Player* player); + void SendRemoveWorldStates(Player* player) override; uint32 GetAllianceTowersControlled() const; void SetAllianceTowersControlled(uint32 count); diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h b/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h index e71fbf79280..352e6f108ea 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h @@ -161,9 +161,9 @@ class OPvPCapturePointZM_Beacon : public OPvPCapturePoint public: OPvPCapturePointZM_Beacon(OutdoorPvP* pvp, ZM_BeaconType type); - void ChangeState(); + void ChangeState() override; - void FillInitialWorldStates(WorldPacket & data); + void FillInitialWorldStates(WorldPacket & data) override; void UpdateTowerState(); @@ -218,18 +218,18 @@ class OutdoorPvPZM : public OutdoorPvP public: OutdoorPvPZM(); - bool SetupOutdoorPvP(); + bool SetupOutdoorPvP() override; - void HandlePlayerEnterZone(Player* player, uint32 zone); - void HandlePlayerLeaveZone(Player* player, uint32 zone); + void HandlePlayerEnterZone(Player* player, uint32 zone) override; + void HandlePlayerLeaveZone(Player* player, uint32 zone) override; - bool Update(uint32 diff); + bool Update(uint32 diff) override; - void FillInitialWorldStates(WorldPacket &data); + void FillInitialWorldStates(WorldPacket &data) override; - void SendRemoveWorldStates(Player* player); + void SendRemoveWorldStates(Player* player) override; - void HandleKillImpl(Player* player, Unit* killed); + void HandleKillImpl(Player* player, Unit* killed) override; uint32 GetAllianceTowersControlled() const; void SetAllianceTowersControlled(uint32 count); diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index 7902c585509..3c651e10a1e 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -745,7 +745,7 @@ public: if (!Trigger) return; - Trigger->SetSpeed(MOVE_WALK, 3); + Trigger->SetSpeedRate(MOVE_WALK, 3); Trigger->SetWalk(true); Trigger->GetMotionMaster()->MovePoint(0, final.x, final.y, final.z); @@ -1524,7 +1524,7 @@ public: void BeginWalk() { me->SetWalk(false); - me->SetSpeed(MOVE_RUN, 1.0f); + me->SetSpeedRate(MOVE_RUN, 1.0f); me->GetMotionMaster()->MovePoint(0, AkamaWP[WalkCount].x, AkamaWP[WalkCount].y, AkamaWP[WalkCount].z); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp index 7e1215488e1..1a9074c2464 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp @@ -238,8 +238,8 @@ public: if (me->GetAuraCount(SPELL_SHADE_SOUL_CHANNEL_2) <= 3) { moveSpeed = (2.0f - (0.6f * me->GetAuraCount(SPELL_SHADE_SOUL_CHANNEL_2))); - me->SetSpeed(MOVE_WALK, moveSpeed / 2.5f); - me->SetSpeed(MOVE_RUN, (moveSpeed * 2) / 7); + me->SetSpeedRate(MOVE_WALK, moveSpeed / 2.5f); + me->SetSpeedRate(MOVE_RUN, (moveSpeed * 2) / 7); me->ClearUnitState(UNIT_STATE_ROOT); } else diff --git a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp index ae4d17bdad4..0999f1fcd6b 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp @@ -117,7 +117,7 @@ public: DummyEntryCheckPredicate pred; summons.DoAction(EVENT_VOLCANO, pred); events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE); - me->SetSpeed(MOVE_RUN, 1.2f); + me->SetSpeedRate(MOVE_RUN, 1.2f); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); } @@ -126,7 +126,7 @@ public: phase = PHASE_CHASE; events.ScheduleEvent(EVENT_VOLCANO, 5000, GCD_CAST, PHASE_CHASE); events.ScheduleEvent(EVENT_SWITCH_TARGET, 10000, 0, PHASE_CHASE); - me->SetSpeed(MOVE_RUN, 0.9f); + me->SetSpeedRate(MOVE_RUN, 0.9f); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); } diff --git a/src/server/scripts/Outland/CMakeLists.txt b/src/server/scripts/Outland/CMakeLists.txt deleted file mode 100644 index 55b0452fb0b..00000000000 --- a/src/server/scripts/Outland/CMakeLists.txt +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - Outland/zone_nagrand.cpp - Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h - Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp - Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp - Outland/HellfireCitadel/HellfireRamparts/instance_hellfire_ramparts.cpp - Outland/HellfireCitadel/HellfireRamparts/boss_omor_the_unscarred.cpp - Outland/HellfireCitadel/HellfireRamparts/boss_watchkeeper_gargolmar.cpp - Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp - Outland/HellfireCitadel/HellfireRamparts/hellfire_ramparts.h - Outland/HellfireCitadel/BloodFurnace/boss_the_maker.cpp - Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp - Outland/HellfireCitadel/BloodFurnace/blood_furnace.h - Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp - Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp - Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h - Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp - Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp - Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp - Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp - Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp - Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp - Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp - Outland/CoilfangReservoir/SteamVault/boss_hydromancer_thespia.cpp - Outland/CoilfangReservoir/SteamVault/boss_warlord_kalithresh.cpp - Outland/CoilfangReservoir/SteamVault/steam_vault.h - Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp - Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp - Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp - Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h - Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp - Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp - Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp - Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp - Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp - Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h - Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp - Outland/CoilfangReservoir/TheSlavePens/boss_rokmar_the_crackler.cpp - Outland/CoilfangReservoir/TheSlavePens/boss_quagmirran.cpp - Outland/CoilfangReservoir/TheUnderbog/instance_the_underbog.cpp - Outland/CoilfangReservoir/TheUnderbog/boss_hungarfen.cpp - Outland/CoilfangReservoir/TheUnderbog/boss_the_black_stalker.cpp - Outland/zone_shattrath_city.cpp - Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp - Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp - Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp - Outland/TempestKeep/Mechanar/mechanar.h - Outland/TempestKeep/Mechanar/boss_gatewatcher_gyrokill.cpp - Outland/TempestKeep/Mechanar/instance_mechanar.cpp - Outland/TempestKeep/Mechanar/boss_gatewatcher_ironhand.cpp - Outland/TempestKeep/Eye/the_eye.h - Outland/TempestKeep/Eye/instance_the_eye.cpp - Outland/TempestKeep/Eye/boss_void_reaver.cpp - Outland/TempestKeep/Eye/boss_astromancer.cpp - Outland/TempestKeep/Eye/boss_alar.cpp - Outland/TempestKeep/Eye/boss_kaelthas.cpp - Outland/TempestKeep/Eye/the_eye.cpp - Outland/TempestKeep/botanica/the_botanica.h - Outland/TempestKeep/botanica/instance_the_botanica.cpp - Outland/TempestKeep/botanica/boss_commander_sarannis.cpp - Outland/TempestKeep/botanica/boss_thorngrin_the_tender.cpp - Outland/TempestKeep/botanica/boss_high_botanist_freywinn.cpp - Outland/TempestKeep/botanica/boss_warp_splinter.cpp - Outland/TempestKeep/botanica/boss_laj.cpp - Outland/TempestKeep/arcatraz/boss_zereketh_the_unbound.cpp - Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp - Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp - Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp - Outland/TempestKeep/arcatraz/instance_arcatraz.cpp - Outland/TempestKeep/arcatraz/arcatraz.h - Outland/TempestKeep/arcatraz/arcatraz.cpp - Outland/Auchindoun/AuchenaiCrypts/boss_shirrak_the_dead_watcher.cpp - Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp - Outland/Auchindoun/AuchenaiCrypts/instance_auchenai_crypts.cpp - Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h - Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp - Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp - Outland/Auchindoun/ManaTombs/instance_mana_tombs.cpp - Outland/Auchindoun/ManaTombs/mana_tombs.h - Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp - Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp - Outland/Auchindoun/SethekkHalls/boss_anzu.cpp - Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp - Outland/Auchindoun/SethekkHalls/sethekk_halls.h - Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp - Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp - Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp - Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp - Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp - Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h - Outland/boss_doomwalker.cpp - Outland/zone_terokkar_forest.cpp - Outland/zone_hellfire_peninsula.cpp - Outland/boss_doomlord_kazzak.cpp - Outland/BlackTemple/boss_teron_gorefiend.cpp - Outland/BlackTemple/black_temple.h - Outland/BlackTemple/illidari_council.cpp - Outland/BlackTemple/boss_shade_of_akama.cpp - Outland/BlackTemple/boss_supremus.cpp - Outland/BlackTemple/black_temple.cpp - Outland/BlackTemple/boss_mother_shahraz.cpp - Outland/BlackTemple/instance_black_temple.cpp - Outland/BlackTemple/boss_reliquary_of_souls.cpp - Outland/BlackTemple/boss_warlord_najentus.cpp - Outland/BlackTemple/boss_gurtogg_bloodboil.cpp - Outland/BlackTemple/boss_illidan.cpp - Outland/zone_shadowmoon_valley.cpp - Outland/zone_blades_edge_mountains.cpp - Outland/GruulsLair/boss_high_king_maulgar.cpp - Outland/GruulsLair/boss_gruul.cpp - Outland/GruulsLair/gruuls_lair.h - Outland/GruulsLair/instance_gruuls_lair.cpp - Outland/zone_netherstorm.cpp - Outland/zone_zangarmarsh.cpp -) - -message(" -> Prepared: Outland") diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp index e24499c3aee..3ddf0fec416 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp @@ -585,8 +585,8 @@ public: void Reset() override { - me->SetSpeed(MOVE_WALK, 0.6f); // walk - me->SetSpeed(MOVE_RUN, 0.6f); // run + me->SetSpeedRate(MOVE_WALK, 0.6f); // walk + me->SetSpeedRate(MOVE_RUN, 0.6f); // run Initialize(); //search for nearest waypoint (up on stairs) diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp index 8d117f7c3ef..f72b9a8d2ca 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp @@ -244,7 +244,7 @@ public: CheckChannelers(); Initialize(); me->SetCanDualWield(true); - me->SetSpeed(MOVE_RUN, 2.0f, true); + me->SetSpeedRate(MOVE_RUN, 2.0f); me->SetDisplayId(MODEL_NIGHTELF); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp new file mode 100644 index 00000000000..89b7a8cbd46 --- /dev/null +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp @@ -0,0 +1,1052 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "CreatureTextMgr.h" +#include "LFGMgr.h" +#include "ScriptedGossip.h" +#include "ScriptedCreature.h" +#include "ScriptMgr.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" +#include "the_slave_pens.h" + +enum Spells +{ + // Ahune + SPELL_SYNCH_HEALTH = 46430, + SPELL_AHUNES_SHIELD = 45954, + SPELL_STAY_SUBMERGED = 46981, + SPELL_AHUNE_SELF_STUN = 46416, + SPELL_AHUNE_ACHIEVEMENT = 62043, + SPELL_AHUNE_SPANKY_HANDS = 46146, + SPELL_COLD_SLAP = 46145, + SPELL_RESURFACE = 46402, + SPELL_SUBMERGED = 37751, + SPELL_STAND = 37752, + + //Earther Ring Flamecaller + SPELL_FIND_OPENING_VISUAL = 45964, + SPELL_FIND_OPENING_BEAM_END = 46333, + SPELL_FIND_OPENING_TRIGGER = 46341, + SPELL_FIND_OPENING_CHANNEL = 46345, + SPELL_BONFIRE_VISUAL = 46339, + SPELL_FOUND_OPENING = 46421, + + //Ahune Bunny + SPELL_SUMMON_COLDWEAVE = 46143, + SPELL_SUMMON_FROSTWIND = 46382, + SPELL_SUMMON_HAILSTONE = 46176, + SPELL_SUMMONING_VISUAL_1 = 45937, + SPELL_SUMMONING_RHYME_AURA = 45926, + SPELL_SUMMONING_RHYME_BONFIRE = 45930, + SPELL_FORCE_WHISP_FLIGHT = 46603, + SPELL_SHAMANS_LOOK_FOR_OPENING = 46422, + SPELL_CLOSE_OPENING_VISUAL = 46236, + SPELL_ICE_BOMBARD = 46397, + SPELL_ICE_BOMBARDMENT_DEST_PICKER = 46398, + SPELL_ICE_BOMBARDMENT = 46396, + + // Ice Spear + SPELL_SUMMON_ICE_SPEAR_BUNNY = 46359, + SPELL_ICE_SPEAR_KNOCKBACK = 46360, + SPELL_SUMMON_ICE_SPEAR_GO = 46369, + SPELL_ICE_SPEAR_AURA = 46371, + SPELL_ICE_SPEAR_TARGET_PICKER = 46372, + SPELL_ICE_SPEAR_DELAY = 46878, + SPELL_ICE_SPEAR_VISUAL = 75498, + + // Slippery Floor + SPELL_SLIPPERY_FLOOR_AMBIENT = 46314, + SPELL_SLIPPERY_FLOOR_PERIODIC = 46320, + SPELL_SLIPPERY_FLOOR_SLIP = 45947, + + // Frozen Core + SPELL_SUICIDE = 45254, + SPELL_SUMMON_LOOT_MISSILE = 45941, + SPELL_FROZEN_CORE_GETS_HIT = 46810, + SPELL_MINION_DESPAWNER = 46843, + SPELL_GHOST_DISGUISE = 46786 +}; + +enum Emotes +{ + EMOTE_EARTHEN_ASSAULT = 0, + EMOTE_RETREAT = 0, + EMOTE_RESURFACE = 1 +}; + +enum Says +{ + SAY_PLAYER_TEXT_1 = 0, + SAY_PLAYER_TEXT_2 = 1, + SAY_PLAYER_TEXT_3 = 2 +}; + +enum Events +{ + EVENT_EMERGE = 1, + EVENT_INITIAL_EMERGE = 2, + EVENT_SYNCH_HEALTH = 3, + EVENT_FOUND_OPENING = 4, + EVENT_LOOKFOROPENING_0 = 5, + EVENT_LOOKFOROPENING_1 = 6, + EVENT_LOOKFOROPENING_2 = 7, + EVENT_SUMMON_HAILSTONE = 8, + EVENT_SUMMON_COLDWEAVE = 9, + EVENT_SUMMON_FROSTWIND = 10, + EVENT_SUMMON_AHUNE = 11, + EVENT_CLOSE_OPENING = 12, + EVENT_AHUNE_PHASE_ONE = 13, + EVENT_AHUNE_PHASE_TWO = 14, + EVENT_START_LOOKING_FOR_OPENING = 15, + EVENT_STOP_LOOKING_FOR_OPENING = 16 +}; + +enum Actions +{ + ACTION_START_EVENT = -2574500, + ACTION_AHUNE_RETREAT = -2586500, + ACTION_AHUNE_RESURFACE = -2586501, + ACTION_EMOTE_RESURFACE = -2575400 +}; + +enum Phases +{ + PHASE_ONE = 0, + PHASE_TWO = 1 +}; + +enum Points +{ + POINT_FLAMECALLER_000, + POINT_FLAMECALLER_001, + POINT_FLAMECALLER_002 +}; + +enum Misc +{ + MAX_FLAMECALLERS = 3 +}; + +Position const SummonPositions[] = +{ + { -99.1021f, -233.7526f, -1.22307f, 1.588250f }, // Ahune + { -98.0151f, -230.4555f, -1.21089f, 1.797689f }, // Frozen Core + { -143.172f, -147.6801f, -3.16113f, 4.852015f }, // Bonfire Bunny 000 + { -134.304f, -145.7803f, -1.70332f, 4.677482f }, // Bonfire Bunny 001 + { -125.036f, -144.2065f, -1.91660f, 4.991642f }, // Bonfire Bunny 002 + { -69.8121f, -162.4954f, -2.30451f, 1.710423f }, // Wisp Source Bunny + { -98.1029f, -230.7864f, -10.8085f, 1.448623f } // Wisp Dest Bunny +}; + +Position const FlameCallerSpots[] = +{ + { -145.2233f, -137.5543f, -1.59056f, 5.427049f }, + { -137.4383f, -136.4050f, -1.72384f, 5.336747f }, + { -129.0413f, -132.1494f, -2.09285f, 5.460842f } +}; + +class boss_ahune : public CreatureScript +{ +public: + boss_ahune() : CreatureScript("boss_ahune") { } + + struct boss_ahuneAI : public BossAI + { + boss_ahuneAI(Creature* creature) : BossAI(creature, DATA_AHUNE) + { + Initialize(); + } + + void Initialize() + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + events.ScheduleEvent(EVENT_INITIAL_EMERGE, 4); + events.ScheduleEvent(EVENT_SYNCH_HEALTH, 3000); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + if (Creature* ahuneBunny = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AHUNE_BUNNY))) + ahuneBunny->AI()->EnterEvadeMode(); + summons.DespawnAll(); + me->DespawnOrUnsummon(); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + instance->DoCastSpellOnPlayers(SPELL_AHUNE_ACHIEVEMENT); + + if (Creature* ahuneBunny = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AHUNE_BUNNY))) + me->Kill(ahuneBunny); + if (Creature* frozenCore = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FROZEN_CORE))) + me->Kill(frozenCore); + + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + if (!players.isEmpty()) + { + if (Group* group = players.begin()->GetSource()->GetGroup()) + if (group->isLFGGroup()) + sLFGMgr->FinishDungeon(group->GetGUID(), 286); + } + } + + void JustSummoned(Creature* summon) override + { + BossAI::JustSummoned(summon); + } + + void DoAction(int32 action) override + { + if (action == ACTION_AHUNE_RETREAT) + { + Submerge(); + events.ScheduleEvent(EVENT_EMERGE, 35000); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INITIAL_EMERGE: + DoCast(me, SPELL_STAND); + DoCast(me, SPELL_AHUNE_SPANKY_HANDS); + DoCast(me, SPELL_AHUNES_SHIELD); + break; + case EVENT_EMERGE: + Emerge(); + break; + case EVENT_SYNCH_HEALTH: + if (Creature* frozenCore = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FROZEN_CORE))) + DoCast(frozenCore, SPELL_SYNCH_HEALTH); + else + DoCast(me, SPELL_SUICIDE); + events.ScheduleEvent(EVENT_SYNCH_HEALTH, 3000); + break; + default: + break; + } + } + DoMeleeAttackIfReady(); + } + + void Emerge() + { + if (Creature* frozenCore = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FROZEN_CORE))) + frozenCore->AI()->DoAction(ACTION_AHUNE_RESURFACE); + + DoCast(me, SPELL_AHUNES_SHIELD); + me->RemoveAurasDueToSpell(SPELL_AHUNE_SELF_STUN); + me->RemoveAurasDueToSpell(SPELL_STAY_SUBMERGED); + DoCast(me, SPELL_STAND); + DoCast(me, SPELL_RESURFACE, true); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + events.ScheduleEvent(EVENT_SYNCH_HEALTH, 3000); + } + + void Submerge() + { + if (Creature* frozenCore = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FROZEN_CORE))) + frozenCore->AI()->DoAction(ACTION_AHUNE_RETREAT); + me->RemoveAurasDueToSpell(SPELL_AHUNES_SHIELD); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + DoCast(me, SPELL_SUBMERGED, true); + DoCast(me, SPELL_AHUNE_SELF_STUN, true); + DoCast(me, SPELL_STAY_SUBMERGED, true); + me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE); + events.Reset(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_ahuneAI>(creature); + } +}; + +class npc_frozen_core : public CreatureScript +{ +public: + npc_frozen_core() : CreatureScript("npc_frozen_core") { } + + struct npc_frozen_coreAI : public ScriptedAI + { + npc_frozen_coreAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + Initialize(); + } + + void Initialize() + { + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + DoCast(me, SPELL_FROZEN_CORE_GETS_HIT); + DoCast(me, SPELL_ICE_SPEAR_AURA); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + DoCast(SPELL_MINION_DESPAWNER); + if (Creature* ahune = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AHUNE))) + ahune->AI()->EnterEvadeMode(); + } + + void JustDied(Unit* /*killer*/) override + { + if (Creature* ahune = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AHUNE))) + me->Kill(ahune); + + DoCast(SPELL_SUMMON_LOOT_MISSILE); + DoCast(SPELL_MINION_DESPAWNER); + } + + void DoAction(int32 action) override + { + if (action == ACTION_AHUNE_RETREAT) + { + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC); + me->RemoveAurasDueToSpell(SPELL_ICE_SPEAR_AURA); + _events.ScheduleEvent(EVENT_SYNCH_HEALTH, 3000, 0, PHASE_TWO); + } + else if (action == ACTION_AHUNE_RESURFACE) + { + _events.Reset(); + DoCast(me, SPELL_ICE_SPEAR_AURA); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_DISABLE_MOVE); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SYNCH_HEALTH: + if (Creature* ahune = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AHUNE))) + DoCast(ahune, SPELL_SYNCH_HEALTH); + else + DoCast(me, SPELL_SUICIDE); + _events.ScheduleEvent(EVENT_SYNCH_HEALTH, 3000); + break; + default: + break; + } + } + } + + private: + InstanceScript* _instance; + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<npc_frozen_coreAI>(creature); + } +}; + +class npc_ahune_bunny : public CreatureScript +{ +public: + npc_ahune_bunny() : CreatureScript("npc_ahune_bunny") { } + + struct npc_ahune_bunnyAI : public ScriptedAI + { + npc_ahune_bunnyAI(Creature* creature) : ScriptedAI(creature), _summons(me) + { + _instance = me->GetInstanceScript(); + _submerged = false; + } + + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_AHUNE) + return; + + summon->SetInCombatWithZone(); + _summons.Summon(summon); + } + + void JustDied(Unit* /*killer*/) override + { + _summons.DespawnAll(); + ResetFlameCallers(); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + _EnterEvadeMode(); + _summons.DespawnAll(); + ResetFlameCallers(); + + me->SummonGameObject(GO_ICE_STONE, -69.90455f, -162.2449f, -2.366563f, 2.426008f, 0.0f, 0.0f, 0.9366722f, 0.3502074f, 0); + } + + void DoAction(int32 action) override + { + if (action == ACTION_START_EVENT) + { + DoCast(me, SPELL_SUMMONING_VISUAL_1); + me->SummonCreature(NPC_WHISP_SOURCE_BUNNY, SummonPositions[5], TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_WHISP_DEST_BUNNY, SummonPositions[6], TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_SHAMAN_BONFIRE_BUNNY_000, SummonPositions[2], TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_SHAMAN_BONFIRE_BUNNY_001, SummonPositions[3], TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_SHAMAN_BONFIRE_BUNNY_002, SummonPositions[4], TEMPSUMMON_MANUAL_DESPAWN); + + for (uint8 counter = 0; counter < MAX_FLAMECALLERS; ++counter) + if (Creature* flameCaller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FLAMECALLER_000 + counter))) + flameCaller->GetMotionMaster()->MovePoint(counter, FlameCallerSpots[counter].GetPosition()); + + _submerged = false; + _events.Reset(); + _events.SetPhase(PHASE_ONE); + _events.ScheduleEvent(EVENT_SUMMON_AHUNE, 10000); + _events.ScheduleEvent(EVENT_START_LOOKING_FOR_OPENING, 14000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_SUMMON_COLDWEAVE, 22000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_SUMMON_HAILSTONE, 14000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_AHUNE_PHASE_TWO, 108000, 0, PHASE_ONE); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_START_LOOKING_FOR_OPENING: + Talk(EMOTE_EARTHEN_ASSAULT); + for (uint8 counter = 0; counter < MAX_FLAMECALLERS; ++counter) + if (Creature* flamecaller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FLAMECALLER_000 + counter))) + DoCast(flamecaller, SPELL_SHAMANS_LOOK_FOR_OPENING, true); + break; + case EVENT_SUMMON_HAILSTONE: + DoCast(SPELL_SUMMON_HAILSTONE); + break; + case EVENT_SUMMON_COLDWEAVE: + DoCast(SPELL_SUMMON_COLDWEAVE); + DoCast(SPELL_SUMMON_COLDWEAVE); + _events.ScheduleEvent(EVENT_SUMMON_COLDWEAVE, 8000, 0, PHASE_ONE); + if (_submerged) + _events.ScheduleEvent(EVENT_SUMMON_FROSTWIND, 4000, 0, PHASE_ONE); + break; + case EVENT_SUMMON_FROSTWIND: + DoCast(SPELL_SUMMON_FROSTWIND); + break; + case EVENT_SUMMON_AHUNE: + if (TempSummon* ahune = me->SummonCreature(NPC_AHUNE, SummonPositions[0], TEMPSUMMON_DEAD_DESPAWN)) + { + ahune->SummonCreature(NPC_FROZEN_CORE, SummonPositions[1], TEMPSUMMON_CORPSE_DESPAWN); + ahune->SetInCombatWithZone(); + DoCast(ahune, SPELL_RESURFACE); + } + break; + case EVENT_CLOSE_OPENING: + if (Creature* flamecaller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FLAMECALLER_000))) + flamecaller->AI()->DoAction(ACTION_EMOTE_RESURFACE); + DoCast(SPELL_CLOSE_OPENING_VISUAL); + DoCast(me, SPELL_ICE_BOMBARD); + break; + case EVENT_AHUNE_PHASE_TWO: + if (Creature* flamecaller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FLAMECALLER_000))) + DoCast(flamecaller, SPELL_FOUND_OPENING); + if (Creature* ahune = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AHUNE))) + ahune->AI()->DoAction(ACTION_AHUNE_RETREAT); + _events.Reset(); + _events.SetPhase(PHASE_TWO); + _events.ScheduleEvent(EVENT_CLOSE_OPENING, 25000, 0, PHASE_TWO); + _events.ScheduleEvent(EVENT_AHUNE_PHASE_ONE, 35000, 0, PHASE_TWO); + break; + case EVENT_AHUNE_PHASE_ONE: + _submerged = true; + _events.Reset(); + _events.SetPhase(PHASE_ONE); + _events.ScheduleEvent(EVENT_SUMMON_COLDWEAVE, 8000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_SUMMON_HAILSTONE, 5000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_START_LOOKING_FOR_OPENING, 5000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_AHUNE_PHASE_TWO, 100000, 0, PHASE_ONE); + break; + default: + break; + } + } + } + + void ResetFlameCallers() + { + for (uint8 counter = 0; counter < MAX_FLAMECALLERS; ++counter) + if (Creature* flamecaller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FLAMECALLER_000 + counter))) + flamecaller->AI()->EnterEvadeMode(); + } + + private: + InstanceScript* _instance; + EventMap _events; + SummonList _summons; + bool _submerged; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<npc_ahune_bunnyAI>(creature); + } +}; + +class npc_earthen_ring_flamecaller : public CreatureScript +{ +public: + npc_earthen_ring_flamecaller() : CreatureScript("npc_earthen_ring_flamecaller") { } + + struct npc_earthen_ring_flamecallerAI : public ScriptedAI + { + npc_earthen_ring_flamecallerAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + _mySpot = 0; + } + + void Reset() override + { + _events.Reset(); + } + + void MovementInform(uint32 motionType, uint32 pointId) override + { + if (motionType != POINT_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_FLAMECALLER_000: + _mySpot = POINT_FLAMECALLER_000; + me->SetOrientation(FlameCallerSpots[_mySpot].GetOrientation()); + break; + case POINT_FLAMECALLER_001: + _mySpot = POINT_FLAMECALLER_001; + me->SetOrientation(FlameCallerSpots[_mySpot].GetOrientation()); + break; + case POINT_FLAMECALLER_002: + _mySpot = POINT_FLAMECALLER_002; + me->SetOrientation(FlameCallerSpots[_mySpot].GetOrientation()); + break; + default: + break; + } + + DoCast(me, SPELL_FIND_OPENING_CHANNEL); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + switch (spellInfo->Id) + { + case SPELL_SHAMANS_LOOK_FOR_OPENING: + _events.ScheduleEvent(EVENT_LOOKFOROPENING_0, 17000); + break; + case SPELL_FOUND_OPENING: + _events.ScheduleEvent(EVENT_FOUND_OPENING, 0); + break; + default: + break; + } + } + + void DoAction(int action) override + { + if (action == ACTION_EMOTE_RESURFACE) + Talk(EMOTE_RESURFACE); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_LOOKFOROPENING_0: + LookOpening(true, 0); + _events.ScheduleEvent(EVENT_LOOKFOROPENING_1, 26000); + break; + case EVENT_LOOKFOROPENING_1: + LookOpening(true, 1); + _events.ScheduleEvent(EVENT_LOOKFOROPENING_2, 25000); + break; + case EVENT_LOOKFOROPENING_2: + LookOpening(true, 2); + _events.ScheduleEvent(EVENT_STOP_LOOKING_FOR_OPENING, 27000); + break; + case EVENT_STOP_LOOKING_FOR_OPENING: + LookOpening(false, _mySpot); + break; + case EVENT_FOUND_OPENING: + Talk(EMOTE_RETREAT); + default: + break; + } + } + } + + void LookOpening(bool activate, uint8 spot) + { + if (_mySpot != spot) + return; + + if (Creature* bonfireBunny = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_BONFIRE_BUNNY_000 + spot))) + if (Creature* beamBunny = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_BEAM_BUNNY_000 + spot))) + { + if (activate) + { + DoCast(bonfireBunny, SPELL_FIND_OPENING_TRIGGER); + bonfireBunny->CastSpell(beamBunny, SPELL_FIND_OPENING_VISUAL, true); + } + else + { + DoCast(me, SPELL_FIND_OPENING_CHANNEL); + bonfireBunny->CastStop(); + beamBunny->RemoveAurasDueToSpell(SPELL_FIND_OPENING_BEAM_END); + } + } + } + + private: + EventMap _events; + InstanceScript* _instance; + uint8 _mySpot; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<npc_earthen_ring_flamecallerAI>(creature); + } +}; + +class go_ahune_ice_stone : public GameObjectScript +{ +public: + go_ahune_ice_stone() : GameObjectScript("go_ahune_ice_stone") { } + + bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 /*action*/) + { + InstanceScript* instance = go->GetInstanceScript(); + if (!instance) + return false; + + player->PlayerTalkClass->ClearMenus(); + + if (Creature* ahuneBunny = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_AHUNE_BUNNY))) + { + ahuneBunny->AI()->DoAction(ACTION_START_EVENT); + ahuneBunny->SetInCombatWithZone(); + } + if (Creature* luma = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_LUMA_SKYMOTHER))) + luma->CastSpell(player, SPELL_SUMMONING_RHYME_AURA, true); + player->CLOSE_GOSSIP_MENU(); + go->Delete(); + + return true; + } +}; + +// 46430 - Synch Health +class spell_ahune_synch_health : public SpellScriptLoader +{ +public: + spell_ahune_synch_health() : SpellScriptLoader("spell_ahune_synch_health") { } + + class spell_ahune_synch_health_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ahune_synch_health_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SYNCH_HEALTH)) + return false; + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + if (Unit* caster = GetCaster()) + target->SetHealth(caster->GetHealth()); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_ahune_synch_health_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_ahune_synch_health_SpellScript(); + } +}; + +// 45926 - Summoning Rhyme Aura +class spell_summoning_rhyme_aura : public SpellScriptLoader +{ +public: + spell_summoning_rhyme_aura() : SpellScriptLoader("spell_summoning_rhyme_aura") { } + + class spell_summoning_rhyme_aura_AuraScript : public AuraScript + { + PrepareAuraScript(spell_summoning_rhyme_aura_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_FORCE_WHISP_FLIGHT) || !sSpellMgr->GetSpellInfo(SPELL_SUMMONING_RHYME_BONFIRE)) + return false; + return true; + } + + void PeriodicTick(AuraEffect const* aurEff) + { + Creature* caster = GetCaster()->ToCreature(); + Player* player = GetTarget()->ToPlayer(); + + if (!caster || !player) + return; + + player->CastSpell(player, SPELL_FORCE_WHISP_FLIGHT); + + switch (aurEff->GetTickNumber()) + { + case 1: + sCreatureTextMgr->SendChat(caster, SAY_PLAYER_TEXT_1, NULL, CHAT_MSG_SAY, LANG_UNIVERSAL, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, player); + player->CastSpell(player, SPELL_SUMMONING_RHYME_BONFIRE, true); + break; + case 2: + sCreatureTextMgr->SendChat(caster, SAY_PLAYER_TEXT_2, NULL, CHAT_MSG_SAY, LANG_UNIVERSAL, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, player); + break; + case 3: + sCreatureTextMgr->SendChat(caster, SAY_PLAYER_TEXT_3, NULL, CHAT_MSG_SAY, LANG_UNIVERSAL, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, player); + Remove(); + break; + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_summoning_rhyme_aura_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_summoning_rhyme_aura_AuraScript(); + } +}; + +// 46878 - Summon Ice Spear Delayer +class spell_summon_ice_spear_delayer : public SpellScriptLoader +{ +public: + spell_summon_ice_spear_delayer() : SpellScriptLoader("spell_summon_ice_spear_delayer") { } + + class spell_summon_ice_spear_delayer_AuraScript : public AuraScript + { + PrepareAuraScript(spell_summon_ice_spear_delayer_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ICE_SPEAR_GO) || !sSpellMgr->GetSpellInfo(SPELL_ICE_SPEAR_KNOCKBACK)) + return false; + return true; + } + + void PeriodicTick(AuraEffect const* aurEff) + { + if (Creature* caster = GetCaster()->ToCreature()) + switch (aurEff->GetTickNumber()) + { + case 1: + caster->CastSpell(caster, SPELL_SUMMON_ICE_SPEAR_GO); + break; + case 3: + if (GameObject* spike = caster->FindNearestGameObject(GO_ICE_SPEAR, 3.0f)) + spike->UseDoorOrButton(); + caster->AI()->DoCastAOE(SPELL_ICE_SPEAR_KNOCKBACK, true); + break; + case 5: + if (GameObject* spike = caster->FindNearestGameObject(GO_ICE_SPEAR, 3.0f)) + spike->Delete(); + caster->DespawnOrUnsummon(); + break; + default: + break; + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_summon_ice_spear_delayer_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_summon_ice_spear_delayer_AuraScript(); + } +}; + +// 46371 - Ice Spear Control Aura +class spell_ice_spear_control_aura : public SpellScriptLoader +{ +public: + spell_ice_spear_control_aura() : SpellScriptLoader("spell_ice_spear_control_aura") { } + + class spell_ice_spear_control_aura_AuraScript : public AuraScript + { + PrepareAuraScript(spell_ice_spear_control_aura_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_ICE_SPEAR_TARGET_PICKER)) + return false; + return true; + } + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + if (Unit* caster = GetCaster()) + caster->CastSpell(caster, SPELL_ICE_SPEAR_TARGET_PICKER); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_ice_spear_control_aura_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_ice_spear_control_aura_AuraScript(); + } +}; + +// 46372 - Ice Spear Target Picker +class spell_ice_spear_target_picker : public SpellScriptLoader +{ +public: + spell_ice_spear_target_picker() : SpellScriptLoader("spell_ice_spear_target_picker") { } + + class spell_ice_spear_target_picker_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ice_spear_target_picker_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ICE_SPEAR_BUNNY)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_SUMMON_ICE_SPEAR_BUNNY, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_ice_spear_target_picker_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_ice_spear_target_picker_SpellScript(); + } +}; + +// 46320 - Spell Slippery Floor Periodic +class spell_slippery_floor_periodic : public SpellScriptLoader +{ +public: + spell_slippery_floor_periodic() : SpellScriptLoader("spell_slippery_floor_periodic") { } + + class spell_slippery_floor_periodic_SpellScript : public SpellScript + { + PrepareSpellScript(spell_slippery_floor_periodic_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SLIPPERY_FLOOR_SLIP)) + return false; + return true; + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + if (target->isMoving()) + target->CastSpell(target, SPELL_SLIPPERY_FLOOR_SLIP, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_slippery_floor_periodic_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_slippery_floor_periodic_SpellScript(); + } +}; + +// 46146 - Ahune Spanky Hands +class spell_ahune_spanky_hands : public SpellScriptLoader +{ +public: + spell_ahune_spanky_hands() : SpellScriptLoader("spell_ahune_spanky_hands") { } + + class spell_ahune_spanky_hands_AuraScript : public AuraScript + { + PrepareAuraScript(spell_ahune_spanky_hands_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_COLD_SLAP)) + return false; + return true; + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_COLD_SLAP, true); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_ahune_spanky_hands_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_ahune_spanky_hands_AuraScript(); + } +}; + +class spell_ahune_minion_despawner : public SpellScriptLoader +{ +public: + spell_ahune_minion_despawner() : SpellScriptLoader("spell_ahune_minion_despawner") { } + + class spell_ahune_minion_despawner_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ahune_minion_despawner_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (GetHitCreature()) + GetHitCreature()->DespawnOrUnsummon(); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_ahune_minion_despawner_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_ahune_minion_despawner_SpellScript(); + } +}; + +// 46398 - Spell Ice Bombardment Dest Picker +class spell_ice_bombardment_dest_picker : public SpellScriptLoader +{ +public: + spell_ice_bombardment_dest_picker() : SpellScriptLoader("spell_ice_bombardment_dest_picker") { } + + class spell_ice_bombardment_dest_picker_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ice_bombardment_dest_picker_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_ICE_BOMBARDMENT)) + return false; + return true; + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitDest()->GetPositionX(), GetHitDest()->GetPositionY(), GetHitDest()->GetPositionZ(), SPELL_ICE_BOMBARDMENT, true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_ice_bombardment_dest_picker_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_ice_bombardment_dest_picker_SpellScript(); + } +}; + +void AddSC_boss_ahune() +{ + new boss_ahune(); + new npc_frozen_core(); + new npc_earthen_ring_flamecaller(); + new npc_ahune_bunny(); + new go_ahune_ice_stone(); + new spell_ahune_synch_health(); + new spell_summoning_rhyme_aura(); + new spell_summon_ice_spear_delayer(); + new spell_ice_spear_control_aura(); + new spell_slippery_floor_periodic(); + new spell_ahune_spanky_hands(); + new spell_ahune_minion_despawner(); + new spell_ice_spear_target_picker(); + new spell_ice_bombardment_dest_picker(); +} diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp index 87a07cd1e5e..0fac7b5a39d 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp @@ -31,15 +31,125 @@ class instance_the_slave_pens : public InstanceMapScript public: instance_the_slave_pens() : InstanceMapScript(SPScriptName, 547) { } + struct instance_the_slave_pens_InstanceMapScript : public InstanceScript + { + instance_the_slave_pens_InstanceMapScript(Map* map) : InstanceScript(map) + { + counter = DATA_FLAMECALLER_000; + } + + void OnCreatureCreate(Creature* creature) override + { + switch (creature->GetEntry()) + { + case NPC_AHUNE: + AhuneGUID = creature->GetGUID(); + break; + case NPC_FROZEN_CORE: + FrozenCoreGUID = creature->GetGUID(); + break; + case NPC_AHUNE_LOC_BUNNY: + AhuneBunnyGUID = creature->GetGUID(); + break; + case NPC_SHAMAN_BONFIRE_BUNNY_000: + BonfireBunnyGUIDs[0] = creature->GetGUID(); + break; + case NPC_SHAMAN_BONFIRE_BUNNY_001: + BonfireBunnyGUIDs[1] = creature->GetGUID(); + break; + case NPC_SHAMAN_BONFIRE_BUNNY_002: + BonfireBunnyGUIDs[2] = creature->GetGUID(); + break; + case NPC_SHAMAN_BEAM_BUNNY_000: + BeamBunnyGUIDs[0] = creature->GetGUID(); + break; + case NPC_SHAMAN_BEAM_BUNNY_001: + BeamBunnyGUIDs[1] = creature->GetGUID(); + break; + case NPC_SHAMAN_BEAM_BUNNY_002: + BeamBunnyGUIDs[2] = creature->GetGUID(); + break; + case NPC_LUMA_SKYMOTHER: + LumaGUID = creature->GetGUID(); + break; + case NPC_EARTHEN_RING_FLAMECALLER: + SetGuidData(counter, creature->GetGUID()); + ++counter; + break; + default: + break; + } + } + + void SetGuidData(uint32 data, ObjectGuid guid) override + { + switch (data) + { + case DATA_FLAMECALLER_000: + FlameCallerGUIDs[0] = guid; + break; + case DATA_FLAMECALLER_001: + FlameCallerGUIDs[1] = guid; + break; + case DATA_FLAMECALLER_002: + FlameCallerGUIDs[2] = guid; + break; + default: + break; + } + } + + ObjectGuid GetGuidData(uint32 type) const override + { + switch (type) + { + case DATA_AHUNE: + return AhuneGUID; + case DATA_AHUNE_BUNNY: + return AhuneBunnyGUID; + case DATA_FROZEN_CORE: + return FrozenCoreGUID; + case DATA_FLAMECALLER_000: + return FlameCallerGUIDs[0]; + case DATA_FLAMECALLER_001: + return FlameCallerGUIDs[1]; + case DATA_FLAMECALLER_002: + return FlameCallerGUIDs[2]; + case DATA_BONFIRE_BUNNY_000: + return BonfireBunnyGUIDs[0]; + case DATA_BONFIRE_BUNNY_001: + return BonfireBunnyGUIDs[1]; + case DATA_BONFIRE_BUNNY_002: + return BonfireBunnyGUIDs[2]; + case DATA_BEAM_BUNNY_000: + return BeamBunnyGUIDs[0]; + case DATA_BEAM_BUNNY_001: + return BeamBunnyGUIDs[1]; + case DATA_BEAM_BUNNY_002: + return BeamBunnyGUIDs[2]; + case DATA_LUMA_SKYMOTHER: + return LumaGUID; + default: + break; + } + return ObjectGuid::Empty; + } + + protected: + ObjectGuid AhuneGUID; + ObjectGuid AhuneBunnyGUID; + ObjectGuid FrozenCoreGUID; + ObjectGuid LumaGUID; + ObjectGuid FlameCallerGUIDs[3]; + ObjectGuid BonfireBunnyGUIDs[3]; + ObjectGuid BeamBunnyGUIDs[3]; + uint8 counter; + }; + InstanceScript* GetInstanceScript(InstanceMap* map) const override { return new instance_the_slave_pens_InstanceMapScript(map); } - - struct instance_the_slave_pens_InstanceMapScript : public InstanceScript - { - instance_the_slave_pens_InstanceMapScript(Map* map) : InstanceScript(map) { } - }; }; void AddSC_instance_the_slave_pens() diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h index 95e6e44121e..544e98fd206 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h @@ -27,7 +27,43 @@ enum DataTypes { DATA_MENNU_THE_BETRAYER = 1, DATA_ROKMAR_THE_CRACKLER = 2, - DATA_QUAGMIRRAN = 3 + DATA_QUAGMIRRAN = 3, + DATA_AHUNE = 4, + DATA_AHUNE_BUNNY = 5, + DATA_FROZEN_CORE = 6, + DATA_FLAMECALLER_000 = 7, + DATA_FLAMECALLER_001 = 8, + DATA_FLAMECALLER_002 = 9, + DATA_BONFIRE_BUNNY_000 = 10, + DATA_BONFIRE_BUNNY_001 = 11, + DATA_BONFIRE_BUNNY_002 = 12, + DATA_BEAM_BUNNY_000 = 13, + DATA_BEAM_BUNNY_001 = 14, + DATA_BEAM_BUNNY_002 = 15, + DATA_LUMA_SKYMOTHER = 16 +}; + +enum CreaturesIds +{ + NPC_AHUNE = 25740, + NPC_FROZEN_CORE = 25865, + NPC_LUMA_SKYMOTHER = 25697, + NPC_AHUNE_LOC_BUNNY = 25745, + NPC_EARTHEN_RING_FLAMECALLER = 25754, + NPC_SHAMAN_BONFIRE_BUNNY_000 = 25971, + NPC_SHAMAN_BONFIRE_BUNNY_001 = 25972, + NPC_SHAMAN_BONFIRE_BUNNY_002 = 25973, + NPC_SHAMAN_BEAM_BUNNY_000 = 25964, + NPC_SHAMAN_BEAM_BUNNY_001 = 25965, + NPC_SHAMAN_BEAM_BUNNY_002 = 25966, + NPC_WHISP_DEST_BUNNY = 26120, + NPC_WHISP_SOURCE_BUNNY = 26121 +}; + +enum GameObjectIds +{ + GO_ICE_SPEAR = 188077, + GO_ICE_STONE = 187882 }; #endif // SLAVE_PENS_H diff --git a/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp b/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp index 4e20e6b0953..9b8220596c9 100644 --- a/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp @@ -372,7 +372,7 @@ class boss_vazruden_the_herald : public CreatureScript if (summon->GetEntry() == NPC_NAZAN) { summon->SetDisableGravity(true); - summon->SetSpeed(MOVE_FLIGHT, 2.5f); + summon->SetSpeedRate(MOVE_FLIGHT, 2.5f); if (victim) AttackStartNoMove(victim); } diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp index 4faab709e16..c29d560529d 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp @@ -109,7 +109,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript { removeAdds(); _Reset(); - me->SetSpeed(MOVE_RUN, 2); + me->SetSpeedRate(MOVE_RUN, 2); me->SetWalk(false); Initialize(); @@ -231,7 +231,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript { // stop bladedance InBlade = false; - me->SetSpeed(MOVE_RUN, 2); + me->SetSpeedRate(MOVE_RUN, 2); me->GetMotionMaster()->MoveChase(me->GetVictim()); Blade_Dance_Timer = 30000; Wait_Timer = 0; @@ -264,7 +264,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript Wait_Timer = 1; InBlade = true; Blade_Dance_Timer = 0; - me->SetSpeed(MOVE_RUN, 4); + me->SetSpeedRate(MOVE_RUN, 4); return; } else diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp index 102d567e810..20d96ecd29c 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp @@ -130,7 +130,7 @@ class boss_alar : public CreatureScript _Reset(); me->SetDisplayId(me->GetNativeDisplayId()); - me->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); + me->SetSpeedRate(MOVE_RUN, DefaultMoveSpeedRate); //me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); //me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10); me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); @@ -178,7 +178,7 @@ class boss_alar : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->AttackStop(); me->SetTarget(ObjectGuid::Empty); - me->SetSpeed(MOVE_RUN, 5.0f); + me->SetSpeedRate(MOVE_RUN, 5.0f); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(0, waypoint[5][0], waypoint[5][1], waypoint[5][2]); } @@ -261,7 +261,7 @@ class boss_alar : public CreatureScript case WE_REVIVE: me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND); me->SetFullHealth(); - me->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); + me->SetSpeedRate(MOVE_RUN, DefaultMoveSpeedRate); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoZoneInCombat(); DoCast(me, SPELL_REBIRTH, true); @@ -289,6 +289,7 @@ class boss_alar : public CreatureScript me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f); me->StopMoving(); WaitEvent = WE_LAND; + return; } else { diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index e5812390bd2..be27932e6b4 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -144,6 +144,7 @@ enum Spells // Thaladred the Darkener spells SPELL_PSYCHIC_BLOW = 10689, SPELL_SILENCE = 30225, + SPELL_REND = 36965, // Lord Sanguinar spells SPELL_BELLOWING_ROAR = 40636, // Grand Astromancer Capernian spells @@ -881,11 +882,13 @@ class boss_thaladred_the_darkener : public CreatureScript { Gaze_Timer = 100; Silence_Timer = 20000; + Rend_Timer = 4000; PsychicBlow_Timer = 10000; } uint32 Gaze_Timer; uint32 Silence_Timer; + uint32 Rend_Timer; uint32 PsychicBlow_Timer; void Reset() override @@ -939,6 +942,15 @@ class boss_thaladred_the_darkener : public CreatureScript else Silence_Timer -= diff; + //Rend_Timer + if (Rend_Timer <= diff) + { + DoCastVictim(SPELL_REND); + Rend_Timer = 4000; + } + else + Rend_Timer -= diff; + //PsychicBlow_Timer if (PsychicBlow_Timer <= diff) { diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp index 46388c3a185..edfa2aedf92 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,13 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Void_Reaver -SD%Complete: 90 -SDComment: Should reset if raid are out of room. -SDCategory: Tempest Keep, The Eye -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "the_eye.h" @@ -43,10 +35,17 @@ enum Spells SPELL_BERSERK = 27680 }; +enum Events +{ + EVENT_POUNDING = 1, + EVENT_ARCANE_ORB, + EVENT_KNOCK_AWAY, + EVENT_BERSERK +}; + class boss_void_reaver : public CreatureScript { public: - boss_void_reaver() : CreatureScript("boss_void_reaver") { } struct boss_void_reaverAI : public BossAI @@ -58,21 +57,9 @@ class boss_void_reaver : public CreatureScript void Initialize() { - Pounding_Timer = 15000; - ArcaneOrb_Timer = 3000; - KnockAway_Timer = 30000; - Berserk_Timer = 600000; - Enraged = false; } - uint32 Pounding_Timer; - uint32 ArcaneOrb_Timer; - uint32 KnockAway_Timer; - uint32 Berserk_Timer; - - bool Enraged; - void Reset() override { Initialize(); @@ -95,71 +82,84 @@ class boss_void_reaver : public CreatureScript { Talk(SAY_AGGRO); _EnterCombat(); + + events.ScheduleEvent(EVENT_POUNDING, 15000); + events.ScheduleEvent(EVENT_ARCANE_ORB, 3000); + events.ScheduleEvent(EVENT_KNOCK_AWAY, 30000); + events.ScheduleEvent(EVENT_BERSERK, 600000); } void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; - // Pounding - if (Pounding_Timer <= diff) - { - DoCastVictim(SPELL_POUNDING); - Talk(SAY_POUNDING); - Pounding_Timer = 15000; //cast time(3000) + cooldown time(12000) - } - else - Pounding_Timer -= diff; - // Arcane Orb - if (ArcaneOrb_Timer <= diff) - { - Unit* target = NULL; - std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); - std::vector<Unit*> target_list; - for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) - { - target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()); - if (!target) - continue; - // exclude pets & totems, 18 yard radius minimum - if (target->GetTypeId() == TYPEID_PLAYER && target->IsAlive() && !target->IsWithinDist(me, 18, false)) - target_list.push_back(target); - target = NULL; - } - if (!target_list.empty()) - target = *(target_list.begin() + rand32() % target_list.size()); - else - target = me->GetVictim(); + events.Update(diff); - if (target) - me->CastSpell(target, SPELL_ARCANE_ORB, false, NULL, NULL); - ArcaneOrb_Timer = 3000; - } - else - ArcaneOrb_Timer -= diff; - // Single Target knock back, reduces aggro - if (KnockAway_Timer <= diff) - { - DoCastVictim(SPELL_KNOCK_AWAY); - //Drop 25% aggro - if (DoGetThreat(me->GetVictim())) - DoModifyThreatPercent(me->GetVictim(), -25); - KnockAway_Timer = 30000; - } - else - KnockAway_Timer -= diff; - //Berserk - if (Berserk_Timer < diff && !Enraged) + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) { - DoCast(me, SPELL_BERSERK); - Enraged = true; + switch (eventId) + { + case EVENT_POUNDING: + DoCastVictim(SPELL_POUNDING); + Talk(SAY_POUNDING); + events.ScheduleEvent(EVENT_POUNDING, 15000); + break; + case EVENT_ARCANE_ORB: + { + Unit* target = NULL; + std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); + std::vector<Unit*> target_list; + for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr != t_list.end(); ++itr) + { + target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()); + if (!target) + continue; + // exclude pets & totems, 18 yard radius minimum + if (target->GetTypeId() == TYPEID_PLAYER && target->IsAlive() && !target->IsWithinDist(me, 18, false)) + target_list.push_back(target); + target = NULL; + } + + if (!target_list.empty()) + target = *(target_list.begin() + rand32() % target_list.size()); + else + target = me->GetVictim(); + + if (target) + me->CastSpell(target, SPELL_ARCANE_ORB, false, NULL, NULL); + + events.ScheduleEvent(EVENT_ARCANE_ORB, 3000); + break; + } + case EVENT_KNOCK_AWAY: + DoCastVictim(SPELL_KNOCK_AWAY); + // Drop 25% aggro + if (DoGetThreat(me->GetVictim())) + DoModifyThreatPercent(me->GetVictim(), -25); + + events.ScheduleEvent(EVENT_KNOCK_AWAY, 30000); + break; + case EVENT_BERSERK: + if (!Enraged) + { + DoCast(me, SPELL_BERSERK); + Enraged = true; + } + break; + default: + break; + } } - else - Berserk_Timer -= diff; DoMeleeAttackIfReady(); } + + private: + bool Enraged; }; CreatureAI* GetAI(Creature* creature) const override diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp index 3aa2674aec6..d45e17bd28d 100644 --- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp +++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp @@ -176,7 +176,7 @@ class npc_ragin_flames : public CreatureScript Initialize(); me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true); me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); - me->SetSpeed(MOVE_RUN, DUNGEON_MODE(0.5f, 0.7f)); + me->SetSpeedRate(MOVE_RUN, DUNGEON_MODE(0.5f, 0.7f)); } void EnterCombat(Unit* /*who*/) override diff --git a/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp b/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp index 856649c6c5e..e64c0fe9f5e 100644 --- a/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp +++ b/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp @@ -167,7 +167,7 @@ class boss_warp_splinter : public CreatureScript { Initialize(); - me->SetSpeed(MOVE_RUN, 0.7f, true); + me->SetSpeedRate(MOVE_RUN, 0.7f); } void EnterCombat(Unit* /*who*/) override diff --git a/src/server/scripts/Outland/outland_script_loader.cpp b/src/server/scripts/Outland/outland_script_loader.cpp new file mode 100644 index 00000000000..ed2c21da6c3 --- /dev/null +++ b/src/server/scripts/Outland/outland_script_loader.cpp @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This is where scripts' loading functions should be declared: +// Auchindoun - Auchenai Crypts +void AddSC_boss_shirrak_the_dead_watcher(); +void AddSC_boss_exarch_maladaar(); +void AddSC_instance_auchenai_crypts(); + +// Auchindoun - Mana Tombs +void AddSC_boss_pandemonius(); +void AddSC_boss_nexusprince_shaffar(); +void AddSC_instance_mana_tombs(); + +// Auchindoun - Sekketh Halls +void AddSC_boss_darkweaver_syth(); +void AddSC_boss_talon_king_ikiss(); +void AddSC_boss_anzu(); +void AddSC_instance_sethekk_halls(); + +// Auchindoun - Shadow Labyrinth +void AddSC_boss_ambassador_hellmaw(); +void AddSC_boss_blackheart_the_inciter(); +void AddSC_boss_grandmaster_vorpil(); +void AddSC_boss_murmur(); +void AddSC_instance_shadow_labyrinth(); + +// Black Temple +void AddSC_black_temple(); +void AddSC_boss_illidan(); +void AddSC_boss_shade_of_akama(); +void AddSC_boss_supremus(); +void AddSC_boss_gurtogg_bloodboil(); +void AddSC_boss_mother_shahraz(); +void AddSC_boss_reliquary_of_souls(); +void AddSC_boss_teron_gorefiend(); +void AddSC_boss_najentus(); +void AddSC_boss_illidari_council(); +void AddSC_instance_black_temple(); + +// Coilfang Reservoir - Serpent Shrine Cavern +void AddSC_boss_fathomlord_karathress(); +void AddSC_boss_hydross_the_unstable(); +void AddSC_boss_lady_vashj(); +void AddSC_boss_leotheras_the_blind(); +void AddSC_boss_morogrim_tidewalker(); +void AddSC_instance_serpentshrine_cavern(); +void AddSC_boss_the_lurker_below(); + +// Coilfang Reservoir - The Steam Vault +void AddSC_boss_hydromancer_thespia(); +void AddSC_boss_mekgineer_steamrigger(); +void AddSC_boss_warlord_kalithresh(); +void AddSC_instance_steam_vault(); + +// Coilfang Reservoir - The Slave Pens +void AddSC_instance_the_slave_pens(); +void AddSC_boss_mennu_the_betrayer(); +void AddSC_boss_rokmar_the_crackler(); +void AddSC_boss_quagmirran(); +void AddSC_boss_ahune(); + +// Coilfang Reservoir - The Underbog +void AddSC_instance_the_underbog(); +void AddSC_boss_hungarfen(); +void AddSC_boss_the_black_stalker(); + +// Gruul's Lair +void AddSC_boss_gruul(); +void AddSC_boss_high_king_maulgar(); +void AddSC_instance_gruuls_lair(); +void AddSC_boss_broggok(); //HC Blood Furnace +void AddSC_boss_kelidan_the_breaker(); +void AddSC_boss_the_maker(); +void AddSC_instance_blood_furnace(); +void AddSC_boss_magtheridon(); //HC Magtheridon's Lair +void AddSC_instance_magtheridons_lair(); +void AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls +void AddSC_boss_warbringer_omrogg(); +void AddSC_boss_warchief_kargath_bladefist(); +void AddSC_shattered_halls(); +void AddSC_instance_shattered_halls(); +void AddSC_boss_watchkeeper_gargolmar(); //HC Ramparts +void AddSC_boss_omor_the_unscarred(); +void AddSC_boss_vazruden_the_herald(); +void AddSC_instance_ramparts(); +void AddSC_arcatraz(); //TK Arcatraz +void AddSC_boss_zereketh_the_unbound(); +void AddSC_boss_dalliah_the_doomsayer(); +void AddSC_boss_wrath_scryer_soccothrates(); +void AddSC_boss_harbinger_skyriss(); +void AddSC_instance_arcatraz(); +void AddSC_boss_high_botanist_freywinn(); //TK Botanica +void AddSC_boss_laj(); +void AddSC_boss_warp_splinter(); +void AddSC_boss_thorngrin_the_tender(); +void AddSC_boss_commander_sarannis(); +void AddSC_instance_the_botanica(); +void AddSC_boss_alar(); //TK The Eye +void AddSC_boss_kaelthas(); +void AddSC_boss_void_reaver(); +void AddSC_boss_high_astromancer_solarian(); +void AddSC_instance_the_eye(); +void AddSC_the_eye(); +void AddSC_boss_gatewatcher_iron_hand(); //TK The Mechanar +void AddSC_boss_gatewatcher_gyrokill(); +void AddSC_boss_nethermancer_sepethrea(); +void AddSC_boss_pathaleon_the_calculator(); +void AddSC_boss_mechano_lord_capacitus(); +void AddSC_instance_mechanar(); + +void AddSC_blades_edge_mountains(); +void AddSC_boss_doomlordkazzak(); +void AddSC_boss_doomwalker(); +void AddSC_hellfire_peninsula(); +void AddSC_nagrand(); +void AddSC_netherstorm(); +void AddSC_shadowmoon_valley(); +void AddSC_shattrath_city(); +void AddSC_terokkar_forest(); +void AddSC_zangarmarsh(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddOutlandScripts() +{ + // Auchindoun - Auchenai Crypts + AddSC_boss_shirrak_the_dead_watcher(); + AddSC_boss_exarch_maladaar(); + AddSC_instance_auchenai_crypts(); + + // Auchindoun - Mana Tombs + AddSC_boss_pandemonius(); + AddSC_boss_nexusprince_shaffar(); + AddSC_instance_mana_tombs(); + + // Auchindoun - Sekketh Halls + AddSC_boss_darkweaver_syth(); + AddSC_boss_talon_king_ikiss(); + AddSC_boss_anzu(); + AddSC_instance_sethekk_halls(); + + // Auchindoun - Shadow Labyrinth + AddSC_boss_ambassador_hellmaw(); + AddSC_boss_blackheart_the_inciter(); + AddSC_boss_grandmaster_vorpil(); + AddSC_boss_murmur(); + AddSC_instance_shadow_labyrinth(); + + // Black Temple + AddSC_black_temple(); + AddSC_boss_illidan(); + AddSC_boss_shade_of_akama(); + AddSC_boss_supremus(); + AddSC_boss_gurtogg_bloodboil(); + AddSC_boss_mother_shahraz(); + AddSC_boss_reliquary_of_souls(); + AddSC_boss_teron_gorefiend(); + AddSC_boss_najentus(); + AddSC_boss_illidari_council(); + AddSC_instance_black_temple(); + + // Coilfang Reservoir - Serpent Shrine Cavern + AddSC_boss_fathomlord_karathress(); + AddSC_boss_hydross_the_unstable(); + AddSC_boss_lady_vashj(); + AddSC_boss_leotheras_the_blind(); + AddSC_boss_morogrim_tidewalker(); + AddSC_instance_serpentshrine_cavern(); + AddSC_boss_the_lurker_below(); + + // Coilfang Reservoir - The Steam Vault + AddSC_instance_steam_vault(); + AddSC_boss_hydromancer_thespia(); + AddSC_boss_mekgineer_steamrigger(); + AddSC_boss_warlord_kalithresh(); + + // Coilfang Reservoir - The Slave Pens + AddSC_instance_the_slave_pens(); + AddSC_boss_mennu_the_betrayer(); + AddSC_boss_rokmar_the_crackler(); + AddSC_boss_quagmirran(); + AddSC_boss_ahune(); + + // Coilfang Reservoir - The Underbog + AddSC_instance_the_underbog(); + AddSC_boss_hungarfen(); + AddSC_boss_the_black_stalker(); + + // Gruul's Lair + AddSC_boss_gruul(); + AddSC_boss_high_king_maulgar(); + AddSC_instance_gruuls_lair(); + AddSC_boss_broggok(); //HC Blood Furnace + AddSC_boss_kelidan_the_breaker(); + AddSC_boss_the_maker(); + AddSC_instance_blood_furnace(); + AddSC_boss_magtheridon(); //HC Magtheridon's Lair + AddSC_instance_magtheridons_lair(); + AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls + AddSC_boss_warbringer_omrogg(); + AddSC_boss_warchief_kargath_bladefist(); + AddSC_shattered_halls(); + AddSC_instance_shattered_halls(); + AddSC_boss_watchkeeper_gargolmar(); //HC Ramparts + AddSC_boss_omor_the_unscarred(); + AddSC_boss_vazruden_the_herald(); + AddSC_instance_ramparts(); + AddSC_arcatraz(); //TK Arcatraz + AddSC_boss_zereketh_the_unbound(); + AddSC_boss_dalliah_the_doomsayer(); + AddSC_boss_wrath_scryer_soccothrates(); + AddSC_boss_harbinger_skyriss(); + AddSC_instance_arcatraz(); + AddSC_boss_high_botanist_freywinn(); //TK Botanica + AddSC_boss_laj(); + AddSC_boss_warp_splinter(); + AddSC_boss_thorngrin_the_tender(); + AddSC_boss_commander_sarannis(); + AddSC_instance_the_botanica(); + AddSC_boss_alar(); //TK The Eye + AddSC_boss_kaelthas(); + AddSC_boss_void_reaver(); + AddSC_boss_high_astromancer_solarian(); + AddSC_instance_the_eye(); + AddSC_the_eye(); + AddSC_boss_gatewatcher_iron_hand(); //TK The Mechanar + AddSC_boss_gatewatcher_gyrokill(); + AddSC_boss_nethermancer_sepethrea(); + AddSC_boss_pathaleon_the_calculator(); + AddSC_boss_mechano_lord_capacitus(); + AddSC_instance_mechanar(); + + AddSC_blades_edge_mountains(); + AddSC_boss_doomlordkazzak(); + AddSC_boss_doomwalker(); + AddSC_hellfire_peninsula(); + AddSC_nagrand(); + AddSC_netherstorm(); + AddSC_shadowmoon_valley(); + AddSC_shattrath_city(); + AddSC_terokkar_forest(); + AddSC_zangarmarsh(); +} diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp index 404cdc7ceb2..668c484dd63 100644 --- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp +++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp @@ -159,7 +159,7 @@ public: else TC_LOG_ERROR("scripts", "TRINITY: npc_ancestral_wolf can not obtain owner or owner is not a player."); - creature->SetSpeed(MOVE_WALK, 1.5f); + creature->SetSpeedRate(MOVE_WALK, 1.5f); Reset(); } @@ -192,7 +192,7 @@ public: if (ryga->IsAlive() && !ryga->IsInCombat()) { ryga->SetWalk(true); - ryga->SetSpeed(MOVE_WALK, 1.5f); + ryga->SetSpeedRate(MOVE_WALK, 1.5f); ryga->GetMotionMaster()->MovePoint(0, 517.340698f, 3885.03975f, 190.455978f, true); Reset(); } @@ -778,7 +778,7 @@ public: me->AddAura(SPELL_JULES_THREATENS_AURA, me); me->SetCanFly(true); - me->SetSpeed(MOVE_RUN, 0.2f); + me->SetSpeedRate(MOVE_RUN, 0.2f); me->SetFacingTo(3.207566f); me->GetMotionMaster()->MoveJump(exorcismPos[2], 2.0f, 2.0f); @@ -798,7 +798,7 @@ public: break; case ACTION_JULES_MOVE_HOME: wpreached = false; - me->SetSpeed(MOVE_RUN, 1.0f); + me->SetSpeedRate(MOVE_RUN, 1.0f); me->GetMotionMaster()->MovePoint(11, exorcismPos[2]); events.CancelEvent(EVENT_SUMMON_SKULL); diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp index c734d000077..e4e51a98348 100644 --- a/src/server/scripts/Outland/zone_shattrath_city.cpp +++ b/src/server/scripts/Outland/zone_shattrath_city.cpp @@ -29,7 +29,6 @@ npc_salsalabim npc_shattrathflaskvendors npc_zephyr npc_kservant -npc_ishanah EndContentData */ #include "ScriptMgr.h" @@ -43,13 +42,15 @@ EndContentData */ ## npc_raliq_the_drunk ######*/ -#define GOSSIP_RALIQ "You owe Sim'salabim money. Hand them over or die!" - -enum Raliq +enum RaliqTheDrunk { - SPELL_UPPERCUT = 10966, - QUEST_CRACK_SKULLS = 10009, - FACTION_HOSTILE_RD = 45 + SAY_RALIQ_ATTACK = 0, + OPTION_ID_COLLECT_A_DEBT = 0, + FACTION_OGRE_HOSTILE = 45, + MENU_ID_COLLECT_A_DEBT = 7729, + NPC_TEXT_WUT_YOU_WANT = 9440, + CRACKIN_SOME_SKULLS = 10009, + SPELL_UPPERCUT = 10966 }; class npc_raliq_the_drunk : public CreatureScript @@ -63,7 +64,8 @@ public: if (action == GOSSIP_ACTION_INFO_DEF+1) { player->CLOSE_GOSSIP_MENU(); - creature->setFaction(FACTION_HOSTILE_RD); + creature->setFaction(FACTION_OGRE_HOSTILE); + creature->AI()->Talk(SAY_RALIQ_ATTACK, player); creature->AI()->AttackStart(player); } return true; @@ -71,10 +73,16 @@ public: bool OnGossipHello(Player* player, Creature* creature) override { - if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_RALIQ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(9440, creature->GetGUID()); + if (player->GetQuestStatus(CRACKIN_SOME_SKULLS) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM_DB(MENU_ID_COLLECT_A_DEBT, OPTION_ID_COLLECT_A_DEBT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(NPC_TEXT_WUT_YOU_WANT, creature->GetGUID()); + } + else + { + player->PlayerTalkClass->ClearMenus(); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + } return true; } @@ -125,16 +133,14 @@ public: enum Salsalabim { - // Factions - FACTION_HOSTILE_SA = 90, - FACTION_FRIENDLY_SA = 35, - - // Quests - QUEST_10004 = 10004, - - // Spells - SPELL_MAGNETIC_PULL = 31705 - + SAY_DEMONIC_AGGRO = 0, + OPTION_ID_ALTRUIS_SENT_ME = 0, + FACTION_FRIENDLY = 35, + FACTION_DEMON_HOSTILE = 90, + MENU_ID_ALTRUIS_SENT_ME = 7725, + NPC_TEXT_SAL_GROWLS_AT_YOU = 9435, + PATIENCE_AND_UNDERSTANDING = 10004, + SPELL_MAGNETIC_PULL = 31705 }; class npc_salsalabim : public CreatureScript @@ -142,13 +148,26 @@ class npc_salsalabim : public CreatureScript public: npc_salsalabim() : CreatureScript("npc_salsalabim") { } - bool OnGossipHello(Player* player, Creature* creature) override + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override { - if (player->GetQuestStatus(QUEST_10004) == QUEST_STATUS_INCOMPLETE) + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) { - creature->setFaction(FACTION_HOSTILE_SA); + player->CLOSE_GOSSIP_MENU(); + creature->setFaction(FACTION_DEMON_HOSTILE); + creature->AI()->Talk(SAY_DEMONIC_AGGRO, player); creature->AI()->AttackStart(player); } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) override + { + if (player->GetQuestStatus(PATIENCE_AND_UNDERSTANDING) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM_DB(MENU_ID_ALTRUIS_SENT_ME, OPTION_ID_ALTRUIS_SENT_ME, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(NPC_TEXT_SAL_GROWLS_AT_YOU, creature->GetGUID()); + } else { if (creature->IsQuestGiver()) @@ -187,7 +206,7 @@ public: { if (done_by->GetTypeId() == TYPEID_PLAYER && me->HealthBelowPctDamaged(20, damage)) { - done_by->ToPlayer()->GroupEventHappens(QUEST_10004, me); + done_by->ToPlayer()->GroupEventHappens(PATIENCE_AND_UNDERSTANDING, me); damage = 0; EnterEvadeMode(); } @@ -220,6 +239,19 @@ Purchase requires exalted reputation with Scryers/Aldor, Cenarion Expedition and ################################################## */ +enum FlaskVendors +{ + ALDOR_REPUTATION = 932, + SCRYERS_REPUTATION = 934, + THE_SHA_TAR_REPUTATION = 935, + CENARION_EXPEDITION_REP = 942, + NPC_TEXT_EXALTED_ALDOR = 11083, // (need to be exalted with Sha'tar, Cenarion Expedition and the Aldor) + NPC_TEXT_EXALTED_SCRYERS = 11084, // (need to be exalted with Sha'tar, Cenarion Expedition and the Scryers) + NPC_TEXT_WELCOME_NAME = 11085, // Access granted + ARCANIST_XORITH = 23483, // Scryer Apothecary + HALDOR_THE_COMPULSIVE = 23484 // Aldor Apothecary +}; + class npc_shattrathflaskvendors : public CreatureScript { public: @@ -236,31 +268,31 @@ public: bool OnGossipHello(Player* player, Creature* creature) override { - if (creature->GetEntry() == 23484) + if (creature->GetEntry() == HALDOR_THE_COMPULSIVE) { // Aldor vendor - if (creature->IsVendor() && (player->GetReputationRank(932) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED)) + if (creature->IsVendor() && (player->GetReputationRank(ALDOR_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(THE_SHA_TAR_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(CENARION_EXPEDITION_REP) == REP_EXALTED)) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(11085, creature->GetGUID()); + player->SEND_GOSSIP_MENU(NPC_TEXT_WELCOME_NAME, creature->GetGUID()); } else { - player->SEND_GOSSIP_MENU(11083, creature->GetGUID()); + player->SEND_GOSSIP_MENU(NPC_TEXT_EXALTED_ALDOR, creature->GetGUID()); } } - if (creature->GetEntry() == 23483) + if (creature->GetEntry() == ARCANIST_XORITH) { // Scryers vendor - if (creature->IsVendor() && (player->GetReputationRank(934) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED)) + if (creature->IsVendor() && (player->GetReputationRank(SCRYERS_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(THE_SHA_TAR_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(CENARION_EXPEDITION_REP) == REP_EXALTED)) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(11085, creature->GetGUID()); + player->SEND_GOSSIP_MENU(NPC_TEXT_WELCOME_NAME, creature->GetGUID()); } else { - player->SEND_GOSSIP_MENU(11084, creature->GetGUID()); + player->SEND_GOSSIP_MENU(NPC_TEXT_EXALTED_SCRYERS, creature->GetGUID()); } } @@ -272,7 +304,13 @@ public: # npc_zephyr ######*/ -#define GOSSIP_HZ "Take me to the Caverns of Time." +enum Zephyr +{ + OPTION_ID_TAKE_ME_TO_C_O_T = 0, + KEEPERS_OF_TIME_REPUTATION = 989, + MENU_ID_TAKE_ME_TO_C_O_T = 9205, + TELEPORT_CAVERNS_OF_TIME = 37778 +}; class npc_zephyr : public CreatureScript { @@ -283,15 +321,15 @@ public: { player->PlayerTalkClass->ClearMenus(); if (action == GOSSIP_ACTION_INFO_DEF+1) - player->CastSpell(player, 37778, false); + player->CastSpell(player, TELEPORT_CAVERNS_OF_TIME, false); return true; } bool OnGossipHello(Player* player, Creature* creature) override { - if (player->GetReputationRank(989) >= REP_REVERED) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HZ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + if (player->GetReputationRank(KEEPERS_OF_TIME_REPUTATION) >= REP_REVERED) + player->ADD_GOSSIP_ITEM_DB(MENU_ID_TAKE_ME_TO_C_O_T, OPTION_ID_TAKE_ME_TO_C_O_T, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); @@ -305,28 +343,29 @@ public: enum KServant { - SAY1 = 0, - WHISP1 = 1, - WHISP2 = 2, - WHISP3 = 3, - WHISP4 = 4, - WHISP5 = 5, - WHISP6 = 6, - WHISP7 = 7, - WHISP8 = 8, - WHISP9 = 9, - WHISP10 = 10, - WHISP11 = 11, - WHISP12 = 12, - WHISP13 = 13, - WHISP14 = 14, - WHISP15 = 15, - WHISP16 = 16, - WHISP17 = 17, - WHISP18 = 18, - WHISP19 = 19, - WHISP20 = 20, - WHISP21 = 21 + SAY1 = 0, + WHISP1 = 1, + WHISP2 = 2, + WHISP3 = 3, + WHISP4 = 4, + WHISP5 = 5, + WHISP6 = 6, + WHISP7 = 7, + WHISP8 = 8, + WHISP9 = 9, + WHISP10 = 10, + WHISP11 = 11, + WHISP12 = 12, + WHISP13 = 13, + WHISP14 = 14, + WHISP15 = 15, + WHISP16 = 16, + WHISP17 = 17, + WHISP18 = 18, + WHISP19 = 19, + WHISP20 = 20, + WHISP21 = 21, + CITY_OF_LIGHT = 10211 }; class npc_kservant : public CreatureScript @@ -417,7 +456,7 @@ public: break; case 56: Talk(WHISP21, player); - player->GroupEventHappens(10211, me); + player->GroupEventHappens(CITY_OF_LIGHT, me); break; } } @@ -429,7 +468,7 @@ public: return; Player* player = who->ToPlayer(); - if (player && player->GetQuestStatus(10211) == QUEST_STATUS_INCOMPLETE) + if (player && player->GetQuestStatus(CITY_OF_LIGHT) == QUEST_STATUS_INCOMPLETE) { float Radius = 10.0f; if (me->IsWithinDistInMap(who, Radius)) @@ -443,43 +482,6 @@ public: }; }; -/*###### -# npc_ishanah -######*/ - -#define ISANAH_GOSSIP_1 "Who are the Sha'tar?" -#define ISANAH_GOSSIP_2 "Isn't Shattrath a draenei city? Why do you allow others here?" - -class npc_ishanah : public CreatureScript -{ -public: - npc_ishanah() : CreatureScript("npc_ishanah") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - player->SEND_GOSSIP_MENU(9458, creature->GetGUID()); - else if (action == GOSSIP_ACTION_INFO_DEF+2) - player->SEND_GOSSIP_MENU(9459, creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, ISANAH_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, ISANAH_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - void AddSC_shattrath_city() { new npc_raliq_the_drunk(); @@ -487,5 +489,4 @@ void AddSC_shattrath_city() new npc_shattrathflaskvendors(); new npc_zephyr(); new npc_kservant(); - new npc_ishanah(); } diff --git a/src/server/scripts/Outland/zone_terokkar_forest.cpp b/src/server/scripts/Outland/zone_terokkar_forest.cpp index 06a8af947b7..4b757544d65 100644 --- a/src/server/scripts/Outland/zone_terokkar_forest.cpp +++ b/src/server/scripts/Outland/zone_terokkar_forest.cpp @@ -27,7 +27,6 @@ EndScriptData */ npc_unkor_the_ruthless npc_infested_root_walker npc_rotting_forest_rager -npc_netherweb_victim npc_floon npc_isla_starmane npc_slim @@ -47,13 +46,13 @@ EndContentData */ enum UnkorTheRuthless { - SAY_SUBMIT = 0, - - FACTION_HOSTILE = 45, - FACTION_FRIENDLY = 35, - QUEST_DONTKILLTHEFATONE = 9889, - - SPELL_PULVERIZE = 2676 + SAY_SUBMIT = 0, + REQUIRED_KILL_COUNT = 10, + FACTION_FRIENDLY = 35, + FACTION_HOSTILE = 45, + SPELL_PULVERIZE = 2676, + QUEST_DONTKILLTHEFATONE = 9889, + NPC_BOULDERFIST_INVADER = 18260 }; class npc_unkor_the_ruthless : public CreatureScript @@ -117,7 +116,7 @@ public: Player* groupie = itr->GetSource(); if (groupie && groupie->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE && - groupie->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, 18260) == 10) + groupie->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, NPC_BOULDERFIST_INVADER) == REQUIRED_KILL_COUNT) { groupie->AreaExploredOrEventHappens(QUEST_DONTKILLTHEFATONE); if (!CanDoQuest) @@ -126,7 +125,7 @@ public: } } else if (player->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE && - player->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, 18260) == 10) + player->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, NPC_BOULDERFIST_INVADER) == REQUIRED_KILL_COUNT) { player->AreaExploredOrEventHappens(QUEST_DONTKILLTHEFATONE); CanDoQuest = true; @@ -171,6 +170,11 @@ public: ## npc_infested_root_walker ######*/ +enum InfestedRootWalker +{ + SPELL_SUMMON_WOOD_MITES = 39130 +}; + class npc_infested_root_walker : public CreatureScript { public: @@ -194,7 +198,7 @@ public: if (me->GetHealth() <= damage) if (rand32() % 100 < 75) //Summon Wood Mites - DoCast(me, 39130, true); + DoCast(me, SPELL_SUMMON_WOOD_MITES, true); } }; }; @@ -202,6 +206,12 @@ public: /*###### ## npc_skywing ######*/ + +enum Skywing +{ + QUEST_SKYWING = 10898 +}; + class npc_skywing : public CreatureScript { public: @@ -226,7 +236,7 @@ public: switch (waypointId) { case 8: - player->AreaExploredOrEventHappens(10898); + player->AreaExploredOrEventHappens(QUEST_SKYWING); break; } } @@ -240,7 +250,7 @@ public: return; Player* player = who->ToPlayer(); - if (player && player->GetQuestStatus(10898) == QUEST_STATUS_INCOMPLETE) + if (player && player->GetQuestStatus(QUEST_SKYWING) == QUEST_STATUS_INCOMPLETE) if (me->IsWithinDistInMap(who, 10.0f)) Start(false, false, who->GetGUID()); } @@ -258,6 +268,11 @@ public: ## npc_rotting_forest_rager ######*/ +enum RottingForestRager +{ + SPELL_SUMMON_LOTS_OF_WOOD_MITES = 39134 +}; + class npc_rotting_forest_rager : public CreatureScript { public: @@ -280,67 +295,8 @@ public: if (done_by->GetTypeId() == TYPEID_PLAYER) if (me->GetHealth() <= damage) if (rand32() % 100 < 75) - //Summon Lots of Wood Mights - DoCast(me, 39134, true); - } - }; -}; - -/*###### -## npc_netherweb_victim -######*/ - -enum NetherwebVictim -{ - QUEST_TARGET = 22459 - //SPELL_FREE_WEBBED = 38950 -}; - -const uint32 netherwebVictims[6] = -{ - 18470, 16805, 21242, 18452, 22482, 21285 -}; - -class npc_netherweb_victim : public CreatureScript -{ -public: - npc_netherweb_victim() : CreatureScript("npc_netherweb_victim") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_netherweb_victimAI(creature); - } - - struct npc_netherweb_victimAI : public ScriptedAI - { - npc_netherweb_victimAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override { } - void EnterCombat(Unit* /*who*/) override { } - void MoveInLineOfSight(Unit* /*who*/) override { } - - - void JustDied(Unit* killer) override - { - Player* player = killer->ToPlayer(); - if (!player) - return; - - if (player->GetQuestStatus(10873) == QUEST_STATUS_INCOMPLETE) - { - if (rand32() % 100 < 25) - { - me->SummonCreature(QUEST_TARGET, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - player->KilledMonsterCredit(QUEST_TARGET); - } - else - me->SummonCreature(netherwebVictims[rand32() % 6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - - if (rand32() % 100 < 75) - me->SummonCreature(netherwebVictims[rand32() % 6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - - me->SummonCreature(netherwebVictims[rand32() % 6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - } + //Summon Lots of Wood Mites + DoCast(me, SPELL_SUMMON_LOTS_OF_WOOD_MITES, true); } }; }; @@ -349,19 +305,22 @@ public: ## npc_floon ######*/ -#define GOSSIP_FLOON1 "You owe Sim'salabim money. Hand them over or die!" -#define GOSSIP_FLOON2 "Hand over the money or die...again!" - enum Floon { - SAY_FLOON_ATTACK = 0, - - SPELL_SILENCE = 6726, - SPELL_FROSTBOLT = 9672, - SPELL_FROST_NOVA = 11831, - - FACTION_HOSTILE_FL = 1738, - QUEST_CRACK_SKULLS = 10009 + SAY_FLOON_ATTACK = 0, + OPTION_ID_PAY_UP_OR_DIE = 0, + OPTION_ID_COLLECT_A_DEBT = 0, + FACTION_HOSTILE_FLOON = 1738, + MENU_ID_PAY_UP_OR_DIE = 7731, + MENU_ID_COLLECT_A_DEBT = 7732, + GOSSIP_FLOON_STRANGE_SOUNDS = 9442, + GOSSIP_HE_ALREADY_KILLED_ME = 9443, + + SPELL_SILENCE = 6726, + SPELL_FROSTBOLT = 9672, + SPELL_FROST_NOVA = 11831, + + QUEST_CRACKIN_SOME_SKULLS = 10009 }; class npc_floon : public CreatureScript @@ -374,13 +333,13 @@ public: player->PlayerTalkClass->ClearMenus(); if (action == GOSSIP_ACTION_INFO_DEF) { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FLOON2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(9443, creature->GetGUID()); + player->ADD_GOSSIP_ITEM_DB(MENU_ID_PAY_UP_OR_DIE, OPTION_ID_PAY_UP_OR_DIE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(GOSSIP_HE_ALREADY_KILLED_ME, creature->GetGUID()); } if (action == GOSSIP_ACTION_INFO_DEF+1) { player->CLOSE_GOSSIP_MENU(); - creature->setFaction(FACTION_HOSTILE_FL); + creature->setFaction(FACTION_HOSTILE_FLOON); creature->AI()->Talk(SAY_FLOON_ATTACK, player); creature->AI()->AttackStart(player); } @@ -389,10 +348,10 @@ public: bool OnGossipHello(Player* player, Creature* creature) override { - if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FLOON1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + if (player->GetQuestStatus(QUEST_CRACKIN_SOME_SKULLS) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM_DB(MENU_ID_COLLECT_A_DEBT, OPTION_ID_COLLECT_A_DEBT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->SEND_GOSSIP_MENU(9442, creature->GetGUID()); + player->SEND_GOSSIP_MENU(GOSSIP_FLOON_STRANGE_SOUNDS, creature->GetGUID()); return true; } @@ -463,15 +422,16 @@ public: ######*/ enum IslaStarmaneData { - SAY_PROGRESS_1 = 0, - SAY_PROGRESS_2 = 1, - SAY_PROGRESS_3 = 2, - SAY_PROGRESS_4 = 3, - - QUEST_EFTW_H = 10052, - QUEST_EFTW_A = 10051, - GO_CAGE = 182794, - SPELL_CAT = 32447, + SAY_PROGRESS_1 = 0, + SAY_PROGRESS_2 = 1, + SAY_PROGRESS_3 = 2, + SAY_PROGRESS_4 = 3, + GO_DISTANCE = 10, + FACTION_ESCORTEE = 113, + ESCAPE_FROM_FIREWING_POINT_A = 10051, + ESCAPE_FROM_FIREWING_POINT_H = 10052, + SPELL_TRAVEL_FORM_CAT = 32447, + GO_CAGE = 182794 }; class npc_isla_starmane : public CreatureScript @@ -492,7 +452,7 @@ public: switch (waypointId) { case 0: - if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 10)) + if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, GO_DISTANCE)) Cage->SetGoState(GO_STATE_ACTIVE); break; case 2: @@ -507,16 +467,16 @@ public: case 29: Talk(SAY_PROGRESS_4, player); if (player->GetTeam() == ALLIANCE) - player->GroupEventHappens(QUEST_EFTW_A, me); + player->GroupEventHappens(ESCAPE_FROM_FIREWING_POINT_A, me); else if (player->GetTeam() == HORDE) - player->GroupEventHappens(QUEST_EFTW_H, me); + player->GroupEventHappens(ESCAPE_FROM_FIREWING_POINT_H, me); me->SetInFront(player); break; case 30: me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); break; case 31: - DoCast(me, SPELL_CAT); + DoCast(me, SPELL_TRAVEL_FORM_CAT); me->SetWalk(false); break; } @@ -532,19 +492,19 @@ public: if (Player* player = GetPlayerForEscort()) { if (player->GetTeam() == ALLIANCE) - player->FailQuest(QUEST_EFTW_A); + player->FailQuest(ESCAPE_FROM_FIREWING_POINT_A); else if (player->GetTeam() == HORDE) - player->FailQuest(QUEST_EFTW_H); + player->FailQuest(ESCAPE_FROM_FIREWING_POINT_H); } } }; bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override { - if (quest->GetQuestId() == QUEST_EFTW_H || quest->GetQuestId() == QUEST_EFTW_A) + if (quest->GetQuestId() == ESCAPE_FROM_FIREWING_POINT_H || quest->GetQuestId() == ESCAPE_FROM_FIREWING_POINT_A) { ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - creature->setFaction(113); + creature->setFaction(FACTION_ESCORTEE); } return true; } @@ -558,10 +518,20 @@ public: /*###### ## go_skull_pile ######*/ -#define GOSSIP_S_DARKSCREECHER_AKKARAI "Summon Darkscreecher Akkarai" -#define GOSSIP_S_KARROG "Summon Karrog" -#define GOSSIP_S_GEZZARAK_THE_HUNTRESS "Summon Gezzarak the Huntress" -#define GOSSIP_S_VAKKIZ_THE_WINDRAGER "Summon Vakkiz the Windrager" + +enum SkullPile +{ + OPTION_ID_GEZZARAK_THE_HUNTRESS = 0, + OPTION_ID_DARKSCREECHER_AKKARAI = 1, + OPTION_ID_KARROG = 2, + OPTION_ID_VAKKIZ_THE_WINDRAGER = 3, + GOSSIP_MENU_ID_SKULL_PILE = 8660, + ADVERSARIAL_BLOOD = 11885, + SUMMON_GEZZARAK_THE_HUNTRESS = 40632, + SUMMON_KARROG = 40640, + SUMMON_DARKSCREECHER_AKKARAI = 40642, + SUMMON_VAKKIZ_THE_WINDRAGER = 40644 +}; class go_skull_pile : public GameObjectScript { @@ -580,12 +550,12 @@ public: bool OnGossipHello(Player* player, GameObject* go) override { - if ((player->GetQuestStatus(11885) == QUEST_STATUS_INCOMPLETE) || player->GetQuestRewardStatus(11885)) + if ((player->GetQuestStatus(ADVERSARIAL_BLOOD) == QUEST_STATUS_INCOMPLETE) || player->GetQuestRewardStatus(ADVERSARIAL_BLOOD)) { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_DARKSCREECHER_AKKARAI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_KARROG, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_GEZZARAK_THE_HUNTRESS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_VAKKIZ_THE_WINDRAGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_GEZZARAK_THE_HUNTRESS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_DARKSCREECHER_AKKARAI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_KARROG, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_VAKKIZ_THE_WINDRAGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); } player->SEND_GOSSIP_MENU(go->GetGOInfo()->questgiver.gossipID, go->GetGUID()); @@ -597,16 +567,16 @@ public: switch (action) { case GOSSIP_ACTION_INFO_DEF + 1: - player->CastSpell(player, 40642, false); + player->CastSpell(player, SUMMON_GEZZARAK_THE_HUNTRESS, false); break; case GOSSIP_ACTION_INFO_DEF + 2: - player->CastSpell(player, 40640, false); + player->CastSpell(player, SUMMON_DARKSCREECHER_AKKARAI, false); break; case GOSSIP_ACTION_INFO_DEF + 3: - player->CastSpell(player, 40632, false); + player->CastSpell(player, SUMMON_KARROG, false); break; case GOSSIP_ACTION_INFO_DEF + 4: - player->CastSpell(player, 40644, false); + player->CastSpell(player, SUMMON_VAKKIZ_THE_WINDRAGER, false); break; } } @@ -618,7 +588,9 @@ public: enum Slim { - FACTION_CONSORTIUM = 933 + FACTION_CONSORTIUM = 933, + NPC_TEXT_NEITHER_SLIM_NOR_SHADY = 9895, + NPC_TEXT_I_SEE_YOU_ARE_A_FRIEND = 9896 }; class npc_slim : public CreatureScript @@ -640,10 +612,10 @@ public: if (creature->IsVendor() && player->GetReputationRank(FACTION_CONSORTIUM) >= REP_FRIENDLY) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(9896, creature->GetGUID()); + player->SEND_GOSSIP_MENU(NPC_TEXT_I_SEE_YOU_ARE_A_FRIEND, creature->GetGUID()); } else - player->SEND_GOSSIP_MENU(9895, creature->GetGUID()); + player->SEND_GOSSIP_MENU(NPC_TEXT_NEITHER_SLIM_NOR_SHADY, creature->GetGUID()); return true; } @@ -719,7 +691,6 @@ void AddSC_terokkar_forest() new npc_unkor_the_ruthless(); new npc_infested_root_walker(); new npc_rotting_forest_rager(); - new npc_netherweb_victim(); new npc_floon(); new npc_isla_starmane(); new go_skull_pile(); diff --git a/src/server/scripts/Pet/CMakeLists.txt b/src/server/scripts/Pet/CMakeLists.txt deleted file mode 100644 index 9ca268a9a3f..00000000000 --- a/src/server/scripts/Pet/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - Pet/pet_dk.cpp - Pet/pet_generic.cpp - Pet/pet_hunter.cpp - Pet/pet_mage.cpp - Pet/pet_priest.cpp - Pet/pet_shaman.cpp -) - -message(" -> Prepared: Pet") diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp index 80b3a00774b..113b14a0d54 100644 --- a/src/server/scripts/Pet/pet_dk.cpp +++ b/src/server/scripts/Pet/pet_dk.cpp @@ -103,8 +103,8 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript //! HACK: Creature's can't have MOVEMENTFLAG_FLYING // Fly Away me->SetCanFly(true); - me->SetSpeed(MOVE_FLIGHT, 0.75f, true); - me->SetSpeed(MOVE_RUN, 0.75f, true); + me->SetSpeedRate(MOVE_FLIGHT, 0.75f); + me->SetSpeedRate(MOVE_RUN, 0.75f); float x = me->GetPositionX() + 20 * std::cos(me->GetOrientation()); float y = me->GetPositionY() + 20 * std::sin(me->GetOrientation()); float z = me->GetPositionZ() + 40; diff --git a/src/server/scripts/Pet/pet_generic.cpp b/src/server/scripts/Pet/pet_generic.cpp index 35455bc474b..ff57bc0415c 100644 --- a/src/server/scripts/Pet/pet_generic.cpp +++ b/src/server/scripts/Pet/pet_generic.cpp @@ -20,10 +20,239 @@ * Scriptnames of files in this file should be prefixed with "npc_pet_gen_". */ + /* ContentData + npc_pet_gen_baby_blizzard_bear 100% Baby Blizzard Bear sits down occasionally + npc_pet_gen_egbert 100% Egbert run's around + npc_pet_gen_pandaren_monk 100% Pandaren Monk drinks and bows with you + npc_pet_gen_mojo 100% Mojo follows you when you kiss it + EndContentData */ + #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "PassiveAI.h" #include "Player.h" +enum BabyBlizzardBearMisc +{ + SPELL_BBB_PET_SIT = 61853, + EVENT_BBB_PET_SIT = 1, + EVENT_BBB_PET_SIT_INTER = 2 +}; + +class npc_pet_gen_baby_blizzard_bear : public CreatureScript +{ +public: + npc_pet_gen_baby_blizzard_bear() : CreatureScript("npc_pet_gen_baby_blizzard_bear") {} + + struct npc_pet_gen_baby_blizzard_bearAI : public NullCreatureAI + { + npc_pet_gen_baby_blizzard_bearAI(Creature* creature) : NullCreatureAI(creature) + { + if (Unit* owner = me->GetCharmerOrOwner()) + me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle()); + _events.ScheduleEvent(EVENT_BBB_PET_SIT, urandms(10, 30)); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + if (Unit* owner = me->GetCharmerOrOwner()) + if (!me->IsWithinDist(owner, 25.f)) + me->InterruptSpell(CURRENT_CHANNELED_SPELL); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BBB_PET_SIT: + me->CastSpell(me, SPELL_BBB_PET_SIT, false); + _events.ScheduleEvent(EVENT_BBB_PET_SIT_INTER, urandms(15, 30)); + break; + case EVENT_BBB_PET_SIT_INTER: + me->InterruptSpell(CURRENT_CHANNELED_SPELL); + _events.ScheduleEvent(EVENT_BBB_PET_SIT, urandms(10, 30)); + break; + default: + break; + } + } + } + + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_pet_gen_baby_blizzard_bearAI(creature); + } +}; + +enum EgbertMisc +{ + SPELL_EGBERT = 40669, + EVENT_RETURN = 3 +}; + +class npc_pet_gen_egbert : public CreatureScript +{ +public: + npc_pet_gen_egbert() : CreatureScript("npc_pet_gen_egbert") {} + + struct npc_pet_gen_egbertAI : public NullCreatureAI + { + npc_pet_gen_egbertAI(Creature* creature) : NullCreatureAI(creature) + { + if (Unit* owner = me->GetCharmerOrOwner()) + if (owner->GetMap()->GetEntry()->addon > 1) + me->SetCanFly(true); + } + + void Reset() override + { + _events.Reset(); + if (Unit* owner = me->GetCharmerOrOwner()) + me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle()); + } + + void EnterEvadeMode(EvadeReason why) override + { + if (!_EnterEvadeMode(why)) + return; + + Reset(); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + if (Unit* owner = me->GetCharmerOrOwner()) + { + if (!me->IsWithinDist(owner, 40.f)) + { + me->RemoveAura(SPELL_EGBERT); + me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle()); + } + } + + if (me->HasAura(SPELL_EGBERT)) + _events.ScheduleEvent(EVENT_RETURN, urandms(5, 20)); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_RETURN: + me->RemoveAura(SPELL_EGBERT); + break; + default: + break; + } + } + } + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_pet_gen_egbertAI(creature); + } +}; + +enum PandarenMonkMisc +{ + SPELL_PANDAREN_MONK = 69800, + EVENT_FOCUS = 1, + EVENT_EMOTE = 2, + EVENT_FOLLOW = 3, + EVENT_DRINK = 4 +}; + +class npc_pet_gen_pandaren_monk : public CreatureScript +{ +public: + npc_pet_gen_pandaren_monk() : CreatureScript("npc_pet_gen_pandaren_monk") {} + + struct npc_pet_gen_pandaren_monkAI : public NullCreatureAI + { + npc_pet_gen_pandaren_monkAI(Creature* creature) : NullCreatureAI(creature) { } + + void Reset() override + { + _events.Reset(); + _events.ScheduleEvent(EVENT_FOCUS, 1000); + } + + void EnterEvadeMode(EvadeReason why) override + { + if (!_EnterEvadeMode(why)) + return; + + Reset(); + } + + void ReceiveEmote(Player* /*player*/, uint32 emote) override + { + me->InterruptSpell(CURRENT_CHANNELED_SPELL); + me->StopMoving(); + + switch (emote) + { + case TEXT_EMOTE_BOW: + _events.ScheduleEvent(EVENT_FOCUS, 1000); + break; + case TEXT_EMOTE_DRINK: + _events.ScheduleEvent(EVENT_DRINK, 1000); + break; + } + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + if (Unit* owner = me->GetCharmerOrOwner()) + if (!me->IsWithinDist(owner, 30.f)) + me->InterruptSpell(CURRENT_CHANNELED_SPELL); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_FOCUS: + if (Unit* owner = me->GetCharmerOrOwner()) + me->SetFacingToObject(owner); + _events.ScheduleEvent(EVENT_EMOTE, 1000); + break; + case EVENT_EMOTE: + me->HandleEmoteCommand(EMOTE_ONESHOT_BOW); + _events.ScheduleEvent(EVENT_FOLLOW, 1000); + break; + case EVENT_FOLLOW: + if (Unit* owner = me->GetCharmerOrOwner()) + me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + break; + case EVENT_DRINK: + me->CastSpell(me, SPELL_PANDAREN_MONK, false); + break; + default: + break; + } + } + } + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_pet_gen_pandaren_monkAI(creature); + } +}; + enum Mojo { SAY_MOJO = 0, @@ -89,5 +318,8 @@ class npc_pet_gen_mojo : public CreatureScript void AddSC_generic_pet_scripts() { + new npc_pet_gen_baby_blizzard_bear(); + new npc_pet_gen_egbert(); + new npc_pet_gen_pandaren_monk(); new npc_pet_gen_mojo(); } diff --git a/src/server/scripts/Pet/pet_script_loader.cpp b/src/server/scripts/Pet/pet_script_loader.cpp new file mode 100644 index 00000000000..c3c0079fd46 --- /dev/null +++ b/src/server/scripts/Pet/pet_script_loader.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This is where scripts' loading functions should be declared: +void AddSC_deathknight_pet_scripts(); +void AddSC_generic_pet_scripts(); +void AddSC_hunter_pet_scripts(); +void AddSC_mage_pet_scripts(); +void AddSC_priest_pet_scripts(); +void AddSC_shaman_pet_scripts(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddPetScripts() +{ + AddSC_deathknight_pet_scripts(); + AddSC_generic_pet_scripts(); + AddSC_hunter_pet_scripts(); + AddSC_mage_pet_scripts(); + AddSC_priest_pet_scripts(); + AddSC_shaman_pet_scripts(); +} diff --git a/src/server/scripts/ScriptLoader.cpp.in.cmake b/src/server/scripts/ScriptLoader.cpp.in.cmake new file mode 100644 index 00000000000..33c336a9a93 --- /dev/null +++ b/src/server/scripts/ScriptLoader.cpp.in.cmake @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This file was created automatically from your script configuration! +// Use CMake to reconfigure this file, never change it on your own! + +#cmakedefine TRINITY_IS_DYNAMIC_SCRIPTLOADER + +#include "Define.h" +#include <vector> +#include <string> + +@TRINITY_SCRIPTS_FORWARD_DECL@ +#ifdef TRINITY_IS_DYNAMIC_SCRIPTLOADER +# include "revision_data.h" +# define TC_SCRIPT_API TC_API_EXPORT +extern "C" { + +/// Exposed in script modules to return the script module revision hash. +TC_SCRIPT_API char const* GetScriptModuleRevisionHash() +{ + return _HASH; +} + +/// Exposed in script module to return the name of the script module +/// contained in this shared library. +TC_SCRIPT_API char const* GetScriptModule() +{ + return "@TRINITY_CURRENT_SCRIPT_PROJECT@"; +} + +#else +# include "ScriptLoader.h" +# define TC_SCRIPT_API +#endif + +/// Exposed in script modules to register all scripts to the ScriptMgr. +TC_SCRIPT_API void AddScripts() +{ +@TRINITY_SCRIPTS_INVOKE@} + +/// Exposed in script modules to get the build directive of the module. +TC_SCRIPT_API char const* GetBuildDirective() +{ + return _BUILD_DIRECTIVE; +} + +#ifdef TRINITY_IS_DYNAMIC_SCRIPTLOADER +} // extern "C" +#endif diff --git a/src/server/scripts/ScriptLoader.h b/src/server/scripts/ScriptLoader.h new file mode 100644 index 00000000000..57b62df22d1 --- /dev/null +++ b/src/server/scripts/ScriptLoader.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SC_SCRIPTLOADER_H +#define SC_SCRIPTLOADER_H + +void AddScripts(); + +#endif diff --git a/src/server/scripts/PrecompiledHeaders/ScriptPCH.cpp b/src/server/scripts/ScriptPCH.cpp index 41fecf3c60d..41fecf3c60d 100644 --- a/src/server/scripts/PrecompiledHeaders/ScriptPCH.cpp +++ b/src/server/scripts/ScriptPCH.cpp diff --git a/src/server/scripts/PrecompiledHeaders/ScriptPCH.h b/src/server/scripts/ScriptPCH.h index 1cd25309055..1cd25309055 100644 --- a/src/server/scripts/PrecompiledHeaders/ScriptPCH.h +++ b/src/server/scripts/ScriptPCH.h diff --git a/src/server/scripts/Spells/CMakeLists.txt b/src/server/scripts/Spells/CMakeLists.txt deleted file mode 100644 index 7434d98cf49..00000000000 --- a/src/server/scripts/Spells/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - Spells/spell_shaman.cpp - Spells/spell_hunter.cpp - Spells/spell_rogue.cpp - Spells/spell_druid.cpp - Spells/spell_dk.cpp - Spells/spell_quest.cpp - Spells/spell_warrior.cpp - Spells/spell_generic.cpp - Spells/spell_warlock.cpp - Spells/spell_priest.cpp - Spells/spell_mage.cpp - Spells/spell_paladin.cpp - Spells/spell_item.cpp - Spells/spell_holiday.cpp - Spells/spell_pet.cpp -) - -message(" -> Prepared: Spells") diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 3cea620559a..724019a1b19 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -22,7 +22,7 @@ */ #include "Player.h" -#include "UnitAI.h" +#include "PlayerAI.h" #include "ScriptMgr.h" #include "SpellScript.h" #include "SpellAuraEffects.h" @@ -65,8 +65,6 @@ enum DeathKnightSpells SPELL_DK_UNHOLY_PRESENCE_TRIGGERED = 49772, SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189, SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284, - SPELL_DK_RAISE_ALLY_INITIAL = 61999, - SPELL_DK_RAISE_ALLY = 46619, SPELL_DK_GHOUL_THRASH = 47480 }; @@ -228,7 +226,7 @@ class spell_dk_anti_magic_zone : public SpellScriptLoader void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) { - SpellInfo const* talentSpell = sSpellMgr->EnsureSpellInfo(SPELL_DK_ANTI_MAGIC_SHELL_TALENT); + SpellInfo const* talentSpell = sSpellMgr->AssertSpellInfo(SPELL_DK_ANTI_MAGIC_SHELL_TALENT); amount = talentSpell->Effects[EFFECT_0].CalcValue(GetCaster()); if (Player* player = GetCaster()->ToPlayer()) amount += int32(2 * player->GetTotalAttackPowerValue(BASE_ATTACK)); @@ -1636,7 +1634,7 @@ class spell_dk_will_of_the_necropolis : public SpellScriptLoader { // min pct of hp is stored in effect 0 of talent spell uint8 rank = GetSpellInfo()->GetRank(); - SpellInfo const* talentProto = sSpellMgr->EnsureSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank)); + SpellInfo const* talentProto = sSpellMgr->AssertSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank)); int32 remainingHp = int32(GetTarget()->GetHealth() - dmgInfo.GetDamage()); int32 minHp = int32(GetTarget()->CountPctFromMaxHealth(talentProto->Effects[EFFECT_0].CalcValue(GetCaster()))); @@ -1733,36 +1731,39 @@ public: { PrepareSpellScript(spell_dk_raise_ally_initial_SpellScript); - bool Validate(SpellInfo const* /*spellInfo*/) override + bool Validate(SpellInfo const* spellInfo) override { - if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY_INITIAL)) + if (!sSpellMgr->GetSpellInfo(uint32(spellInfo->Effects[EFFECT_0].CalcValue()))) return false; return true; } + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + SpellCastResult CheckCast() { - // Raise Ally cannot be casted on alive players Unit* target = GetExplTargetUnit(); if (!target) return SPELL_FAILED_NO_VALID_TARGETS; if (target->IsAlive()) return SPELL_FAILED_TARGET_NOT_DEAD; - if (Player* playerCaster = GetCaster()->ToPlayer()) - if (playerCaster->InArena()) - return SPELL_FAILED_NOT_IN_ARENA; if (target->IsGhouled()) return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - return SPELL_CAST_OK; } void HandleDummy(SpellEffIndex /*effIndex*/) { - Player* caster = GetCaster()->ToPlayer(); - Player* target = GetHitPlayer(); - if (caster && target) - caster->SendGhoulResurrectRequest(target); + if (Player* target = GetHitPlayer()) + { + if (target->IsResurrectRequested()) // already have one active request + return; + target->SetResurrectRequestData(GetCaster(), 0, 0, uint32(GetEffectValue())); + GetSpell()->SendResurrectRequest(target); + } } void Register() override @@ -1785,12 +1786,8 @@ class player_ghoulAI : public PlayerAI void UpdateAI(uint32 /*diff*/) override { - if (Creature* ghoul = ObjectAccessor::GetCreature(*me, _ghoulGUID)) - { - if (!ghoul->IsAlive()) - me->RemoveAura(SPELL_DK_RAISE_ALLY); - } - else + Creature* ghoul = ObjectAccessor::GetCreature(*me, _ghoulGUID); + if (!ghoul || !ghoul->IsAlive()) me->RemoveAura(SPELL_DK_RAISE_ALLY); } @@ -1799,28 +1796,25 @@ class player_ghoulAI : public PlayerAI }; // 46619 - Raise Ally +#define DkRaiseAllyScriptName "spell_dk_raise_ally" class spell_dk_raise_ally : public SpellScriptLoader { public: - spell_dk_raise_ally() : SpellScriptLoader("spell_dk_raise_ally") { } + spell_dk_raise_ally() : SpellScriptLoader(DkRaiseAllyScriptName) { } class spell_dk_raise_ally_SpellScript : public SpellScript { PrepareSpellScript(spell_dk_raise_ally_SpellScript); - bool Validate(SpellInfo const* /*spellInfo*/) override + bool Load() override { - if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY)) - return false; - return true; + return GetCaster()->GetTypeId() == TYPEID_PLAYER; } void SendText() { - Player* caster = GetCaster()->ToPlayer(); - Unit* original = GetOriginalCaster(); - if (caster && original) - original->Whisper(TEXT_RISE_ALLY, caster, true); + if (Unit* original = GetOriginalCaster()) + original->Whisper(TEXT_RISE_ALLY, GetCaster()->ToPlayer(), true); } void HandleSummon(SpellEffIndex effIndex) @@ -1839,9 +1833,8 @@ public: SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(829); uint32 duration = uint32(GetSpellInfo()->GetDuration()); - Position pos = caster->GetPosition(); - TempSummon* summon = originalCaster->GetMap()->SummonCreature(entry, pos, properties, duration, originalCaster, GetSpellInfo()->Id); + TempSummon* summon = originalCaster->GetMap()->SummonCreature(entry, *GetHitDest(), properties, duration, originalCaster, GetSpellInfo()->Id); if (!summon) return; @@ -1868,15 +1861,25 @@ public: // SMSG_POWER_UPDATE is sent summon->SetMaxPower(POWER_ENERGY, 100); - if (Player* player = GetCaster()->ToPlayer()) - player->SetGhoulResurrectGhoulGUID(summon->GetGUID()); + _ghoulGuid = summon->GetGUID(); + } + + void SetGhoul(SpellEffIndex /*effIndex*/) + { + if (Aura* aura = GetHitAura()) + if (spell_dk_raise_ally_AuraScript* script = dynamic_cast<spell_dk_raise_ally_AuraScript*>(aura->GetScriptByName(DkRaiseAllyScriptName))) + script->SetGhoulGuid(_ghoulGuid); } void Register() override { AfterHit += SpellHitFn(spell_dk_raise_ally_SpellScript::SendText); OnEffectHit += SpellEffectFn(spell_dk_raise_ally_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); + OnEffectHitTarget += SpellEffectFn(spell_dk_raise_ally_SpellScript::SetGhoul, EFFECT_1, SPELL_EFFECT_APPLY_AURA); } + + private: + ObjectGuid _ghoulGuid; }; SpellScript* GetSpellScript() const override @@ -1895,45 +1898,45 @@ public: oldAIState = false; } + void SetGhoulGuid(ObjectGuid guid) + { + ghoulGuid = guid; + } + private: - bool Validate(SpellInfo const* /*spellInfo*/) override + bool Load() override { - if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY)) - return false; - return true; + return GetUnitOwner()->GetTypeId() == TYPEID_PLAYER; } void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Player* player = GetTarget()->ToPlayer(); - if (!player || player->GetGhoulResurrectGhoulGUID().IsEmpty()) + if (ghoulGuid.IsEmpty()) return; - oldAI = player->GetAI(); + oldAI = player->AI(); oldAIState = player->IsAIEnabled; - player->SetAI(new player_ghoulAI(player, player->GetGhoulResurrectGhoulGUID())); + player->SetAI(new player_ghoulAI(player, ghoulGuid)); player->IsAIEnabled = true; } void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Player* player = GetTarget()->ToPlayer(); - if (!player) - return; player->IsAIEnabled = oldAIState; - UnitAI* thisAI = player->GetAI(); + PlayerAI* thisAI = player->AI(); player->SetAI(oldAI); delete thisAI; // Dismiss ghoul if necessary - if (Creature* ghoul = ObjectAccessor::GetCreature(*player, player->GetGhoulResurrectGhoulGUID())) + if (Creature* ghoul = ObjectAccessor::GetCreature(*player, ghoulGuid)) { - ghoul->RemoveCharmedBy(nullptr); + ghoul->RemoveCharmedBy(player); ghoul->DespawnOrUnsummon(1000); } - player->SetGhoulResurrectGhoulGUID(ObjectGuid::Empty); player->RemoveAura(SPELL_GHOUL_FRENZY); } @@ -1943,7 +1946,8 @@ public: AfterEffectRemove += AuraEffectRemoveFn(spell_dk_raise_ally_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } - UnitAI* oldAI; + ObjectGuid ghoulGuid; + PlayerAI* oldAI; bool oldAIState; }; @@ -1965,7 +1969,7 @@ public: bool Validate(SpellInfo const* /*spellInfo*/) override { - if (!sSpellMgr->GetSpellInfo(SPELL_DK_GHOUL_THRASH)) + if (!sSpellMgr->GetSpellInfo(SPELL_GHOUL_FRENZY)) return false; return true; } diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 7b853c36075..c088ae07e66 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -991,6 +991,37 @@ class spell_dru_swift_flight_passive : public SpellScriptLoader } }; +// -33943 - Flight Form +class spell_dru_flight_form : public SpellScriptLoader +{ + public: + spell_dru_flight_form() : SpellScriptLoader("spell_dru_flight_form") { } + + class spell_dru_flight_form_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dru_flight_form_SpellScript); + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (caster->IsInDisallowedMountForm()) + return SPELL_FAILED_NOT_SHAPESHIFT; + + return SPELL_CAST_OK; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_dru_flight_form_SpellScript::CheckCast); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_dru_flight_form_SpellScript(); + } +}; + // -5217 - Tiger's Fury class spell_dru_tiger_s_fury : public SpellScriptLoader { @@ -1196,6 +1227,7 @@ void AddSC_druid_spell_scripts() new spell_dru_starfall_dummy(); new spell_dru_survival_instincts(); new spell_dru_swift_flight_passive(); + new spell_dru_flight_form(); new spell_dru_tiger_s_fury(); new spell_dru_typhoon(); new spell_dru_t10_restoration_4p_bonus(); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 5c3ee1d7f4a..8b8c5300a9e 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1245,7 +1245,7 @@ class spell_gen_defend : public SpellScriptLoader void Register() override { - SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(m_scriptSpellId); + SpellInfo const* spell = sSpellMgr->AssertSpellInfo(m_scriptSpellId); // Defend spells cast by NPCs (add visuals) if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) @@ -1930,10 +1930,7 @@ class spell_gen_mount : public SpellScriptLoader if (map == 530 || (map == 571 && target->HasSpell(SPELL_COLD_WEATHER_FLYING))) canFly = true; - float x, y, z; - target->GetPosition(x, y, z); - uint32 areaFlag = target->GetBaseMap()->GetAreaFlag(x, y, z); - AreaTableEntry const* area = sAreaStore.LookupEntry(areaFlag); + AreaTableEntry const* area = sAreaTableStore.LookupEntry(target->GetAreaId()); if (!area || (canFly && (area->flags & AREA_FLAG_NO_FLY_ZONE))) canFly = false; @@ -2151,7 +2148,7 @@ class spell_gen_mounted_charge: public SpellScriptLoader void Register() override { - SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(m_scriptSpellId); + SpellInfo const* spell = sSpellMgr->AssertSpellInfo(m_scriptSpellId); if (spell->HasEffect(SPELL_EFFECT_SCRIPT_EFFECT)) OnEffectHitTarget += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT); @@ -4158,6 +4155,40 @@ public: } }; +// 34098 - ClearAllDebuffs +class spell_gen_clear_debuffs : public SpellScriptLoader +{ + public: + spell_gen_clear_debuffs() : SpellScriptLoader("spell_gen_clear_debuffs") { } + + class spell_gen_clear_debuffs_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_clear_debuffs_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + { + target->RemoveOwnedAuras([](Aura const* aura) + { + SpellInfo const* spellInfo = aura->GetSpellInfo(); + return !spellInfo->IsPositive() && !spellInfo->IsPassive(); + }); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_clear_debuffs_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_gen_clear_debuffs_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -4244,4 +4275,5 @@ void AddSC_generic_spell_scripts() new spell_gen_stand(); new spell_gen_mixology_bonus(); new spell_gen_landmine_knockback_achievement(); + new spell_gen_clear_debuffs(); } diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp index 7fe1f54a594..6442eb8acca 100644 --- a/src/server/scripts/Spells/spell_holiday.cpp +++ b/src/server/scripts/Spells/spell_holiday.cpp @@ -29,6 +29,7 @@ #include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "CellImpl.h" +#include "Vehicle.h" // 45102 Romantic Picnic enum SpellsPicnic @@ -64,7 +65,7 @@ class spell_love_is_in_the_air_romantic_picnic : public SpellScriptLoader Unit* caster = GetCaster(); // If our player is no longer sit, remove all auras - if (target->getStandState() != UNIT_STAND_STATE_SIT) + if (target->GetStandState() != UNIT_STAND_STATE_SIT) { target->RemoveAura(SPELL_ROMANTIC_PICNIC_ACHIEV); target->RemoveAura(GetAura()); @@ -83,7 +84,7 @@ class spell_love_is_in_the_air_romantic_picnic : public SpellScriptLoader target->VisitNearbyWorldObject(INTERACTION_DISTANCE*2, searcher); for (std::list<Player*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) { - if ((*itr) != target && (*itr)->HasAura(GetId())) // && (*itr)->getStandState() == UNIT_STAND_STATE_SIT) + if ((*itr) != target && (*itr)->HasAura(GetId())) // && (*itr)->GetStandState() == UNIT_STAND_STATE_SIT) { if (caster) { @@ -410,6 +411,84 @@ class spell_pilgrims_bounty_buff_food : public SpellScriptLoader } }; +enum FeastOnSpells +{ + FEAST_ON_TURKEY = 61784, + FEAST_ON_CRANBERRIES = 61785, + FEAST_ON_SWEET_POTATOES = 61786, + FEAST_ON_PIE = 61787, + FEAST_ON_STUFFING = 61788, + SPELL_CRANBERRY_HELPINS = 61841, + SPELL_TURKEY_HELPINS = 61842, + SPELL_STUFFING_HELPINS = 61843, + SPELL_SWEET_POTATO_HELPINS = 61844, + SPELL_PIE_HELPINS = 61845, + SPELL_ON_PLATE_EAT_VISUAL = 61826 +}; + +class spell_pilgrims_bounty_feast_on : public SpellScriptLoader +{ + public: + spell_pilgrims_bounty_feast_on() : SpellScriptLoader("spell_pilgrims_bounty_feast_on") { } + + class spell_pilgrims_bounty_feast_on_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pilgrims_bounty_feast_on_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + + uint32 _spellId = 0; + switch (GetSpellInfo()->Id) + { + case FEAST_ON_TURKEY: + _spellId = SPELL_TURKEY_HELPINS; + break; + case FEAST_ON_CRANBERRIES: + _spellId = SPELL_CRANBERRY_HELPINS; + break; + case FEAST_ON_SWEET_POTATOES: + _spellId = SPELL_SWEET_POTATO_HELPINS; + break; + case FEAST_ON_PIE: + _spellId = SPELL_PIE_HELPINS; + break; + case FEAST_ON_STUFFING: + _spellId = SPELL_STUFFING_HELPINS; + break; + default: + return; + } + + if (Vehicle* vehicle = caster->GetVehicleKit()) + if (Unit* target = vehicle->GetPassenger(0)) + if (Player* player = target->ToPlayer()) + { + player->CastSpell(player, SPELL_ON_PLATE_EAT_VISUAL, true); + caster->CastSpell(player, _spellId, true, NULL, NULL, player->GetGUID()); + } + + if (Aura* aura = caster->GetAura(GetEffectValue())) + { + if (aura->GetStackAmount() == 1) + caster->RemoveAurasDueToSpell(aura->GetSpellInfo()->Effects[EFFECT_0].CalcValue()); + aura->ModStackAmount(-1); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_pilgrims_bounty_feast_on_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_pilgrims_bounty_feast_on_SpellScript(); + } +}; + enum TheTurkinator { SPELL_KILL_COUNTER_VISUAL = 62015, @@ -429,7 +508,7 @@ class spell_pilgrims_bounty_turkey_tracker : public SpellScriptLoader { PrepareSpellScript(spell_pilgrims_bounty_turkey_tracker_SpellScript); - bool Validate(SpellInfo const* /*spell*/) + bool Validate(SpellInfo const* /*spell*/) override { if (!sSpellMgr->GetSpellInfo(SPELL_KILL_COUNTER_VISUAL) || !sSpellMgr->GetSpellInfo(SPELL_KILL_COUNTER_VISUAL_MAX)) return false; @@ -472,18 +551,90 @@ class spell_pilgrims_bounty_turkey_tracker : public SpellScriptLoader } } - void Register() + void Register() override { OnEffectHitTarget += SpellEffectFn(spell_pilgrims_bounty_turkey_tracker_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; - SpellScript* GetSpellScript() const + SpellScript* GetSpellScript() const override { return new spell_pilgrims_bounty_turkey_tracker_SpellScript(); } }; +enum SpiritOfSharing +{ + SPELL_THE_SPIRIT_OF_SHARING = 61849 +}; + +class spell_pilgrims_bounty_well_fed : public SpellScriptLoader +{ + private: + uint32 _triggeredSpellId; + + public: + spell_pilgrims_bounty_well_fed(const char* name, uint32 triggeredSpellId) : SpellScriptLoader(name), _triggeredSpellId(triggeredSpellId) { } + + class spell_pilgrims_bounty_well_fed_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pilgrims_bounty_well_fed_SpellScript); + private: + uint32 _triggeredSpellId; + + public: + spell_pilgrims_bounty_well_fed_SpellScript(uint32 triggeredSpellId) : SpellScript(), _triggeredSpellId(triggeredSpellId) { } + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(_triggeredSpellId)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + Player* target = GetHitPlayer(); + if (!target) + return; + + if (Aura const* aura = target->GetAura(GetSpellInfo()->Id)) + { + if (aura->GetStackAmount() == 5) + target->CastSpell(target, _triggeredSpellId, true); + } + + Aura const* turkey = target->GetAura(SPELL_TURKEY_HELPINS); + Aura const* cranberies = target->GetAura(SPELL_CRANBERRY_HELPINS); + Aura const* stuffing = target->GetAura(SPELL_STUFFING_HELPINS); + Aura const* sweetPotatoes = target->GetAura(SPELL_SWEET_POTATO_HELPINS); + Aura const* pie = target->GetAura(SPELL_PIE_HELPINS); + + if ((turkey && turkey->GetStackAmount() == 5) && (cranberies && cranberies->GetStackAmount() == 5) && (stuffing && stuffing->GetStackAmount() == 5) + && (sweetPotatoes && sweetPotatoes->GetStackAmount() == 5) && (pie && pie->GetStackAmount() == 5)) + { + target->CastSpell(target, SPELL_THE_SPIRIT_OF_SHARING, true); + target->RemoveAurasDueToSpell(SPELL_TURKEY_HELPINS); + target->RemoveAurasDueToSpell(SPELL_CRANBERRY_HELPINS); + target->RemoveAurasDueToSpell(SPELL_STUFFING_HELPINS); + target->RemoveAurasDueToSpell(SPELL_SWEET_POTATO_HELPINS); + target->RemoveAurasDueToSpell(SPELL_PIE_HELPINS); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_pilgrims_bounty_well_fed_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_pilgrims_bounty_well_fed_SpellScript(_triggeredSpellId); + } +}; + enum Mistletoe { SPELL_CREATE_MISTLETOE = 26206, @@ -1047,6 +1198,12 @@ void AddSC_holiday_spell_scripts() new spell_pilgrims_bounty_buff_food("spell_gen_spice_bread_stuffing", SPELL_WELL_FED_HIT_TRIGGER); new spell_pilgrims_bounty_buff_food("spell_gen_pumpkin_pie", SPELL_WELL_FED_SPIRIT_TRIGGER); new spell_pilgrims_bounty_buff_food("spell_gen_candied_sweet_potato", SPELL_WELL_FED_HASTE_TRIGGER); + new spell_pilgrims_bounty_feast_on(); + new spell_pilgrims_bounty_well_fed("spell_pilgrims_bounty_well_fed_turkey", SPELL_WELL_FED_AP_TRIGGER); + new spell_pilgrims_bounty_well_fed("spell_pilgrims_bounty_well_fed_cranberry", SPELL_WELL_FED_ZM_TRIGGER); + new spell_pilgrims_bounty_well_fed("spell_pilgrims_bounty_well_fed_stuffing", SPELL_WELL_FED_HIT_TRIGGER); + new spell_pilgrims_bounty_well_fed("spell_pilgrims_bounty_well_fed_sweet_potatoes", SPELL_WELL_FED_HASTE_TRIGGER); + new spell_pilgrims_bounty_well_fed("spell_pilgrims_bounty_well_fed_pie", SPELL_WELL_FED_SPIRIT_TRIGGER); new spell_pilgrims_bounty_turkey_tracker(); // Winter Veil new spell_winter_veil_mistletoe(); diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index abf4c6c1ad8..82d9d134445 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -40,6 +40,7 @@ enum HunterSpells SPELL_HUNTER_CHIMERA_SHOT_SERPENT = 53353, SPELL_HUNTER_CHIMERA_SHOT_VIPER = 53358, SPELL_HUNTER_CHIMERA_SHOT_SCORPID = 53359, + SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT = 61389, SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER = 56851, SPELL_HUNTER_IMPROVED_MEND_PET = 24406, SPELL_HUNTER_INVIGORATION_TRIGGERED = 53398, @@ -192,8 +193,8 @@ class spell_hun_chimera_shot : public SpellScriptLoader { uint32 spellId = 0; int32 basePoint = 0; - Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras(); - for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i) + Unit::AuraApplicationMap const& auras = unitTarget->GetAppliedAuras(); + for (Unit::AuraApplicationMap::const_iterator i = auras.begin(); i != auras.end(); ++i) { Aura* aura = i->second->GetBase(); if (aura->GetCasterGUID() != caster->GetGUID()) @@ -296,6 +297,68 @@ class spell_hun_disengage : public SpellScriptLoader } }; +// 56841 - Glyph of Arcane Shot +class spell_hun_glyph_of_arcane_shot : public SpellScriptLoader +{ + public: + spell_hun_glyph_of_arcane_shot() : SpellScriptLoader("spell_hun_glyph_of_arcane_shot") { } + + class spell_hun_glyph_of_arcane_shot_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_glyph_of_arcane_shot_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (Unit* procTarget = eventInfo.GetProcTarget()) + { + Unit::AuraApplicationMap const& auras = procTarget->GetAppliedAuras(); + for (Unit::AuraApplicationMap::const_iterator i = auras.begin(); i != auras.end(); ++i) + { + Aura const* aura = i->second->GetBase(); + if (aura->GetCasterGUID() != GetTarget()->GetGUID()) + continue; + // Search only Serpent Sting, Viper Sting, Scorpid Sting, Wyvern Sting + if (aura->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_HUNTER + && aura->GetSpellInfo()->SpellFamilyFlags.HasFlag(0xC000, 0x1080)) + return true; + } + } + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + if (!procSpell) + return; + + int32 mana = procSpell->CalcPowerCost(GetTarget(), procSpell->GetSchoolMask()); + ApplyPct(mana, aurEff->GetAmount()); + + GetTarget()->CastCustomSpell(SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT, SPELLVALUE_BASE_POINT0, mana, GetTarget()); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_hun_glyph_of_arcane_shot_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_hun_glyph_of_arcane_shot_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_hun_glyph_of_arcane_shot_AuraScript(); + } +}; + // -19572 - Improved Mend Pet class spell_hun_improved_mend_pet : public SpellScriptLoader { @@ -336,6 +399,7 @@ class spell_hun_improved_mend_pet : public SpellScriptLoader return new spell_hun_improved_mend_pet_AuraScript(); } }; + // 53412 - Invigoration class spell_hun_invigoration : public SpellScriptLoader { @@ -699,7 +763,7 @@ class spell_hun_readiness : public SpellScriptLoader // immediately finishes the cooldown on your other Hunter abilities except Bestial Wrath GetCaster()->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool { - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); ///! If spellId in cooldown map isn't valid, the above will return a null pointer. if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && @@ -952,6 +1016,7 @@ void AddSC_hunter_spell_scripts() new spell_hun_ascpect_of_the_viper(); new spell_hun_chimera_shot(); new spell_hun_disengage(); + new spell_hun_glyph_of_arcane_shot(); new spell_hun_improved_mend_pet(); new spell_hun_invigoration(); new spell_hun_last_stand_pet(); diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 9475da91a77..84c67bad63b 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -29,6 +29,7 @@ #include "SpellAuraEffects.h" #include "SkillDiscovery.h" #include "Battleground.h" +#include "DBCStores.h" // Generic script for handling item dummy effects which trigger another spell. class spell_item_trigger_spell : public SpellScriptLoader @@ -200,6 +201,55 @@ class spell_item_blessing_of_ancient_kings : public SpellScriptLoader } }; +// 47770 - Roll Dice +class spell_item_decahedral_dwarven_dice : public SpellScriptLoader +{ + public: + spell_item_decahedral_dwarven_dice() : SpellScriptLoader("spell_item_decahedral_dwarven_dice") { } + + class spell_item_decahedral_dwarven_dice_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_decahedral_dwarven_dice_SpellScript); + + enum + { + TEXT_DECAHEDRAL_DWARVEN_DICE = 26147 + }; + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sObjectMgr->GetBroadcastText(TEXT_DECAHEDRAL_DWARVEN_DICE)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->TextEmote(TEXT_DECAHEDRAL_DWARVEN_DICE, GetHitUnit()); + + static uint32 const minimum = 1; + static uint32 const maximum = 100; + + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_decahedral_dwarven_dice_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_item_decahedral_dwarven_dice_SpellScript(); + } +}; + // 8342 - Defibrillate (Goblin Jumper Cables) have 33% chance on success // 22999 - Defibrillate (Goblin Jumper Cables XL) have 50% chance on success // 54732 - Defibrillate (Gnomish Army Knife) have 67% chance on success @@ -1318,6 +1368,57 @@ class spell_item_underbelly_elixir : public SpellScriptLoader } }; +// 47776 - Roll 'dem Bones +class spell_item_worn_troll_dice : public SpellScriptLoader +{ + public: + spell_item_worn_troll_dice() : SpellScriptLoader("spell_item_worn_troll_dice") { } + + class spell_item_worn_troll_dice_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_worn_troll_dice_SpellScript); + + enum + { + TEXT_WORN_TROLL_DICE = 26152 + }; + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sObjectMgr->GetBroadcastText(TEXT_WORN_TROLL_DICE)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->TextEmote(TEXT_WORN_TROLL_DICE, GetHitUnit()); + + static uint32 const minimum = 1; + static uint32 const maximum = 6; + + // roll twice + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_worn_troll_dice_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_item_worn_troll_dice_SpellScript(); + } +}; + enum AirRifleSpells { SPELL_AIR_RIFLE_HOLD_VISUAL = 65582, @@ -2630,6 +2731,43 @@ public: } }; +class spell_item_toy_train_set_pulse : public SpellScriptLoader +{ +public: + spell_item_toy_train_set_pulse() : SpellScriptLoader("spell_item_toy_train_set_pulse") { } + + class spell_item_toy_train_set_pulse_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_toy_train_set_pulse_SpellScript); + + void HandleDummy(SpellEffIndex /*index*/) + { + if (Player* target = GetHitUnit()->ToPlayer()) + { + target->HandleEmoteCommand(EMOTE_ONESHOT_TRAIN); + if (EmotesTextSoundEntry const* soundEntry = FindTextSoundEmoteFor(TEXT_EMOTE_TRAIN, target->getRace(), target->getGender())) + target->PlayDistanceSound(soundEntry->SoundId); + } + } + + void HandleTargets(std::list<WorldObject*>& targetList) + { + targetList.remove_if([](WorldObject const* obj) { return obj->GetTypeId() != TYPEID_PLAYER; }); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_toy_train_set_pulse_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_item_toy_train_set_pulse_SpellScript::HandleTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ALLY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_item_toy_train_set_pulse_SpellScript(); + } +}; + void AddSC_item_spell_scripts() { // 23074 Arcanite Dragonling @@ -2644,6 +2782,7 @@ void AddSC_item_spell_scripts() new spell_item_aegis_of_preservation(); new spell_item_arcane_shroud(); new spell_item_blessing_of_ancient_kings(); + new spell_item_decahedral_dwarven_dice(); new spell_item_defibrillate("spell_item_goblin_jumper_cables", 67, SPELL_GOBLIN_JUMPER_CABLES_FAIL); new spell_item_defibrillate("spell_item_goblin_jumper_cables_xl", 50, SPELL_GOBLIN_JUMPER_CABLES_XL_FAIL); new spell_item_defibrillate("spell_item_gnomish_army_knife", 33); @@ -2668,6 +2807,7 @@ void AddSC_item_spell_scripts() new spell_item_six_demon_bag(); new spell_item_the_eye_of_diminution(); new spell_item_underbelly_elixir(); + new spell_item_worn_troll_dice(); new spell_item_red_rider_air_rifle(); new spell_item_create_heart_candy(); @@ -2698,4 +2838,5 @@ void AddSC_item_spell_scripts() new spell_item_chicken_cover(); new spell_item_muisek_vessel(); new spell_item_greatmothers_soulcatcher(); + new spell_item_toy_train_set_pulse(); } diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index d08968fbf55..2f4e4fa6f44 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -180,7 +180,7 @@ class spell_mage_cold_snap : public SpellScriptLoader { GetCaster()->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool { - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); return spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) && spellInfo->Id != SPELL_MAGE_COLD_SNAP && spellInfo->GetRecoveryTime() > 0; }, true); @@ -405,7 +405,7 @@ class spell_mage_ignite : public SpellScriptLoader { PreventDefaultAction(); - SpellInfo const* igniteDot = sSpellMgr->EnsureSpellInfo(SPELL_MAGE_IGNITE); + SpellInfo const* igniteDot = sSpellMgr->AssertSpellInfo(SPELL_MAGE_IGNITE); int32 pct = 8 * GetSpellInfo()->GetRank(); int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks()); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 8bd4b3eb070..d9fd36f5fd4 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -1195,7 +1195,7 @@ class spell_pal_light_s_beacon : public SpellScriptLoader if (!procSpell) return; - uint32 healSpellId = procSpell->IsRankOf(sSpellMgr->EnsureSpellInfo(SPELL_PALADIN_HOLY_LIGHT)) ? SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_1 : SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_3; + uint32 healSpellId = procSpell->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_PALADIN_HOLY_LIGHT)) ? SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_1 : SPELL_PALADIN_BEACON_OF_LIGHT_HEAL_3; uint32 heal = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount()); Unit* beaconTarget = GetCaster(); diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp index 7393a7d3bcb..cde291cd82b 100644 --- a/src/server/scripts/Spells/spell_pet.cpp +++ b/src/server/scripts/Spells/spell_pet.cpp @@ -916,7 +916,7 @@ public: if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt { - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value AddPct(mod, spellInfo->Effects[EFFECT_0].CalcValue()); } @@ -959,7 +959,7 @@ public: if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt { - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value mod += CalculatePct(1.0f, spellInfo->Effects[EFFECT_1].CalcValue()); } @@ -989,7 +989,7 @@ public: if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt { - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value mod += CalculatePct(1.0f, spellInfo->Effects[EFFECT_1].CalcValue()); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index ecf5b7b5acf..51f03346df1 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -236,7 +236,7 @@ class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader { PreventDefaultAction(); - SpellInfo const* triggeredSpellInfo = sSpellMgr->EnsureSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL); + SpellInfo const* triggeredSpellInfo = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL); int32 heal = int32(CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks()); GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, NULL, aurEff); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 3121a18734d..ae761413ca5 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -1707,7 +1707,7 @@ enum Quest13291_13292_13239_13261Data NPC_SKYTALON = 31583, NPC_DECOY = 31578, // Spells - SPELL_RIDE = 56687 + SPELL_RIDE = 59319 }; class spell_q13291_q13292_q13239_q13261_frostbrood_skytalon_grab_decoy : public SpellScriptLoader diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 3ca2db40d65..affc4d1c26c 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -41,6 +41,9 @@ enum RogueSpells SPELL_ROGUE_SHIV_TRIGGERED = 5940, SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933, SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628, + SPELL_ROGUE_HONOR_AMONG_THIEVES = 51698, + SPELL_ROGUE_HONOR_AMONG_THIEVES_PROC = 52916, + SPELL_ROGUE_HONOR_AMONG_THIEVES_2 = 51699 }; // 13877, 33735, (check 51211, 65956) - Blade Flurry @@ -447,7 +450,7 @@ class spell_rog_preparation : public SpellScriptLoader Unit* caster = GetCaster(); caster->GetSpellHistory()->ResetCooldowns([caster](SpellHistory::CooldownStorageType::iterator itr) -> bool { - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); if (spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE) return false; @@ -703,6 +706,143 @@ class spell_rog_tricks_of_the_trade_proc : public SpellScriptLoader } }; +// 51698,51700,51701 - Honor Among Thieves +class spell_rog_honor_among_thieves : public SpellScriptLoader +{ +public: + spell_rog_honor_among_thieves() : SpellScriptLoader("spell_rog_honor_among_thieves") { } + + class spell_rog_honor_among_thieves_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_honor_among_thieves_AuraScript); + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + Unit* caster = GetCaster(); + if (!caster) + return false; + + if (!caster->GetSpellHistory()->HasCooldown(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell)) + return true; + + return false; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + Unit* caster = GetCaster(); + if (!caster) + return; + + Unit* target = GetTarget(); + target->CastSpell(target, GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), nullptr, aurEff, caster->GetGUID()); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_rog_honor_among_thieves_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_rog_honor_among_thieves_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_rog_honor_among_thieves_AuraScript(); + } +}; + +// 52916 - Honor Among Thieves (Proc) +class spell_rog_honor_among_thieves_proc : public SpellScriptLoader +{ +public: + spell_rog_honor_among_thieves_proc() : SpellScriptLoader("spell_rog_honor_among_thieves_proc") { } + + class spell_rog_honor_among_thieves_proc_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rog_honor_among_thieves_proc_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_HONOR_AMONG_THIEVES_PROC)) + return false; + + return true; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.clear(); + + Unit* target = GetOriginalCaster(); + if (!target) + return; + + targets.push_back(target); + } + + void HandleBeforeHit() + { + Unit* target = GetHitUnit(); + if (!target) + return; + + /* + * The applied aura has a duration of 8 seconds + * This prevents new applications while its active + * Removing it on each new proc enables the application from different sources (different grouped players) + * and on new procs after the source cooldown is finished (1 second) + */ + if (target->HasAura(GetSpellInfo()->Id)) + target->RemoveAura(GetSpellInfo()->Id); + } + + void TriggerCooldown() + { + Unit* target = GetHitUnit(); + if (!target) + return; + + target->GetSpellHistory()->AddCooldown(GetSpellInfo()->Id, 0, std::chrono::seconds(1)); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rog_honor_among_thieves_proc_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY); + BeforeHit += SpellHitFn(spell_rog_honor_among_thieves_proc_SpellScript::HandleBeforeHit); + AfterHit += SpellHitFn(spell_rog_honor_among_thieves_proc_SpellScript::TriggerCooldown); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_rog_honor_among_thieves_proc_SpellScript(); + } + + class spell_rog_honor_among_thieves_proc_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_honor_among_thieves_proc_AuraScript); + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Player* player = GetTarget()->ToPlayer()) + if (Unit* spellTarget = ObjectAccessor::GetUnit(*player, player->GetTarget())) + player->CastSpell(spellTarget, SPELL_ROGUE_HONOR_AMONG_THIEVES_2, true); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_rog_honor_among_thieves_proc_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_rog_honor_among_thieves_proc_AuraScript(); + } +}; + void AddSC_rogue_spell_scripts() { new spell_rog_blade_flurry(); @@ -716,4 +856,6 @@ void AddSC_rogue_spell_scripts() new spell_rog_shiv(); new spell_rog_tricks_of_the_trade(); new spell_rog_tricks_of_the_trade_proc(); + new spell_rog_honor_among_thieves(); + new spell_rog_honor_among_thieves_proc(); } diff --git a/src/server/scripts/Spells/spell_script_loader.cpp b/src/server/scripts/Spells/spell_script_loader.cpp new file mode 100644 index 00000000000..b2c8d6663fa --- /dev/null +++ b/src/server/scripts/Spells/spell_script_loader.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// This is where scripts' loading functions should be declared: +void AddSC_deathknight_spell_scripts(); +void AddSC_druid_spell_scripts(); +void AddSC_generic_spell_scripts(); +void AddSC_hunter_spell_scripts(); +void AddSC_mage_spell_scripts(); +void AddSC_paladin_spell_scripts(); +void AddSC_priest_spell_scripts(); +void AddSC_rogue_spell_scripts(); +void AddSC_shaman_spell_scripts(); +void AddSC_warlock_spell_scripts(); +void AddSC_warrior_spell_scripts(); +void AddSC_quest_spell_scripts(); +void AddSC_item_spell_scripts(); +void AddSC_holiday_spell_scripts(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddSpellsScripts() +{ + AddSC_deathknight_spell_scripts(); + AddSC_druid_spell_scripts(); + AddSC_generic_spell_scripts(); + AddSC_hunter_spell_scripts(); + AddSC_mage_spell_scripts(); + AddSC_paladin_spell_scripts(); + AddSC_priest_spell_scripts(); + AddSC_rogue_spell_scripts(); + AddSC_shaman_spell_scripts(); + AddSC_warlock_spell_scripts(); + AddSC_warrior_spell_scripts(); + AddSC_quest_spell_scripts(); + AddSC_item_spell_scripts(); + AddSC_holiday_spell_scripts(); +} diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index c8b0264995b..41e72b1388b 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -55,7 +55,8 @@ enum ShamanSpells SPELL_SHAMAN_TOTEM_EARTHBIND_EARTHGRAB = 64695, SPELL_SHAMAN_TOTEM_EARTHBIND_TOTEM = 6474, SPELL_SHAMAN_TOTEM_EARTHEN_POWER = 59566, - SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL = 52042 + SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL = 52042, + SPELL_SHAMAN_TOTEMIC_MASTERY = 38437 }; enum ShamanSpellIcons @@ -1025,6 +1026,46 @@ class spell_sha_thunderstorm : public SpellScriptLoader } }; +// 38443 - Totemic Mastery (Tier 6 - 2P) +class spell_sha_totemic_mastery : public SpellScriptLoader +{ +public: + spell_sha_totemic_mastery() : SpellScriptLoader("spell_sha_totemic_mastery") { } + + class spell_sha_totemic_mastery_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_totemic_mastery_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEMIC_MASTERY)) + return false; + return true; + } + + void HandleDummy(AuraEffect const* /*aurEff*/) + { + Unit* target = GetTarget(); + for (uint8 i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i) + if (!target->m_SummonSlot[i]) + return; + + target->CastSpell(target, SPELL_SHAMAN_TOTEMIC_MASTERY, true); + PreventDefaultAction(); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_totemic_mastery_AuraScript::HandleDummy, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_totemic_mastery_AuraScript(); + } +}; + void AddSC_shaman_spell_scripts() { new spell_sha_ancestral_awakening_proc(); @@ -1048,4 +1089,5 @@ void AddSC_shaman_spell_scripts() new spell_sha_mana_tide_totem(); new spell_sha_sentry_totem(); new spell_sha_thunderstorm(); + new spell_sha_totemic_mastery(); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 7cc6fe888e9..a0a6189cbe2 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -271,7 +271,7 @@ class spell_warl_demonic_circle_summon : public SpellScriptLoader // WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST; allowing him to cast the WARLOCK_DEMONIC_CIRCLE_TELEPORT. // If not in range remove the WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST. - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT); if (GetTarget()->IsWithinDist(circle, spellInfo->GetMaxRange(true))) { @@ -362,7 +362,7 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader break; case CREATURE_FAMILY_VOIDWALKER: { - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER); int32 hp = int32(targetCreature->CountPctFromMaxHealth(GetCaster()->CalculateSpellDamage(targetCreature, spellInfo, 0))); targetCreature->CastCustomSpell(targetCreature, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER, &hp, NULL, NULL, true); //unitTarget->CastSpell(unitTarget, 54441, true); diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index d224c234cb4..ea9ccc956e5 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -271,7 +271,7 @@ class spell_warr_deep_wounds : public SpellScriptLoader { ApplyPct(damage, 16 * GetSpellInfo()->GetRank()); - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC); uint32 ticks = uint32(spellInfo->GetDuration()) / spellInfo->Effects[EFFECT_0].Amplitude; // Add remaining ticks to damage done diff --git a/src/server/scripts/World/CMakeLists.txt b/src/server/scripts/World/CMakeLists.txt deleted file mode 100644 index 17b3f2d8492..00000000000 --- a/src/server/scripts/World/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -file(GLOB_RECURSE sources_World World/*.cpp World/*.h) - -set(scripts_STAT_SRCS - ${scripts_STAT_SRCS} - ${sources_World} -) - -message(" -> Prepared: World") diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp index 1f89720803d..65dec74414b 100644 --- a/src/server/scripts/World/boss_emerald_dragons.cpp +++ b/src/server/scripts/World/boss_emerald_dragons.cpp @@ -205,7 +205,7 @@ class npc_dream_fog : public CreatureScript } // Seeping fog movement is slow enough for a player to be able to walk backwards and still outpace it me->SetWalk(true); - me->SetSpeed(MOVE_WALK, 0.75f); + me->SetSpeedRate(MOVE_WALK, 0.75f); } else _roamTimer -= diff; diff --git a/src/server/scripts/World/duel_reset.cpp b/src/server/scripts/World/duel_reset.cpp index 3c46255a1bf..b04f3ec0aa7 100644 --- a/src/server/scripts/World/duel_reset.cpp +++ b/src/server/scripts/World/duel_reset.cpp @@ -98,16 +98,16 @@ class DuelResetScript : public PlayerScript static void ResetSpellCooldowns(Player* player, bool onStartDuel) { - if (onStartDuel) + if (onStartDuel) { // remove cooldowns on spells that have < 10 min CD > 30 sec and has no onHold player->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool { SpellHistory::Clock::time_point now = SpellHistory::Clock::now(); uint32 cooldownDuration = itr->second.CooldownEnd > now ? std::chrono::duration_cast<std::chrono::milliseconds>(itr->second.CooldownEnd - now).count() : 0; - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); - return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS - && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); + return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS + && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS && !itr->second.OnHold && cooldownDuration > 0 && ( spellInfo->RecoveryTime - cooldownDuration ) > (MINUTE / 2) * IN_MILLISECONDS @@ -119,11 +119,11 @@ class DuelResetScript : public PlayerScript // remove cooldowns on spells that have < 10 min CD and has no onHold player->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool { - SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); - return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS - && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); + return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS + && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS && !itr->second.OnHold; - }, true); + }, true); } // pet cooldowns diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index ef4a2b0e32f..3094ecd660a 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -41,6 +41,7 @@ go_tadpole_cage go_amberpine_outhouse go_hive_pod go_veil_skith_cage +go_toy_train_set EndContentData */ #include "ScriptMgr.h" @@ -1196,6 +1197,48 @@ public: } }; + +enum ToyTrainSpells +{ + SPELL_TOY_TRAIN_PULSE = 61551, +}; + +class go_toy_train_set : public GameObjectScript +{ + public: + go_toy_train_set() : GameObjectScript("go_toy_train_set") { } + + struct go_toy_train_setAI : public GameObjectAI + { + go_toy_train_setAI(GameObject* go) : GameObjectAI(go), _pulseTimer(3 * IN_MILLISECONDS) { } + + void UpdateAI(uint32 diff) override + { + if (diff < _pulseTimer) + _pulseTimer -= diff; + else + { + go->CastSpell(nullptr, SPELL_TOY_TRAIN_PULSE, true); + _pulseTimer = 6 * IN_MILLISECONDS; + } + } + + // triggered on wrecker'd + void DoAction(int32 /*action*/) override + { + go->Delete(); + } + + private: + uint32 _pulseTimer; + }; + + GameObjectAI* GetAI(GameObject* go) const override + { + return new go_toy_train_setAI(go); + } +}; + void AddSC_go_scripts() { new go_cat_figurine(); @@ -1231,4 +1274,5 @@ void AddSC_go_scripts() new go_veil_skith_cage(); new go_frostblade_shrine(); new go_midsummer_bonfire(); + new go_toy_train_set(); } diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 16b95e555bb..159faa38c62 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -38,6 +38,7 @@ npc_snake_trap_serpents 80% AI for snakes that summoned by Snake Trap npc_shadowfiend 100% restore 5% of owner's mana when shadowfiend die from damage npc_locksmith 75% list of keys needs to be confirmed npc_firework 100% NPC's summoned by rockets and rocket clusters, for making them cast visual +npc_train_wrecker 100% Wind-Up Train Wrecker that kills train set EndContentData */ #include "ScriptMgr.h" @@ -519,6 +520,67 @@ public: }; /*###### +## npc_torch_tossing_target_bunny_controller +######*/ + +enum TorchTossingTarget +{ + NPC_TORCH_TOSSING_TARGET_BUNNY = 25535, + SPELL_TARGET_INDICATOR = 45723 +}; + +class npc_torch_tossing_target_bunny_controller : public CreatureScript +{ +public: + npc_torch_tossing_target_bunny_controller() : CreatureScript("npc_torch_tossing_target_bunny_controller") { } + + struct npc_torch_tossing_target_bunny_controllerAI : public ScriptedAI + { + npc_torch_tossing_target_bunny_controllerAI(Creature* creature) : ScriptedAI(creature) + { + _targetTimer = 3000; + } + + ObjectGuid DoSearchForTargets(ObjectGuid lastTargetGUID) + { + std::list<Creature*> targets; + me->GetCreatureListWithEntryInGrid(targets, NPC_TORCH_TOSSING_TARGET_BUNNY, 60.0f); + targets.remove_if([lastTargetGUID](Creature* creature) { return creature->GetGUID() == lastTargetGUID; }); + + if (!targets.empty()) + { + _lastTargetGUID = Trinity::Containers::SelectRandomContainerElement(targets)->GetGUID(); + + return _lastTargetGUID; + } + return ObjectGuid::Empty; + } + + void UpdateAI(uint32 diff) override + { + if (_targetTimer < diff) + { + if (Unit* target = ObjectAccessor::GetUnit(*me, DoSearchForTargets(_lastTargetGUID))) + target->CastSpell(target, SPELL_TARGET_INDICATOR, true); + + _targetTimer = 3000; + } + else + _targetTimer -= diff; + } + + private: + uint32 _targetTimer; + ObjectGuid _lastTargetGUID; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_torch_tossing_target_bunny_controllerAI(creature); + } +}; + +/*###### ## Triage quest ######*/ @@ -1422,7 +1484,6 @@ public: void Reset() override { me->SetControlled(true, UNIT_STATE_STUNNED);//disable rotate - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);//imune to knock aways like blast wave _events.Reset(); _damageTimes.clear(); @@ -2130,7 +2191,7 @@ public: // Check if we are near Elune'ara lake south, if so try to summon Omen or a minion if (me->GetZoneId() == ZONE_MOONGLADE) { - if (!me->FindNearestCreature(NPC_OMEN, 100.0f, false) && me->GetDistance2d(omenSummonPos.GetPositionX(), omenSummonPos.GetPositionY()) <= 100.0f) + if (!me->FindNearestCreature(NPC_OMEN, 100.0f) && me->GetDistance2d(omenSummonPos.GetPositionX(), omenSummonPos.GetPositionY()) <= 100.0f) { switch (urand(0, 9)) { @@ -2387,12 +2448,136 @@ class npc_stable_master : public CreatureScript } }; +enum TrainWrecker +{ + GO_TOY_TRAIN = 193963, + SPELL_TOY_TRAIN_PULSE = 61551, + SPELL_WRECK_TRAIN = 62943, + ACTION_WRECKED = 1, + EVENT_DO_JUMP = 1, + EVENT_DO_FACING = 2, + EVENT_DO_WRECK = 3, + EVENT_DO_DANCE = 4, + MOVEID_CHASE = 1, + MOVEID_JUMP = 2 +}; +class npc_train_wrecker : public CreatureScript +{ + public: + npc_train_wrecker() : CreatureScript("npc_train_wrecker") { } + + struct npc_train_wreckerAI : public NullCreatureAI + { + npc_train_wreckerAI(Creature* creature) : NullCreatureAI(creature), _isSearching(true), _nextAction(0), _timer(1 * IN_MILLISECONDS) { } + + GameObject* VerifyTarget() const + { + if (GameObject* target = ObjectAccessor::GetGameObject(*me, _target)) + return target; + me->HandleEmoteCommand(EMOTE_ONESHOT_RUDE); + me->DespawnOrUnsummon(3 * IN_MILLISECONDS); + return nullptr; + } + + void UpdateAI(uint32 diff) override + { + if (_isSearching) + { + if (diff < _timer) + _timer -= diff; + else + { + if (GameObject* target = me->FindNearestGameObject(GO_TOY_TRAIN, 15.0f)) + { + _isSearching = false; + _target = target->GetGUID(); + me->SetWalk(true); + me->GetMotionMaster()->MovePoint(MOVEID_CHASE, target->GetNearPosition(3.0f, target->GetAngle(me))); + } + else + _timer = 3 * IN_MILLISECONDS; + } + } + else + { + switch (_nextAction) + { + case EVENT_DO_JUMP: + if (GameObject* target = VerifyTarget()) + me->GetMotionMaster()->MoveJump(*target, 5.0, 10.0, MOVEID_JUMP); + _nextAction = 0; + break; + case EVENT_DO_FACING: + if (GameObject* target = VerifyTarget()) + { + me->SetFacingTo(target->GetOrientation()); + me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H); + _timer = 1.5 * IN_MILLISECONDS; + _nextAction = EVENT_DO_WRECK; + } + else + _nextAction = 0; + break; + case EVENT_DO_WRECK: + if (diff < _timer) + { + _timer -= diff; + break; + } + if (GameObject* target = VerifyTarget()) + { + me->CastSpell(target, SPELL_WRECK_TRAIN, false); + target->AI()->DoAction(ACTION_WRECKED); + _timer = 2 * IN_MILLISECONDS; + _nextAction = EVENT_DO_DANCE; + } + else + _nextAction = 0; + break; + case EVENT_DO_DANCE: + if (diff < _timer) + { + _timer -= diff; + break; + } + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_DANCE); + me->DespawnOrUnsummon(5 * IN_MILLISECONDS); + _nextAction = 0; + break; + default: + break; + } + } + } + + void MovementInform(uint32 /*type*/, uint32 id) override + { + if (id == MOVEID_CHASE) + _nextAction = EVENT_DO_JUMP; + else if (id == MOVEID_JUMP) + _nextAction = EVENT_DO_FACING; + } + + private: + bool _isSearching; + uint8 _nextAction; + uint32 _timer; + ObjectGuid _target; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_train_wreckerAI(creature); + } +}; + void AddSC_npcs_special() { new npc_air_force_bots(); new npc_lunaclaw_spirit(); new npc_chicken_cluck(); new npc_dancing_flames(); + new npc_torch_tossing_target_bunny_controller(); new npc_doctor(); new npc_injured_patient(); new npc_garments_of_quests(); @@ -2410,4 +2595,5 @@ void AddSC_npcs_special() new npc_spring_rabbit(); new npc_imp_in_a_ball(); new npc_stable_master(); + new npc_train_wrecker(); } diff --git a/src/server/scripts/World/world_script_loader.cpp b/src/server/scripts/World/world_script_loader.cpp new file mode 100644 index 00000000000..0167024799f --- /dev/null +++ b/src/server/scripts/World/world_script_loader.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "World.h" + +// This is where scripts' loading functions should be declared: +// world +void AddSC_areatrigger_scripts(); +void AddSC_emerald_dragons(); +void AddSC_generic_creature(); +void AddSC_go_scripts(); +void AddSC_guards(); +void AddSC_item_scripts(); +void AddSC_npc_professions(); +void AddSC_npc_innkeeper(); +void AddSC_npcs_special(); +void AddSC_achievement_scripts(); +void AddSC_action_ip_logger(); +void AddSC_duel_reset(); +// player +void AddSC_chat_log(); +void AddSC_action_ip_logger(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddWorldScripts() +{ + AddSC_areatrigger_scripts(); + AddSC_emerald_dragons(); + AddSC_generic_creature(); + AddSC_go_scripts(); + AddSC_guards(); + AddSC_item_scripts(); + AddSC_npc_professions(); + AddSC_npc_innkeeper(); + AddSC_npcs_special(); + AddSC_achievement_scripts(); + AddSC_chat_log(); // location: scripts\World\chat_log.cpp + + // FIXME: This should be moved in a script validation hook. + // To avoid duplicate code, we check once /*ONLY*/ if logging is permitted or not. + if (sWorld->getBoolConfig(CONFIG_IP_BASED_ACTION_LOGGING)) + AddSC_action_ip_logger(); // location: scripts\World\action_ip_logger.cpp + AddSC_duel_reset(); +} |
