diff --git a/src/common/WindowsSettings.manifest b/cmake/platform/win/WindowsSettings.manifest similarity index 100% rename from src/common/WindowsSettings.manifest rename to cmake/platform/win/WindowsSettings.manifest diff --git a/cmake/platform/win/settings.cmake b/cmake/platform/win/settings.cmake index efae7696e1767..dcec80a08c416 100644 --- a/cmake/platform/win/settings.cmake +++ b/cmake/platform/win/settings.cmake @@ -8,3 +8,8 @@ target_compile_definitions(trinity-compile-option-interface # set up output paths for executable binaries (.exe-files, and .dll-files on DLL-capable platforms) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$") + +# add WindowsSettings.manifest to all executables +target_sources(trinity-core-interface + INTERFACE + $<$,EXECUTABLE>:${CMAKE_SOURCE_DIR}/cmake/platform/win/WindowsSettings.manifest>) diff --git a/sql/updates/world/master/2024_09_15_00_world.sql b/sql/updates/world/master/2024_09_15_00_world.sql new file mode 100644 index 0000000000000..9514593bed06c --- /dev/null +++ b/sql/updates/world/master/2024_09_15_00_world.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_warl_cataclysm'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(152108, 'spell_warl_cataclysm'); diff --git a/sql/updates/world/master/2024_09_15_01_world.sql b/sql/updates/world/master/2024_09_15_01_world.sql new file mode 100644 index 0000000000000..f758fce55b3d4 --- /dev/null +++ b/sql/updates/world/master/2024_09_15_01_world.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_warl_backdraft'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(17962, 'spell_warl_backdraft'); + +DELETE FROM `spell_proc` WHERE `SpellId` IN (117828); +INSERT INTO `spell_proc` (`SpellId`,`SchoolMask`,`SpellFamilyName`,`SpellFamilyMask0`,`SpellFamilyMask1`,`SpellFamilyMask2`,`SpellFamilyMask3`,`ProcFlags`,`ProcFlags2`,`SpellTypeMask`,`SpellPhaseMask`,`HitMask`,`AttributesMask`,`DisableEffectsMask`,`ProcsPerMinute`,`Chance`,`Cooldown`,`Charges`) VALUES +(117828,0x00,5,0x00000000,0x00002040,0x00000002,0x00000000,0x0,0x0,0x1,0x2,0x0,0x18,0x0,0,0,0,0); -- Backdraft diff --git a/sql/updates/world/master/2024_09_16_00_world.sql b/sql/updates/world/master/2024_09_16_00_world.sql new file mode 100644 index 0000000000000..1b5ed037eec35 --- /dev/null +++ b/sql/updates/world/master/2024_09_16_00_world.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_warl_pyrogenics'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(387095, 'spell_warl_pyrogenics'); + +DELETE FROM `spell_proc` WHERE `SpellId` IN (387095); +INSERT INTO `spell_proc` (`SpellId`,`SchoolMask`,`SpellFamilyName`,`SpellFamilyMask0`,`SpellFamilyMask1`,`SpellFamilyMask2`,`SpellFamilyMask3`,`ProcFlags`,`ProcFlags2`,`SpellTypeMask`,`SpellPhaseMask`,`HitMask`,`AttributesMask`,`DisableEffectsMask`,`ProcsPerMinute`,`Chance`,`Cooldown`,`Charges`) VALUES +(387095,0x00,5,0x00000000,0x00000000,0x10000000,0x00000000,0x50000,0x0,0x1,0x2,0x0,0x2,0x0,0,100,0,0); -- Pyrogenics diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1d2ea3093f910..12a4db5584541 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,14 +8,6 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -if(WIN32 AND MSVC) - set(sources_windows - ${CMAKE_SOURCE_DIR}/src/common/Debugging/WheatyExceptionReport.cpp - ${CMAKE_SOURCE_DIR}/src/common/Debugging/WheatyExceptionReport.h - ${CMAKE_SOURCE_DIR}/src/common/WindowsSettings.manifest - ) -endif() - add_subdirectory(genrev) add_subdirectory(common) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 95cb07f8f8b48..4eec8a9987e9e 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -12,16 +12,22 @@ CollectSourceFiles( ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE_SOURCES # Exclude - ${CMAKE_CURRENT_SOURCE_DIR}/Debugging + ${CMAKE_CURRENT_SOURCE_DIR}/Debugging/Windows ${CMAKE_CURRENT_SOURCE_DIR}/Platform ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders) -# Manually set sources for Debugging directory as we don't want to include WheatyExceptionReport in common project -# It needs to be included both in authserver and worldserver for the static global variable to be properly initialized -# and to handle crash logs on windows -list(APPEND PRIVATE_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/Debugging/Errors.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Debugging/Errors.h) +if(WIN32) + CollectSourceFiles( + ${CMAKE_CURRENT_SOURCE_DIR}/Debugging/Windows + WINDOWS_DEBUGGING_SOURCES) + list(APPEND PRIVATE_SOURCES + ${WINDOWS_DEBUGGING_SOURCES}) + CollectSourceFiles( + ${CMAKE_CURRENT_SOURCE_DIR}/Platform/Windows + WINDOWS_PLATFORM_SOURCES) + list(APPEND PRIVATE_SOURCES + ${WINDOWS_PLATFORM_SOURCES}) +endif() if(USE_COREPCH) set(PRIVATE_PCH_HEADER PrecompiledHeaders/commonPCH.h) diff --git a/src/common/Debugging/WheatyExceptionReport.cpp b/src/common/Debugging/Windows/WheatyExceptionReport.cpp similarity index 99% rename from src/common/Debugging/WheatyExceptionReport.cpp rename to src/common/Debugging/Windows/WheatyExceptionReport.cpp index c9e3a985543a6..cec3a27e002f4 100644 --- a/src/common/Debugging/WheatyExceptionReport.cpp +++ b/src/common/Debugging/Windows/WheatyExceptionReport.cpp @@ -67,9 +67,6 @@ std::stack WheatyExceptionReport::symbolDetails; bool WheatyExceptionReport::alreadyCrashed; std::mutex WheatyExceptionReport::alreadyCrashedLock; WheatyExceptionReport::pRtlGetVersion WheatyExceptionReport::RtlGetVersion; - -// Declare global instance of class -WheatyExceptionReport g_WheatyExceptionReport; #pragma warning(pop) //============================== Class Methods ============================= diff --git a/src/common/Debugging/WheatyExceptionReport.h b/src/common/Debugging/Windows/WheatyExceptionReport.h similarity index 97% rename from src/common/Debugging/WheatyExceptionReport.h rename to src/common/Debugging/Windows/WheatyExceptionReport.h index baca9699c5b05..d154fce0d1380 100644 --- a/src/common/Debugging/WheatyExceptionReport.h +++ b/src/common/Debugging/Windows/WheatyExceptionReport.h @@ -3,6 +3,7 @@ #define _NO_CVCONST_H +#include "Define.h" #include "Optional.h" #include #include @@ -322,7 +323,7 @@ struct SymbolDetail bool HasChildren; }; -class WheatyExceptionReport +class TC_COMMON_API WheatyExceptionReport { public: @@ -396,5 +397,11 @@ class WheatyExceptionReport }; -extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class +#define INIT_CRASH_HANDLER() \ + __pragma(warning(push)) \ + __pragma(warning(disable:4073)) /* C4073: initializers put in library initialization area */ \ + __pragma(init_seg(lib)) \ + WheatyExceptionReport g_WheatyExceptionReport; \ + __pragma(warning(pop)) + #endif // _WHEATYEXCEPTIONREPORT_ diff --git a/src/common/Platform/ServiceWin32.cpp b/src/common/Platform/Windows/ServiceWin32.cpp similarity index 57% rename from src/common/Platform/ServiceWin32.cpp rename to src/common/Platform/Windows/ServiceWin32.cpp index 19e572081fc5d..80914d2a41511 100644 --- a/src/common/Platform/ServiceWin32.cpp +++ b/src/common/Platform/Windows/ServiceWin32.cpp @@ -15,49 +15,50 @@ * with this program. If not, see . */ -#ifdef _WIN32 - -#include "Log.h" +#include "ServiceWin32.h" +#include // for std::size +#include +#include #include -#include #include #include -#if !defined(WINADVAPI) -#if !defined(_ADVAPI32_) -#define WINADVAPI DECLSPEC_IMPORT -#else -#define WINADVAPI -#endif -#endif - -extern int main(int argc, char ** argv); -extern TCHAR serviceLongName[]; -extern TCHAR serviceName[]; -extern TCHAR serviceDescription[]; - -extern int m_ServiceStatus; - -SERVICE_STATUS serviceStatus; +namespace +{ +_TCHAR* ServiceLongName; +_TCHAR* ServiceName; +_TCHAR* ServiceDescription; +int(*ServiceEntryPoint)(int argc, char** argv); +int* ServiceStatusPtr; + +SERVICE_STATUS ServiceStatus; +SERVICE_STATUS_HANDLE ServiceStatusHandle = nullptr; +} -SERVICE_STATUS_HANDLE serviceStatusHandle = nullptr; +typedef BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID); -typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID); +void Trinity::Service::Init(_TCHAR* serviceLongName, _TCHAR* serviceName, _TCHAR* serviceDescription, int(* entryPoint)(int argc, char** argv), int* status) +{ + ServiceLongName = serviceLongName; + ServiceName = serviceName; + ServiceDescription = serviceDescription; + ServiceEntryPoint = entryPoint; + ServiceStatusPtr = status; +} -bool WinServiceInstall() +int32 Trinity::Service::Install() { SC_HANDLE serviceControlManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE); if (serviceControlManager) { TCHAR path[_MAX_PATH + 10]; - if (GetModuleFileName( nullptr, path, sizeof(path)/sizeof(path[0]) ) > 0) + if (GetModuleFileName(nullptr, path, std::size(path)) > 0) { - SC_HANDLE service; _tcscat(path, _T(" --service run")); - service = CreateService(serviceControlManager, - serviceName, // name of service - serviceLongName, // service name to display + SC_HANDLE service = CreateService(serviceControlManager, + ServiceName, // name of service + ServiceLongName, // service name to display SERVICE_ALL_ACCESS, // desired access // service type SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, @@ -71,25 +72,9 @@ bool WinServiceInstall() nullptr); // no password if (service) { - HMODULE advapi32 = GetModuleHandle(_T("ADVAPI32.DLL")); - if (!advapi32) - { - CloseServiceHandle(service); - CloseServiceHandle(serviceControlManager); - return false; - } - - CSD_T ChangeService_Config2 = (CSD_T) GetProcAddress(advapi32, "ChangeServiceConfig2A"); - if (!ChangeService_Config2) - { - CloseServiceHandle(service); - CloseServiceHandle(serviceControlManager); - return false; - } - SERVICE_DESCRIPTION sdBuf; - sdBuf.lpDescription = serviceDescription; - ChangeService_Config2( + sdBuf.lpDescription = ServiceDescription; + ChangeServiceConfig2( service, // handle to service SERVICE_CONFIG_DESCRIPTION, // change: description &sdBuf); // new data @@ -101,8 +86,8 @@ bool WinServiceInstall() ZeroMemory(&sfa, sizeof(SERVICE_FAILURE_ACTIONS)); sfa.lpsaActions = _action; sfa.cActions = 1; - sfa.dwResetPeriod =INFINITE; - ChangeService_Config2( + sfa.dwResetPeriod = INFINITE; + ChangeServiceConfig2( service, // handle to service SERVICE_CONFIG_FAILURE_ACTIONS, // information level &sfa); // new data @@ -115,17 +100,17 @@ bool WinServiceInstall() } printf("Service installed\n"); - return true; + return 0; } -bool WinServiceUninstall() +int32 Trinity::Service::Uninstall() { SC_HANDLE serviceControlManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT); if (serviceControlManager) { SC_HANDLE service = OpenService(serviceControlManager, - serviceName, SERVICE_QUERY_STATUS | DELETE); + ServiceName, SERVICE_QUERY_STATUS | DELETE); if (service) { SERVICE_STATUS serviceStatus2; @@ -141,7 +126,7 @@ bool WinServiceUninstall() } printf("Service uninstalled\n"); - return true; + return 0; } void WINAPI ServiceControlHandler(DWORD controlCode) @@ -153,26 +138,26 @@ void WINAPI ServiceControlHandler(DWORD controlCode) case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: - serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); + ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); - m_ServiceStatus = 0; + *ServiceStatusPtr = 0; return; case SERVICE_CONTROL_PAUSE: - m_ServiceStatus = 2; - serviceStatus.dwCurrentState = SERVICE_PAUSED; - SetServiceStatus(serviceStatusHandle, &serviceStatus); + *ServiceStatusPtr = 2; + ServiceStatus.dwCurrentState = SERVICE_PAUSED; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); break; case SERVICE_CONTROL_CONTINUE: - serviceStatus.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - m_ServiceStatus = 1; + ServiceStatus.dwCurrentState = SERVICE_RUNNING; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); + *ServiceStatusPtr = 1; break; default: - if ( controlCode >= 128 && controlCode <= 255 ) + if (controlCode >= 128 && controlCode <= 255) // user defined control code break; else @@ -180,7 +165,7 @@ void WINAPI ServiceControlHandler(DWORD controlCode) break; } - SetServiceStatus(serviceStatusHandle, &serviceStatus); + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); } template @@ -195,81 +180,77 @@ void TCharToChar(TCHAR const* src, char(&dst)[size]) void WINAPI ServiceMain(DWORD /*argc*/, TCHAR *argv[]) { // initialise service status - serviceStatus.dwServiceType = SERVICE_WIN32; - serviceStatus.dwCurrentState = SERVICE_START_PENDING; - serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; - serviceStatus.dwWin32ExitCode = NO_ERROR; - serviceStatus.dwServiceSpecificExitCode = NO_ERROR; - serviceStatus.dwCheckPoint = 0; - serviceStatus.dwWaitHint = 0; + ServiceStatus.dwServiceType = SERVICE_WIN32; + ServiceStatus.dwCurrentState = SERVICE_START_PENDING; + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; + ServiceStatus.dwWin32ExitCode = NO_ERROR; + ServiceStatus.dwServiceSpecificExitCode = NO_ERROR; + ServiceStatus.dwCheckPoint = 0; + ServiceStatus.dwWaitHint = 0; - serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler); + ServiceStatusHandle = RegisterServiceCtrlHandler(ServiceName, ServiceControlHandler); - if ( serviceStatusHandle ) + if (ServiceStatusHandle) { TCHAR path[_MAX_PATH + 1]; - unsigned int i, last_slash = 0; + size_t last_slash = 0; - GetModuleFileName(nullptr, path, sizeof(path)/sizeof(path[0])); - - size_t pathLen = _tcslen(path); - for (i = 0; i < pathLen; i++) - { - if (path[i] == '\\') last_slash = i; - } + size_t pathLen = GetModuleFileName(nullptr, path, std::size(path)); + for (size_t i = 0; i < pathLen; i++) + if (path[i] == '\\') + last_slash = i; path[last_slash] = 0; // service is starting - serviceStatus.dwCurrentState = SERVICE_START_PENDING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); + ServiceStatus.dwCurrentState = SERVICE_START_PENDING; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); // do initialisation here SetCurrentDirectory(path); // running - serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); - serviceStatus.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus( serviceStatusHandle, &serviceStatus ); + ServiceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); + ServiceStatus.dwCurrentState = SERVICE_RUNNING; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); //////////////////////// // service main cycle // //////////////////////// - m_ServiceStatus = 1; + *ServiceStatusPtr = 1; char cArg[_MAX_PATH + 1]; TCharToChar(argv[0], cArg); char* cArgv[] = { cArg }; - main(1, cArgv); + ServiceEntryPoint(1, cArgv); // service was stopped - serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); + ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); // do cleanup here // service is now stopped - serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); - serviceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(serviceStatusHandle, &serviceStatus); + ServiceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); + ServiceStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); } } -bool WinServiceRun() +int32 Trinity::Service::Run() { SERVICE_TABLE_ENTRY serviceTable[] = { - { serviceName, ServiceMain }, + { ServiceName, ServiceMain }, { nullptr, nullptr } }; if (!StartServiceCtrlDispatcher(serviceTable)) { - TC_LOG_ERROR("server.worldserver", "StartService Failed. Error [{}]", uint32(::GetLastError())); - return false; + printf("StartService Failed. Error [%u]", uint32(::GetLastError())); + return 1; } - return true; + return 0; } -#endif diff --git a/src/common/Platform/ServiceWin32.h b/src/common/Platform/Windows/ServiceWin32.h similarity index 60% rename from src/common/Platform/ServiceWin32.h rename to src/common/Platform/Windows/ServiceWin32.h index baa983f8f6f75..8602c12fedfa5 100644 --- a/src/common/Platform/ServiceWin32.h +++ b/src/common/Platform/Windows/ServiceWin32.h @@ -15,13 +15,19 @@ * with this program. If not, see . */ -#ifdef _WIN32 -#ifndef _WIN32_SERVICE_ -#define _WIN32_SERVICE_ +#ifndef TRINITYCORE_WIN32_SERVICE +#define TRINITYCORE_WIN32_SERVICE -bool WinServiceInstall(); -bool WinServiceUninstall(); -bool WinServiceRun(); +#include "Define.h" +#include -#endif // _WIN32_SERVICE_ -#endif // _WIN32 +namespace Trinity::Service +{ + TC_COMMON_API void Init(_TCHAR* serviceLongName, _TCHAR* serviceName, _TCHAR* serviceDescription, + int(*entryPoint)(int argc, char** argv), int* status); + TC_COMMON_API int32 Install(); + TC_COMMON_API int32 Uninstall(); + TC_COMMON_API int32 Run(); +} + +#endif // TRINITYCORE_WIN32_SERVICE diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 235ad973a40dd..ca39031f95f37 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -8,13 +8,6 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -if(WIN32) - list(APPEND sources_windows - ${CMAKE_SOURCE_DIR}/src/common/Platform/ServiceWin32.cpp - ${CMAKE_SOURCE_DIR}/src/common/Platform/ServiceWin32.h - ) -endif(WIN32) - add_subdirectory(database) add_subdirectory(proto) add_subdirectory(shared) diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt index ffb37f4012f8d..951e4abb2e10f 100644 --- a/src/server/bnetserver/CMakeLists.txt +++ b/src/server/bnetserver/CMakeLists.txt @@ -16,8 +16,6 @@ CollectSourceFiles( # Exclude ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders) -list(APPEND PRIVATE_SOURCES ${sources_windows}) - if (WIN32) if (MSVC) list(APPEND PRIVATE_SOURCES bnetserver.rc) diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index e9ae51847c5ed..cc28891ecefbb 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -111,12 +111,13 @@ int main(int argc, char** argv) auto protobufHandle = Trinity::make_unique_ptr_with_deleter(&dummy, [](void*) { google::protobuf::ShutdownProtobufLibrary(); }); #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS + Trinity::Service::Init(serviceLongName, serviceName, serviceDescription, &main, &m_ServiceStatus); if (winServiceAction == "install") - return WinServiceInstall() ? 0 : 1; + return Trinity::Service::Install(); if (winServiceAction == "uninstall") - return WinServiceUninstall() ? 0 : 1; + return Trinity::Service::Uninstall(); if (winServiceAction == "run") - return WinServiceRun() ? 0 : 1; + return Trinity::Service::Run(); #endif std::string configError; @@ -434,3 +435,9 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, f return variablesMap; } + +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS +#include "WheatyExceptionReport.h" +// must be at end of file because of init_seg pragma +INIT_CRASH_HANDLER(); +#endif diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 1eb7523ccec33..fc810d573e693 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -21,26 +21,6 @@ * Scriptnames of files in this file should be prefixed with "spell_warl_". */ -#include "AreaTriggerAI.h" -#include "AreaTriggerTemplate.h" -#include "Battleground.h" -#include "SpellPackets.h" -#include "ObjectMgr.h" -#include "Object.h" -#include "CellImpl.h" -#include "DatabaseEnv.h" -#include "GridNotifiersImpl.h" -#include "GameObjectAI.h" -#include "Unit.h" -#include "Spell.h" -#include "PetAI.h" -#include "ScriptedCreature.h" -#include "PassiveAI.h" -#include "CombatAI.h" -#include "Item.h" -#include -#include - #include "ScriptMgr.h" #include "AreaTrigger.h" #include "Containers.h" @@ -59,10 +39,10 @@ enum WarlockSpells { - SPELL_WARLOCK_BACKDRAFT = 196406, - SPELL_WARLOCK_BACKDRAFT_PROC = 117828, SPELL_WARLOCK_ABSOLUTE_CORRUPTION = 196103, SPELL_WARLOCK_AGONY = 980, + SPELL_WARLOCK_BACKDRAFT = 196406, + SPELL_WARLOCK_BACKDRAFT_PROC = 117828, SPELL_WARLOCK_CONFLAGRATE_DEBUFF = 265931, SPELL_WARLOCK_CONFLAGRATE_ENERGIZE = 245330, SPELL_WARLOCK_CORRUPTION_DAMAGE = 146739, @@ -75,6 +55,7 @@ enum WarlockSpells SPELL_WARLOCK_DEVOUR_MAGIC_HEAL = 19658, SPELL_WARLOCK_DOOM_ENERGIZE = 193318, SPELL_WARLOCK_DRAIN_SOUL_ENERGIZE = 205292, + SPELL_WARLOCK_FLAMESHADOW = 37379, SPELL_WARLOCK_GLYPH_OF_DEMON_TRAINING = 56249, SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP = 56226, SPELL_WARLOCK_GLYPH_OF_SUCCUBUS = 56250, @@ -83,90 +64,34 @@ enum WarlockSpells SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2 = 60956, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R2 = 18704, - SPELL_WARLOCK_PERPETUAL_UNSTABILITY_TALENT = 459376, + SPELL_WARLOCK_INCUBUS_PACT = 365355, SPELL_WARLOCK_PERPETUAL_UNSTABILITY_DAMAGE = 459461, - SPELL_WARLOCK_PYROGENICS_TALENT = 387095, + SPELL_WARLOCK_PERPETUAL_UNSTABILITY_TALENT = 459376, SPELL_WARLOCK_PYROGENICS_DEBUFF = 387096, + SPELL_WARLOCK_PYROGENICS_TALENT = 387095, SPELL_WARLOCK_RAIN_OF_FIRE = 5740, SPELL_WARLOCK_RAIN_OF_FIRE_DAMAGE = 42223, SPELL_WARLOCK_ROARING_BLAZE = 205184, SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE = 27285, SPELL_WARLOCK_SEED_OF_CORRUPTION_GENERIC = 32865, SPELL_WARLOCK_SHADOW_BOLT_ENERGIZE = 194192, + SPELL_WARLOCK_SHADOWFLAME = 37378, SPELL_WARLOCK_SIPHON_LIFE_HEAL = 453000, - SPELL_WARLOCK_SOULSHATTER_EFFECT = 32835, SPELL_WARLOCK_SOUL_SWAP_CD_MARKER = 94229, - SPELL_WARLOCK_SOUL_SWAP_OVERRIDE = 86211, - SPELL_WARLOCK_SOUL_SWAP_MOD_COST = 92794, SPELL_WARLOCK_SOUL_SWAP_DOT_MARKER = 92795, - SPELL_WARLOCK_UNSTABLE_AFFLICTION_DAMAGE = 196364, - SPELL_WARLOCK_UNSTABLE_AFFLICTION_ENERGIZE = 31117, - SPELL_WARLOCK_SHADOWFLAME = 37378, - SPELL_WARLOCK_FLAMESHADOW = 37379, - SPELL_WARLOCK_SUMMON_SUCCUBUS = 712, - SPELL_WARLOCK_SUMMON_INCUBUS = 365349, - SPELL_WARLOCK_STRENGTHEN_PACT_SUCCUBUS = 366323, + SPELL_WARLOCK_SOUL_SWAP_MOD_COST = 92794, + SPELL_WARLOCK_SOUL_SWAP_OVERRIDE = 86211, + SPELL_WARLOCK_SOULSHATTER_EFFECT = 32835, SPELL_WARLOCK_STRENGTHEN_PACT_INCUBUS = 366325, + SPELL_WARLOCK_STRENGTHEN_PACT_SUCCUBUS = 366323, SPELL_WARLOCK_SUCCUBUS_PACT = 365360, - SPELL_WARLOCK_INCUBUS_PACT = 365355, + SPELL_WARLOCK_SUMMON_INCUBUS = 365349, + SPELL_WARLOCK_SUMMON_SUCCUBUS = 712, + SPELL_WARLOCK_UNSTABLE_AFFLICTION_DAMAGE = 196364, + SPELL_WARLOCK_UNSTABLE_AFFLICTION_ENERGIZE = 31117, SPELL_WARLOCK_VILE_TAINT_DAMAGE = 386931, - SPELL_WARLOCK_VOLATILE_AGONY_TALENT = 453034, SPELL_WARLOCK_VOLATILE_AGONY_DAMAGE = 453035, - - SPELL_WARLOCK_FEAR = 5782, - SPELL_WARLOCK_FEAR_BUFF = 118699, - SPELL_WARLOCK_FEAR_EFFECT = 118699, - SPELL_WARLOCK_PHANTOMATIC_SINGULARITY_DAMAGE = 205246, - SPELL_WARLOCK_HAUNT = 48181, - SPELL_WARLOCK_DOOM = 603, - SPELL_WARLOCK_EYE_LASER = 205231, - SPELL_WARLOCK_SOULBURN = 74434, - SPELL_WARLOCK_SOULBURN_UNENDING_BREATH = 104242, - SPELL_WARLOCK_DEMONIC_GATEWAY_PERIODIC_CHARGE = 113901, - SPELL_WARLOCK_DEMONIC_GATEWAY_SUMMON_GREEN = 113886, - SPELL_WARLOCK_DEMONIC_GATEWAY_SUMMON_PURPLE = 113890, - SPELL_WARLOCK_DEMONIC_GATEWAY_JUMP_GREEN = 113896, - SPELL_WARLOCK_DEMONIC_GATEWAY_JUMP_PURPLE = 120729, - SPELL_WARLOCK_DEMONIC_GATEWAY_VISUAL = 113900, - SPELL_WARLOCK_DEMONIC_GATEWAY_DEBUFF = 113942, - SPELL_WARLOCK_PLANESWALKER = 196675, - SPELL_WARLOCK_PLANESWALKER_BUFF = 196674, - SPELL_WARLOCK_PVP_4P_BONUS = 143395, - SPELL_WARLOCK_HAND_OF_DOOM = 196283, - SPELL_WARLOCK_HAND_OF_GULDAN_DAMAGE = 86040, - SPELL_WARLOCK_CALL_DREADSTALKERS_SUMMON = 364750, - SPELL_WARLOCK_IMPROVED_DREADSTALKERS = 196272, - SPELL_WARLOCK_WILD_IMP_SUMMON = 104317, - SPELL_DEMONBOLT_ENERGIZE = 280127, - SPELL_WARLOCK_DEMONIC_CALLING_TRIGGER = 205146, - SPELL_WARLOCK_DEMONBOLT = 157695, - SPELL_WARLOCK_SHADOW_BOLT = 686, - SPELL_WARLOCK_IMPLOSION_DAMAGE = 196278, - SPELL_WARLOCK_IMPLOSION_JUMP = 205205, - SPELL_WARLOCK_IMPENDING_DOOM = 196270, - SPELL_WARLOCK_DOOM_DOUBLED = 218572, - SPELL_WARLOCK_IMMOLATE = 348, - SPELL_WARLOCK_IMMOLATE_DOT = 157736, - SPELL_WARLOCK_GLYPH_OF_CONFLAGRATE = 56235, - SPELL_WARLOCK_CONFLAGRATE = 17962, - SPELL_WARLOCK_CONFLAGRATE_FIRE_AND_BRIMSTONE = 108685, - SPELL_WARLOCK_IMMOLATE_FIRE_AND_BRIMSTONE = 108686, - SPELL_WARLOCK_SOUL_FIRE = 6353, - SPELL_WARLOCK_CHANNEL_DEMONFIRE_DAMAGE = 196448, - SPELL_WARLOCK_SOUL_CONDUIT_REFUND = 215942, - SPELL_SHADOW_EMBRACE = 32388, - SPELL_SHADOW_EMBRACE_TARGET_DEBUFF = 32390, - SPELL_WARLOCK_INFERNAL_FURNACE = 211119, - SPELL_WARLOCK_STOLEN_POWER = 211530, - SPELL_WARLOCK_STOLEN_POWER_COUNTER = 211529, - SPELL_WARLOCK_STOLEN_POWER_BUFF = 211583, - SPELL_WARLOCK_FEL_FIREBOLT = 104318, - SPELL_INQUISITORS_GAZE = 386344, - SPELL_WARLOCK_FIRE_AND_BRIMSTONE = 196408, - SPELL_WARLOCK_FIREBOLT_BONUS = 231795, - SPELL_WARLOCK_DREADSTALKER_CHARGE = 194247, - SPELL_WARLOCK_SHARPENED_DREADFANGS_BUFF = 215111, - SPELL_WARLOCK_SHARPENED_DREADFANGS = 211123, + SPELL_WARLOCK_VOLATILE_AGONY_TALENT = 453034 }; enum MiscSpells @@ -175,33 +100,6 @@ enum MiscSpells SPELL_PRIEST_SHADOW_WORD_DEATH = 32409 }; -enum FreakzWarlockNPCs -{ - NPC_WARLOCK_DEMONIC_GATEWAY_PURPLE = 59271, - NPC_WARLOCK_DEMONIC_GATEWAY_GREEN = 59262, -}; - -// Called by 17962 - Conflagrate -class spell_warl_backdraft : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_BACKDRAFT, SPELL_WARLOCK_BACKDRAFT_PROC }); - } - - void HandleAfterCast() - { - Unit* caster = GetCaster(); - if (caster->HasAura(SPELL_WARLOCK_BACKDRAFT)) - caster->CastSpell(caster, SPELL_WARLOCK_BACKDRAFT_PROC, true); - } - - void Register() override - { - AfterCast += SpellCastFn(spell_warl_backdraft::HandleAfterCast); - } -}; - // 146739 - Corruption // 445474 - Wither class spell_warl_absolute_corruption : public SpellScript @@ -235,6 +133,34 @@ class spell_warl_absolute_corruption : public SpellScript } }; +// Called by 17962 - Conflagrate +class spell_warl_backdraft : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo ({ SPELL_WARLOCK_BACKDRAFT, SPELL_WARLOCK_BACKDRAFT_PROC }); + } + + bool Load() override + { + return GetCaster()->HasAura(SPELL_WARLOCK_BACKDRAFT); + } + + void HandleAfterCast() const + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, SPELL_WARLOCK_BACKDRAFT_PROC, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .TriggeringSpell = GetSpell() + }); + } + + void Register() override + { + AfterCast += SpellCastFn(spell_warl_backdraft::HandleAfterCast); + } +}; + // 710 - Banish class spell_warl_banish : public SpellScript { @@ -306,6 +232,28 @@ class spell_warl_burning_rush_aura : public AuraScript } }; +// 152108 - Cataclysm +class spell_warl_cataclysm : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_IMMOLATE_PERIODIC }); + } + + void HandleHit(SpellEffIndex /*effIndex*/) const + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_WARLOCK_IMMOLATE_PERIODIC, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .TriggeringSpell = GetSpell() + }); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_warl_cataclysm::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } +}; + // 116858 - Chaos Bolt class spell_warl_chaos_bolt : public SpellScript { @@ -331,25 +279,6 @@ class spell_warl_chaos_bolt : public SpellScript } }; -// 152108 - Cataclysm -class spell_warl_cataclysm : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_IMMOLATE_PERIODIC }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_WARLOCK_IMMOLATE_PERIODIC, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warl_cataclysm::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } -}; - // 77220 - Mastery: Chaotic Energies class spell_warl_chaotic_energies : public AuraScript { @@ -801,6 +730,28 @@ class spell_warl_perpetual_unstability : public SpellScript } }; +// 387095 - Pyrogenics +class spell_warl_pyrogenics : public AuraScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_PYROGENICS_DEBUFF }); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& procInfo) const + { + GetTarget()->CastSpell(procInfo.GetActionTarget(), SPELL_WARLOCK_PYROGENICS_DEBUFF, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .TriggeringAura = aurEff + }); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_warl_pyrogenics::HandleProc, EFFECT_0, SPELL_AURA_ADD_FLAT_MODIFIER_BY_SPELL_LABEL); + } +}; + // 5740 - Rain of Fire /// Updated 11.0.2 class spell_warl_rain_of_fire : public AuraScript @@ -1516,1322 +1467,15 @@ class spell_warl_volatile_agony : public SpellScript } }; -//5782 - Fear -class spell_warl_fear : public SpellScriptLoader -{ -public: - spell_warl_fear() : SpellScriptLoader("spell_warl_fear") {} - - class spell_warl_fear_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warl_fear_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_FEAR, DIFFICULTY_NONE)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_FEAR_BUFF, DIFFICULTY_NONE)) - return false; - return true; - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - Unit* target = GetExplTargetUnit(); - if (!target) - return; - - caster->CastSpell(target, SPELL_WARLOCK_FEAR_BUFF, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warl_fear_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warl_fear_SpellScript(); - } -}; - -//204730 - Fear (effect) -class spell_warl_fear_buff : public SpellScriptLoader -{ -public: - spell_warl_fear_buff() : SpellScriptLoader("spell_warl_fear_buff") {} - - class spell_warl_fear_buff_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warl_fear_buff_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_FEAR_BUFF, DIFFICULTY_NONE)) - return false; - return true; - } - - void HandleAfterHit() - { - if (Aura* aura = GetHitAura()) - { - aura->SetMaxDuration(20 * IN_MILLISECONDS); - aura->SetDuration(20 * IN_MILLISECONDS); - aura->RefreshDuration(); - } - } - - void Register() override - { - AfterHit += SpellHitFn(spell_warl_fear_buff_SpellScript::HandleAfterHit); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warl_fear_buff_SpellScript(); - } -}; - -//146739 - Corruption effect -class spell_warl_corruption_effect : public AuraScript -{ - PrepareAuraScript(spell_warl_corruption_effect); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_ABSOLUTE_CORRUPTION, DIFFICULTY_NONE)) - return false; - return true; - } - - void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - Unit* caster = GetCaster(); - if (!target || !caster) - return; - - //If the target is a player, only cast for the time said in ABSOLUTE_CORRUPTION - if (caster->HasAura(SPELL_WARLOCK_ABSOLUTE_CORRUPTION)) - GetAura()->SetDuration(target->GetTypeId() == TYPEID_PLAYER ? sSpellMgr->GetSpellInfo(SPELL_WARLOCK_ABSOLUTE_CORRUPTION, DIFFICULTY_NONE)->GetEffect(EFFECT_0).BasePoints * IN_MILLISECONDS : 60 * 60 * IN_MILLISECONDS); //If not player, 1 hour - } - - /* - Removes the aura if the caster is null, far away or dead. - */ - void HandlePeriodic(AuraEffect const* /*aurEff*/) - { - Unit* target = GetTarget(); - Unit* caster = GetCaster(); - if (!target) - return; - - if (!caster) - { - target->RemoveAura(SPELL_WARLOCK_CORRUPTION_DAMAGE); - return; - } - - if (caster->isDead()) - target->RemoveAura(SPELL_WARLOCK_CORRUPTION_DAMAGE); - - if (!caster->IsInRange(target, 0, 80)) - target->RemoveAura(SPELL_WARLOCK_CORRUPTION_DAMAGE); - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_warl_corruption_effect::HandleApply, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); - OnEffectPeriodic += AuraEffectPeriodicFn(spell_warl_corruption_effect::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); - } -}; - -// 234153 - Drain Life -class spell_warl_drain_life : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_DEATHS_EMBRACE }); - } - - void CalculateHeal(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& /*damage*/, int32& /*flatMod*/, float& pctMod) const - { - if (Unit* caster = GetCaster()) - { - if (AuraEffect const* deathsEmbraceHealthPct = caster->GetAuraEffect(SPELL_WARLOCK_DEATHS_EMBRACE, EFFECT_1)) - { - if (caster->HealthBelowPct(deathsEmbraceHealthPct->GetAmount())) - { - AuraEffect const* deathsEmbraceHealBonus = caster->GetAuraEffect(SPELL_WARLOCK_DEATHS_EMBRACE, EFFECT_0); - AddPct(pctMod, deathsEmbraceHealBonus->GetAmount()); - } - } - } - } - - void Register() override - { - DoEffectCalcDamageAndHealing += AuraEffectCalcDamageFn(spell_warl_drain_life::CalculateHeal, EFFECT_0, SPELL_AURA_PERIODIC_LEECH); - } -}; - -// 205179 -class aura_warl_phantomatic_singularity : public AuraScript -{ - PrepareAuraScript(aura_warl_phantomatic_singularity); - - void OnTick(const AuraEffect* /*aurEff*/) - { - if (Unit* caster = GetCaster()) - caster->CastSpell(GetTarget()->GetPosition(), SPELL_WARLOCK_PHANTOMATIC_SINGULARITY_DAMAGE, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(aura_warl_phantomatic_singularity::OnTick, EFFECT_0, SPELL_AURA_PERIODIC_LEECH); - } -}; - -// 48181 - Haunt -class aura_warl_haunt : public AuraScript -{ - PrepareAuraScript(aura_warl_haunt); - - void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* caster = GetCaster(); - if (!caster || GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH) - return; - - caster->GetSpellHistory()->ResetCooldown(SPELL_WARLOCK_HAUNT, true); - } - - void Register() override - { - OnEffectRemove += AuraEffectApplyFn(aura_warl_haunt::HandleRemove, EFFECT_1, SPELL_AURA_MOD_SCHOOL_MASK_DAMAGE_FROM_CASTER, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - } -}; - -// Summon Darkglare - 205180 -class spell_warlock_summon_darkglare : public SpellScript -{ - PrepareSpellScript(spell_warlock_summon_darkglare); - - void HandleOnHitTarget(SpellEffIndex /*effIndex*/) - { - if (Unit* target = GetHitUnit()) - { - Player::AuraEffectList effectList = target->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE); - /* - // crash here - for (AuraEffect* effect : effectList) - if (Aura* aura = effect->GetBase()) - aura->ModDuration(8 * IN_MILLISECONDS); - */ - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warlock_summon_darkglare::HandleOnHitTarget, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - } -}; - -// Darkglare - 103673 -class npc_pet_warlock_darkglare : public CreatureScript -{ -public: - npc_pet_warlock_darkglare() : CreatureScript("npc_pet_warlock_darkglare") {} - - struct npc_pet_warlock_darkglare_PetAI : public PetAI - { - npc_pet_warlock_darkglare_PetAI(Creature* creature) : PetAI(creature) {} - - void UpdateAI(uint32 /*diff*/) override - { - Unit* owner = me->GetOwner(); - if (!owner) - return; - - std::list targets; - owner->GetAttackableUnitListInRange(targets, 100.0f); - targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_WARLOCK_DOOM, owner->GetGUID())); - if (!targets.empty()) - me->CastSpell(targets.front(), SPELL_WARLOCK_EYE_LASER, CastSpellExtraArgs(TRIGGERED_NONE).SetOriginalCaster(owner->GetGUID())); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_pet_warlock_darkglare_PetAI(creature); - } -}; - -// 5697 - Unending Breath -class spell_warlock_unending_breath : public SpellScriptLoader -{ -public: - spell_warlock_unending_breath() : SpellScriptLoader("spell_warlock_unending_breath") { } - - class spell_warlock_unending_breath_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warlock_unending_breath_SpellScript); - - void HandleHit(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) - if (caster->HasAura(SPELL_WARLOCK_SOULBURN)) - caster->CastSpell(target, SPELL_WARLOCK_SOULBURN_UNENDING_BREATH, true); - } - - void Register() override - { - OnEffectLaunchTarget += SpellEffectFn(spell_warlock_unending_breath_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_APPLY_AURA); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warlock_unending_breath_SpellScript(); - } -}; - -// Demonic Gateway - 111771 -class spell_warl_demonic_gateway : public SpellScriptLoader -{ -public: - spell_warl_demonic_gateway() : SpellScriptLoader("spell_warl_demonic_gateway") { } - - class spell_warl_demonic_gateway_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warl_demonic_gateway_SpellScript); - - void HandleLaunch(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - - // despawn all other gateways - std::list targets1, targets2; - caster->GetCreatureListWithEntryInGrid(targets1, NPC_WARLOCK_DEMONIC_GATEWAY_GREEN, 200.0f); - caster->GetCreatureListWithEntryInGrid(targets2, NPC_WARLOCK_DEMONIC_GATEWAY_PURPLE, 200.0f); - targets1.insert(targets1.end(), targets2.begin(), targets2.end()); - for (auto target : targets1) - { - if (target->GetOwnerGUID() != caster->GetGUID()) - continue; - target->DespawnOrUnsummon(100ms); // despawn at next tick - } - - if (WorldLocation const* dest = GetExplTargetDest()) { - caster->CastSpell(caster, SPELL_WARLOCK_DEMONIC_GATEWAY_SUMMON_PURPLE, true); - caster->CastSpell(*dest, SPELL_WARLOCK_DEMONIC_GATEWAY_SUMMON_GREEN, true); - } - } - - SpellCastResult CheckRequirement() - { - // don't allow during Arena Preparation - if (GetCaster()->HasAura(SPELL_ARENA_PREPARATION)) - return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - - // check if player can reach the location - Spell* spell = GetSpell(); - if (spell->m_targets.HasDst()) - { - Position pos; - pos = spell->m_targets.GetDst()->_position.GetPosition(); - Unit* caster = GetCaster(); - - if (caster->GetPositionZ() + 6.0f < pos.GetPositionZ() || - caster->GetPositionZ() - 6.0f > pos.GetPositionZ()) - return SPELL_FAILED_NOPATH; - } - - return SPELL_CAST_OK; - } - - void HandleVisual(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - WorldLocation const* dest = GetExplTargetDest(); - if (!caster || !dest) - return; - - Position pos = dest->GetPosition(); - - caster->SendPlaySpellVisual(pos, 63644, 0, 0, 2.0f); - } - - void Register() override - { - OnEffectLaunch += SpellEffectFn(spell_warl_demonic_gateway_SpellScript::HandleVisual, EFFECT_0, SPELL_EFFECT_SUMMON); - OnEffectLaunch += SpellEffectFn(spell_warl_demonic_gateway_SpellScript::HandleLaunch, EFFECT_1, SPELL_EFFECT_DUMMY); - OnCheckCast += SpellCheckCastFn(spell_warl_demonic_gateway_SpellScript::CheckRequirement); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warl_demonic_gateway_SpellScript(); - } -}; - -class npc_warl_demonic_gateway : public CreatureScript -{ -public: - npc_warl_demonic_gateway() : CreatureScript("npc_warl_demonic_gateway") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_warl_demonic_gatewayAI(creature); - } - - struct npc_warl_demonic_gatewayAI : public CreatureAI - { - npc_warl_demonic_gatewayAI(Creature* creature) : CreatureAI(creature) { } - - EventMap events; - bool firstTick = true; - - void UpdateAI(uint32 /*diff*/) override - { - if (firstTick) - { - me->CastSpell(me, SPELL_WARLOCK_DEMONIC_GATEWAY_VISUAL, true); - - //todo me->SetInteractSpellId(SPELL_WARLOCK_DEMONIC_GATEWAY_ACTIVATE); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetNpcFlag(UNIT_NPC_FLAG_SPELLCLICK); - me->SetReactState(ReactStates::REACT_PASSIVE); - me->SetControlled(true, UNIT_STATE_ROOT); - - firstTick = false; - } - } - - void OnSpellClick(Unit* player, bool /*result*/) override - { - // don't allow using the gateway while having specific auras - uint32 aurasToCheck[4] = { 121164, 121175, 121176, 121177 }; // Orbs of Power @ Temple of Kotmogu - for (auto auraToCheck : aurasToCheck) - if (player->HasAura(auraToCheck)) - return; - - TeleportTarget(player, true); - return; - } - - void TeleportTarget(Unit* target, bool allowAnywhere) - { - Unit* owner = me->GetOwner(); - if (!owner) - return; - - // only if target stepped through the portal - if (!allowAnywhere && me->GetDistance2d(target) > 1.0f) - return; - // check if target wasn't recently teleported - if (target->HasAura(SPELL_WARLOCK_DEMONIC_GATEWAY_DEBUFF)) - return; - // only if in same party - if (!target->IsInRaidWith(owner)) - return; - // not allowed while CC'ed - if (!target->CanFreeMove()) - return; - - uint32 otherGateway = me->GetEntry() == NPC_WARLOCK_DEMONIC_GATEWAY_GREEN ? NPC_WARLOCK_DEMONIC_GATEWAY_PURPLE : NPC_WARLOCK_DEMONIC_GATEWAY_GREEN; - uint32 teleportSpell = me->GetEntry() == NPC_WARLOCK_DEMONIC_GATEWAY_GREEN ? SPELL_WARLOCK_DEMONIC_GATEWAY_JUMP_GREEN : SPELL_WARLOCK_DEMONIC_GATEWAY_JUMP_PURPLE; - std::list gateways; - me->GetCreatureListWithEntryInGrid(gateways, otherGateway, 100.0f); - for (auto gateway : gateways) - { - if (gateway->GetOwnerGUID() != me->GetOwnerGUID()) - continue; - - target->CastSpell(gateway, teleportSpell, true); - if (target->HasAura(SPELL_WARLOCK_PLANESWALKER)) - target->CastSpell(target, SPELL_WARLOCK_PLANESWALKER_BUFF, true); - // Item - Warlock PvP Set 4P Bonus: "Your allies can use your Demonic Gateway again 15 sec sooner" - if (int32 amount = owner->GetAuraEffectAmount(SPELL_WARLOCK_PVP_4P_BONUS, EFFECT_0)) - if (Aura* aura = target->GetAura(SPELL_WARLOCK_DEMONIC_GATEWAY_DEBUFF)) - aura->SetDuration(aura->GetDuration() - amount * IN_MILLISECONDS); - break; - } - } - }; -}; - -// Hand of Gul'Dan - 105174 -class spell_warl_hand_of_guldan : public SpellScript -{ - PrepareSpellScript(spell_warl_hand_of_guldan); - - void HandleOnHit() - { - if (Unit* caster = GetCaster()) - { - if (Unit* target = GetHitUnit()) - { - int32 nrofsummons = 1; - nrofsummons += caster->GetPower(POWER_SOUL_SHARDS); - if (nrofsummons > 4) - nrofsummons = 4; - - int8 offsetX[4]{ 0, 0, 1, 1 }; - int8 offsetY[4]{ 0, 1, 0, 1 }; - - for (int i = 0; i < nrofsummons; i++) - caster->CastSpell(Position(target->GetPositionX() + offsetX[i], target->GetPositionY() + offsetY[i], target->GetPositionZ()), 104317, true); - caster->CastSpell(target, SPELL_WARLOCK_HAND_OF_GULDAN_DAMAGE, true); - } - } - } - - void Register() override - { - OnHit += SpellHitFn(spell_warl_hand_of_guldan::HandleOnHit); - } -}; - -// Hand of Guldan damage - 86040 -class spell_warl_hand_of_guldan_damage : public SpellScriptLoader -{ -public: - spell_warl_hand_of_guldan_damage() : SpellScriptLoader("spell_warl_hand_of_guldan_damage") { } - - class spell_warl_hand_of_guldan_damage_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warl_hand_of_guldan_damage_SpellScript); - - public: - spell_warl_hand_of_guldan_damage_SpellScript() - { - soulshards = 1; - } - - private: - - bool Load() override - { - soulshards += GetCaster()->GetPower(POWER_SOUL_SHARDS); - if (soulshards > 4) - { - GetCaster()->SetPower(POWER_SOUL_SHARDS, 1); - soulshards = 4; - - } - else - GetCaster()->SetPower(POWER_SOUL_SHARDS, 0); - return true; - } - - uint32 soulshards; - - void HandleOnHit(SpellEffIndex /*effIndex*/) - { - if (Unit* caster = GetCaster()) - { - if (Unit* target = GetHitUnit()) - { - uint32 dmg = GetHitDamage(); - SetHitDamage(dmg * soulshards); - - if (caster->HasAura(SPELL_WARLOCK_HAND_OF_DOOM)) - caster->CastSpell(target, SPELL_WARLOCK_DOOM, true); - } - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warl_hand_of_guldan_damage_SpellScript::HandleOnHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warl_hand_of_guldan_damage_SpellScript(); - } -}; - -// Call Dreadstalkers - 104316 -class spell_warlock_call_dreadstalkers : public SpellScriptLoader -{ -public: - spell_warlock_call_dreadstalkers() : SpellScriptLoader("spell_warlock_call_dreadstalkers") {} - - class spell_warlock_call_dreadstalkers_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warlock_call_dreadstalkers_SpellScript); - - void HandleHit(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - for (int32 i = 0; i < GetEffectValue(); ++i) - caster->CastSpell(caster, SPELL_WARLOCK_CALL_DREADSTALKERS_SUMMON, true); - - Player* player = caster->ToPlayer(); - if (!player) - return; - - // Check if player has aura with ID 387485 - if (Aura* aura = caster->GetAura(387485)) - { - auto effect = aura->GetEffect(0); - - if (roll_chance_i(effect->GetBaseAmount())) - caster->CastSpell(caster, SPELL_WARLOCK_CALL_DREADSTALKERS_SUMMON, true); - } - } - - void HandleAfterCast() - { - Unit* caster = GetCaster(); - Unit* target = GetExplTargetUnit(); - if (!caster || !target) - return; - - std::list dreadstalkers; - caster->GetCreatureListWithEntryInGrid(dreadstalkers, 98035); - for (auto it = dreadstalkers.begin(); it != dreadstalkers.end(); ++it) - { - Creature* dreadstalker = *it; - if (dreadstalker && dreadstalker->GetOwner() == caster) - { - int index = std::distance(dreadstalkers.begin(), it); - Position TeleportPos = Hoff::GetTargetFollowPosition(dreadstalker->GetOwner(), static_cast(7 - index), 3.f); - dreadstalker->NearTeleportTo(TeleportPos, false); - - dreadstalker->SetLevel(caster->GetLevel()); - dreadstalker->SetMaxHealth(caster->GetMaxHealth() / 3); - dreadstalker->SetHealth(caster->GetHealth() / 3); - - dreadstalker->AI()->AttackStart(target); - caster->GetThreatManager().AddThreat(target, 9999999.f); - } - } - - if (uint32 impsToSummon = caster->GetAuraEffectAmount(SPELL_WARLOCK_IMPROVED_DREADSTALKERS, EFFECT_0)) - for (uint32 i = 0; i < impsToSummon; ++i) - caster->CastSpell(target->GetRandomNearPosition(3.f), SPELL_WARLOCK_WILD_IMP_SUMMON, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warlock_call_dreadstalkers_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - AfterCast += SpellCastFn(spell_warlock_call_dreadstalkers_SpellScript::HandleAfterCast); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warlock_call_dreadstalkers_SpellScript(); - } -}; - -// Dreadstalker - 98035 -class npc_warlock_dreadstalker : public CreatureScript -{ -public: - npc_warlock_dreadstalker() : CreatureScript("npc_warlock_dreadstalker") {} - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_warlock_dreadstalkerAI(creature); - } - - struct npc_warlock_dreadstalkerAI : public ScriptedAI - { - npc_warlock_dreadstalkerAI(Creature* creature) : ScriptedAI(creature) {} - - bool firstTick = true; - - void UpdateAI(uint32 /*diff*/) override - { - if (firstTick) - { - Unit* owner = me->GetOwner(); - if (!me->GetOwner() || !me->GetOwner()->ToPlayer()) - return; - - me->SetMaxHealth(owner->CountPctFromMaxHealth(40)); - me->SetHealth(me->GetMaxHealth()); - - if (Unit* target = owner->ToPlayer()->GetSelectedUnit()) - me->CastSpell(target, SPELL_WARLOCK_DREADSTALKER_CHARGE, true); - - firstTick = false; - - me->CastSpell(me, SPELL_WARLOCK_SHARPENED_DREADFANGS_BUFF, SPELLVALUE_BASE_POINT0); - owner->GetAuraEffectAmount(SPELL_WARLOCK_SHARPENED_DREADFANGS, EFFECT_0), me, true; - } - - UpdateVictim(); - } - }; -}; - -// Eye Laser - 205231 -class spell_warl_eye_laser : public SpellScriptLoader -{ -public: - spell_warl_eye_laser() : SpellScriptLoader("spell_warl_eye_laser") {} - - class spell_warl_eye_laser_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warl_eye_laser_SpellScript); - - void HandleTargets(std::list& targets) - { - Unit* caster = GetOriginalCaster(); - if (!caster) - return; - targets.clear(); - Trinity::AllWorldObjectsInRange check(caster, 100.f); - Trinity::WorldObjectListSearcher search(caster, targets, check); - Cell::VisitAllObjects(caster, search, 100.f); - targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_WARLOCK_DOOM, caster->GetGUID())); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_eye_laser_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_TARGET_ENEMY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warl_eye_laser_SpellScript(); - } -}; - -// 264178 - Demonbolt -class spell_warlock_demonbolt_new : public SpellScriptLoader -{ -public: - spell_warlock_demonbolt_new() : SpellScriptLoader("spell_warlock_demonbolt_new") { } - - class spell_warlock_demonbolt_new_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warlock_demonbolt_new_SpellScript); - - void HandleHit(SpellEffIndex /*effIndex*/) - { - if (GetCaster()) - { - GetCaster()->CastSpell(GetCaster(), SPELL_DEMONBOLT_ENERGIZE, true); - GetCaster()->CastSpell(GetCaster(), SPELL_DEMONBOLT_ENERGIZE, true); - } - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_warlock_demonbolt_new_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warlock_demonbolt_new_SpellScript(); - } -}; - -// Demonic Calling - 205145 -class spell_warl_demonic_calling : public SpellScriptLoader -{ -public: - spell_warl_demonic_calling() : SpellScriptLoader("spell_warl_demonic_calling") {} - - class spell_warl_demonic_calling_AuraScript : public AuraScript - { - PrepareAuraScript(spell_warl_demonic_calling_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMONIC_CALLING_TRIGGER, DIFFICULTY_NONE)) - return false; - return true; - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - Unit* caster = GetCaster(); - if (!caster) - return false; - if (eventInfo.GetSpellInfo() && (eventInfo.GetSpellInfo()->Id == SPELL_WARLOCK_DEMONBOLT || eventInfo.GetSpellInfo()->Id == SPELL_WARLOCK_SHADOW_BOLT) && roll_chance_i(20)) - caster->CastSpell(caster, SPELL_WARLOCK_DEMONIC_CALLING_TRIGGER, true); - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_warl_demonic_calling_AuraScript::CheckProc); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_warl_demonic_calling_AuraScript(); - } -}; - -// Demonbolt - 157695 -class spell_warl_demonbolt : public SpellScript -{ - PrepareSpellScript(spell_warl_demonbolt); - - int32 _summons = 0; - - void HandleHit(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - Unit* target = GetHitUnit(); - if (!caster || !target) - return; - - int32 damage = GetHitDamage(); - AddPct(damage, _summons * 20); - SetHitDamage(damage); - } - - void CountSummons(std::list& targets) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - for (WorldObject* wo : targets) - { - if (!wo->ToCreature()) - continue; - if (wo->ToCreature()->GetOwner() != caster) - continue; - if (wo->ToCreature()->GetCreatureType() != CREATURE_TYPE_DEMON) - continue; - - _summons++; - } - - targets.clear(); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warl_demonbolt::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_demonbolt::CountSummons, EFFECT_2, TARGET_UNIT_CASTER_AND_SUMMONS); - } -}; - -class ImplosionDamageEvent : public BasicEvent -{ -public: - ImplosionDamageEvent(Unit* caster, Unit* target) : _caster(caster), _target(target) { } - - bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override - { - if (_caster && _target) - { - _caster->CastSpell(_target, SPELL_WARLOCK_IMPLOSION_DAMAGE, true); - _target->ToCreature()->DisappearAndDie(); - } - return true; - } -private: - Unit* _caster; - Unit* _target; -}; - -// 196277 - Implosion -class spell_warl_implosion : public SpellScriptLoader -{ -public: - spell_warl_implosion() : SpellScriptLoader("spell_warl_implosion") { } - - class spell_warl_implosion_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warl_implosion_SpellScript); - - void HandleHit(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - Unit* target = GetHitUnit(); - if (!caster || !target) - return; - - std::list imps; - caster->GetCreatureListWithEntryInGrid(imps, 55659); // Wild Imps - for (Creature* imp : imps) - { - if (imp->ToTempSummon()->GetSummoner() == caster) - { - imp->VariableStorage.Set("ForceUpdateTimers", true); - imp->CastSpell(target, SPELL_WARLOCK_IMPLOSION_JUMP, true); - imp->GetMotionMaster()->MoveJump(*target, 300.f, 1.f, EVENT_JUMP); - ObjectGuid casterGuid = caster->GetGUID(); - caster->GetScheduler().Schedule(500ms, [imp, casterGuid](TaskContext /*context*/) - { - imp->CastSpell(imp, SPELL_WARLOCK_IMPLOSION_DAMAGE, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetOriginalCaster(casterGuid)); - imp->DisappearAndDie(); - }); - } - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warl_implosion_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warl_implosion_SpellScript(); - } -}; - -// 603 - Doom -class spell_warlock_doom : public SpellScriptLoader -{ -public: - spell_warlock_doom() : SpellScriptLoader("spell_warlock_doom") { } - - class spell_warlock_doom_AuraScript : public AuraScript - { - PrepareAuraScript(spell_warlock_doom_AuraScript); - - void PeriodicTick(AuraEffect const* aurEff) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - caster->CastSpell(caster, SPELL_WARLOCK_DOOM_ENERGIZE, true); - if (caster->HasAura(SPELL_WARLOCK_IMPENDING_DOOM)) - caster->CastSpell(GetTarget(), SPELL_WARLOCK_WILD_IMP_SUMMON, true); - - if (caster->HasAura(SPELL_WARLOCK_DOOM_DOUBLED) && roll_chance_i(25)) - GetEffect(EFFECT_0)->SetAmount(aurEff->GetAmount() * 2); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_warlock_doom_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_warlock_doom_AuraScript(); - } -}; - -// 6353 - Soul Fire -class spell_warlock_soul_fire : public SpellScriptLoader -{ -public: - spell_warlock_soul_fire() : SpellScriptLoader("spell_warlock_soul_fire") { } - - class spell_warlock_soul_fire_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warlock_soul_fire_SpellScript); - - void HandleHit(SpellEffIndex /*effIndex*/) - { - if (GetCaster()) - GetCaster()->ModifyPower(POWER_SOUL_SHARDS, +40); - - //TODO: Improve it later - GetCaster()->GetSpellHistory()->ModifyCooldown(SPELL_WARLOCK_SOUL_FIRE, Seconds(-2000)); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_warlock_soul_fire_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warlock_soul_fire_SpellScript(); - } -}; - -// Channel Demonfire - 196447 -class spell_warl_channel_demonfire : public SpellScriptLoader -{ -public: - spell_warl_channel_demonfire() : SpellScriptLoader("spell_warl_channel_demonfire") {} - - class spell_warl_channel_demonfire_AuraScript : public AuraScript - { - PrepareAuraScript(spell_warl_channel_demonfire_AuraScript); - - void HandlePeriodic(AuraEffect const* /*aurEff*/) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - std::list enemies; - Trinity::AnyUnfriendlyUnitInObjectRangeCheck check(caster, caster, 100.f); - Trinity::UnitListSearcher searcher(caster, enemies, check); - Cell::VisitAllObjects(caster, searcher, 100.f); - enemies.remove_if(Trinity::UnitAuraCheck(false, SPELL_WARLOCK_IMMOLATE_DOT, caster->GetGUID())); - if (enemies.empty()) - return; - - Unit* target = Trinity::Containers::SelectRandomContainerElement(enemies); - caster->CastSpell(target, SPELL_WARLOCK_CHANNEL_DEMONFIRE_DAMAGE, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_warl_channel_demonfire_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_warl_channel_demonfire_AuraScript(); - } -}; - -// Soul Conduit - 215941 -class spell_warl_soul_conduit : public SpellScriptLoader -{ -public: - spell_warl_soul_conduit() : SpellScriptLoader("spell_warl_soul_conduit") {} - - class spell_warl_soul_conduit_AuraScript : public AuraScript - { - PrepareAuraScript(spell_warl_soul_conduit_AuraScript); - - int32 refund = 0; - - bool CheckProc(ProcEventInfo& eventInfo) - { - Unit* caster = GetCaster(); - if (!caster) - return false; - if (eventInfo.GetActor() && eventInfo.GetActor() != caster) - return false; - - if (Spell const* spell = eventInfo.GetProcSpell()) - { - std::vector const& costs = spell->GetPowerCost(); - auto costData = std::find_if(costs.begin(), costs.end(), [](SpellPowerCost const& cost) { return cost.Power == POWER_MANA && cost.Amount > 0; }); - if (costData == costs.end()) - return false; - - refund = costData->Amount; - return true; - } - - return false; - } - - void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& /*eventInfo*/) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - if (roll_chance_i(GetSpellInfo()->GetEffect(EFFECT_0).BasePoints)) - caster->CastSpell(caster, SPELL_WARLOCK_SOUL_CONDUIT_REFUND, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellBP0(refund)); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_warl_soul_conduit_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_warl_soul_conduit_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_warl_soul_conduit_AuraScript(); - } -}; - -//232670 -class spell_warr_shadowbolt_affliction : public SpellScript -{ - PrepareSpellScript(spell_warr_shadowbolt_affliction); - - void HandleOnHit() - { - Unit* caster = GetCaster(); - Unit* target = GetHitUnit(); - if (!caster || !target) - return; - - if (caster->HasAura(SPELL_SHADOW_EMBRACE)) - caster->AddAura(SPELL_SHADOW_EMBRACE_TARGET_DEBUFF, target); - } - - void Register() override - { - OnHit += SpellHitFn(spell_warr_shadowbolt_affliction::HandleOnHit); - } -}; - -// 104318 - Fel Firebolt @ Wild Imp -class spell_warlock_fel_firebolt_wild_imp : public SpellScriptLoader -{ -public: - spell_warlock_fel_firebolt_wild_imp() : SpellScriptLoader("spell_warlock_fel_firebolt_wild_imp") { } - - class spell_warlock_fel_firebolt_wild_imp_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warlock_fel_firebolt_wild_imp_SpellScript); - - void HandleHit(SpellEffIndex /*effIndex*/) - { - // "Increases damage dealt by your Wild Imps' Firebolt by 10%." - if (Unit* owner = GetCaster()->GetOwner()) - { - if (uint32 pct = owner->GetAuraEffectAmount(SPELL_WARLOCK_INFERNAL_FURNACE, EFFECT_0)) - SetHitDamage(GetHitDamage() + CalculatePct(GetHitDamage(), pct)); - - if (owner->HasAura(SPELL_WARLOCK_STOLEN_POWER)) - { - if (Aura* aur = owner->AddAura(SPELL_WARLOCK_STOLEN_POWER_COUNTER, owner)) - { - if (aur->GetStackAmount() == 100) - { - owner->CastSpell(owner, SPELL_WARLOCK_STOLEN_POWER_BUFF, true); - aur->Remove(); - } - } - } - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warlock_fel_firebolt_wild_imp_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warlock_fel_firebolt_wild_imp_SpellScript(); - } -}; - -// Wild Imp - 99739 -struct npc_pet_warlock_wild_imp : public PetAI -{ - npc_pet_warlock_wild_imp(Creature* creature) : PetAI(creature) - { - if (Unit* owner = me->GetOwner()) - { - me->SetLevel(owner->GetLevel()); - me->SetMaxHealth(owner->GetMaxHealth() / 3); - me->SetHealth(owner->GetHealth() / 3); - } - } - - void UpdateAI(uint32 /*diff*/) override - { - Unit* owner = me->GetOwner(); - if (!owner) - return; - - Unit* target = GetTarget(); - ObjectGuid newtargetGUID = owner->GetTarget(); - if (newtargetGUID.IsEmpty() || newtargetGUID == _targetGUID) - { - CastSpellOnTarget(owner, target); - return; - } - - if (Unit* newTarget = ObjectAccessor::GetUnit(*me, newtargetGUID)) - if (target != newTarget && me->IsValidAttackTarget(newTarget)) - target = newTarget; - - CastSpellOnTarget(owner, target); - } - -private: - Unit* GetTarget() const - { - return ObjectAccessor::GetUnit(*me, _targetGUID); - } - - void CastSpellOnTarget(Unit* owner, Unit* target) - { - if (target && me->IsValidAttackTarget(target)) - { - _targetGUID = target->GetGUID(); - me->CastSpell(target, SPELL_WARLOCK_FEL_FIREBOLT, CastSpellExtraArgs(TRIGGERED_NONE).SetOriginalCaster(owner->GetGUID())); - } - } - - ObjectGuid _targetGUID; -}; - -// Inquisitor's Gaze - 386344 -class spell_warlock_inquisitors_gaze : public SpellScript -{ - PrepareSpellScript(spell_warlock_inquisitors_gaze); - - void HandleOnHit(SpellEffIndex /*effIndex*/) - { - if (Unit* target = GetHitUnit()) - { - int32 damage = (GetCaster()->SpellBaseDamageBonusDone(GetSpellInfo()->GetSchoolMask()) * 15 * 16) / 100; - GetCaster()->CastSpell(target, SPELL_INQUISITORS_GAZE, &damage); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warlock_inquisitors_gaze::HandleOnHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// Incinerate - 29722 -class spell_warl_incinerate : public SpellScript -{ - PrepareSpellScript(spell_warl_incinerate); - - void HandleOnHitMainTarget(SpellEffIndex /*effIndex*/) - { - GetCaster()->ModifyPower(POWER_SOUL_SHARDS, 5.0f); - } - - void HandleOnHitTarget(SpellEffIndex /*effIndex*/) - { - if (Unit* target = GetHitUnit()) - if (!GetCaster()->HasAura(SPELL_WARLOCK_FIRE_AND_BRIMSTONE)) - if (target != GetExplTargetUnit()) - PreventHitDamage(); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warl_incinerate::HandleOnHitMainTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - OnEffectHitTarget += SpellEffectFn(spell_warl_incinerate::HandleOnHitTarget, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); - } -}; - -// 980 - Agony -class spell_warlock_agony : public SpellScriptLoader -{ -public: - spell_warlock_agony() : SpellScriptLoader("spell_warlock_agony") {} - - class spell_warlock_agony_AuraScript : public AuraScript - { - PrepareAuraScript(spell_warlock_agony_AuraScript); - - void HandleDummyPeriodic(AuraEffect const* auraEffect) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - float soulShardAgonyTick = caster->VariableStorage.GetValue("SoulShardAgonyTick", frand(0.0f, 99.0f)); - soulShardAgonyTick += 16.0f; - - if (soulShardAgonyTick >= 100.0f) - { - soulShardAgonyTick = frand(0.0f, 99.0f); - - if (Player* player = GetCaster()->ToPlayer()) - if (player->GetPower(POWER_SOUL_SHARDS) < player->GetMaxPower(POWER_SOUL_SHARDS)) - player->SetPower(POWER_SOUL_SHARDS, player->GetPower(POWER_SOUL_SHARDS) + 10); - } - - caster->VariableStorage.Set("SoulShardAgonyTick", soulShardAgonyTick); - - // If we have more than maxStackAmount, dont do anything - if (GetStackAmount() >= auraEffect->GetBase()->GetMaxStackAmount()) - return; - - SetStackAmount(GetStackAmount() + 1); - } - - void OnRemove(const AuraEffect* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - // If last agony removed, remove tick counter - if (Unit* caster = GetCaster()) - if (!caster->GetOwnedAura(SPELL_WARLOCK_AGONY)) - caster->VariableStorage.Remove("SoulShardAgonyTick"); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_warlock_agony_AuraScript::HandleDummyPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY); - AfterEffectRemove += AuraEffectRemoveFn(spell_warlock_agony_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_warlock_agony_AuraScript(); - } -}; - -// 3110 - Firebolt -class spell_warlock_imp_firebolt : public SpellScriptLoader -{ -public: - spell_warlock_imp_firebolt() : SpellScriptLoader("spell_warlock_imp_firebolt") { } - - class spell_warlock_imp_firebolt_SpellScript : public SpellScript - { - PrepareSpellScript(spell_warlock_imp_firebolt_SpellScript); - - void HandleHit(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - Unit* target = GetHitUnit(); - if (!caster || !caster->GetOwner() || !target) - return; - - Unit* owner = caster->GetOwner(); - int32 damage = GetHitDamage(); - if (target->HasAura(SPELL_WARLOCK_IMMOLATE_DOT, owner->GetGUID())) - AddPct(damage, owner->GetAuraEffectAmount(SPELL_WARLOCK_FIREBOLT_BONUS, EFFECT_0)); - - SetHitDamage(damage); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_warlock_imp_firebolt_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_warlock_imp_firebolt_SpellScript(); - } -}; - -void AddSC_warlock_spell_scripts() +void AddSC_warlock_spell_scripts() { + RegisterSpellScript(spell_warl_absolute_corruption); + RegisterSpellScript(spell_warl_backdraft); RegisterSpellScript(spell_warl_banish); RegisterSpellAndAuraScriptPair(spell_warl_burning_rush, spell_warl_burning_rush_aura); RegisterSpellScript(spell_warl_cataclysm); RegisterSpellScript(spell_warl_chaos_bolt); RegisterSpellScript(spell_warl_chaotic_energies); - RegisterSpellScript(spell_warl_absolute_corruption); RegisterSpellScript(spell_warl_conflagrate); RegisterSpellScript(spell_warl_create_healthstone); RegisterSpellScript(spell_warl_dark_pact); @@ -2848,6 +1492,7 @@ void AddSC_warlock_spell_scripts() RegisterSpellScript(spell_warl_healthstone_heal); RegisterSpellScript(spell_warl_immolate); RegisterSpellScript(spell_warl_perpetual_unstability); + RegisterSpellScript(spell_warl_pyrogenics); RegisterSpellScript(spell_warl_rain_of_fire); RegisterSpellScript(spell_warl_random_sayaad); RegisterSpellScript(spell_warl_roaring_blaze); @@ -2863,45 +1508,12 @@ void AddSC_warlock_spell_scripts() RegisterSpellScript(spell_warl_soul_swap_exhale); RegisterSpellScript(spell_warl_soul_swap_override); RegisterSpellScript(spell_warl_soulshatter); - RegisterSpellScript(spell_warl_strengthen_pact_succubus); RegisterSpellScript(spell_warl_strengthen_pact_incubus); + RegisterSpellScript(spell_warl_strengthen_pact_succubus); RegisterSpellScript(spell_warl_summon_sayaad); RegisterSpellScriptWithArgs(spell_warl_t4_2p_bonus, "spell_warl_t4_2p_bonus_shadow"); RegisterSpellScriptWithArgs(spell_warl_t4_2p_bonus, "spell_warl_t4_2p_bonus_fire"); RegisterSpellScript(spell_warl_unstable_affliction); RegisterSpellScript(spell_warl_vile_taint); RegisterSpellScript(spell_warl_volatile_agony); - - //Fix - new spell_warl_fear(); - new spell_warl_fear_buff(); - RegisterSpellScript(spell_warl_corruption_effect); - RegisterSpellScript(spell_warl_drain_life); - RegisterSpellScript(aura_warl_phantomatic_singularity); - RegisterSpellScript(aura_warl_haunt); - RegisterSpellScript(spell_warlock_summon_darkglare); - new npc_pet_warlock_darkglare(); - new spell_warlock_unending_breath(); - new spell_warl_demonic_gateway(); - new npc_warl_demonic_gateway(); - RegisterSpellScript(spell_warl_hand_of_guldan); - new spell_warl_hand_of_guldan_damage(); - new spell_warlock_call_dreadstalkers(); - new npc_warlock_dreadstalker(); - new spell_warl_eye_laser(); - new spell_warlock_demonbolt_new(); - new spell_warl_demonic_calling(); - RegisterSpellScript(spell_warl_demonbolt); - new spell_warl_implosion(); - new spell_warlock_doom(); - new spell_warlock_soul_fire(); - new spell_warl_channel_demonfire(); - new spell_warl_soul_conduit(); - RegisterSpellScript(spell_warr_shadowbolt_affliction); - new spell_warlock_fel_firebolt_wild_imp(); - RegisterCreatureAI(npc_pet_warlock_wild_imp); - new spell_warlock_inquisitors_gaze(); - RegisterSpellScript(spell_warl_incinerate); - new spell_warlock_agony(); - new spell_warlock_imp_firebolt(); } diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index 1b85fefd128e3..ca7a869ba1635 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -14,8 +14,6 @@ CollectSourceFiles( # Exclude ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders) -list(APPEND PRIVATE_SOURCES ${sources_windows}) - if(WIN32) if(MSVC) list(APPEND PRIVATE_SOURCES worldserver.rc) diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index ee359c129656e..4bbf31964b979 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -79,7 +79,7 @@ namespace fs = boost::filesystem; #define _TRINITY_CORE_CONFIG_DIR "worldserver.conf.d" #endif -#ifdef _WIN32 +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS #include "ServiceWin32.h" #include TCHAR serviceName[] = _T("worldserver"); @@ -132,7 +132,7 @@ struct ShutdownCLIThread { void operator()(std::thread* cliThread) const; }; variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, fs::path& configDir, std::string& winServiceAction); /// Launch the Trinity server -extern int main(int argc, char** argv) +int main(int argc, char** argv) { signal(SIGABRT, &Trinity::AbortHandler); @@ -156,12 +156,13 @@ extern int main(int argc, char** argv) auto protobufHandle = Trinity::make_unique_ptr_with_deleter(&dummy, [](void*) { google::protobuf::ShutdownProtobufLibrary(); }); #ifdef _WIN32 + Trinity::Service::Init(serviceLongName, serviceName, serviceDescription, &main, &m_ServiceStatus); if (winServiceAction == "install") - return WinServiceInstall() ? 0 : 1; + return Trinity::Service::Install(); if (winServiceAction == "uninstall") - return WinServiceUninstall() ? 0 : 1; + return Trinity::Service::Uninstall(); if (winServiceAction == "run") - return WinServiceRun() ? 0 : 1; + return Trinity::Service::Run(); Optional newTimerResolution; boost::system::error_code dllError; @@ -741,3 +742,9 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, f return vm; } + +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS +#include "WheatyExceptionReport.h" +// must be at end of file because of init_seg pragma +INIT_CRASH_HANDLER(); +#endif diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt index 0613d0a7d4f0b..7da1f5fc94900 100644 --- a/src/tools/map_extractor/CMakeLists.txt +++ b/src/tools/map_extractor/CMakeLists.txt @@ -12,8 +12,6 @@ CollectSourceFiles( ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE_SOURCES) -list(APPEND PRIVATE_SOURCES ${sources_windows}) - add_executable(mapextractor ${PRIVATE_SOURCES} ) diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index ca91068a2346d..698adff25c173 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -1567,3 +1567,9 @@ int main(int argc, char * arg[]) return 0; } + +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS +#include "WheatyExceptionReport.h" +// must be at end of file because of init_seg pragma +INIT_CRASH_HANDLER(); +#endif diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt index 61a2548f89883..371b80604fb5d 100644 --- a/src/tools/mmaps_generator/CMakeLists.txt +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -12,8 +12,6 @@ CollectSourceFiles( ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE_SOURCES) -list(APPEND PRIVATE_SOURCES ${sources_windows}) - add_executable(mmaps_generator ${PRIVATE_SOURCES}) target_link_libraries(mmaps_generator diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 4b9620bff1f10..f3ba4ab48b658 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -458,3 +458,9 @@ int main(int argc, char** argv) printf("Finished. MMAPS were built in %s\n", secsToTimeString(GetMSTimeDiffToNow(start) / 1000).c_str()); return 0; } + +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS +#include "WheatyExceptionReport.h" +// must be at end of file because of init_seg pragma +INIT_CRASH_HANDLER(); +#endif diff --git a/src/tools/vmap4_assembler/CMakeLists.txt b/src/tools/vmap4_assembler/CMakeLists.txt index 2511946d7020b..71378937f04f4 100644 --- a/src/tools/vmap4_assembler/CMakeLists.txt +++ b/src/tools/vmap4_assembler/CMakeLists.txt @@ -13,8 +13,6 @@ set(PRIVATE_SOURCES TileAssembler.h VMapAssembler.cpp) -list(APPEND PRIVATE_SOURCES ${sources_windows}) - add_executable(vmap4assembler ${PRIVATE_SOURCES}) target_link_libraries(vmap4assembler diff --git a/src/tools/vmap4_assembler/VMapAssembler.cpp b/src/tools/vmap4_assembler/VMapAssembler.cpp index 444f748753c53..5cdc214665eab 100644 --- a/src/tools/vmap4_assembler/VMapAssembler.cpp +++ b/src/tools/vmap4_assembler/VMapAssembler.cpp @@ -111,3 +111,9 @@ Optional HandleArgs(int argc, char* argv[], std::string* src, std::string* return {}; } + +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS +#include "WheatyExceptionReport.h" +// must be at end of file because of init_seg pragma +INIT_CRASH_HANDLER(); +#endif diff --git a/src/tools/vmap4_extractor/CMakeLists.txt b/src/tools/vmap4_extractor/CMakeLists.txt index 075021e860b85..95ae191053df8 100644 --- a/src/tools/vmap4_extractor/CMakeLists.txt +++ b/src/tools/vmap4_extractor/CMakeLists.txt @@ -12,8 +12,6 @@ CollectSourceFiles( ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE_SOURCES) -list(APPEND PRIVATE_SOURCES ${sources_windows}) - add_executable(vmap4extractor ${PRIVATE_SOURCES}) target_link_libraries(vmap4extractor diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 9ab9ccfac1958..cc518cfab500a 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -604,3 +604,9 @@ int main(int argc, char ** argv) printf("Extract %s. Work complete. No errors.\n", VMAP::VMAP_MAGIC); return 0; } + +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS +#include "WheatyExceptionReport.h" +// must be at end of file because of init_seg pragma +INIT_CRASH_HANDLER(); +#endif