aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Debugging/WheatyExceptionReport.cpp194
-rw-r--r--src/common/Debugging/WheatyExceptionReport.h19
-rw-r--r--src/common/Utilities/Util.h7
-rw-r--r--src/server/game/AI/CreatureAI.cpp16
-rw-r--r--src/server/game/AI/CreatureAI.h5
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp4
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp3
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp34
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
-rw-r--r--src/server/game/Entities/Creature/CreatureData.h31
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp8
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.h1
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp3
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h4
-rw-r--r--src/server/game/Entities/Item/Item.cpp4
-rw-r--r--src/server/game/Entities/Item/Item.h1
-rw-r--r--src/server/game/Entities/Object/Object.cpp84
-rw-r--r--src/server/game/Entities/Object/Object.h6
-rw-r--r--src/server/game/Entities/Object/ObjectDefines.h10
-rw-r--r--src/server/game/Entities/Object/Position.cpp6
-rw-r--r--src/server/game/Entities/Object/Position.h5
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp18
-rw-r--r--src/server/game/Entities/Player/Player.cpp471
-rw-r--r--src/server/game/Entities/Player/Player.h37
-rw-r--r--src/server/game/Entities/Player/SocialMgr.cpp5
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp124
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp304
-rw-r--r--src/server/game/Entities/Unit/Unit.h142
-rw-r--r--src/server/game/Entities/Unit/UnitDefines.h1
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp411
-rw-r--r--src/server/game/Globals/ObjectMgr.h15
-rw-r--r--src/server/game/Grids/Cells/CellImpl.h2
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h59
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp1
-rw-r--r--src/server/game/Instances/InstanceScript.cpp2
-rw-r--r--src/server/game/Instances/InstanceScript.h2
-rw-r--r--src/server/game/Maps/AreaBoundary.cpp24
-rw-r--r--src/server/game/Maps/AreaBoundary.h83
-rw-r--r--src/server/game/Miscellaneous/Language.h2
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h8
-rw-r--r--src/server/game/Movement/MotionMaster.cpp45
-rw-r--r--src/server/game/Movement/MotionMaster.h23
-rw-r--r--src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp6
-rw-r--r--src/server/game/Quests/QuestDef.cpp219
-rw-r--r--src/server/game/Quests/QuestDef.h413
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp338
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h1
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp10
-rw-r--r--src/server/game/Spells/Spell.cpp37
-rw-r--r--src/server/game/Spells/SpellEffects.cpp24
-rw-r--r--src/server/game/Spells/SpellInfo.cpp29
-rw-r--r--src/server/game/Spells/SpellInfo.h1
-rw-r--r--src/server/game/Spells/SpellMgr.cpp22
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp2
-rw-r--r--src/server/scripts/Commands/cs_group.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp5
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/SunkenTemple/sunken_temple.h16
-rw-r--r--src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp2
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp11
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/boss_king_dred.cpp2
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp6
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp316
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h4
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp18
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp6
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h12
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp8
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp11
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp30
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp8
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp38
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp40
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp77
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp58
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp44
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp323
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h2
-rw-r--r--src/server/scripts/Northrend/zone_zuldrak.cpp4
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp8
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp4
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h8
-rw-r--r--src/server/scripts/Outland/zone_shadowmoon_valley.cpp2
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp37
-rw-r--r--src/server/scripts/Spells/spell_item.cpp41
-rw-r--r--src/server/scripts/Spells/spell_pet.cpp2
-rw-r--r--src/server/scripts/World/go_scripts.cpp2
-rw-r--r--src/server/scripts/World/item_scripts.cpp2
96 files changed, 2416 insertions, 2079 deletions
diff --git a/src/common/Debugging/WheatyExceptionReport.cpp b/src/common/Debugging/WheatyExceptionReport.cpp
index 6e98bf23c5f..836ae7b0837 100644
--- a/src/common/Debugging/WheatyExceptionReport.cpp
+++ b/src/common/Debugging/WheatyExceptionReport.cpp
@@ -420,18 +420,18 @@ void WheatyExceptionReport::PrintSystemInfo()
MemoryStatus.dwLength = sizeof (MEMORYSTATUS);
::GlobalMemoryStatus(&MemoryStatus);
TCHAR sString[1024];
- _tprintf(_T("//=====================================================\r\n"));
+ Log(_T("//=====================================================\r\n"));
if (_GetProcessorName(sString, countof(sString)))
- _tprintf(_T("*** Hardware ***\r\nProcessor: %s\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
+ Log(_T("*** Hardware ***\r\nProcessor: %s\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
sString, SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys/0x400, MemoryStatus.dwAvailPhys/0x400, MemoryStatus.dwTotalPageFile/0x400);
else
- _tprintf(_T("*** Hardware ***\r\nProcessor: <unknown>\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
+ Log(_T("*** Hardware ***\r\nProcessor: <unknown>\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys/0x400, MemoryStatus.dwAvailPhys/0x400, MemoryStatus.dwTotalPageFile/0x400);
if (_GetWindowsVersion(sString, countof(sString)))
- _tprintf(_T("\r\n*** Operation System ***\r\n%s\r\n"), sString);
+ Log(_T("\r\n*** Operation System ***\r\n%s\r\n"), sString);
else
- _tprintf(_T("\r\n*** Operation System:\r\n<unknown>\r\n"));
+ Log(_T("\r\n*** Operation System:\r\n<unknown>\r\n"));
}
//===========================================================================
@@ -494,14 +494,14 @@ PEXCEPTION_POINTERS pExceptionInfo)
GetLocalTime(&systime);
// Start out with a banner
- _tprintf(_T("Revision: %s\r\n"), GitRevision::GetFullVersion());
- _tprintf(_T("Date %u:%u:%u. Time %u:%u \r\n"), systime.wDay, systime.wMonth, systime.wYear, systime.wHour, systime.wMinute);
+ Log(_T("Revision: %s\r\n"), GitRevision::GetFullVersion());
+ Log(_T("Date %u:%u:%u. Time %u:%u \r\n"), systime.wDay, systime.wMonth, systime.wYear, systime.wHour, systime.wMinute);
PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
PrintSystemInfo();
// First print information about the type of fault
- _tprintf(_T("\r\n//=====================================================\r\n"));
- _tprintf(_T("Exception code: %08X %s\r\n"),
+ Log(_T("\r\n//=====================================================\r\n"));
+ Log(_T("Exception code: %08X %s\r\n"),
pExceptionRecord->ExceptionCode,
GetExceptionString(pExceptionRecord->ExceptionCode));
@@ -515,12 +515,12 @@ PEXCEPTION_POINTERS pExceptionInfo)
section, offset);
#ifdef _M_IX86
- _tprintf(_T("Fault address: %08X %02X:%08X %s\r\n"),
+ Log(_T("Fault address: %08X %02X:%08X %s\r\n"),
pExceptionRecord->ExceptionAddress,
section, offset, szFaultingModule);
#endif
#ifdef _M_X64
- _tprintf(_T("Fault address: %016I64X %02X:%016I64X %s\r\n"),
+ Log(_T("Fault address: %016I64X %02X:%016I64X %s\r\n"),
pExceptionRecord->ExceptionAddress,
section, offset, szFaultingModule);
#endif
@@ -529,32 +529,32 @@ PEXCEPTION_POINTERS pExceptionInfo)
// Show the registers
#ifdef _M_IX86 // X86 Only!
- _tprintf(_T("\r\nRegisters:\r\n"));
+ Log(_T("\r\nRegisters:\r\n"));
- _tprintf(_T("EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n")
+ Log(_T("EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n")
, pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx,
pCtx->Esi, pCtx->Edi);
- _tprintf(_T("CS:EIP:%04X:%08X\r\n"), pCtx->SegCs, pCtx->Eip);
- _tprintf(_T("SS:ESP:%04X:%08X EBP:%08X\r\n"),
+ Log(_T("CS:EIP:%04X:%08X\r\n"), pCtx->SegCs, pCtx->Eip);
+ Log(_T("SS:ESP:%04X:%08X EBP:%08X\r\n"),
pCtx->SegSs, pCtx->Esp, pCtx->Ebp);
- _tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
+ Log(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs);
- _tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags);
+ Log(_T("Flags:%08X\r\n"), pCtx->EFlags);
#endif
#ifdef _M_X64
- _tprintf(_T("\r\nRegisters:\r\n"));
- _tprintf(_T("RAX:%016I64X\r\nRBX:%016I64X\r\nRCX:%016I64X\r\nRDX:%016I64X\r\nRSI:%016I64X\r\nRDI:%016I64X\r\n")
+ Log(_T("\r\nRegisters:\r\n"));
+ Log(_T("RAX:%016I64X\r\nRBX:%016I64X\r\nRCX:%016I64X\r\nRDX:%016I64X\r\nRSI:%016I64X\r\nRDI:%016I64X\r\n")
_T("R8: %016I64X\r\nR9: %016I64X\r\nR10:%016I64X\r\nR11:%016I64X\r\nR12:%016I64X\r\nR13:%016I64X\r\nR14:%016I64X\r\nR15:%016I64X\r\n")
, pCtx->Rax, pCtx->Rbx, pCtx->Rcx, pCtx->Rdx,
pCtx->Rsi, pCtx->Rdi, pCtx->R9, pCtx->R10, pCtx->R11, pCtx->R12, pCtx->R13, pCtx->R14, pCtx->R15);
- _tprintf(_T("CS:RIP:%04X:%016I64X\r\n"), pCtx->SegCs, pCtx->Rip);
- _tprintf(_T("SS:RSP:%04X:%016X RBP:%08X\r\n"),
+ Log(_T("CS:RIP:%04X:%016I64X\r\n"), pCtx->SegCs, pCtx->Rip);
+ Log(_T("SS:RSP:%04X:%016X RBP:%08X\r\n"),
pCtx->SegSs, pCtx->Rsp, pCtx->Rbp);
- _tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
+ Log(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs);
- _tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags);
+ Log(_T("Flags:%08X\r\n"), pCtx->EFlags);
#endif
SymSetOptions(SYMOPT_DEFERRED_LOADS);
@@ -562,7 +562,7 @@ PEXCEPTION_POINTERS pExceptionInfo)
// Initialize DbgHelp
if (!SymInitialize(GetCurrentProcess(), 0, TRUE))
{
- _tprintf(_T("\n\rCRITICAL ERROR.\n\r Couldn't initialize the symbol handler for process.\n\rError [%s].\n\r\n\r"),
+ Log(_T("\n\rCRITICAL ERROR.\n\r Couldn't initialize the symbol handler for process.\n\rError [%s].\n\r\n\r"),
ErrorMessage(GetLastError()));
}
@@ -573,28 +573,20 @@ PEXCEPTION_POINTERS pExceptionInfo)
// #ifdef _M_IX86 // X86 Only!
- _tprintf(_T("========================\r\n"));
- _tprintf(_T("Local Variables And Parameters\r\n"));
+ Log(_T("========================\r\n"));
+ Log(_T("Local Variables And Parameters\r\n"));
trashableContext = *pCtx;
WriteStackDetails(&trashableContext, true, NULL);
printTracesForAllThreads(true);
- /*_tprintf(_T("========================\r\n"));
- _tprintf(_T("Global Variables\r\n"));
-
- SymEnumSymbols(GetCurrentProcess(),
- (UINT_PTR)GetModuleHandle(szFaultingModule),
- 0, EnumerateSymbolsCallback, 0);*/
- // #endif // X86 Only!
-
SymCleanup(GetCurrentProcess());
- _tprintf(_T("\r\n"));
+ Log(_T("\r\n"));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
- _tprintf(_T("Error writing the crash log\r\n"));
+ Log(_T("Error writing the crash log\r\n"));
}
}
@@ -720,9 +712,9 @@ void WheatyExceptionReport::WriteStackDetails(
PCONTEXT pContext,
bool bWriteVariables, HANDLE pThreadHandle) // true if local/params should be output
{
- _tprintf(_T("\r\nCall stack:\r\n"));
+ Log(_T("\r\nCall stack:\r\n"));
- _tprintf(_T("Address Frame Function SourceFile\r\n"));
+ Log(_T("Address Frame Function SourceFile\r\n"));
DWORD dwMachineType = 0;
// Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag
@@ -769,10 +761,10 @@ bool bWriteVariables, HANDLE pThreadHandle)
if (0 == sf.AddrFrame.Offset) // Basic sanity check to make sure
break; // the frame is OK. Bail if not.
#ifdef _M_IX86
- _tprintf(_T("%08X %08X "), sf.AddrPC.Offset, sf.AddrFrame.Offset);
+ Log(_T("%08X %08X "), sf.AddrPC.Offset, sf.AddrFrame.Offset);
#endif
#ifdef _M_X64
- _tprintf(_T("%016I64X %016I64X "), sf.AddrPC.Offset, sf.AddrFrame.Offset);
+ Log(_T("%016I64X %016I64X "), sf.AddrPC.Offset, sf.AddrFrame.Offset);
#endif
DWORD64 symDisplacement = 0; // Displacement of the input address,
@@ -786,7 +778,7 @@ bool bWriteVariables, HANDLE pThreadHandle)
&symDisplacement, // Address of the variable that will receive the displacement
&sip.si)) // Address of the SYMBOL_INFO structure (inside "sip" object)
{
- _tprintf(_T("%hs+%I64X"), sip.si.Name, symDisplacement);
+ Log(_T("%hs+%I64X"), sip.si.Name, symDisplacement);
}
else // No symbol found. Print out the logical address instead.
@@ -798,10 +790,10 @@ bool bWriteVariables, HANDLE pThreadHandle)
GetLogicalAddress((PVOID)sf.AddrPC.Offset,
szModule, sizeof(szModule), section, offset);
#ifdef _M_IX86
- _tprintf(_T("%04X:%08X %s"), section, offset, szModule);
+ Log(_T("%04X:%08X %s"), section, offset, szModule);
#endif
#ifdef _M_X64
- _tprintf(_T("%04X:%016I64X %s"), section, offset, szModule);
+ Log(_T("%04X:%016I64X %s"), section, offset, szModule);
#endif
}
@@ -811,10 +803,10 @@ bool bWriteVariables, HANDLE pThreadHandle)
if (SymGetLineFromAddr64(m_hProcess, sf.AddrPC.Offset,
&dwLineDisplacement, &lineInfo))
{
- _tprintf(_T(" %s line %u"), lineInfo.FileName, lineInfo.LineNumber);
+ Log(_T(" %s line %u"), lineInfo.FileName, lineInfo.LineNumber);
}
- _tprintf(_T("\r\n"));
+ Log(_T("\r\n"));
// Write out the variables, if desired
if (bWriteVariables)
@@ -827,7 +819,7 @@ bool bWriteVariables, HANDLE pThreadHandle)
// Enumerate the locals/parameters
SymEnumSymbols(m_hProcess, 0, 0, EnumerateSymbolsCallback, &sf);
- _tprintf(_T("\r\n"));
+ Log(_T("\r\n"));
}
}
@@ -843,22 +835,15 @@ PSYMBOL_INFO pSymInfo,
ULONG /*SymbolSize*/,
PVOID UserContext)
{
-
- char szBuffer[WER_LARGE_BUFFER_SIZE];
- memset(szBuffer, 0, sizeof(szBuffer));
-
__try
{
ClearSymbols();
- if (FormatSymbolValue(pSymInfo, (STACKFRAME64*)UserContext,
- szBuffer, sizeof(szBuffer)))
- _tprintf(_T("%s"), szBuffer);
+ FormatSymbolValue(pSymInfo, (STACKFRAME64*)UserContext);
+
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
- _tprintf(_T("punting on symbol %s, partial output:\r\n"), pSymInfo->Name);
- if (szBuffer[0] != '\0')
- _tprintf(_T("%s"), szBuffer);
+ Log(_T("punting on symbol %s, partial output:\r\n"), pSymInfo->Name);
}
return TRUE;
@@ -871,12 +856,8 @@ PVOID UserContext)
//////////////////////////////////////////////////////////////////////////////
bool WheatyExceptionReport::FormatSymbolValue(
PSYMBOL_INFO pSym,
-STACKFRAME64 * sf,
-char * pszBuffer,
-unsigned /*cbBuffer*/)
+STACKFRAME64 * sf)
{
- char * pszCurrBuffer = pszBuffer;
-
// If it's a function, don't do anything.
if (pSym->Tag == SymTagFunction) // SymTagFunction from CVCONST.H from the DIA SDK
return false;
@@ -904,7 +885,7 @@ unsigned /*cbBuffer*/)
pVariable = (DWORD_PTR)pSym->Address; // It must be a global variable
}
- pszCurrBuffer = PushSymbolDetail(pszCurrBuffer);
+ PushSymbolDetail();
// Indicate if the variable is a local or parameter
if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER)
@@ -915,8 +896,7 @@ unsigned /*cbBuffer*/)
// Determine if the variable is a user defined type (UDT). IF so, bHandled
// will return true.
bool bHandled;
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, pSym->ModBase, pSym->TypeIndex,
- pVariable, bHandled, pSym->Name, "", false, true);
+ DumpTypeIndex(pSym->ModBase, pSym->TypeIndex, pVariable, bHandled, pSym->Name, "", false, true);
if (!bHandled)
{
@@ -936,7 +916,7 @@ unsigned /*cbBuffer*/)
symbolDetails.top().Value = buffer;
}
- pszCurrBuffer = PopSymbolDetail(pszCurrBuffer);
+ PopSymbolDetail();
return true;
}
@@ -945,8 +925,7 @@ unsigned /*cbBuffer*/)
// at fundamental types. When he hit fundamental types, return
// bHandled = false, so that FormatSymbolValue() will format them.
//////////////////////////////////////////////////////////////////////////////
-char * WheatyExceptionReport::DumpTypeIndex(
-char * pszCurrBuffer,
+void WheatyExceptionReport::DumpTypeIndex(
DWORD64 modBase,
DWORD dwTypeIndex,
DWORD_PTR offset,
@@ -959,11 +938,11 @@ bool logChildren)
bHandled = false;
if (newSymbol)
- pszCurrBuffer = PushSymbolDetail(pszCurrBuffer);
+ PushSymbolDetail();
DWORD typeTag;
if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMTAG, &typeTag))
- return pszCurrBuffer;
+ return;
// Get the name of the symbol. This will either be a Type name (if a UDT),
// or the structure member name.
@@ -982,12 +961,12 @@ bool logChildren)
if (Name != NULL && Name[0] != '\0')
symbolDetails.top().Name = Name;
bHandled = true;
- return pszCurrBuffer;
+ return;
}
- char buffer[200];
+ char buffer[WER_SMALL_BUFFER_SIZE];
wcstombs(buffer, pwszTypeName, sizeof(buffer));
- buffer[199] = '\0';
+ buffer[WER_SMALL_BUFFER_SIZE - 1] = '\0';
if (Name != NULL && Name[0] != '\0')
{
symbolDetails.top().Type = buffer;
@@ -1006,7 +985,7 @@ bool logChildren)
// Skip printing address and base class if it has been printed already
if (typeTag == SymTagBaseClass)
bHandled = true;
- return pszCurrBuffer;
+ return;
}
DWORD innerTypeID;
@@ -1032,7 +1011,7 @@ bool logChildren)
// Try to dereference the pointer in a try/except block since it might be invalid
DWORD_PTR address = DereferenceUnsafePointer(offset);
- char buffer[50];
+ char buffer[WER_SMALL_BUFFER_SIZE];
FormatOutputValue(buffer, btVoid, sizeof(PVOID), (PVOID)offset, sizeof(buffer));
symbolDetails.top().Value = buffer;
@@ -1043,8 +1022,7 @@ bool logChildren)
if (address == NULL || address == DWORD_PTR(-1))
logChildren = false;
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID,
- address, bHandled, Name, addressStr, false, logChildren);
+ DumpTypeIndex(modBase, innerTypeID, address, bHandled, Name, addressStr, false, logChildren);
if (!bHandled)
{
@@ -1066,7 +1044,7 @@ bool logChildren)
symbolDetails.top().Value = buffer2;
}
bHandled = true;
- return pszCurrBuffer;
+ return;
}
else if (address == NULL)
symbolDetails.top().Value = "NULL";
@@ -1074,7 +1052,7 @@ bool logChildren)
{
symbolDetails.top().Value = "<Unable to read memory>";
bHandled = true;
- return pszCurrBuffer;
+ return;
}
}
break;
@@ -1090,17 +1068,17 @@ bool logChildren)
case SymTagUDT:
if (symbolDetails.size() >= WER_MAX_NESTING_LEVEL)
logChildren = false;
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID,
+ DumpTypeIndex(modBase, innerTypeID,
offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
break;
case SymTagPointerType:
if (Name != NULL && Name[0] != '\0')
symbolDetails.top().Name = Name;
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID,
+ DumpTypeIndex(modBase, innerTypeID,
offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
break;
case SymTagArrayType:
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID,
+ DumpTypeIndex(modBase, innerTypeID,
offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
break;
default:
@@ -1114,7 +1092,7 @@ bool logChildren)
symbolDetails.top().HasChildren = true;
BasicType basicType = btNoType;
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID,
+ DumpTypeIndex(modBase, innerTypeID,
offset, bHandled, Name, "", false, false);
// Set Value back to an empty string since the Array object itself has no value, only its elements have
@@ -1149,22 +1127,22 @@ bool logChildren)
default:
for (DWORD index = 0; index < elementsCount && index < WER_MAX_ARRAY_ELEMENTS_COUNT; index++)
{
- pszCurrBuffer = PushSymbolDetail(pszCurrBuffer);
+ PushSymbolDetail();
symbolDetails.top().Suffix += "[" + std::to_string(index) + "]";
FormatOutputValue(buffer, basicType, length, (PVOID)(offset + length * index), sizeof(buffer));
symbolDetails.top().Value = buffer;
- pszCurrBuffer = PopSymbolDetail(pszCurrBuffer);
+ PopSymbolDetail();
}
break;
}
- return pszCurrBuffer;
+ return;
}
break;
case SymTagBaseType:
break;
case SymTagEnum:
- return pszCurrBuffer;
+ return;
default:
break;
}
@@ -1174,7 +1152,7 @@ bool logChildren)
SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &dwChildrenCount);
if (!dwChildrenCount) // If no children, we're done
- return pszCurrBuffer;
+ return;
// Prepare to get an array of "TypeIds", representing each of the children.
// SymGetTypeInfo(TI_FINDCHILDREN) expects more memory than just a
@@ -1192,7 +1170,7 @@ bool logChildren)
if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_FINDCHILDREN,
&children))
{
- return pszCurrBuffer;
+ return;
}
// Iterate through each of the children
@@ -1220,7 +1198,7 @@ bool logChildren)
if (!logChildren)
{
bHandled = false;
- return pszCurrBuffer;
+ return;
}
// Recurse for each of the child types
@@ -1235,7 +1213,7 @@ bool logChildren)
// Calculate the address of the member
DWORD_PTR dwFinalOffset = offset + dwMemberOffset;
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase,
+ DumpTypeIndex(modBase,
children.ChildId[i],
dwFinalOffset, bHandled2, ""/*Name */, "", true, true);
@@ -1260,11 +1238,11 @@ bool logChildren)
symbolDetails.top().Value = buffer;
}
- pszCurrBuffer = PopSymbolDetail(pszCurrBuffer);
+ PopSymbolDetail();
}
bHandled = true;
- return pszCurrBuffer;
+ return;
}
void WheatyExceptionReport::FormatOutputValue(char * pszCurrBuffer,
@@ -1386,26 +1364,26 @@ DWORD_PTR WheatyExceptionReport::DereferenceUnsafePointer(DWORD_PTR address)
// Helper function that writes to the report file, and allows the user to use
// printf style formating
//============================================================================
-int __cdecl WheatyExceptionReport::_tprintf(const TCHAR * format, ...)
+int __cdecl WheatyExceptionReport::Log(const TCHAR * format, ...)
{
int retValue;
va_list argptr;
va_start(argptr, format);
if (stackOverflowException)
{
- retValue = heapprintf(format, argptr);
+ retValue = HeapLog(format, argptr);
va_end(argptr);
}
else
{
- retValue = stackprintf(format, argptr);
+ retValue = StackLog(format, argptr);
va_end(argptr);
}
return retValue;
}
-int __cdecl WheatyExceptionReport::stackprintf(const TCHAR * format, va_list argptr)
+int __cdecl WheatyExceptionReport::StackLog(const TCHAR * format, va_list argptr)
{
int retValue;
DWORD cbWritten;
@@ -1417,7 +1395,7 @@ int __cdecl WheatyExceptionReport::stackprintf(const TCHAR * format, va_list arg
return retValue;
}
-int __cdecl WheatyExceptionReport::heapprintf(const TCHAR * format, va_list argptr)
+int __cdecl WheatyExceptionReport::HeapLog(const TCHAR * format, va_list argptr)
{
int retValue = 0;
DWORD cbWritten;
@@ -1444,37 +1422,35 @@ void WheatyExceptionReport::ClearSymbols()
symbolDetails.pop();
}
-char* WheatyExceptionReport::PushSymbolDetail(char* pszCurrBuffer)
+void WheatyExceptionReport::PushSymbolDetail()
{
// Log current symbol and then add another to the stack to keep the hierarchy format
- pszCurrBuffer = PrintSymbolDetail(pszCurrBuffer);
+ PrintSymbolDetail();
symbolDetails.emplace();
- return pszCurrBuffer;
}
-char* WheatyExceptionReport::PopSymbolDetail(char* pszCurrBuffer)
+void WheatyExceptionReport::PopSymbolDetail()
{
- pszCurrBuffer = PrintSymbolDetail(pszCurrBuffer);
+ PrintSymbolDetail();
symbolDetails.pop();
- return pszCurrBuffer;
}
-char* WheatyExceptionReport::PrintSymbolDetail(char* pszCurrBuffer)
+void WheatyExceptionReport::PrintSymbolDetail()
{
if (symbolDetails.empty())
- return pszCurrBuffer;
+ return;
// Don't log anything if has been logged already or if it's empty
if (symbolDetails.top().Logged || symbolDetails.top().empty())
- return pszCurrBuffer;
+ return;
// Add appropriate indentation level (since this routine is recursive)
for (size_t i = 0; i < symbolDetails.size(); i++)
- pszCurrBuffer += sprintf(pszCurrBuffer, "\t");
+ Log(_T("\t"));
- pszCurrBuffer += sprintf(pszCurrBuffer, "%s\r\n", symbolDetails.top().ToString().c_str());
+ Log(_T("%s\r\n"), symbolDetails.top().ToString().c_str());
- return pszCurrBuffer;
+ return;
}
#endif // _WIN32
diff --git a/src/common/Debugging/WheatyExceptionReport.h b/src/common/Debugging/WheatyExceptionReport.h
index 7d7ae3feb4e..42d4d3e0a2a 100644
--- a/src/common/Debugging/WheatyExceptionReport.h
+++ b/src/common/Debugging/WheatyExceptionReport.h
@@ -14,7 +14,8 @@
#define WER_MAX_ARRAY_ELEMENTS_COUNT 10
#define WER_MAX_NESTING_LEVEL 4
-#define WER_LARGE_BUFFER_SIZE 1024 * 128
+#define WER_SMALL_BUFFER_SIZE 1024
+#define WER_LARGE_BUFFER_SIZE WER_SMALL_BUFFER_SIZE * 16
enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK
{
@@ -173,18 +174,18 @@ class WheatyExceptionReport
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO, ULONG, PVOID);
- static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME64 *, char * pszBuffer, unsigned cbBuffer);
+ static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME64 *);
- static char * DumpTypeIndex(char *, DWORD64, DWORD, DWORD_PTR, bool &, const char*, char*, bool, bool);
+ static void DumpTypeIndex(DWORD64, DWORD, DWORD_PTR, bool &, const char*, char*, bool, bool);
static void FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, size_t bufferSize, size_t countOverride = 0);
static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase);
static DWORD_PTR DereferenceUnsafePointer(DWORD_PTR address);
- static int __cdecl _tprintf(const TCHAR * format, ...);
- static int __cdecl stackprintf(const TCHAR * format, va_list argptr);
- static int __cdecl heapprintf(const TCHAR * format, va_list argptr);
+ static int __cdecl Log(const TCHAR * format, ...);
+ static int __cdecl StackLog(const TCHAR * format, va_list argptr);
+ static int __cdecl HeapLog(const TCHAR * format, va_list argptr);
static bool StoreSymbol(DWORD type , DWORD_PTR offset);
static void ClearSymbols();
@@ -205,9 +206,9 @@ class WheatyExceptionReport
typedef NTSTATUS(NTAPI* pRtlGetVersion)(PRTL_OSVERSIONINFOW lpVersionInformation);
static pRtlGetVersion RtlGetVersion;
- static char* PushSymbolDetail(char* pszCurrBuffer);
- static char* PopSymbolDetail(char* pszCurrBuffer);
- static char* PrintSymbolDetail(char* pszCurrBuffer);
+ static void PushSymbolDetail();
+ static void PopSymbolDetail();
+ static void PrintSymbolDetail();
};
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index 20520cb2068..a18fd16ad15 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -63,13 +63,6 @@ TC_COMMON_API std::string secsToTimeString(uint64 timeInSecs, bool shortText = f
TC_COMMON_API uint32 TimeStringToSecs(const std::string& timestring);
TC_COMMON_API std::string TimeToTimestampStr(time_t t);
-inline void ApplyPercentModFloatVar(float& var, float val, bool apply)
-{
- if (val == -100.0f) // prevent set var to zero
- val = -99.99f;
- var *= (apply ? (100.0f + val) / 100.0f : 100.0f / (100.0f + val));
-}
-
// Percentage calculation
template <class T, class U>
inline T CalculatePct(T base, U pct)
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp
index 7fbc8ed2ed5..b9d052cb528 100644
--- a/src/server/game/AI/CreatureAI.cpp
+++ b/src/server/game/AI/CreatureAI.cpp
@@ -368,13 +368,25 @@ bool CreatureAI::CheckBoundary(Position const* who) const
who = me;
if (_boundary)
- for (AreaBoundary const* boundary : *_boundary)
- if (!boundary->IsWithinBoundary(who))
+ for (AreaBoundary const* areaBoundary : *_boundary)
+ if (!areaBoundary->IsWithinBoundary(who))
return false;
return true;
}
+bool CreatureAI::IsInBounds(CreatureBoundary const* boundary, Position const* pos)
+{
+ if (!boundary)
+ return true;
+
+ for (AreaBoundary const* areaBoundary : *boundary)
+ if (!areaBoundary->IsWithinBoundary(pos))
+ return false;
+
+ return true;
+}
+
void CreatureAI::SetBoundary(CreatureBoundary const* boundary)
{
_boundary = boundary;
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index e36a41795a0..5fe93e7675a 100644
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -31,7 +31,7 @@ class PlayerAI;
class WorldObject;
struct Position;
-typedef std::set<AreaBoundary const*> CreatureBoundary;
+typedef std::vector<AreaBoundary const*> CreatureBoundary;
#define TIME_INTERVAL_LOOK 5000
#define VISIBILITY_RANGE 10000
@@ -82,6 +82,7 @@ class TC_GAME_API CreatureAI : public UnitAI
Creature* DoSummonFlyer(uint32 entry, WorldObject* obj, float flightZ, float radius = 5.0f, uint32 despawnTime = 30000, TempSummonType summonType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
bool CheckBoundary(Position const* who = nullptr) const;
+
void SetBoundary(CreatureBoundary const* boundary);
public:
enum EvadeReason
@@ -214,6 +215,8 @@ class TC_GAME_API CreatureAI : public UnitAI
virtual bool CheckInRoom();
CreatureBoundary const* GetBoundary() const { return _boundary; }
+ static bool IsInBounds(CreatureBoundary const* boundary, Position const* who);
+
protected:
virtual void MoveInLineOfSight(Unit* /*who*/);
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 8bee4794975..6224533846e 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -2341,12 +2341,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
if (Creature* creature = (*itr)->ToCreature())
- {
- creature->GetMotionMaster()->Clear();
creature->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, 0.0f, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); // @todo add optional jump orientation support?
- }
}
- /// @todo Resume path when reached jump location
delete targets;
break;
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 77ed2075a33..12e33cf9ee3 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -1016,6 +1016,9 @@ bool AchievementGlobalMgr::IsRealmCompleted(AchievementEntry const* achievement)
if (itr->second == std::chrono::system_clock::time_point::min())
return false;
+ if (itr->second == std::chrono::system_clock::time_point::max())
+ return true;
+
// Allow completing the realm first kill for entire minute after first person did it
// it may allow more than one group to achieve it (highly unlikely)
// but apparently this is how blizz handles it as well
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 748e1ac26ee..4bbb29d43c1 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -536,12 +536,12 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/,
UpdateLevelDependantStats(); // We still re-initialize level dependant stats on entry update
SetMeleeDamageSchool(SpellSchools(cInfo->dmgschool));
- SetModifierValue(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_HOLY]));
- SetModifierValue(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_FIRE]));
- SetModifierValue(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_NATURE]));
- SetModifierValue(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_FROST]));
- SetModifierValue(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_SHADOW]));
- SetModifierValue(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_ARCANE]));
+ SetStatFlatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_HOLY]));
+ SetStatFlatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_FIRE]));
+ SetStatFlatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_NATURE]));
+ SetStatFlatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_FROST]));
+ SetStatFlatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_SHADOW]));
+ SetStatFlatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_ARCANE]));
SetCanModifyStats(true);
UpdateAllStats();
@@ -1043,8 +1043,7 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, float
LastUsedScriptID = GetScriptId();
- /// @todo Replace with spell, handle from DB
- if (IsSpiritHealer() || IsSpiritGuide())
+ if (IsSpiritHealer() || IsSpiritGuide() || (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_GHOST_VISIBILITY))
{
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST);
m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST);
@@ -1409,7 +1408,7 @@ void Creature::UpdateLevelDependantStats()
break;
}
- SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
+ SetStatFlatModifier(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
// damage
float basedamage = stats->GenerateBaseDamage(cInfo);
@@ -1426,11 +1425,11 @@ void Creature::UpdateLevelDependantStats()
SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, weaponBaseMinDamage);
SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
- SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, stats->AttackPower);
- SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, stats->RangedAttackPower);
+ SetStatFlatModifier(UNIT_MOD_ATTACK_POWER, BASE_VALUE, stats->AttackPower);
+ SetStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, stats->RangedAttackPower);
float armor = (float)stats->GenerateArmor(cInfo); /// @todo Why is this treated as uint32 when it's a float?
- SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, armor);
+ SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, armor);
}
float Creature::_GetHealthMod(int32 Rank)
@@ -1906,7 +1905,7 @@ void Creature::setDeathState(DeathState s)
SetCannotReachTarget(false);
UpdateMovementFlags();
- ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~UNIT_STATE_IGNORE_PATHFINDING));
+ ClearUnitState(UNIT_STATE_ALL_ERASABLE);
if (!IsPet())
{
@@ -2437,7 +2436,7 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const
else
{
// include sizes for huge npcs
- dist += GetObjectSize() + victim->GetObjectSize();
+ dist += GetCombatReach() + victim->GetCombatReach();
// to prevent creatures in air ignore attacks because distance is already too high...
if (GetCreatureTemplate()->InhabitType & INHABIT_AIR)
@@ -2755,7 +2754,8 @@ std::string Creature::GetScriptName() const
uint32 Creature::GetScriptId() const
{
if (CreatureData const* creatureData = GetCreatureData())
- return creatureData->ScriptId;
+ if (uint32 scriptId = creatureData->ScriptId)
+ return scriptId;
return sObjectMgr->GetCreatureTemplate(GetEntry())->ScriptID;
}
@@ -2995,7 +2995,7 @@ void Creature::SetObjectScale(float scale)
if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(GetDisplayId()))
{
SetBoundingRadius((IsPet() ? 1.0f : minfo->bounding_radius) * scale);
- SetCombatReach((IsPet() ? DEFAULT_COMBAT_REACH : minfo->combat_reach) * scale);
+ SetCombatReach((IsPet() ? DEFAULT_PLAYER_COMBAT_REACH : minfo->combat_reach) * scale);
}
}
@@ -3006,7 +3006,7 @@ void Creature::SetDisplayId(uint32 modelId, float displayScale /*= 1.f*/)
if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId))
{
SetBoundingRadius((IsPet() ? 1.0f : minfo->bounding_radius) * GetObjectScale());
- SetCombatReach((IsPet() ? DEFAULT_COMBAT_REACH : minfo->combat_reach) * GetObjectScale());
+ SetCombatReach((IsPet() ? DEFAULT_PLAYER_COMBAT_REACH : minfo->combat_reach) * GetObjectScale());
}
}
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index afd07d44053..1be3e00e39a 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -155,7 +155,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
void UpdateMaxPower(Powers power) override;
uint32 GetPowerIndex(Powers power) const override;
void UpdateAttackPowerAndDamage(bool ranged = false) override;
- void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) override;
+ void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) const override;
void SetCanDualWield(bool value) override;
int8 GetOriginalEquipmentId() const { return m_originalEquipmentId; }
diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h
index f94e8dbe22a..d5657ced163 100644
--- a/src/server/game/Entities/Creature/CreatureData.h
+++ b/src/server/game/Entities/Creature/CreatureData.h
@@ -255,7 +255,7 @@ enum CreatureDifficultyFlags7
CREATURE_DIFFICULTYFLAGS_7_UNK1 = 0x00000008
};
-enum CreatureFlagsExtra
+enum CreatureFlagsExtra : uint32
{
CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group
CREATURE_FLAG_EXTRA_CIVILIAN = 0x00000002, // not aggro (ignore faction/reputation hostility)
@@ -267,24 +267,37 @@ enum CreatureFlagsExtra
CREATURE_FLAG_EXTRA_TRIGGER = 0x00000080, // trigger creature
CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00000100, // creature is immune to taunt auras and effect attack me
CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE = 0x00000200, // creature won't update movement flags
+ CREATURE_FLAG_EXTRA_GHOST_VISIBILITY = 0x00000400, // creature will be only visible for dead players
+ CREATURE_FLAG_EXTRA_UNUSED_11 = 0x00000800,
+ CREATURE_FLAG_EXTRA_UNUSED_12 = 0x00001000,
+ CREATURE_FLAG_EXTRA_UNUSED_13 = 0x00002000,
CREATURE_FLAG_EXTRA_WORLDEVENT = 0x00004000, // custom flag for world event creatures (left room for merging)
CREATURE_FLAG_EXTRA_GUARD = 0x00008000, // Creature is guard
+ CREATURE_FLAG_EXTRA_UNUSED_16 = 0x00010000,
CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes
CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills
CREATURE_FLAG_EXTRA_TAUNT_DIMINISH = 0x00080000, // Taunt is a subject to diminishing returns on this creautre
CREATURE_FLAG_EXTRA_ALL_DIMINISH = 0x00100000, // creature is subject to all diminishing returns as player are
CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ = 0x00200000, // creature does not need to take player damage for kill credit
+ CREATURE_FLAG_EXTRA_UNUSED_22 = 0x00400000,
+ CREATURE_FLAG_EXTRA_UNUSED_23 = 0x00800000,
+ CREATURE_FLAG_EXTRA_UNUSED_24 = 0x01000000,
+ CREATURE_FLAG_EXTRA_UNUSED_25 = 0x02000000,
+ CREATURE_FLAG_EXTRA_UNUSED_26 = 0x04000000,
+ CREATURE_FLAG_EXTRA_UNUSED_27 = 0x08000000,
CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000, // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB)
CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING = 0x20000000, // creature ignore pathfinding
- CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK = 0x40000000 // creature is immune to knockback effects
-};
+ CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK = 0x40000000, // creature is immune to knockback effects
+ CREATURE_FLAG_EXTRA_UNUSED_31 = 0x80000000,
+
+ // Masks
+ CREATURE_FLAG_EXTRA_UNUSED = (CREATURE_FLAG_EXTRA_UNUSED_11 | CREATURE_FLAG_EXTRA_UNUSED_12 | CREATURE_FLAG_EXTRA_UNUSED_13 |
+ CREATURE_FLAG_EXTRA_UNUSED_16 | CREATURE_FLAG_EXTRA_UNUSED_22 | CREATURE_FLAG_EXTRA_UNUSED_23 |
+ CREATURE_FLAG_EXTRA_UNUSED_24 | CREATURE_FLAG_EXTRA_UNUSED_25 | CREATURE_FLAG_EXTRA_UNUSED_26 |
+ CREATURE_FLAG_EXTRA_UNUSED_27 | CREATURE_FLAG_EXTRA_UNUSED_31),
-#define CREATURE_FLAG_EXTRA_DB_ALLOWED (CREATURE_FLAG_EXTRA_INSTANCE_BIND | CREATURE_FLAG_EXTRA_CIVILIAN | \
- CREATURE_FLAG_EXTRA_NO_PARRY | CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN | CREATURE_FLAG_EXTRA_NO_BLOCK | \
- CREATURE_FLAG_EXTRA_NO_CRUSH | CREATURE_FLAG_EXTRA_NO_XP_AT_KILL | CREATURE_FLAG_EXTRA_TRIGGER | \
- CREATURE_FLAG_EXTRA_NO_TAUNT | CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE | CREATURE_FLAG_EXTRA_WORLDEVENT | CREATURE_FLAG_EXTRA_NO_CRIT | \
- CREATURE_FLAG_EXTRA_NO_SKILLGAIN | CREATURE_FLAG_EXTRA_TAUNT_DIMINISH | CREATURE_FLAG_EXTRA_ALL_DIMINISH | \
- CREATURE_FLAG_EXTRA_GUARD | CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING | CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ | CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK)
+ CREATURE_FLAG_EXTRA_DB_ALLOWED = (0xFFFFFFFF & ~(CREATURE_FLAG_EXTRA_UNUSED | CREATURE_FLAG_EXTRA_DUNGEON_BOSS))
+};
const uint32 CREATURE_REGEN_INTERVAL = 2 * IN_MILLISECONDS;
const uint32 PET_FOCUS_REGEN_INTERVAL = 4 * IN_MILLISECONDS;
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 05aadcc1709..76be982fdb2 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -598,13 +598,13 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU
if (canComplete)
{
- packet.CompEmoteDelay = quest->EmoteOnCompleteDelay;
- packet.CompEmoteType = quest->EmoteOnComplete;
+ packet.CompEmoteDelay = quest->GetCompleteEmoteDelay();
+ packet.CompEmoteType = quest->GetCompleteEmote();
}
else
{
- packet.CompEmoteDelay = quest->EmoteOnIncompleteDelay;
- packet.CompEmoteType = quest->EmoteOnIncomplete;
+ packet.CompEmoteDelay = quest->GetIncompleteEmoteDelay();
+ packet.CompEmoteType = quest->GetIncompleteEmote();
}
packet.QuestFlags[0] = quest->GetFlags();
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index 056fe78c99d..c91af442cef 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -120,6 +120,7 @@ class TC_GAME_API Guardian : public Minion
void UpdateDamagePhysical(WeaponAttackType attType) override;
int32 GetBonusDamage() const { return m_bonusSpellDamage; }
+ float GetBonusStatFromOwner(Stats stat) const { return m_statFromOwner[stat]; }
void SetBonusDamage(int32 damage);
protected:
int32 m_bonusSpellDamage;
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index b9e17565702..4e34c8b4785 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2183,7 +2183,8 @@ void GameObject::EventInform(uint32 eventId, WorldObject* invoker /*= nullptr*/)
uint32 GameObject::GetScriptId() const
{
if (GameObjectData const* gameObjectData = GetGOData())
- return gameObjectData->ScriptId;
+ if (uint32 scriptId = gameObjectData->ScriptId)
+ return scriptId;
return GetGOInfo()->ScriptId;
}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index b34f5e7951d..da06d1842f8 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -280,7 +280,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void EventInform(uint32 eventId, WorldObject* invoker = NULL);
- virtual uint32 GetScriptId() const;
+ uint32 GetScriptId() const;
GameObjectAI* AI() const { return m_AI; }
std::string GetAIName() const;
@@ -363,7 +363,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void UpdatePackedRotation();
//! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size.
- bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/) const override
+ bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/, bool /*incOwnRadius*/, bool /*incTargetRadius*/) const override
{
//! Following check does check 3d distance
return IsInRange(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), dist2compare);
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 57be82a51ef..8b7eea39e98 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -844,7 +844,9 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
SetDurability(durability);
// update max durability (and durability) if need
SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::MaxDurability), proto->MaxDurability);
- if (durability > proto->MaxDurability)
+
+ // do not overwrite durability for wrapped items
+ if (durability > proto->MaxDurability && !HasItemFlag(ITEM_FIELD_FLAG_WRAPPED))
{
SetDurability(proto->MaxDurability);
need_save = true;
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index 13f0cb7de66..c4c5ee62d5a 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -258,6 +258,7 @@ class TC_GAME_API Item : public Object
bool IsNotEmptyBag() const;
bool IsBroken() const { return *m_itemData->MaxDurability > 0 && *m_itemData->Durability == 0; }
void SetDurability(uint32 durability) { SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::Durability), durability); }
+ void SetMaxDurability(uint32 maxDurability) { SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::MaxDurability), maxDurability); }
bool CanBeTraded(bool mail = false, bool trade = false) const;
void SetInTrade(bool b = true) { mb_in_trade = b; }
bool IsInTrade() const { return mb_in_trade; }
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index b34b3523fc4..94fd3e932c8 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -969,39 +969,31 @@ InstanceScript* WorldObject::GetInstanceScript()
float WorldObject::GetDistanceZ(const WorldObject* obj) const
{
float dz = std::fabs(GetPositionZ() - obj->GetPositionZ());
- float sizefactor = GetObjectSize() + obj->GetObjectSize();
+ float sizefactor = GetCombatReach() + obj->GetCombatReach();
float dist = dz - sizefactor;
return (dist > 0 ? dist : 0);
}
-bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const
+bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D, bool incOwnRadius, bool incTargetRadius) const
{
- float sizefactor = GetObjectSize() + obj->GetObjectSize();
+ float sizefactor = 0;
+ sizefactor += incOwnRadius ? GetCombatReach() : 0.0f;
+ sizefactor += incTargetRadius ? obj->GetCombatReach() : 0.0f;
float maxdist = dist2compare + sizefactor;
+ Position const* thisOrTransport = this;
+ Position const* objOrObjTransport = obj;
+
if (GetTransport() && obj->GetTransport() && obj->GetTransport()->GetGUID() == GetTransport()->GetGUID())
{
- float dtx = m_movementInfo.transport.pos.m_positionX - obj->m_movementInfo.transport.pos.m_positionX;
- float dty = m_movementInfo.transport.pos.m_positionY - obj->m_movementInfo.transport.pos.m_positionY;
- float disttsq = dtx * dtx + dty * dty;
- if (is3D)
- {
- float dtz = m_movementInfo.transport.pos.m_positionZ - obj->m_movementInfo.transport.pos.m_positionZ;
- disttsq += dtz * dtz;
- }
- return disttsq < (maxdist * maxdist);
+ thisOrTransport = &m_movementInfo.transport.pos;
+ objOrObjTransport = &obj->m_movementInfo.transport.pos;
}
- float dx = GetPositionX() - obj->GetPositionX();
- float dy = GetPositionY() - obj->GetPositionY();
- float distsq = dx*dx + dy*dy;
if (is3D)
- {
- float dz = GetPositionZ() - obj->GetPositionZ();
- distsq += dz*dz;
- }
-
- return distsq < maxdist * maxdist;
+ return thisOrTransport->IsInDist(objOrObjTransport, maxdist);
+ else
+ return thisOrTransport->IsInDist2d(objOrObjTransport, maxdist);
}
bool WorldObject::IsWithinLOSInMap(const WorldObject* obj, VMAP::ModelIgnoreFlags ignoreFlags) const
@@ -1020,31 +1012,31 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj, VMAP::ModelIgnoreFlag
float WorldObject::GetDistance(const WorldObject* obj) const
{
- float d = GetExactDist(obj) - GetObjectSize() - obj->GetObjectSize();
+ float d = GetExactDist(obj) - GetCombatReach() - obj->GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
float WorldObject::GetDistance(const Position &pos) const
{
- float d = GetExactDist(&pos) - GetObjectSize();
+ float d = GetExactDist(&pos) - GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
float WorldObject::GetDistance(float x, float y, float z) const
{
- float d = GetExactDist(x, y, z) - GetObjectSize();
+ float d = GetExactDist(x, y, z) - GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
float WorldObject::GetDistance2d(const WorldObject* obj) const
{
- float d = GetExactDist2d(obj) - GetObjectSize() - obj->GetObjectSize();
+ float d = GetExactDist2d(obj) - GetCombatReach() - obj->GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
float WorldObject::GetDistance2d(float x, float y) const
{
- float d = GetExactDist2d(x, y) - GetObjectSize();
+ float d = GetExactDist2d(x, y) - GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
@@ -1064,22 +1056,22 @@ bool WorldObject::IsInMap(const WorldObject* obj) const
bool WorldObject::IsWithinDist3d(float x, float y, float z, float dist) const
{
- return IsInDist(x, y, z, dist + GetObjectSize());
+ return IsInDist(x, y, z, dist + GetCombatReach());
}
bool WorldObject::IsWithinDist3d(const Position* pos, float dist) const
{
- return IsInDist(pos, dist + GetObjectSize());
+ return IsInDist(pos, dist + GetCombatReach());
}
bool WorldObject::IsWithinDist2d(float x, float y, float dist) const
{
- return IsInDist2d(x, y, dist + GetObjectSize());
+ return IsInDist2d(x, y, dist + GetCombatReach());
}
bool WorldObject::IsWithinDist2d(const Position* pos, float dist) const
{
- return IsInDist2d(pos, dist + GetObjectSize());
+ return IsInDist2d(pos, dist + GetCombatReach());
}
bool WorldObject::IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const
@@ -1087,9 +1079,9 @@ bool WorldObject::IsWithinDist(WorldObject const* obj, float dist2compare, bool
return obj && _IsWithinDist(obj, dist2compare, is3D);
}
-bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const
+bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D /*= true*/, bool incOwnRadius /*= true*/, bool incTargetRadius /*= true*/) const
{
- return obj && IsInMap(obj) && IsInPhase(obj) && _IsWithinDist(obj, dist2compare, is3D);
+ return obj && IsInMap(obj) && IsInPhase(obj) && _IsWithinDist(obj, dist2compare, is3D, incOwnRadius, incTargetRadius);
}
bool WorldObject::IsWithinLOS(float ox, float oy, float oz, VMAP::ModelIgnoreFlags ignoreFlags) const
@@ -1116,7 +1108,7 @@ Position WorldObject::GetHitSpherePointFor(Position const& dest) const
{
G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ());
G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
- G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * GetObjectSize();
+ G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(GetPosition()), GetCombatReach());
return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y));
}
@@ -1163,7 +1155,7 @@ bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRan
distsq += dz*dz;
}
- float sizefactor = GetObjectSize() + obj->GetObjectSize();
+ float sizefactor = GetCombatReach() + obj->GetCombatReach();
// check only for real range
if (minRange > 0.0f)
@@ -1183,7 +1175,7 @@ bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange)
float dy = GetPositionY() - y;
float distsq = dx*dx + dy*dy;
- float sizefactor = GetObjectSize();
+ float sizefactor = GetCombatReach();
// check only for real range
if (minRange > 0.0f)
@@ -1204,7 +1196,7 @@ bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float m
float dz = GetPositionZ() - z;
float distsq = dx*dx + dy*dy + dz*dz;
- float sizefactor = GetObjectSize();
+ float sizefactor = GetCombatReach();
// check only for real range
if (minRange > 0.0f)
@@ -1227,7 +1219,7 @@ bool WorldObject::IsInBetween(Position const& pos1, Position const& pos2, float
return false;
if (!size)
- size = GetObjectSize() / 2;
+ size = GetCombatReach() / 2;
float angle = pos1.GetAngle(pos2);
@@ -1837,7 +1829,7 @@ TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, fl
{
if (!x && !y && !z)
{
- GetClosePoint(x, y, z, GetObjectSize());
+ GetClosePoint(x, y, z, GetCombatReach());
ang = GetOrientation();
}
@@ -1879,7 +1871,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float
{
if (!x && !y && !z)
{
- GetClosePoint(x, y, z, GetObjectSize());
+ GetClosePoint(x, y, z, GetCombatReach());
ang = GetOrientation();
}
@@ -1993,8 +1985,8 @@ void WorldObject::GetPlayerListInGrid(Container& playerContainer, float maxSearc
void WorldObject::GetNearPoint2D(float &x, float &y, float distance2d, float absAngle) const
{
- x = GetPositionX() + (GetObjectSize() + distance2d) * std::cos(absAngle);
- y = GetPositionY() + (GetObjectSize() + distance2d) * std::sin(absAngle);
+ x = GetPositionX() + (GetCombatReach() + distance2d) * std::cos(absAngle);
+ y = GetPositionY() + (GetCombatReach() + distance2d) * std::sin(absAngle);
Trinity::NormalizeMapCoord(x);
Trinity::NormalizeMapCoord(y);
@@ -2066,15 +2058,7 @@ Position WorldObject::GetRandomNearPosition(float radius)
void WorldObject::GetContactPoint(const WorldObject* obj, float &x, float &y, float &z, float distance2d /*= CONTACT_DISTANCE*/) const
{
// angle to face `obj` to `this` using distance includes size of `obj`
- GetNearPoint(obj, x, y, z, obj->GetObjectSize(), distance2d, GetAngle(obj));
-}
-
-float WorldObject::GetObjectSize() const
-{
- if (Unit const* thisUnit = ToUnit())
- return thisUnit->m_unitData->CombatReach;
-
- return DEFAULT_WORLD_OBJECT_SIZE;
+ GetNearPoint(obj, x, y, z, obj->GetCombatReach(), distance2d, GetAngle(obj));
}
void WorldObject::MovePosition(Position &pos, float dist, float angle)
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index c5e22c86c3a..1d48e1f2384 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -395,7 +395,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
Position GetRandomNearPosition(float radius);
void GetContactPoint(WorldObject const* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const;
- float GetObjectSize() const;
+ virtual float GetCombatReach() const { return 0.0f; } // overridden (only) in Unit
void UpdateGroundPositionZ(float x, float y, float &z) const;
void UpdateAllowedPositionZ(float x, float y, float &z) const;
@@ -445,7 +445,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
bool IsWithinDist2d(Position const* pos, float dist) const;
// use only if you will sure about placing both object at same map
bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const;
- bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const;
+ bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true, bool incOwnRadius = true, bool incTargetRadius = true) const;
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const;
bool IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const;
Position GetHitSpherePointFor(Position const& dest) const;
@@ -605,7 +605,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
uint16 m_notifyflags;
uint16 m_executed_notifies;
- virtual bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const;
+ virtual bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D, bool incOwnRadius = true, bool incTargetRadius = true) const;
bool CanNeverSee(WorldObject const* obj) const;
virtual bool CanAlwaysSee(WorldObject const* /*obj*/) const { return false; }
diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h
index b0db49bcf9f..43f2ea15a4d 100644
--- a/src/server/game/Entities/Object/ObjectDefines.h
+++ b/src/server/game/Entities/Object/ObjectDefines.h
@@ -36,11 +36,11 @@
#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
-#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
-#define DEFAULT_COMBAT_REACH 1.5f
-#define MIN_MELEE_REACH 2.0f
-#define NOMINAL_MELEE_RANGE 5.0f
-#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
+#define DEFAULT_PLAYER_BOUNDING_RADIUS 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
+#define DEFAULT_PLAYER_COMBAT_REACH 1.5f
+#define MIN_MELEE_REACH 2.0f
+#define NOMINAL_MELEE_RANGE 5.0f
+#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
enum class VisibilityDistanceType : uint8
{
diff --git a/src/server/game/Entities/Object/Position.cpp b/src/server/game/Entities/Object/Position.cpp
index ae0fc14e173..a63a3da76d6 100644
--- a/src/server/game/Entities/Object/Position.cpp
+++ b/src/server/game/Entities/Object/Position.cpp
@@ -148,6 +148,12 @@ bool Position::IsWithinBox(const Position& center, float xradius, float yradius,
return true;
}
+bool Position::IsWithinDoubleVerticalCylinder(Position const* center, float radius, float height) const
+{
+ float verticalDelta = GetPositionZ() - center->GetPositionZ();
+ return IsInDist2d(center, radius) && std::abs(verticalDelta) <= height;
+}
+
bool Position::HasInArc(float arc, const Position* obj, float border) const
{
// always have self in arc
diff --git a/src/server/game/Entities/Object/Position.h b/src/server/game/Entities/Object/Position.h
index 37f1231e709..f247c7fb860 100644
--- a/src/server/game/Entities/Object/Position.h
+++ b/src/server/game/Entities/Object/Position.h
@@ -218,6 +218,11 @@ public:
}
bool IsWithinBox(const Position& center, float xradius, float yradius, float zradius) const;
+
+ /*
+ search using this relation: dist2d < radius && abs(dz) < height
+ */
+ bool IsWithinDoubleVerticalCylinder(Position const* center, float radius, float height) const;
bool HasInArc(float arcangle, Position const* pos, float border = 2.0f) const;
bool HasInLine(Position const* pos, float objSize, float width) const;
std::string ToString() const;
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 7563289b480..9c16502dd25 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -192,7 +192,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
if (IsCritter())
{
float px, py, pz;
- owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, GetFollowAngle());
+ owner->GetClosePoint(px, py, pz, GetCombatReach(), PET_FOLLOW_DIST, GetFollowAngle());
Relocate(px, py, pz, owner->GetOrientation());
if (!IsPositionValid())
@@ -245,7 +245,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
// Set pet's position after setting level, its size depends on it
float px, py, pz;
- owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, GetFollowAngle());
+ owner->GetClosePoint(px, py, pz, GetCombatReach(), PET_FOLLOW_DIST, GetFollowAngle());
Relocate(px, py, pz, owner->GetOrientation());
if (!IsPositionValid())
{
@@ -375,6 +375,8 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
if (owner->GetTypeId() == TYPEID_PLAYER && isControlled() && !isTemporarySummoned() && (getPetType() == SUMMON_PET || getPetType() == HUNTER_PET))
owner->ToPlayer()->SetLastPetNumber(petId);
+ // must be after SetMinion (owner guid check)
+ LoadMechanicTemplateImmunity();
m_loading = false;
return true;
@@ -794,7 +796,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
- SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(petlevel*50));
+ SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(petlevel * 50));
SetBaseAttackTime(BASE_ATTACK, BASE_ATTACK_TIME);
SetBaseAttackTime(OFF_ATTACK, BASE_ATTACK_TIME);
@@ -819,7 +821,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
// Hunters pet should not inherit resistances from creature_template, they have separate auras for that
if (!IsHunterPet())
for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
- SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(cinfo->resistance[i]));
+ SetStatFlatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(cinfo->resistance[i]));
// Health, Mana or Power, Armor
PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(creature_ID, petlevel);
@@ -829,7 +831,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
SetCreateMana(pInfo->mana);
if (pInfo->armor > 0)
- SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
+ SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
for (uint8 stat = 0; stat < MAX_STATS; ++stat)
SetCreateStat(Stats(stat), float(pInfo->stats[stat]));
@@ -875,7 +877,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
- //SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, float(cinfo->attackpower));
+ //SetStatFlatModifier(UNIT_MOD_ATTACK_POWER, BASE_VALUE, float(cinfo->attackpower));
break;
}
case HUNTER_PET:
@@ -963,8 +965,8 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel)));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel)));
- SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(GetOwner()->GetArmor()) * 0.35f); // Bonus Armor (35% of player armor)
- SetModifierValue(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(GetOwner()->GetStat(STAT_STAMINA)) * 0.3f); // Bonus Stamina (30% of player stamina)
+ SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(GetOwner()->GetArmor()) * 0.35f); // Bonus Armor (35% of player armor)
+ SetStatFlatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(GetOwner()->GetStat(STAT_STAMINA)) * 0.3f); // Bonus Stamina (30% of player stamina)
if (!HasAura(58877))//prevent apply twice for the 2 wolves
AddAura(58877, this);//Spirit Hunt, passive, Spirit Wolves' attacks heal them and their master for 150% of damage done.
break;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index daeaf3d8877..5f2199d9f52 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -269,8 +269,8 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this)
for (uint8 i = 0; i < BASEMOD_END; ++i)
{
- m_auraBaseMod[i][FLAT_MOD] = 0.0f;
- m_auraBaseMod[i][PCT_MOD] = 1.0f;
+ m_auraBaseFlatMod[i] = 0.0f;
+ m_auraBasePctMod[i] = 1.0f;
}
for (uint8 i = 0; i < MAX_COMBAT_RATING; i++)
@@ -1767,8 +1767,8 @@ void Player::RemoveFromWorld()
void Player::SetObjectScale(float scale)
{
Unit::SetObjectScale(scale);
- SetBoundingRadius(scale * DEFAULT_WORLD_OBJECT_SIZE);
- SetCombatReach(scale * DEFAULT_COMBAT_REACH);
+ SetBoundingRadius(scale * DEFAULT_PLAYER_BOUNDING_RADIUS);
+ SetCombatReach(scale * DEFAULT_PLAYER_COMBAT_REACH);
if (IsInWorld())
SendMovementSetCollisionHeight(scale * GetCollisionHeight(IsMounted()));
}
@@ -4952,20 +4952,104 @@ void Player::LeaveLFGChannel()
}
}
-void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply)
+void Player::HandleBaseModFlatValue(BaseModGroup modGroup, float amount, bool apply)
{
- if (modGroup >= BASEMOD_END || modType >= MOD_END)
+ if (modGroup >= BASEMOD_END)
{
TC_LOG_ERROR("spells", "Player::HandleBaseModValue: Invalid BaseModGroup/BaseModType (%u/%u) for player '%s' (%s)",
- modGroup, modType, GetName().c_str(), GetGUID().ToString().c_str());
+ modGroup, FLAT_MOD, GetName().c_str(), GetGUID().ToString().c_str());
+ return;
+ }
+
+ m_auraBaseFlatMod[modGroup] += apply ? amount : -amount;
+ UpdateBaseModGroup(modGroup);
+}
+
+void Player::ApplyBaseModPctValue(BaseModGroup modGroup, float pct)
+{
+ if (modGroup >= BASEMOD_END)
+ {
+ TC_LOG_ERROR("spells", "Player::HandleBaseModValue: Invalid BaseModGroup/BaseModType (%u/%u) for player '%s' (%s)",
+ modGroup, FLAT_MOD, GetName().c_str(), GetGUID().ToString().c_str());
+ return;
+ }
+
+ AddPct(m_auraBasePctMod[modGroup], pct);
+ UpdateBaseModGroup(modGroup);
+}
+
+void Player::SetBaseModFlatValue(BaseModGroup modGroup, float val)
+{
+ if (m_auraBaseFlatMod[modGroup] == val)
+ return;
+
+ m_auraBaseFlatMod[modGroup] = val;
+ UpdateBaseModGroup(modGroup);
+}
+
+void Player::SetBaseModPctValue(BaseModGroup modGroup, float val)
+{
+ if (m_auraBasePctMod[modGroup] == val)
return;
+
+ m_auraBasePctMod[modGroup] = val;
+ UpdateBaseModGroup(modGroup);
+}
+
+void Player::UpdateDamageDoneMods(WeaponAttackType attackType)
+{
+ Unit::UpdateDamageDoneMods(attackType);
+
+ UnitMods unitMod;
+ switch (attackType)
+ {
+ case BASE_ATTACK:
+ unitMod = UNIT_MOD_DAMAGE_MAINHAND;
+ break;
+ case OFF_ATTACK:
+ unitMod = UNIT_MOD_DAMAGE_OFFHAND;
+ break;
+ case RANGED_ATTACK:
+ unitMod = UNIT_MOD_DAMAGE_RANGED;
+ break;
+ default:
+ ABORT();
+ break;
}
- if (modType == FLAT_MOD)
- m_auraBaseMod[modGroup][modType] += apply ? amount : -amount;
- else // PCT_MOD
- ApplyPercentModFloatVar(m_auraBaseMod[modGroup][modType], amount, apply);
+ float amount = 0.0f;
+ Item* item = GetWeaponForAttack(attackType, true);
+ if (!item)
+ return;
+ for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
+ {
+ SpellItemEnchantmentEntry const* enchantmentEntry = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot)));
+ if (!enchantmentEntry)
+ continue;
+
+ for (uint8 i = 0; i < MAX_ITEM_ENCHANTMENT_EFFECTS; ++i)
+ {
+ switch (enchantmentEntry->Effect[i])
+ {
+ case ITEM_ENCHANTMENT_TYPE_DAMAGE:
+ amount += enchantmentEntry->EffectScalingPoints[i];
+ break;
+ case ITEM_ENCHANTMENT_TYPE_TOTEM:
+ if (getClass() == CLASS_SHAMAN)
+ amount += enchantmentEntry->EffectScalingPoints[i] * item->GetTemplate()->GetDelay() / 1000.0f;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ HandleStatFlatModifier(unitMod, TOTAL_VALUE, amount, true);
+}
+
+void Player::UpdateBaseModGroup(BaseModGroup modGroup)
+{
if (!CanModifyStats())
return;
@@ -4987,10 +5071,7 @@ float Player::GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const
return 0.0f;
}
- if (modType == PCT_MOD && m_auraBaseMod[modGroup][PCT_MOD] <= 0.0f)
- return 0.0f;
-
- return m_auraBaseMod[modGroup][modType];
+ return (modType == FLAT_MOD ? m_auraBaseFlatMod[modGroup] : m_auraBasePctMod[modGroup]);
}
float Player::GetTotalBaseModValue(BaseModGroup modGroup) const
@@ -5002,10 +5083,7 @@ float Player::GetTotalBaseModValue(BaseModGroup modGroup) const
return 0.0f;
}
- if (m_auraBaseMod[modGroup][PCT_MOD] <= 0.0f)
- return 0.0f;
-
- return m_auraBaseMod[modGroup][FLAT_MOD] * m_auraBaseMod[modGroup][PCT_MOD];
+ return m_auraBaseFlatMod[modGroup] * m_auraBasePctMod[modGroup];
}
void Player::GetDodgeFromAgility(float &/*diminishing*/, float &/*nondiminishing*/) const
@@ -5053,7 +5131,7 @@ void Player::GetDodgeFromAgility(float &/*diminishing*/, float &/*nondiminishing
// return;
///// @todo research if talents/effects that increase total agility by x% should increase non-diminishing part
- //float base_agility = GetCreateStat(STAT_AGILITY) * m_auraModifiersGroup[UNIT_MOD_STAT_START + STAT_AGILITY][BASE_PCT];
+ //float base_agility = GetCreateStat(STAT_AGILITY) * GetPctModifierValue(UnitMods(UNIT_MOD_STAT_START + STAT_AGILITY), BASE_PCT);
//float bonus_agility = GetStat(STAT_AGILITY) - base_agility;
//// calculate diminishing (green in char screen) and non-diminishing (white) contribution
@@ -5312,7 +5390,7 @@ void Player::UpdateRating(CombatRating cr)
void Player::UpdateAllRatings()
{
- for (int cr = 0; cr < MAX_COMBAT_RATING; ++cr)
+ for (uint8 cr = 0; cr < MAX_COMBAT_RATING; ++cr)
UpdateRating(CombatRating(cr));
}
@@ -7419,7 +7497,13 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply, bool updateItemA
_ApplyItemBonuses(item, slot, apply);
ApplyItemEquipSpell(item, apply);
if (updateItemAuras)
+ {
ApplyItemDependentAuras(item, apply);
+
+ WeaponAttackType const attackType = Player::GetAttackBySlot(slot, item->GetTemplate()->GetInventoryType());
+ if (attackType != MAX_ATTACK)
+ UpdateWeaponDependentAuras(attackType);
+ }
ApplyArtifactPowers(item, apply);
ApplyAzeritePowers(item, apply);
ApplyEnchantment(item, apply);
@@ -7452,22 +7536,22 @@ void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply)
switch (statType)
{
case ITEM_MOD_MANA:
- HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_MANA, BASE_VALUE, float(val), apply);
break;
case ITEM_MOD_HEALTH: // modify HP
- HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(val), apply);
break;
case ITEM_MOD_AGILITY: // modify agility
- HandleStatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_AGILITY, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_AGILITY, BASE_PCT_EXCLUDE_CREATE)), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
+ UpdateStatBuffMod(STAT_AGILITY);
break;
case ITEM_MOD_STRENGTH: //modify strength
- HandleStatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_STRENGTH, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_STRENGTH, BASE_PCT_EXCLUDE_CREATE)), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
+ UpdateStatBuffMod(STAT_STRENGTH);
break;
case ITEM_MOD_INTELLECT: //modify intellect
- HandleStatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_INTELLECT, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_INTELLECT, BASE_PCT_EXCLUDE_CREATE)), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
+ UpdateStatBuffMod(STAT_INTELLECT);
break;
// case ITEM_MOD_SPIRIT: //modify spirit
// HandleStatModifier(UNIT_MOD_STAT_SPIRIT, BASE_VALUE, float(val), apply);
@@ -7477,8 +7561,8 @@ void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply)
{
if (GtStaminaMultByILvl const* staminaMult = sStaminaMultByILvlGameTable.GetRow(itemLevel))
val = int32(val * GetIlvlStatMultiplier(staminaMult, proto->GetInventoryType()));
- HandleStatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_STAMINA, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_STAMINA, BASE_PCT_EXCLUDE_CREATE)), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(val), apply);
+ UpdateStatBuffMod(STAT_STAMINA);
break;
}
case ITEM_MOD_DEFENSE_SKILL_RATING:
@@ -7570,11 +7654,11 @@ void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply)
ApplyRatingMod(CR_EXPERTISE, int32(val * combatRatingMultiplier), apply);
break;
case ITEM_MOD_ATTACK_POWER:
- HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(val), apply);
- HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
break;
case ITEM_MOD_RANGED_ATTACK_POWER:
- HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
break;
case ITEM_MOD_VERSATILITY:
ApplyRatingMod(CR_VERSATILITY_DAMAGE_DONE, int32(val * combatRatingMultiplier), apply);
@@ -7600,25 +7684,25 @@ void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply)
ApplyRatingMod(CR_MASTERY, int32(val * combatRatingMultiplier), apply);
break;
case ITEM_MOD_EXTRA_ARMOR:
- HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(val), apply);
break;
case ITEM_MOD_FIRE_RESISTANCE:
- HandleStatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(val), apply);
break;
case ITEM_MOD_FROST_RESISTANCE:
- HandleStatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(val), apply);
break;
case ITEM_MOD_HOLY_RESISTANCE:
- HandleStatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(val), apply);
break;
case ITEM_MOD_SHADOW_RESISTANCE:
- HandleStatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(val), apply);
break;
case ITEM_MOD_NATURE_RESISTANCE:
- HandleStatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(val), apply);
break;
case ITEM_MOD_ARCANE_RESISTANCE:
- HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(val), apply);
break;
case ITEM_MOD_PVP_POWER:
ApplyRatingMod(CR_PVP_POWER, int32(val), apply);
@@ -7654,36 +7738,36 @@ void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply)
ApplyRatingMod(CR_UNUSED_12, int32(val), apply);
break;
case ITEM_MOD_AGI_STR_INT:
- HandleStatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
- HandleStatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
- HandleStatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_AGILITY, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_AGILITY, BASE_PCT_EXCLUDE_CREATE)), apply);
- ApplyStatBuffMod(STAT_STRENGTH, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_STRENGTH, BASE_PCT_EXCLUDE_CREATE)), apply);
- ApplyStatBuffMod(STAT_INTELLECT, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_INTELLECT, BASE_PCT_EXCLUDE_CREATE)), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
+ UpdateStatBuffMod(STAT_AGILITY);
+ UpdateStatBuffMod(STAT_STRENGTH);
+ UpdateStatBuffMod(STAT_INTELLECT);
break;
case ITEM_MOD_AGI_STR:
- HandleStatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
- HandleStatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_AGILITY, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_AGILITY, BASE_PCT_EXCLUDE_CREATE)), apply);
- ApplyStatBuffMod(STAT_STRENGTH, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_STRENGTH, BASE_PCT_EXCLUDE_CREATE)), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
+ UpdateStatBuffMod(STAT_AGILITY);
+ UpdateStatBuffMod(STAT_STRENGTH);
break;
case ITEM_MOD_AGI_INT:
- HandleStatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
- HandleStatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_AGILITY, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_AGILITY, BASE_PCT_EXCLUDE_CREATE)), apply);
- ApplyStatBuffMod(STAT_INTELLECT, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_INTELLECT, BASE_PCT_EXCLUDE_CREATE)), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
+ UpdateStatBuffMod(STAT_AGILITY);
+ UpdateStatBuffMod(STAT_INTELLECT);
break;
case ITEM_MOD_STR_INT:
- HandleStatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
- HandleStatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_STRENGTH, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_STRENGTH, BASE_PCT_EXCLUDE_CREATE)), apply);
- ApplyStatBuffMod(STAT_INTELLECT, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_INTELLECT, BASE_PCT_EXCLUDE_CREATE)), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
+ UpdateStatBuffMod(STAT_STRENGTH);
+ UpdateStatBuffMod(STAT_INTELLECT);
break;
}
}
if (uint32 armor = item->GetArmor(this))
- HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(armor), apply);
+ HandleStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(armor), apply);
WeaponAttackType attType = BASE_ATTACK;
@@ -7775,6 +7859,49 @@ void Player::ApplyItemObtainSpells(Item* item, bool apply)
}
}
+// this one rechecks weapon auras and stores them in BaseModGroup container
+// needed for things like axe specialization applying only to axe weapons in case of dual-wield
+void Player::UpdateWeaponDependentCritAuras(WeaponAttackType attackType)
+{
+ BaseModGroup modGroup;
+ switch (attackType)
+ {
+ case BASE_ATTACK:
+ modGroup = CRIT_PERCENTAGE;
+ break;
+ case OFF_ATTACK:
+ modGroup = OFFHAND_CRIT_PERCENTAGE;
+ break;
+ case RANGED_ATTACK:
+ modGroup = RANGED_CRIT_PERCENTAGE;
+ break;
+ default:
+ ABORT();
+ break;
+ }
+
+ float amount = 0.0f;
+ amount += GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT, std::bind(&Unit::CheckAttackFitToAuraRequirement, this, attackType, std::placeholders::_1));
+
+ // these auras don't have item requirement (only Combat Expertise in 3.3.5a)
+ amount += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+
+ SetBaseModFlatValue(modGroup, amount);
+}
+
+void Player::UpdateAllWeaponDependentCritAuras()
+{
+ for (uint8 i = BASE_ATTACK; i < MAX_ATTACK; ++i)
+ UpdateWeaponDependentCritAuras(WeaponAttackType(i));
+}
+
+void Player::UpdateWeaponDependentAuras(WeaponAttackType attackType)
+{
+ UpdateWeaponDependentCritAuras(attackType);
+ UpdateDamageDoneMods(attackType);
+ UpdateDamagePctDoneMods(attackType);
+}
+
void Player::ApplyItemDependentAuras(Item* item, bool apply)
{
if (apply)
@@ -7797,6 +7924,19 @@ void Player::ApplyItemDependentAuras(Item* item, bool apply)
RemoveItemDependentAurasAndCasts(item);
}
+bool Player::CheckAttackFitToAuraRequirement(WeaponAttackType attackType, AuraEffect const* aurEff) const
+{
+ SpellInfo const* spellInfo = aurEff->GetSpellInfo();
+ if (spellInfo->EquippedItemClass == -1)
+ return true;
+
+ Item* item = GetWeaponForAttack(attackType, true);
+ if (!item || !item->IsFitToSpellRequirements(spellInfo))
+ return false;
+
+ return true;
+}
+
void Player::ApplyItemEquipSpell(Item* item, bool apply, bool formChange /*= false*/)
{
if (!item)
@@ -8427,6 +8567,10 @@ void Player::_ApplyAllItemMods()
ApplyItemDependentAuras(m_items[i], true);
_ApplyItemBonuses(m_items[i], i, true);
+
+ WeaponAttackType const attackType = Player::GetAttackBySlot(i, m_items[i]->GetTemplate()->GetInventoryType());
+ if (attackType != MAX_ATTACK)
+ UpdateWeaponDependentAuras(attackType);
}
}
@@ -10094,7 +10238,7 @@ Item* Player::GetChildItemByGuid(ObjectGuid guid) const
return nullptr;
}
-uint8 Player::GetAttackBySlot(uint8 slot, InventoryType inventoryType)
+WeaponAttackType Player::GetAttackBySlot(uint8 slot, InventoryType inventoryType)
{
switch (slot)
{
@@ -14124,16 +14268,12 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
// processed in Player::CastItemCombatSpell
break;
case ITEM_ENCHANTMENT_TYPE_DAMAGE:
- if (item->GetSlot() == EQUIPMENT_SLOT_MAINHAND)
- {
- if (item->GetTemplate()->GetInventoryType() != INVTYPE_RANGED && item->GetTemplate()->GetInventoryType() != INVTYPE_RANGEDRIGHT)
- HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(enchant_amount), apply);
- else
- HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
- }
- else if (item->GetSlot() == EQUIPMENT_SLOT_OFFHAND)
- HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(enchant_amount), apply);
+ {
+ WeaponAttackType const attackType = Player::GetAttackBySlot(item->GetSlot(), item->GetTemplate()->GetInventoryType());
+ if (attackType != MAX_ATTACK)
+ UpdateDamageDoneMods(attackType);
break;
+ }
case ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL:
if (enchant_spell_id)
{
@@ -14163,7 +14303,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
enchant_amount = uint32(pEnchant->EffectScalingPoints[s] * GetSpellScalingColumnForClass(spellScaling, scalingClass));
}
enchant_amount = std::max(enchant_amount, 1u);
- HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + enchant_spell_id), TOTAL_VALUE, float(enchant_amount), apply);
+ HandleStatFlatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + enchant_spell_id), TOTAL_VALUE, float(enchant_amount), apply);
break;
case ITEM_ENCHANTMENT_TYPE_STAT:
{
@@ -14193,26 +14333,26 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
{
case ITEM_MOD_MANA:
TC_LOG_DEBUG("entities.player.items", "+ %u MANA", enchant_amount);
- HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(enchant_amount), apply);
+ HandleStatFlatModifier(UNIT_MOD_MANA, BASE_VALUE, float(enchant_amount), apply);
break;
case ITEM_MOD_HEALTH:
TC_LOG_DEBUG("entities.player.items", "+ %u HEALTH", enchant_amount);
- HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(enchant_amount), apply);
+ HandleStatFlatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(enchant_amount), apply);
break;
case ITEM_MOD_AGILITY:
TC_LOG_DEBUG("entities.player.items", "+ %u AGILITY", enchant_amount);
- HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, float(enchant_amount), apply);
- ApplyStatBuffMod(STAT_AGILITY, (float)enchant_amount, apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, float(enchant_amount), apply);
+ UpdateStatBuffMod(STAT_AGILITY);
break;
case ITEM_MOD_STRENGTH:
TC_LOG_DEBUG("entities.player.items", "+ %u STRENGTH", enchant_amount);
- HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, float(enchant_amount), apply);
- ApplyStatBuffMod(STAT_STRENGTH, (float)enchant_amount, apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, float(enchant_amount), apply);
+ UpdateStatBuffMod(STAT_STRENGTH);
break;
case ITEM_MOD_INTELLECT:
TC_LOG_DEBUG("entities.player.items", "+ %u INTELLECT", enchant_amount);
- HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, float(enchant_amount), apply);
- ApplyStatBuffMod(STAT_INTELLECT, (float)enchant_amount, apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, float(enchant_amount), apply);
+ UpdateStatBuffMod(STAT_INTELLECT);
break;
// case ITEM_MOD_SPIRIT:
// TC_LOG_DEBUG("entities.player.items", "+ %u SPIRIT", enchant_amount);
@@ -14221,8 +14361,8 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
// break;
case ITEM_MOD_STAMINA:
TC_LOG_DEBUG("entities.player.items", "+ %u STAMINA", enchant_amount);
- HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, float(enchant_amount), apply);
- ApplyStatBuffMod(STAT_STAMINA, (float)enchant_amount, apply);
+ HandleStatFlatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, float(enchant_amount), apply);
+ UpdateStatBuffMod(STAT_STAMINA);
break;
case ITEM_MOD_DEFENSE_SKILL_RATING:
ApplyRatingMod(CR_DEFENSE_SKILL, enchant_amount, apply);
@@ -14330,12 +14470,12 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
TC_LOG_DEBUG("entities.player.items", "+ %u EXPERTISE", enchant_amount);
break;
case ITEM_MOD_ATTACK_POWER:
- HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(enchant_amount), apply);
- HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
+ HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(enchant_amount), apply);
+ HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
TC_LOG_DEBUG("entities.player.items", "+ %u ATTACK_POWER", enchant_amount);
break;
case ITEM_MOD_RANGED_ATTACK_POWER:
- HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
+ HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
TC_LOG_DEBUG("entities.player.items", "+ %u RANGED_ATTACK_POWER", enchant_amount);
break;
case ITEM_MOD_MANA_REGENERATION:
@@ -14359,7 +14499,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
TC_LOG_DEBUG("entities.player.items", "+ %u SPELL_PENETRATION", enchant_amount);
break;
case ITEM_MOD_BLOCK_VALUE:
- HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(enchant_amount), apply);
+ HandleBaseModFlatValue(SHIELD_BLOCK_VALUE, float(enchant_amount), apply);
TC_LOG_DEBUG("entities.player.items", "+ %u BLOCK_VALUE", enchant_amount);
break;
case ITEM_MOD_MASTERY_RATING:
@@ -14379,20 +14519,9 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
}
case ITEM_ENCHANTMENT_TYPE_TOTEM: // Shaman Rockbiter Weapon
{
- if (getClass() == CLASS_SHAMAN)
- {
- float addValue;
- if (item->GetSlot() == EQUIPMENT_SLOT_MAINHAND)
- {
- addValue = float(enchant_amount * item->GetTemplate()->GetDelay() / 1000.0f);
- HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, addValue, apply);
- }
- else if (item->GetSlot() == EQUIPMENT_SLOT_OFFHAND)
- {
- addValue = float(enchant_amount * item->GetTemplate()->GetDelay() / 1000.0f);
- HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, addValue, apply);
- }
- }
+ WeaponAttackType const attackType = Player::GetAttackBySlot(item->GetSlot(), item->GetTemplate()->GetInventoryType());
+ if (attackType != MAX_ATTACK)
+ UpdateDamageDoneMods(attackType);
break;
}
case ITEM_ENCHANTMENT_TYPE_USE_SPELL:
@@ -15075,7 +15204,7 @@ bool Player::CanSeeStartQuest(Quest const* quest)
{
if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this) && SatisfyQuestClass(quest, false) && SatisfyQuestRace(quest, false) &&
SatisfyQuestSkill(quest, false) && SatisfyQuestExclusiveGroup(quest, false) && SatisfyQuestReputation(quest, false) &&
- SatisfyQuestPreviousQuest(quest, false) && SatisfyQuestNextChain(quest, false) &&
+ SatisfyQuestDependentQuests(quest, false) && SatisfyQuestNextChain(quest, false) &&
SatisfyQuestPrevChain(quest, false) && SatisfyQuestDay(quest, false) && SatisfyQuestWeek(quest, false) &&
SatisfyQuestMonth(quest, false) && SatisfyQuestSeasonal(quest, false))
{
@@ -15091,7 +15220,7 @@ bool Player::CanTakeQuest(Quest const* quest, bool msg)
&& SatisfyQuestStatus(quest, msg) && SatisfyQuestExclusiveGroup(quest, msg)
&& SatisfyQuestClass(quest, msg) && SatisfyQuestRace(quest, msg) && SatisfyQuestLevel(quest, msg)
&& SatisfyQuestSkill(quest, msg) && SatisfyQuestReputation(quest, msg)
- && SatisfyQuestPreviousQuest(quest, msg) && SatisfyQuestTimed(quest, msg)
+ && SatisfyQuestDependentQuests(quest, msg) && SatisfyQuestTimed(quest, msg)
&& SatisfyQuestNextChain(quest, msg) && SatisfyQuestPrevChain(quest, msg)
&& SatisfyQuestDay(quest, msg) && SatisfyQuestWeek(quest, msg)
&& SatisfyQuestMonth(quest, msg) && SatisfyQuestSeasonal(quest, msg)
@@ -15956,97 +16085,90 @@ bool Player::SatisfyQuestLog(bool msg) const
return false;
}
-bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg)
+bool Player::SatisfyQuestDependentQuests(Quest const* qInfo, bool msg) const
+{
+ return SatisfyQuestPreviousQuest(qInfo, msg) && SatisfyQuestDependentPreviousQuests(qInfo, msg);
+}
+
+bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg) const
{
// No previous quest (might be first quest in a series)
- if (qInfo->prevQuests.empty())
+ if (!qInfo->GetPrevQuestId())
return true;
- for (Quest::PrevQuests::const_iterator iter = qInfo->prevQuests.begin(); iter != qInfo->prevQuests.end(); ++iter)
- {
- uint32 prevId = abs(*iter);
+ uint32 prevId = std::abs(qInfo->GetPrevQuestId());
+ // If positive previous quest rewarded, return true
+ if (qInfo->GetPrevQuestId() > 0 && m_RewardedQuests.count(prevId) > 0)
+ return true;
- Quest const* qPrevInfo = sObjectMgr->GetQuestTemplate(prevId);
+ // If negative previous quest active, return true
+ if (qInfo->GetPrevQuestId() < 0 && GetQuestStatus(prevId) == QUEST_STATUS_INCOMPLETE)
+ return true;
- if (qPrevInfo)
- {
- // If any of the positive previous quests completed, return true
- if (*iter > 0 && m_RewardedQuests.find(prevId) != m_RewardedQuests.end())
- {
- // skip one-from-all exclusive group
- if (qPrevInfo->GetExclusiveGroup() >= 0)
- return true;
+ // Has positive prev. quest in non-rewarded state
+ // and negative prev. quest in non-active state
+ if (msg)
+ {
+ SendCanTakeQuestResponse(QUEST_ERR_NONE);
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have required quest %u.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str(), prevId);
+ }
- // each-from-all exclusive group (< 0)
- // can be start if only all quests in prev quest exclusive group completed and rewarded
- ObjectMgr::ExclusiveQuestGroupsBounds range(sObjectMgr->mExclusiveQuestGroups.equal_range(qPrevInfo->GetExclusiveGroup()));
+ return false;
+}
- for (; range.first != range.second; ++range.first)
- {
- uint32 exclude_Id = range.first->second;
+bool Player::SatisfyQuestDependentPreviousQuests(Quest const* qInfo, bool msg) const
+{
+ // No previous quest (might be first quest in a series)
+ if (qInfo->DependentPreviousQuests.empty())
+ return true;
- // skip checked quest id, only state of other quests in group is interesting
- if (exclude_Id == prevId)
- continue;
+ for (uint32 prevId : qInfo->DependentPreviousQuests)
+ {
+ // checked in startup
+ Quest const* questInfo = sObjectMgr->GetQuestTemplate(prevId);
+ ASSERT(questInfo);
- // alternative quest from group also must be completed and rewarded (reported)
- if (m_RewardedQuests.find(exclude_Id) == m_RewardedQuests.end())
- {
- if (msg)
- {
- SendCanTakeQuestResponse(QUEST_ERR_NONE);
- TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have the required quest (1).",
- qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
- }
- return false;
- }
- }
+ // If any of the previous quests completed, return true
+ if (IsQuestRewarded(prevId))
+ {
+ // skip one-from-all exclusive group
+ if (questInfo->GetExclusiveGroup() >= 0)
return true;
- }
- // If any of the negative previous quests active, return true
- if (*iter < 0 && GetQuestStatus(prevId) != QUEST_STATUS_NONE)
+ // each-from-all exclusive group (< 0)
+ // can be start if only all quests in prev quest exclusive group completed and rewarded
+ auto bounds = sObjectMgr->GetExclusiveQuestGroupBounds(questInfo->GetExclusiveGroup());
+ for (auto itr = bounds.first; itr != bounds.second; ++itr)
{
- // skip one-from-all exclusive group
- if (qPrevInfo->GetExclusiveGroup() >= 0)
- return true;
-
- // each-from-all exclusive group (< 0)
- // can be start if only all quests in prev quest exclusive group active
- ObjectMgr::ExclusiveQuestGroupsBounds range(sObjectMgr->mExclusiveQuestGroups.equal_range(qPrevInfo->GetExclusiveGroup()));
+ // skip checked quest id, only state of other quests in group is interesting
+ uint32 exclusiveQuestId = itr->second;
+ if (exclusiveQuestId == prevId)
+ continue;
- for (; range.first != range.second; ++range.first)
+ // alternative quest from group also must be completed and rewarded (reported)
+ if (!IsQuestRewarded(exclusiveQuestId))
{
- uint32 exclude_Id = range.first->second;
-
- // skip checked quest id, only state of other quests in group is interesting
- if (exclude_Id == prevId)
- continue;
-
- // alternative quest from group also must be active
- if (GetQuestStatus(exclude_Id) != QUEST_STATUS_NONE)
+ if (msg)
{
- if (msg)
- {
- SendCanTakeQuestResponse(QUEST_ERR_NONE);
- TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have the required quest (2).",
- qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
-
- }
- return false;
+ SendCanTakeQuestResponse(QUEST_ERR_NONE);
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestDependentPreviousQuests: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have the required quest (1).",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
+
+ return false;
}
- return true;
}
+
+ return true;
}
}
- // Has only positive prev. quests in non-rewarded state
- // and negative prev. quests in non-active state
+ // Has only prev. quests in non-rewarded state
if (msg)
{
SendCanTakeQuestResponse(QUEST_ERR_NONE);
- TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have required quest (3).",
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestDependentPreviousQuests: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have required quest (2).",
qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
@@ -16191,17 +16313,16 @@ bool Player::SatisfyQuestTimed(Quest const* qInfo, bool msg) const
return true;
}
-bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg)
+bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg) const
{
// non positive exclusive group, if > 0 then can be start if any other quest in exclusive group already started/completed
if (qInfo->GetExclusiveGroup() <= 0)
return true;
- ObjectMgr::ExclusiveQuestGroupsBounds range(sObjectMgr->mExclusiveQuestGroups.equal_range(qInfo->GetExclusiveGroup()));
-
- for (; range.first != range.second; ++range.first)
+ auto bounds = sObjectMgr->GetExclusiveQuestGroupBounds(qInfo->GetExclusiveGroup());
+ for (auto itr = bounds.first; itr != bounds.second; ++itr)
{
- uint32 exclude_Id = range.first->second;
+ uint32 exclude_Id = itr->second;
// skip checked quest id, only state of other quests in group is interesting
if (exclude_Id == qInfo->GetQuestId())
@@ -16264,12 +16385,12 @@ bool Player::SatisfyQuestNextChain(Quest const* qInfo, bool msg) const
bool Player::SatisfyQuestPrevChain(Quest const* qInfo, bool msg)
{
// No previous quest in chain
- if (qInfo->prevChainQuests.empty())
+ if (qInfo->PrevChainQuests.empty())
return true;
- for (Quest::PrevChainQuests::const_iterator iter = qInfo->prevChainQuests.begin(); iter != qInfo->prevChainQuests.end(); ++iter)
+ for (uint32 prevQuestId : qInfo->PrevChainQuests)
{
- QuestStatusMap::const_iterator itr = m_QuestStatus.find(*iter);
+ auto itr = m_QuestStatus.find(prevQuestId);
// If any of the previous quests in chain active, return false
if (itr != m_QuestStatus.end() && itr->second.Status != QUEST_STATUS_NONE)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 476aa0d7492..acbc5dd6086 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1128,8 +1128,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
Item* GetWeaponForAttack(WeaponAttackType attackType, bool useable = false) const;
Item* GetShield(bool useable = false) const;
Item* GetChildItemByGuid(ObjectGuid guid) const;
- static uint8 GetAttackBySlot(uint8 slot, InventoryType inventoryType); // MAX_ATTACK if not weapon slot
- std::vector<Item*> &GetItemUpdateQueue() { return m_itemUpdateQueue; }
+ static WeaponAttackType GetAttackBySlot(uint8 slot, InventoryType inventoryType); // MAX_ATTACK if not weapon slot
+ std::vector<Item*>& GetItemUpdateQueue() { return m_itemUpdateQueue; }
static bool IsInventoryPos(uint16 pos) { return IsInventoryPos(pos >> 8, pos & 255); }
static bool IsInventoryPos(uint8 bag, uint8 slot);
static bool IsEquipmentPos(uint16 pos) { return IsEquipmentPos(pos >> 8, pos & 255); }
@@ -1342,14 +1342,16 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool SatisfyQuestSkill(Quest const* qInfo, bool msg) const;
bool SatisfyQuestLevel(Quest const* qInfo, bool msg) const;
bool SatisfyQuestLog(bool msg) const;
- bool SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg);
+ bool SatisfyQuestDependentQuests(Quest const* qInfo, bool msg) const;
+ bool SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg) const;
+ bool SatisfyQuestDependentPreviousQuests(Quest const* qInfo, bool msg) const;
bool SatisfyQuestClass(Quest const* qInfo, bool msg) const;
bool SatisfyQuestRace(Quest const* qInfo, bool msg) const;
bool SatisfyQuestReputation(Quest const* qInfo, bool msg);
bool SatisfyQuestStatus(Quest const* qInfo, bool msg) const;
bool SatisfyQuestConditions(Quest const* qInfo, bool msg);
bool SatisfyQuestTimed(Quest const* qInfo, bool msg) const;
- bool SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg);
+ bool SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg) const;
bool SatisfyQuestNextChain(Quest const* qInfo, bool msg) const;
bool SatisfyQuestPrevChain(Quest const* qInfo, bool msg);
bool SatisfyQuestDay(Quest const* qInfo, bool msg) const;
@@ -1771,6 +1773,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void ApplyModDamageDonePos(SpellSchools school, int32 mod, bool apply) { ApplyModUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::ModDamageDonePos, school), mod, apply); }
void ApplyModDamageDoneNeg(SpellSchools school, int32 mod, bool apply) { ApplyModUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::ModDamageDoneNeg, school), mod, apply); }
void ApplyModDamageDonePercent(SpellSchools school, float pct, bool apply) { ApplyPercentModUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::ModDamageDonePercent, school), pct, apply); }
+ void SetModDamageDonePercent(uint8 school, float pct) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::ModDamageDonePercent, school), pct); }
void ApplyRatingMod(CombatRating cr, int32 value, bool apply);
void UpdateRating(CombatRating cr);
void UpdateAllRatings();
@@ -1779,7 +1782,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void UpdateHealingDonePercentMod();
bool CanUseMastery() const;
- void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) override;
+ void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) const override;
void RecalculateRating(CombatRating cr) { ApplyRatingMod(cr, 0, true);}
void GetDodgeFromAgility(float &diminishing, float &nondiminishing) const;
@@ -2003,11 +2006,19 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool CanTameExoticPets() const { return IsGameMaster() || HasAuraType(SPELL_AURA_ALLOW_TAME_PET_TYPE); }
void SetRegularAttackTime();
- void SetBaseModValue(BaseModGroup modGroup, BaseModType modType, float value) { m_auraBaseMod[modGroup][modType] = value; }
- void HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply);
+
+ void HandleBaseModFlatValue(BaseModGroup modGroup, float amount, bool apply);
+ void ApplyBaseModPctValue(BaseModGroup modGroup, float pct);
+
+ void SetBaseModFlatValue(BaseModGroup modGroup, float val);
+ void SetBaseModPctValue(BaseModGroup modGroup, float val);
+
+ void UpdateDamageDoneMods(WeaponAttackType attackType) override;
+ void UpdateBaseModGroup(BaseModGroup modGroup);
+
float GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const;
float GetTotalBaseModValue(BaseModGroup modGroup) const;
- float GetTotalPercentageModValue(BaseModGroup modGroup) const { return m_auraBaseMod[modGroup][FLAT_MOD] + m_auraBaseMod[modGroup][PCT_MOD]; }
+
void _ApplyAllStatBonuses();
void _RemoveAllStatBonuses();
@@ -2015,8 +2026,15 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void CastAllObtainSpells();
void ApplyItemObtainSpells(Item* item, bool apply);
+
+ void UpdateWeaponDependentCritAuras(WeaponAttackType attackType);
+ void UpdateAllWeaponDependentCritAuras();
+
+ void UpdateWeaponDependentAuras(WeaponAttackType attackType);
void ApplyItemDependentAuras(Item* item, bool apply);
+ bool CheckAttackFitToAuraRequirement(WeaponAttackType attackType, AuraEffect const* aurEff) const override;
+
void _ApplyItemMods(Item* item, uint8 slot, bool apply, bool updateItemAuras = true);
void _RemoveAllItemMods();
void _ApplyAllItemMods();
@@ -2651,7 +2669,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
ActionButtonList m_actionButtons;
- float m_auraBaseMod[BASEMOD_END][MOD_END];
+ float m_auraBaseFlatMod[BASEMOD_END];
+ float m_auraBasePctMod[BASEMOD_END];
int16 m_baseRatingValue[MAX_COMBAT_RATING];
uint32 m_baseSpellPower;
uint32 m_baseManaRegen;
diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp
index 96b400892de..201e3ef4db6 100644
--- a/src/server/game/Entities/Player/SocialMgr.cpp
+++ b/src/server/game/Entities/Player/SocialMgr.cpp
@@ -203,8 +203,13 @@ void SocialMgr::GetFriendInfo(Player* player, ObjectGuid const& friendGUID, Frie
else if (target->isAFK())
friendInfo.Status = FRIEND_STATUS_AFK;
else
+ {
friendInfo.Status = FRIEND_STATUS_ONLINE;
+ if (target->GetSession()->GetRecruiterId() == player->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == player->GetSession()->GetRecruiterId())
+ friendInfo.Status = FriendStatus(uint32(friendInfo.Status) | FRIEND_STATUS_RAF);
+ }
+
friendInfo.Area = target->GetZoneId();
friendInfo.Level = target->getLevel();
friendInfo.Class = target->getClass();
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index e9f1fc359d9..2170ba4d7c7 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -200,7 +200,7 @@ void Player::UpdateSpellDamageAndHealingBonus()
bool Player::UpdateAllStats()
{
- for (int8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
+ for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
{
float value = GetTotalStatValue(Stats(i));
SetStat(Stats(i), int32(value));
@@ -254,10 +254,10 @@ void Player::UpdateArmor()
{
UnitMods unitMod = UNIT_MOD_ARMOR;
- float value = GetModifierValue(unitMod, BASE_VALUE); // base armor (from items)
+ float value = GetFlatModifierValue(unitMod, BASE_VALUE); // base armor (from items)
float baseValue = value;
- value *= GetModifierValue(unitMod, BASE_PCT); // armor percent from items
- value += GetModifierValue(unitMod, TOTAL_VALUE);
+ value *= GetPctModifierValue(unitMod, BASE_PCT); // armor percent from items
+ value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
//add dynamic flat mods
AuraEffectList const& mResbyIntellect = GetAuraEffectsByType(SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT);
@@ -267,7 +267,7 @@ void Player::UpdateArmor()
value += CalculatePct(GetStat(Stats((*i)->GetMiscValueB())), (*i)->GetAmount());
}
- value *= GetModifierValue(unitMod, TOTAL_PCT);
+ value *= GetPctModifierValue(unitMod, TOTAL_PCT);
SetArmor(int32(baseValue), int32(value - baseValue));
@@ -294,10 +294,10 @@ void Player::UpdateMaxHealth()
{
UnitMods unitMod = UNIT_MOD_HEALTH;
- float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
- value *= GetModifierValue(unitMod, BASE_PCT);
- value += GetModifierValue(unitMod, TOTAL_VALUE) + GetHealthBonusFromStamina();
- value *= GetModifierValue(unitMod, TOTAL_PCT);
+ float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
+ value *= GetPctModifierValue(unitMod, BASE_PCT);
+ value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + GetHealthBonusFromStamina();
+ value *= GetPctModifierValue(unitMod, TOTAL_PCT);
SetMaxHealth((uint32)value);
}
@@ -315,10 +315,10 @@ void Player::UpdateMaxPower(Powers power)
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power);
- float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);
- value *= GetModifierValue(unitMod, BASE_PCT);
- value += GetModifierValue(unitMod, TOTAL_VALUE);
- value *= GetModifierValue(unitMod, TOTAL_PCT);
+ float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);
+ value *= GetPctModifierValue(unitMod, BASE_PCT);
+ value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
+ value *= GetPctModifierValue(unitMod, TOTAL_PCT);
SetMaxPower(power, (int32)std::lroundf(value));
}
@@ -357,11 +357,11 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
val2 = CalculatePct(float(minSpellPower), *m_activePlayerData->OverrideAPBySpellPowerPercent);
}
- SetModifierValue(unitMod, BASE_VALUE, val2);
+ SetStatFlatModifier(unitMod, BASE_VALUE, val2);
- float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
- float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
- float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
+ float base_attPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
+ float attPowerMod = GetFlatModifierValue(unitMod, TOTAL_VALUE);
+ float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
if (ranged)
{
@@ -405,7 +405,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
}
}
-void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage)
+void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) const
{
UnitMods unitMod;
@@ -425,10 +425,10 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo
float attackPowerMod = std::max(GetAPMultiplier(attType, normalized), 0.25f);
- float baseValue = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 3.5f * attackPowerMod;
- float basePct = GetModifierValue(unitMod, BASE_PCT);
- float totalValue = GetModifierValue(unitMod, TOTAL_VALUE);
- float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f;
+ float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 3.5f * attackPowerMod;
+ float basePct = GetPctModifierValue(unitMod, BASE_PCT);
+ float totalValue = GetFlatModifierValue(unitMod, TOTAL_VALUE);
+ float totalPct = addTotalPct ? GetPctModifierValue(unitMod, TOTAL_PCT) : 1.0f;
float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE);
float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE);
@@ -492,16 +492,16 @@ void Player::UpdateCritPercentage(WeaponAttackType attType)
{
case OFF_ATTACK:
SetUpdateFieldStatValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::OffhandCritPercentage),
- applyCritLimit(GetTotalPercentageModValue(OFFHAND_CRIT_PERCENTAGE) + GetRatingBonusValue(CR_CRIT_MELEE)));
+ applyCritLimit(GetBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD) + GetBaseModValue(OFFHAND_CRIT_PERCENTAGE, PCT_MOD) + GetRatingBonusValue(CR_CRIT_MELEE)));
break;
case RANGED_ATTACK:
SetUpdateFieldStatValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::RangedCritPercentage),
- applyCritLimit(GetTotalPercentageModValue(RANGED_CRIT_PERCENTAGE) + GetRatingBonusValue(CR_CRIT_RANGED)));
+ applyCritLimit(GetBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD) + GetBaseModValue(RANGED_CRIT_PERCENTAGE, PCT_MOD) + GetRatingBonusValue(CR_CRIT_RANGED)));
break;
case BASE_ATTACK:
default:
SetUpdateFieldStatValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::CritPercentage),
- applyCritLimit(GetTotalPercentageModValue(CRIT_PERCENTAGE) + GetRatingBonusValue(CR_CRIT_MELEE)));
+ applyCritLimit(GetBaseModValue(CRIT_PERCENTAGE, FLAT_MOD) + GetBaseModValue(CRIT_PERCENTAGE, PCT_MOD) + GetRatingBonusValue(CR_CRIT_MELEE)));
break;
}
}
@@ -510,9 +510,9 @@ void Player::UpdateAllCritPercentages()
{
float value = 5.0f;
- SetBaseModValue(CRIT_PERCENTAGE, PCT_MOD, value);
- SetBaseModValue(OFFHAND_CRIT_PERCENTAGE, PCT_MOD, value);
- SetBaseModValue(RANGED_CRIT_PERCENTAGE, PCT_MOD, value);
+ SetBaseModPctValue(CRIT_PERCENTAGE, value);
+ SetBaseModPctValue(OFFHAND_CRIT_PERCENTAGE, value);
+ SetBaseModPctValue(RANGED_CRIT_PERCENTAGE, value);
UpdateCritPercentage(BASE_ATTACK);
UpdateCritPercentage(OFF_ATTACK);
@@ -835,7 +835,7 @@ bool Creature::UpdateAllStats()
void Creature::UpdateArmor()
{
- float baseValue = GetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE);
+ float baseValue = GetFlatModifierValue(UNIT_MOD_ARMOR, BASE_VALUE);
float value = GetTotalAuraModValue(UNIT_MOD_ARMOR);
SetArmor(int32(baseValue), int32(value - baseValue));
}
@@ -864,10 +864,10 @@ void Creature::UpdateMaxPower(Powers power)
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power);
- float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);
- value *= GetModifierValue(unitMod, BASE_PCT);
- value += GetModifierValue(unitMod, TOTAL_VALUE);
- value *= GetModifierValue(unitMod, TOTAL_PCT);
+ float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);
+ value *= GetPctModifierValue(unitMod, BASE_PCT);
+ value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
+ value *= GetPctModifierValue(unitMod, TOTAL_PCT);
SetMaxPower(power, (int32)std::lroundf(value));
}
@@ -876,8 +876,8 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
{
UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER;
- float baseAttackPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
- float attackPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
+ float baseAttackPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
+ float attackPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
if (ranged)
{
@@ -900,7 +900,7 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
}
}
-void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage)
+void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) const
{
float variance = 1.0f;
UnitMods unitMod;
@@ -939,10 +939,10 @@ void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized,
float attackPower = GetTotalAttackPowerValue(attType);
float attackSpeedMulti = GetAPMultiplier(attType, normalized);
- float baseValue = GetModifierValue(unitMod, BASE_VALUE) + (attackPower / 3.5f) * variance;
- float basePct = GetModifierValue(unitMod, BASE_PCT) * attackSpeedMulti;
- float totalValue = GetModifierValue(unitMod, TOTAL_VALUE);
- float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f;
+ float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + (attackPower / 3.5f) * variance;
+ float basePct = GetPctModifierValue(unitMod, BASE_PCT) * attackSpeedMulti;
+ float totalValue = GetFlatModifierValue(unitMod, TOTAL_VALUE);
+ float totalPct = addTotalPct ? GetPctModifierValue(unitMod, TOTAL_PCT) : 1.0f;
float dmgMultiplier = GetCreatureTemplate()->ModDamage; // = ModDamage * _GetDamageMod(rank);
minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
@@ -970,7 +970,7 @@ bool Guardian::UpdateStats(Stats stat)
{
// value = ((base_value * base_pct) + total_value) * total_pct
float value = GetTotalStatValue(stat);
- ApplyStatBuffMod(stat, m_statFromOwner[stat], false);
+ UpdateStatBuffMod(stat);
float ownersBonus = 0.0f;
Unit* owner = GetOwner();
@@ -1010,7 +1010,7 @@ bool Guardian::UpdateStats(Stats stat)
SetStat(stat, int32(value));
m_statFromOwner[stat] = ownersBonus;
- ApplyStatBuffMod(stat, m_statFromOwner[stat], true);
+ UpdateStatBuffMod(stat);
switch (stat)
{
@@ -1044,7 +1044,7 @@ void Guardian::UpdateResistances(uint32 school)
{
if (school > SPELL_SCHOOL_NORMAL)
{
- float baseValue = GetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + school), BASE_VALUE);
+ float baseValue = GetFlatModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + school), BASE_VALUE);
float bonusValue = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)) - baseValue;
// hunter and warlock pets gain 40% of owner's resistance
@@ -1074,11 +1074,11 @@ void Guardian::UpdateArmor()
else if (IsPet())
bonus_armor = m_owner->GetArmor();
- value = GetModifierValue(unitMod, BASE_VALUE);
+ value = GetFlatModifierValue(unitMod, BASE_VALUE);
baseValue = value;
- value *= GetModifierValue(unitMod, BASE_PCT);
- value += GetModifierValue(unitMod, TOTAL_VALUE) + bonus_armor;
- value *= GetModifierValue(unitMod, TOTAL_PCT);
+ value *= GetPctModifierValue(unitMod, BASE_PCT);
+ value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + bonus_armor;
+ value *= GetPctModifierValue(unitMod, TOTAL_PCT);
SetArmor(int32(baseValue), int32(value - baseValue));
}
@@ -1100,10 +1100,10 @@ void Guardian::UpdateMaxHealth()
default: multiplicator = 10.0f; break;
}
- float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
- value *= GetModifierValue(unitMod, BASE_PCT);
- value += GetModifierValue(unitMod, TOTAL_VALUE) + stamina * multiplicator;
- value *= GetModifierValue(unitMod, TOTAL_PCT);
+ float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
+ value *= GetPctModifierValue(unitMod, BASE_PCT);
+ value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + stamina * multiplicator;
+ value *= GetPctModifierValue(unitMod, TOTAL_PCT);
SetMaxHealth((uint32)value);
}
@@ -1115,10 +1115,10 @@ void Guardian::UpdateMaxPower(Powers power)
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power);
- float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);
- value *= GetModifierValue(unitMod, BASE_PCT);
- value += GetModifierValue(unitMod, TOTAL_VALUE);
- value *= GetModifierValue(unitMod, TOTAL_PCT);
+ float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);
+ value *= GetPctModifierValue(unitMod, BASE_PCT);
+ value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
+ value *= GetPctModifierValue(unitMod, TOTAL_PCT);
SetMaxPower(power, int32(value));
}
@@ -1178,11 +1178,11 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
}
}
- SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, val + bonusAP);
+ SetStatFlatModifier(UNIT_MOD_ATTACK_POWER, BASE_VALUE, val + bonusAP);
//in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
- float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
- float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
+ float base_attPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
+ float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
SetAttackPower(int32(base_attPower));
SetAttackPowerMultiplier(attPowerMultiplier);
@@ -1219,10 +1219,10 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType)
float att_speed = float(GetBaseAttackTime(BASE_ATTACK))/1000.0f;
- float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 3.5f * att_speed + bonusDamage;
- float base_pct = GetModifierValue(unitMod, BASE_PCT);
- float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
- float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
+ float base_value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 3.5f * att_speed + bonusDamage;
+ float base_pct = GetPctModifierValue(unitMod, BASE_PCT);
+ float total_value = GetFlatModifierValue(unitMod, TOTAL_VALUE);
+ float total_pct = GetPctModifierValue(unitMod, TOTAL_PCT);
float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 62790919a9c..a0ddb919106 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -331,14 +331,14 @@ Unit::Unit(bool isWorldObject) :
for (uint8 i = 0; i < UNIT_MOD_END; ++i)
{
- m_auraModifiersGroup[i][BASE_VALUE] = 0.0f;
- m_auraModifiersGroup[i][BASE_PCT_EXCLUDE_CREATE] = 100.0f;
- m_auraModifiersGroup[i][BASE_PCT] = 1.0f;
- m_auraModifiersGroup[i][TOTAL_VALUE] = 0.0f;
- m_auraModifiersGroup[i][TOTAL_PCT] = 1.0f;
+ m_auraFlatModifiersGroup[i][BASE_VALUE] = 0.0f;
+ m_auraFlatModifiersGroup[i][BASE_PCT_EXCLUDE_CREATE] = 100.0f;
+ m_auraFlatModifiersGroup[i][TOTAL_VALUE] = 0.0f;
+ m_auraPctModifiersGroup[i][BASE_PCT] = 1.0f;
+ m_auraPctModifiersGroup[i][TOTAL_PCT] = 1.0f;
}
// implement 50% base damage from offhand
- m_auraModifiersGroup[UNIT_MOD_DAMAGE_OFFHAND][TOTAL_PCT] = 0.5f;
+ m_auraPctModifiersGroup[UNIT_MOD_DAMAGE_OFFHAND][TOTAL_PCT] = 0.5f;
for (uint8 i = 0; i < MAX_ATTACK; ++i)
{
@@ -627,7 +627,7 @@ void Unit::GetRandomContactPoint(const Unit* obj, float &x, float &y, float &z,
{
float combat_reach = GetCombatReach();
if (combat_reach < 0.1f) // sometimes bugged for players
- combat_reach = DEFAULT_COMBAT_REACH;
+ combat_reach = DEFAULT_PLAYER_COMBAT_REACH;
uint32 attacker_number = uint32(getAttackers().size());
if (attacker_number > 0)
@@ -2258,7 +2258,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(Unit const* victim, WeaponAttackTy
return MELEE_HIT_NORMAL;
}
-uint32 Unit::CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct)
+uint32 Unit::CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct) const
{
float minDamage = 0.0f;
float maxDamage = 0.0f;
@@ -4892,16 +4892,69 @@ void Unit::InitStatBuffMods()
}
}
-void Unit::ApplyStatBuffMod(Stats stat, float val, bool apply)
+void Unit::UpdateStatBuffMod(Stats stat)
{
- ApplyPercentModFloatVar((val > 0 ? m_floatStatPosBuff[stat] : m_floatStatNegBuff[stat]), val, apply);
- UpdateStatBuffModForClient(stat);
-}
+ float modPos = 0.0f;
+ float modNeg = 0.0f;
+ float factor = 0.0f;
-void Unit::ApplyStatPercentBuffMod(Stats stat, float val, bool apply)
-{
- ApplyPercentModFloatVar(m_floatStatPosBuff[stat], val, apply);
- ApplyPercentModFloatVar(m_floatStatNegBuff[stat], val, apply);
+ UnitMods const unitMod = static_cast<UnitMods>(UNIT_MOD_STAT_START + stat);
+
+ // includes value from items and enchantments
+ float modValue = GetFlatModifierValue(unitMod, BASE_VALUE);
+ if (modValue > 0.f)
+ modPos += modValue;
+ else
+ modNeg += modValue;
+
+ if (IsGuardian())
+ {
+ modValue = static_cast<Guardian*>(this)->GetBonusStatFromOwner(stat);
+ if (modValue > 0.f)
+ modPos += modValue;
+ else
+ modNeg += modValue;
+ }
+
+ // SPELL_AURA_MOD_STAT_BONUS_PCT only affects BASE_VALUE
+ modPos = CalculatePct(modPos, std::max(GetFlatModifierValue(unitMod, BASE_PCT_EXCLUDE_CREATE), -100.0f));
+ modNeg = CalculatePct(modNeg, std::max(GetFlatModifierValue(unitMod, BASE_PCT_EXCLUDE_CREATE), -100.0f));
+
+ modPos += GetTotalAuraModifier(SPELL_AURA_MOD_STAT, [stat](AuraEffect const* aurEff) -> bool
+ {
+ if ((aurEff->GetMiscValue() < 0 || aurEff->GetMiscValue() == stat) && aurEff->GetAmount() > 0)
+ return true;
+ return false;
+ });
+
+ modNeg += GetTotalAuraModifier(SPELL_AURA_MOD_STAT, [stat](AuraEffect const* aurEff) -> bool
+ {
+ if ((aurEff->GetMiscValue() < 0 || aurEff->GetMiscValue() == stat) && aurEff->GetAmount() < 0)
+ return true;
+ return false;
+ });
+
+ factor = GetTotalAuraMultiplier(SPELL_AURA_MOD_PERCENT_STAT, [stat](AuraEffect const* aurEff) -> bool
+ {
+ if (aurEff->GetMiscValue() == -1 || aurEff->GetMiscValue() == stat)
+ return true;
+ return false;
+ });
+
+ factor *= GetTotalAuraMultiplier(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, [stat](AuraEffect const* aurEff) -> bool
+ {
+ if (aurEff->GetMiscValue() == -1 || aurEff->GetMiscValue() == stat)
+ return true;
+ return false;
+ });
+
+ modPos *= factor;
+ modNeg *= factor;
+
+ m_floatStatPosBuff[stat] = modPos;
+ m_floatStatNegBuff[stat] = modNeg;
+
+ UpdateStatBuffModForClient(stat);
}
void Unit::UpdateStatBuffModForClient(Stats stat)
@@ -9371,31 +9424,99 @@ bool Unit::IsDisallowedMountForm(uint32 spellId, ShapeshiftForm form, uint32 dis
######## ########
#######################################*/
-bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply)
+void Unit::HandleStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float amount, bool apply)
{
- if (unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_END)
+ if (unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_FLAT_END)
{
- TC_LOG_ERROR("entities.unit", "ERROR in HandleStatModifier(): non-existing UnitMods or wrong UnitModifierType!");
- return false;
+ TC_LOG_ERROR("entities.unit", "ERROR in HandleStatFlatModifier(): non-existing UnitMods or wrong UnitModifierType!");
+ return;
}
+ if (!amount)
+ return;
+
switch (modifierType)
{
case BASE_VALUE:
case BASE_PCT_EXCLUDE_CREATE:
case TOTAL_VALUE:
- m_auraModifiersGroup[unitMod][modifierType] += apply ? amount : -amount;
+ m_auraFlatModifiersGroup[unitMod][modifierType] += apply ? amount : -amount;
break;
+ default:
+ break;
+ }
+
+ UpdateUnitMod(unitMod);
+}
+
+void Unit::ApplyStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float pct)
+{
+ if (unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_PCT_END)
+ {
+ TC_LOG_ERROR("entities.unit", "ERROR in ApplyStatPctModifier(): non-existing UnitMods or wrong UnitModifierType!");
+ return;
+ }
+
+ if (!pct)
+ return;
+
+ switch (modifierType)
+ {
case BASE_PCT:
case TOTAL_PCT:
- ApplyPercentModFloatVar(m_auraModifiersGroup[unitMod][modifierType], amount, apply);
+ AddPct(m_auraPctModifiersGroup[unitMod][modifierType], pct);
break;
default:
break;
}
+ UpdateUnitMod(unitMod);
+}
+
+void Unit::SetStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float val)
+{
+ if (m_auraFlatModifiersGroup[unitMod][modifierType] == val)
+ return;
+
+ m_auraFlatModifiersGroup[unitMod][modifierType] = val;
+ UpdateUnitMod(unitMod);
+}
+
+void Unit::SetStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float val)
+{
+ if (m_auraPctModifiersGroup[unitMod][modifierType] == val)
+ return;
+
+ m_auraPctModifiersGroup[unitMod][modifierType] = val;
+ UpdateUnitMod(unitMod);
+}
+
+float Unit::GetFlatModifierValue(UnitMods unitMod, UnitModifierFlatType modifierType) const
+{
+ if (unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_FLAT_END)
+ {
+ TC_LOG_ERROR("entities.unit", "attempt to access non-existing modifier value from UnitMods!");
+ return 0.0f;
+ }
+
+ return m_auraFlatModifiersGroup[unitMod][modifierType];
+}
+
+float Unit::GetPctModifierValue(UnitMods unitMod, UnitModifierPctType modifierType) const
+{
+ if (unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_PCT_END)
+ {
+ TC_LOG_ERROR("entities.unit", "attempt to access non-existing modifier value from UnitMods!");
+ return 0.0f;
+ }
+
+ return m_auraPctModifiersGroup[unitMod][modifierType];
+}
+
+void Unit::UpdateUnitMod(UnitMods unitMod)
+{
if (!CanModifyStats())
- return false;
+ return;
switch (unitMod)
{
@@ -9445,37 +9566,92 @@ bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, f
ASSERT(false, "Not implemented UnitMod %u", unitMod);
break;
}
+}
+
+void Unit::UpdateDamageDoneMods(WeaponAttackType attackType)
+{
+ UnitMods unitMod;
+ switch (attackType)
+ {
+ case BASE_ATTACK:
+ unitMod = UNIT_MOD_DAMAGE_MAINHAND;
+ break;
+ case OFF_ATTACK:
+ unitMod = UNIT_MOD_DAMAGE_OFFHAND;
+ break;
+ case RANGED_ATTACK:
+ unitMod = UNIT_MOD_DAMAGE_RANGED;
+ break;
+ default:
+ ABORT();
+ break;
+ }
- return true;
+ float amount = GetTotalAuraModifier(SPELL_AURA_MOD_DAMAGE_DONE, std::bind(&Unit::CheckAttackFitToAuraRequirement, this, attackType, std::placeholders::_1));
+
+ SetStatFlatModifier(unitMod, TOTAL_VALUE, amount);
+}
+
+void Unit::UpdateAllDamageDoneMods()
+{
+ for (uint8 i = BASE_ATTACK; i < MAX_ATTACK; ++i)
+ UpdateDamageDoneMods(WeaponAttackType(i));
}
-float Unit::GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
+void Unit::UpdateDamagePctDoneMods(WeaponAttackType attackType)
{
- if (unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_END)
+ float factor;
+ UnitMods unitMod;
+ switch (attackType)
{
- TC_LOG_ERROR("entities.unit", "attempt to access non-existing modifier value from UnitMods!");
- return 0.0f;
+ case BASE_ATTACK:
+ factor = 1.0f;
+ unitMod = UNIT_MOD_DAMAGE_MAINHAND;
+ break;
+ case OFF_ATTACK:
+ // off hand has 50% penalty
+ factor = 0.5f;
+ unitMod = UNIT_MOD_DAMAGE_OFFHAND;
+ break;
+ case RANGED_ATTACK:
+ factor = 1.0f;
+ unitMod = UNIT_MOD_DAMAGE_RANGED;
+ break;
+ default:
+ ABORT();
+ break;
}
- if (modifierType == TOTAL_PCT && m_auraModifiersGroup[unitMod][modifierType] <= 0.0f)
- return 0.0f;
+ factor *= GetTotalAuraMultiplier(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, [attackType, this](AuraEffect const* aurEff) -> bool
+ {
+ if (!(aurEff->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
+ return false;
+
+ return CheckAttackFitToAuraRequirement(attackType, aurEff);
+ });
+
+ if (attackType == OFF_ATTACK)
+ factor *= GetTotalAuraMultiplier(SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT, std::bind(&Unit::CheckAttackFitToAuraRequirement, this, attackType, std::placeholders::_1));
- return m_auraModifiersGroup[unitMod][modifierType];
+ SetStatPctModifier(unitMod, TOTAL_PCT, factor);
+}
+
+void Unit::UpdateAllDamagePctDoneMods()
+{
+ for (uint8 i = BASE_ATTACK; i < MAX_ATTACK; ++i)
+ UpdateDamagePctDoneMods(WeaponAttackType(i));
}
float Unit::GetTotalStatValue(Stats stat) const
{
UnitMods unitMod = UnitMods(UNIT_MOD_STAT_START + stat);
- if (m_auraModifiersGroup[unitMod][TOTAL_PCT] <= 0.0f)
- return 0.0f;
-
// value = ((base_value * base_pct) + total_value) * total_pct
- float value = CalculatePct(m_auraModifiersGroup[unitMod][BASE_VALUE], std::max(m_auraModifiersGroup[unitMod][BASE_PCT_EXCLUDE_CREATE], -100.0f));
+ float value = CalculatePct(GetFlatModifierValue(unitMod, BASE_VALUE), std::max(GetFlatModifierValue(unitMod, BASE_PCT_EXCLUDE_CREATE), -100.0f));
value += GetCreateStat(stat);
- value *= m_auraModifiersGroup[unitMod][BASE_PCT];
- value += m_auraModifiersGroup[unitMod][TOTAL_VALUE];
- value *= m_auraModifiersGroup[unitMod][TOTAL_PCT];
+ value *= GetPctModifierValue(unitMod, BASE_PCT);
+ value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
+ value *= GetPctModifierValue(unitMod, TOTAL_PCT);
return value;
}
@@ -9488,13 +9664,10 @@ float Unit::GetTotalAuraModValue(UnitMods unitMod) const
return 0.0f;
}
- if (m_auraModifiersGroup[unitMod][TOTAL_PCT] <= 0.0f)
- return 0.0f;
-
- float value = CalculatePct(m_auraModifiersGroup[unitMod][BASE_VALUE], std::max(m_auraModifiersGroup[unitMod][BASE_PCT_EXCLUDE_CREATE], -100.0f));
- value *= m_auraModifiersGroup[unitMod][BASE_PCT];
- value += m_auraModifiersGroup[unitMod][TOTAL_VALUE];
- value *= m_auraModifiersGroup[unitMod][TOTAL_PCT];
+ float value = CalculatePct(GetFlatModifierValue(unitMod, BASE_VALUE), std::max(GetFlatModifierValue(unitMod, BASE_PCT_EXCLUDE_CREATE), -100.0f));
+ value *= GetPctModifierValue(unitMod, BASE_PCT);
+ value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
+ value *= GetPctModifierValue(unitMod, TOTAL_PCT);
return value;
}
@@ -9542,7 +9715,7 @@ void Unit::UpdateResistances(uint32 school)
{
UnitMods unitMod = UnitMods(UNIT_MOD_RESISTANCE_START + school);
- SetResistance(SpellSchools(school), int32(m_auraModifiersGroup[unitMod][BASE_VALUE]));
+ SetResistance(SpellSchools(school), int32(GetFlatModifierValue(unitMod, BASE_VALUE)));
SetBonusResistanceMod(SpellSchools(school), int32(GetTotalAuraModValue(unitMod) - GetResistance(SpellSchools(school))));
}
else
@@ -9802,7 +9975,6 @@ void Unit::CleanupBeforeRemoveFromMap(bool finalCleanup)
CombatStop();
DeleteThreatList();
getHostileRefManager().deleteReferences();
- GetMotionMaster()->Clear(false); // remove different non-standard movement generators.
}
void Unit::CleanupsBeforeDelete(bool finalCleanup)
@@ -10609,7 +10781,10 @@ void Unit::RestoreDisplayId(bool ignorePositiveAurasPreventingMounting /*= false
// transform aura was found
if (handledAura)
+ {
handledAura->HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true);
+ return;
+ }
// we've found shapeshift
else if (!shapeshiftAura.empty()) // we've found shapeshift
{
@@ -10620,11 +10795,11 @@ void Unit::RestoreDisplayId(bool ignorePositiveAurasPreventingMounting /*= false
SetDisplayId(modelId);
else
SetDisplayId(GetNativeDisplayId());
+ return;
}
}
// no auras found - set modelid to default
- else
- SetDisplayId(GetNativeDisplayId());
+ SetDisplayId(GetNativeDisplayId());
}
void Unit::ClearAllReactives()
@@ -10734,10 +10909,15 @@ void Unit::UpdateAttackTimeField(WeaponAttackType att)
}
}
+void ApplyPercentModFloatVar(float& var, float val, bool apply)
+{
+ var *= (apply ? (100.0f + val) / 100.0f : 100.0f / (100.0f + val));
+}
+
void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply)
{
float remainingTimePct = float(m_attackTimer[att]) / (m_baseAttackSpeed[att] * m_modAttackSpeedPct[att]);
- if (val > 0)
+ if (val > 0.f)
{
ApplyPercentModFloatVar(m_modAttackSpeedPct[att], val, !apply);
@@ -10762,7 +10942,7 @@ void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply
void Unit::ApplyCastTimePercentMod(float val, bool apply)
{
- if (val > 0)
+ if (val > 0.f)
{
ApplyPercentModUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ModCastingSpeed), val, !apply);
ApplyPercentModUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ModSpellHaste), val, !apply);
@@ -10920,7 +11100,7 @@ float Unit::CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffect
return (CastingTime / 3500.0f) * DotFactor;
}
-float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)
+float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized) const
{
if (GetTypeId() != TYPEID_PLAYER || (IsInFeralForm() && !normalized))
return GetBaseAttackTime(attType) / 1000.0f;
@@ -11999,8 +12179,8 @@ bool Unit::IsInPartyWith(Unit const* unit) const
if (this == unit)
return true;
- const Unit* u1 = GetCharmerOrOwnerOrSelf();
- const Unit* u2 = unit->GetCharmerOrOwnerOrSelf();
+ Unit const* u1 = GetCharmerOrOwnerOrSelf();
+ Unit const* u2 = unit->GetCharmerOrOwnerOrSelf();
if (u1 == u2)
return true;
@@ -12010,8 +12190,7 @@ bool Unit::IsInPartyWith(Unit const* unit) const
(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_UNIT && u2->ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_TREAT_AS_RAID_UNIT))
return true;
- // else u1->GetTypeId() == u2->GetTypeId() == TYPEID_UNIT
- return u1->getFaction() == u2->getFaction();
+ return u1->GetTypeId() == TYPEID_UNIT && u2->GetTypeId() == TYPEID_UNIT && u1->getFaction() == u2->getFaction();
}
bool Unit::IsInRaidWith(Unit const* unit) const
@@ -12019,8 +12198,8 @@ bool Unit::IsInRaidWith(Unit const* unit) const
if (this == unit)
return true;
- const Unit* u1 = GetCharmerOrOwnerOrSelf();
- const Unit* u2 = unit->GetCharmerOrOwnerOrSelf();
+ Unit const* u1 = GetCharmerOrOwnerOrSelf();
+ Unit const* u2 = unit->GetCharmerOrOwnerOrSelf();
if (u1 == u2)
return true;
@@ -12030,8 +12209,7 @@ bool Unit::IsInRaidWith(Unit const* unit) const
(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_UNIT && u2->ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_TREAT_AS_RAID_UNIT))
return true;
- // else u1->GetTypeId() == u2->GetTypeId() == TYPEID_UNIT
- return u1->getFaction() == u2->getFaction();
+ return u1->GetTypeId() == TYPEID_UNIT && u2->GetTypeId() == TYPEID_UNIT && u1->getFaction() == u2->getFaction();
}
void Unit::GetPartyMembers(std::list<Unit*> &TagUnitMap)
@@ -12852,6 +13030,8 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
{
bool result = false;
uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->GetCreatureEntry() : GetEntry();
+ TriggerCastFlags const flags = GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE;
+
SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry);
for (SpellClickInfoContainer::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
{
@@ -12894,7 +13074,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
}
if (IsInMap(caster))
- caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId + 1, target, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, NULL, NULL, origCasterGUID);
+ caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0 + i), seatId + 1, target, flags, NULL, NULL, origCasterGUID);
else // This can happen during Player::_LoadAuras
{
int32 bp0[MAX_SPELL_EFFECTS];
@@ -12909,7 +13089,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
else
{
if (IsInMap(caster))
- caster->CastSpell(target, spellEntry, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, NULL, NULL, origCasterGUID);
+ caster->CastSpell(target, spellEntry, flags, NULL, NULL, origCasterGUID);
else
Aura::TryRefreshStackOrCreate(spellEntry, ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellEntry->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>()), MAX_EFFECT_MASK, this, clicker, NULL, NULL, origCasterGUID);
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 1f9de500ad1..7db8583f69f 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -257,14 +257,19 @@ typedef std::vector<DispelableAura> DispelChargesList;
typedef std::unordered_multimap<uint32 /*type*/, uint32 /*spellId*/> SpellImmuneContainer;
-enum UnitModifierType
+enum UnitModifierFlatType
{
BASE_VALUE = 0,
BASE_PCT_EXCLUDE_CREATE = 1, // percent modifier affecting all stat values from auras and gear but not player base for level
- BASE_PCT = 2,
- TOTAL_VALUE = 3,
- TOTAL_PCT = 4,
- MODIFIER_TYPE_END = 5
+ TOTAL_VALUE = 2,
+ MODIFIER_TYPE_FLAT_END = 3
+};
+
+enum UnitModifierPctType
+{
+ BASE_PCT = 0,
+ TOTAL_PCT = 1,
+ MODIFIER_TYPE_PCT_END = 2
};
enum WeaponDamageRange
@@ -378,66 +383,60 @@ enum DeathState
JUST_RESPAWNED = 4
};
-enum UnitState
+enum UnitState : uint32
{
- UNIT_STATE_DIED = 0x00000001, // player has fake death aura
- UNIT_STATE_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone
- //UNIT_STATE_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone
- UNIT_STATE_STUNNED = 0x00000008,
- UNIT_STATE_ROAMING = 0x00000010,
- UNIT_STATE_CHASE = 0x00000020,
- //UNIT_STATE_SEARCHING = 0x00000040,
- UNIT_STATE_FLEEING = 0x00000080,
- UNIT_STATE_IN_FLIGHT = 0x00000100, // player is in flight mode
- UNIT_STATE_FOLLOW = 0x00000200,
- UNIT_STATE_ROOT = 0x00000400,
- UNIT_STATE_CONFUSED = 0x00000800,
- UNIT_STATE_DISTRACTED = 0x00001000,
- UNIT_STATE_ISOLATED = 0x00002000, // area auras do not affect other players
- UNIT_STATE_ATTACK_PLAYER = 0x00004000,
- UNIT_STATE_CASTING = 0x00008000,
- UNIT_STATE_POSSESSED = 0x00010000,
- UNIT_STATE_CHARGING = 0x00020000,
- UNIT_STATE_JUMPING = 0x00040000,
- UNIT_STATE_MOVE = 0x00100000,
- UNIT_STATE_ROTATING = 0x00200000,
- UNIT_STATE_EVADE = 0x00400000,
- UNIT_STATE_ROAMING_MOVE = 0x00800000,
- UNIT_STATE_CONFUSED_MOVE = 0x01000000,
- UNIT_STATE_FLEEING_MOVE = 0x02000000,
- UNIT_STATE_CHASE_MOVE = 0x04000000,
- UNIT_STATE_FOLLOW_MOVE = 0x08000000,
- UNIT_STATE_IGNORE_PATHFINDING = 0x10000000, // do not use pathfinding in any MovementGenerator
+ UNIT_STATE_DIED = 0x00000001, // player has fake death aura
+ UNIT_STATE_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone
+ //UNIT_STATE_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone
+ UNIT_STATE_STUNNED = 0x00000008,
+ UNIT_STATE_ROAMING = 0x00000010,
+ UNIT_STATE_CHASE = 0x00000020,
+ //UNIT_STATE_SEARCHING = 0x00000040,
+ UNIT_STATE_FLEEING = 0x00000080,
+ UNIT_STATE_IN_FLIGHT = 0x00000100, // player is in flight mode
+ UNIT_STATE_FOLLOW = 0x00000200,
+ UNIT_STATE_ROOT = 0x00000400,
+ UNIT_STATE_CONFUSED = 0x00000800,
+ UNIT_STATE_DISTRACTED = 0x00001000,
+ UNIT_STATE_ISOLATED = 0x00002000, // area auras do not affect other players
+ UNIT_STATE_ATTACK_PLAYER = 0x00004000,
+ UNIT_STATE_CASTING = 0x00008000,
+ UNIT_STATE_POSSESSED = 0x00010000,
+ UNIT_STATE_CHARGING = 0x00020000,
+ UNIT_STATE_JUMPING = 0x00040000,
+ UNIT_STATE_MOVE = 0x00100000,
+ UNIT_STATE_ROTATING = 0x00200000,
+ UNIT_STATE_EVADE = 0x00400000,
+ UNIT_STATE_ROAMING_MOVE = 0x00800000,
+ UNIT_STATE_CONFUSED_MOVE = 0x01000000,
+ UNIT_STATE_FLEEING_MOVE = 0x02000000,
+ UNIT_STATE_CHASE_MOVE = 0x04000000,
+ UNIT_STATE_FOLLOW_MOVE = 0x08000000,
+ UNIT_STATE_IGNORE_PATHFINDING = 0x10000000, // do not use pathfinding in any MovementGenerator
+
UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE
| UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED
| UNIT_STATE_DISTRACTED | UNIT_STATE_ISOLATED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING
| UNIT_STATE_POSSESSED | UNIT_STATE_CHARGING | UNIT_STATE_JUMPING | UNIT_STATE_MOVE | UNIT_STATE_ROTATING
| UNIT_STATE_EVADE | UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE
| UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE | UNIT_STATE_IGNORE_PATHFINDING,
- UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT,
- // for real move using movegen check and stop (except unstoppable flight)
- UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE,
- UNIT_STATE_CONTROLLED = (UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING),
- UNIT_STATE_LOST_CONTROL = (UNIT_STATE_CONTROLLED | UNIT_STATE_JUMPING | UNIT_STATE_CHARGING),
- UNIT_STATE_SIGHTLESS = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_EVADE),
- UNIT_STATE_CANNOT_AUTOATTACK = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_CASTING),
- UNIT_STATE_CANNOT_TURN = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_ROTATING),
- // stay by different reasons
- UNIT_STATE_NOT_MOVE = UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DIED | UNIT_STATE_DISTRACTED,
- UNIT_STATE_ALL_STATE = 0xffffffff //(UNIT_STATE_STOPPED | UNIT_STATE_MOVING | UNIT_STATE_IN_COMBAT | UNIT_STATE_IN_FLIGHT)
+
+ UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT,
+ UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE,
+ UNIT_STATE_CONTROLLED = UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING,
+ UNIT_STATE_LOST_CONTROL = UNIT_STATE_CONTROLLED | UNIT_STATE_JUMPING | UNIT_STATE_CHARGING,
+ UNIT_STATE_SIGHTLESS = UNIT_STATE_LOST_CONTROL | UNIT_STATE_EVADE,
+ UNIT_STATE_CANNOT_AUTOATTACK = UNIT_STATE_LOST_CONTROL | UNIT_STATE_CASTING,
+ UNIT_STATE_CANNOT_TURN = UNIT_STATE_LOST_CONTROL | UNIT_STATE_ROTATING,
+ UNIT_STATE_NOT_MOVE = UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DIED | UNIT_STATE_DISTRACTED,
+
+ UNIT_STATE_ALL_ERASABLE = UNIT_STATE_ALL_STATE_SUPPORTED & ~(UNIT_STATE_IGNORE_PATHFINDING),
+ UNIT_STATE_ALL_STATE = 0xffffffff
};
TC_GAME_API extern float baseMoveSpeed[MAX_MOVE_TYPE];
TC_GAME_API extern float playerBaseMoveSpeed[MAX_MOVE_TYPE];
-enum WeaponAttackType : uint8
-{
- BASE_ATTACK = 0,
- OFF_ATTACK = 1,
- RANGED_ATTACK = 2,
- MAX_ATTACK
-};
-
enum CombatRating
{
CR_AMPLIFY = 0,
@@ -966,7 +965,7 @@ class TC_GAME_API Unit : public WorldObject
bool haveOffhandWeapon() const;
bool CanDualWield() const { return m_canDualWield; }
virtual void SetCanDualWield(bool value) { m_canDualWield = value; }
- float GetCombatReach() const { return m_unitData->CombatReach; }
+ float GetCombatReach() const override { return m_unitData->CombatReach; }
void SetCombatReach(float combatReach) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::CombatReach), combatReach); }
float GetBoundingRadius() const { return m_unitData->BoundingRadius; }
void SetBoundingRadius(float boundingRadius) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::BoundingRadius), boundingRadius); }
@@ -1608,8 +1607,7 @@ class TC_GAME_API Unit : public WorldObject
int32 GetMaxNegativeAuraModifierByAffectMask(AuraType auratype, SpellInfo const* affectedSpell) const;
void InitStatBuffMods();
- void ApplyStatBuffMod(Stats stat, float val, bool apply);
- void ApplyStatPercentBuffMod(Stats stat, float val, bool apply);
+ void UpdateStatBuffMod(Stats stat);
void UpdateStatBuffModForClient(Stats stat);
void SetCreateStat(Stats stat, float val) { m_createStats[stat] = val; }
void SetCreateHealth(uint32 val) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::BaseHealth), val); }
@@ -1693,9 +1691,26 @@ class TC_GAME_API Unit : public WorldObject
EventProcessor m_Events;
// stat system
- bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply);
- void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value) { m_auraModifiersGroup[unitMod][modifierType] = value; }
- float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const;
+ void HandleStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float amount, bool apply);
+ void ApplyStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float amount);
+
+ void SetStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float val);
+ void SetStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float val);
+
+ float GetFlatModifierValue(UnitMods unitMod, UnitModifierFlatType modifierType) const;
+ float GetPctModifierValue(UnitMods unitMod, UnitModifierPctType modifierType) const;
+
+ void UpdateUnitMod(UnitMods unitMod);
+
+ // only players have item requirements
+ virtual bool CheckAttackFitToAuraRequirement(WeaponAttackType /*attackType*/, AuraEffect const* /*aurEff*/) const { return true; }
+
+ virtual void UpdateDamageDoneMods(WeaponAttackType attackType);
+ void UpdateAllDamageDoneMods();
+
+ void UpdateDamagePctDoneMods(WeaponAttackType attackType);
+ void UpdateAllDamagePctDoneMods();
+
float GetTotalStatValue(Stats stat) const;
float GetTotalAuraModValue(UnitMods unitMod) const;
SpellSchools GetSpellSchoolByAuraGroup(UnitMods unitMod) const;
@@ -1723,9 +1738,9 @@ class TC_GAME_API Unit : public WorldObject
float GetTotalAttackPowerValue(WeaponAttackType attType) const;
float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type) const;
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }
- virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) = 0;
- uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct);
- float GetAPMultiplier(WeaponAttackType attType, bool normalized);
+ virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) const = 0;
+ uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct) const;
+ float GetAPMultiplier(WeaponAttackType attType, bool normalized) const;
bool isInFrontInMap(Unit const* target, float distance, float arc = float(M_PI)) const;
bool isInBackInMap(Unit const* target, float distance, float arc = float(M_PI)) const;
@@ -2066,7 +2081,8 @@ class TC_GAME_API Unit : public WorldObject
AuraStateAurasMap m_auraStateAuras; // Used for improve performance of aura state checks on aura apply/remove
std::array<uint32, 2> m_interruptMask;
- float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END];
+ float m_auraFlatModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_FLAT_END];
+ float m_auraPctModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_PCT_END];
float m_weaponDamage[MAX_ATTACK][2];
bool m_canModifyStats;
diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h
index 158943800c8..9bf875ee810 100644
--- a/src/server/game/Entities/Unit/UnitDefines.h
+++ b/src/server/game/Entities/Unit/UnitDefines.h
@@ -21,7 +21,6 @@
#include "Define.h"
#include <string>
-#define DEFAULT_COMBAT_REACH 1.5f
#define MIN_MELEE_REACH 2.0f
#define NOMINAL_MELEE_RANGE 5.0f
#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index abc2a7b9189..4ab04447914 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -1538,7 +1538,7 @@ void ObjectMgr::LoadCreatureModelInfo()
}
if (modelInfo.combat_reach < 0.1f)
- modelInfo.combat_reach = DEFAULT_COMBAT_REACH;
+ modelInfo.combat_reach = DEFAULT_PLAYER_COMBAT_REACH;
if (CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(creatureDisplay->ModelID))
{
@@ -1986,8 +1986,6 @@ void ObjectMgr::LoadCreatures()
data.phaseGroup = fields[25].GetUInt32();
data.terrainSwapMap = fields[26].GetInt32();
data.ScriptId = GetScriptId(fields[27].GetString());
- if (!data.ScriptId)
- data.ScriptId = cInfo->ScriptID;
MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
if (!mapEntry)
@@ -2459,8 +2457,6 @@ void ObjectMgr::LoadGameobjects()
}
data.ScriptId = GetScriptId(fields[21].GetString());
- if (!data.ScriptId)
- data.ScriptId = gInfo->ScriptId;
if (std::abs(data.orientation) > 2 * float(M_PI))
{
@@ -3874,12 +3870,12 @@ void ObjectMgr::LoadQuests()
uint32 oldMSTime = getMSTime();
// For reload case
- for (QuestMap::const_iterator itr=_questTemplates.begin(); itr != _questTemplates.end(); ++itr)
+ for (auto itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
delete itr->second;
_questTemplates.clear();
_questObjectives.clear();
- mExclusiveQuestGroups.clear();
+ _exclusiveQuestGroups.clear();
QueryResult result = WorldDatabase.Query("SELECT "
//0 1 2 3 4 5 6 7 8 9 10 11 12
@@ -3930,123 +3926,63 @@ void ObjectMgr::LoadQuests()
_questTemplates[newQuest->GetQuestId()] = newQuest;
} while (result->NextRow());
- // Load `quest_details`
- // 0 1 2 3 4 5 6 7 8
- result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4 FROM quest_details");
-
- if (!result)
- {
- TC_LOG_ERROR("server.loading", ">> Loaded 0 quest details. DB table `quest_details` is empty.");
- }
- else
+ struct QuestLoaderHelper
{
- do
- {
- Field* fields = result->Fetch();
- uint32 questId = fields[0].GetUInt32();
-
- auto itr = _questTemplates.find(questId);
- if (itr != _questTemplates.end())
- itr->second->LoadQuestDetails(fields);
- else
- TC_LOG_ERROR("server.loading", "Table `quest_details` has data for quest %u but such quest does not exist", questId);
- } while (result->NextRow());
- }
+ typedef void(Quest::* QuestLoaderFunction)(Field* fields);
- // Load `quest_request_items`
- // 0 1 2 3 4 5
- result = WorldDatabase.Query("SELECT ID, EmoteOnComplete, EmoteOnIncomplete, EmoteOnCompleteDelay, EmoteOnIncompleteDelay, CompletionText FROM quest_request_items");
+ char const* QueryFields;
+ char const* TableName;
+ char const* QueryExtra;
+ char const* TableDesc;
+ QuestLoaderFunction LoaderFunction;
+ };
- if (!result)
+ static std::vector<QuestLoaderHelper> const QuestLoaderHelpers =
{
- TC_LOG_ERROR("server.loading", ">> Loaded 0 quest request items. DB table `quest_request_items` is empty.");
- }
- else
- {
- do
- {
- Field* fields = result->Fetch();
- uint32 questId = fields[0].GetUInt32();
+ // 0 1 2 3 4 5 6 7 8
+ { "ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4", "quest_details", "", "details", &Quest::LoadQuestDetails },
- auto itr = _questTemplates.find(questId);
- if (itr != _questTemplates.end())
- itr->second->LoadQuestRequestItems(fields);
- else
- TC_LOG_ERROR("server.loading", "Table `quest_request_items` has data for quest %u but such quest does not exist", questId);
- } while (result->NextRow());
- }
+ // 0 1 2 3 4 5
+ { "ID, EmoteOnComplete, EmoteOnIncomplete, EmoteOnCompleteDelay, EmoteOnIncompleteDelay, CompletionText", "quest_request_items", "", "request items", &Quest::LoadQuestRequestItems },
- // Load `quest_offer_reward`
- // 0 1 2 3 4 5 6 7 8 9
- result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText FROM quest_offer_reward");
+ // 0 1 2 3 4 5 6 7 8 9
+ { "ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText", "quest_offer_reward", "", "reward emotes", &Quest::LoadQuestOfferReward },
- if (!result)
- {
- TC_LOG_ERROR("server.loading", ">> Loaded 0 quest reward emotes. DB table `quest_offer_reward` is empty.");
- }
- else
- {
- do
- {
- Field* fields = result->Fetch();
- uint32 questId = fields[0].GetUInt32();
+ // 0 1 2 3 4 5 6 7 8
+ { "ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, RewardMailTemplateID, RewardMailDelay,"
+ // 9 10 11 12 13 14 15 16
+ " RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, SpecialFlags,"
+ // 17
+ " ScriptName", "quest_template_addon", "", "template addons", &Quest::LoadQuestTemplateAddon },
- auto itr = _questTemplates.find(questId);
- if (itr != _questTemplates.end())
- itr->second->LoadQuestOfferReward(fields);
- else
- TC_LOG_ERROR("server.loading", "Table `quest_offer_reward` has data for quest %u but such quest does not exist", questId);
- } while (result->NextRow());
- }
+ // 0 1
+ { "QuestId, RewardMailSenderEntry", "quest_mail_sender", "", "mail sender entries", &Quest::LoadQuestMailSender },
- // Load `quest_template_addon`
- // 0 1 2 3 4 5 6 7 8
- result = WorldDatabase.Query("SELECT ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, RewardMailTemplateID, RewardMailDelay, "
- //9 10 11 12 13 14 15 16
- "RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, RewardMailSenderEntry, "
- //17 18
- "SpecialFlags, ScriptName FROM quest_template_addon LEFT JOIN quest_mail_sender ON Id=QuestId");
+ // QuestID needs to be fields[0]
+ // 0 1 2 3 4 5 6 7 8 9
+ { "QuestID, ID, Type, StorageIndex, ObjectID, Amount, Flags, Flags2, ProgressBarWeight, Description", "quest_objectives", "ORDER BY `Order` ASC, StorageIndex ASC", "quest objectives", &Quest::LoadQuestObjective }
+ };
- if (!result)
- {
- TC_LOG_ERROR("server.loading", ">> Loaded 0 quest template addons. DB table `quest_template_addon` is empty.");
- }
- else
+ for (QuestLoaderHelper const& loader : QuestLoaderHelpers)
{
- do
- {
- Field* fields = result->Fetch();
- uint32 questId = fields[0].GetUInt32();
-
- auto itr = _questTemplates.find(questId);
- if (itr != _questTemplates.end())
- itr->second->LoadQuestTemplateAddon(fields);
- else
- TC_LOG_ERROR("server.loading", "Table `quest_template_addon` has data for quest %u but such quest does not exist", questId);
- } while (result->NextRow());
- }
-
- // Load `quest_objectives`
- // 0 1 2 3 4 5 6 7 8 9
- result = WorldDatabase.Query("SELECT ID, QuestID, Type, StorageIndex, ObjectID, Amount, Flags, Flags2, ProgressBarWeight, Description FROM quest_objectives ORDER BY `Order` ASC, StorageIndex ASC");
+ QueryResult result = WorldDatabase.PQuery("SELECT %s FROM %s", loader.QueryFields, loader.TableName, loader.QueryExtra);
- if (!result)
- {
- TC_LOG_ERROR("server.loading", ">> Loaded 0 quest objectives. DB table `quest_objectives` is empty.");
- }
- else
- {
- do
+ if (!result)
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 quest %s. DB table `%s` is empty.", loader.TableDesc, loader.TableName);
+ else
{
- Field* fields = result->Fetch();
- uint32 questId = fields[1].GetUInt32();
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 questId = fields[0].GetUInt32();
- auto itr = _questTemplates.find(questId);
- if (itr != _questTemplates.end())
- itr->second->LoadQuestObjective(fields);
- else
- TC_LOG_ERROR("server.loading", "Table `quest_objectives` has objective for quest %u but such quest does not exist", questId);
- } while (result->NextRow());
+ auto itr = _questTemplates.find(questId);
+ if (itr != _questTemplates.end())
+ (itr->second->*loader.LoaderFunction)(fields);
+ else
+ TC_LOG_ERROR("server.loading", "Table `%s` has data for quest %u but such quest does not exist", loader.TableName, questId);
+ } while (result->NextRow());
+ }
}
// Load `quest_visual_effect` join table with quest_objectives because visual effects are based on objective ID (core stores objectives by their index in quest)
@@ -4103,223 +4039,223 @@ void ObjectMgr::LoadQuests()
if (qinfo->GetQuestType() >= MAX_QUEST_TYPES)
TC_LOG_ERROR("sql.sql", "Quest %u has `Method` = %u, expected values are 0, 1 or 2.", qinfo->GetQuestId(), qinfo->GetQuestType());
- if (qinfo->SpecialFlags & ~QUEST_SPECIAL_FLAGS_DB_ALLOWED)
+ if (qinfo->_specialFlags & ~QUEST_SPECIAL_FLAGS_DB_ALLOWED)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `SpecialFlags` = %u > max allowed value. Correct `SpecialFlags` to value <= %u",
- qinfo->GetQuestId(), qinfo->SpecialFlags, QUEST_SPECIAL_FLAGS_DB_ALLOWED);
- qinfo->SpecialFlags &= QUEST_SPECIAL_FLAGS_DB_ALLOWED;
+ qinfo->GetQuestId(), qinfo->_specialFlags, QUEST_SPECIAL_FLAGS_DB_ALLOWED);
+ qinfo->_specialFlags &= QUEST_SPECIAL_FLAGS_DB_ALLOWED;
}
- if (qinfo->Flags & QUEST_FLAGS_DAILY && qinfo->Flags & QUEST_FLAGS_WEEKLY)
+ if (qinfo->_flags & QUEST_FLAGS_DAILY && qinfo->_flags & QUEST_FLAGS_WEEKLY)
{
TC_LOG_ERROR("sql.sql", "Weekly Quest %u is marked as daily quest in `Flags`, removed daily flag.", qinfo->GetQuestId());
- qinfo->Flags &= ~QUEST_FLAGS_DAILY;
+ qinfo->_flags &= ~QUEST_FLAGS_DAILY;
}
- if (qinfo->Flags & QUEST_FLAGS_DAILY)
+ if (qinfo->_flags & QUEST_FLAGS_DAILY)
{
- if (!(qinfo->SpecialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE))
+ if (!(qinfo->_specialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE))
{
TC_LOG_DEBUG("sql.sql", "Daily Quest %u not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
- qinfo->SpecialFlags |= QUEST_SPECIAL_FLAGS_REPEATABLE;
+ qinfo->_specialFlags |= QUEST_SPECIAL_FLAGS_REPEATABLE;
}
}
- if (qinfo->Flags & QUEST_FLAGS_WEEKLY)
+ if (qinfo->_flags & QUEST_FLAGS_WEEKLY)
{
- if (!(qinfo->SpecialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE))
+ if (!(qinfo->_specialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE))
{
TC_LOG_DEBUG("sql.sql", "Weekly Quest %u not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
- qinfo->SpecialFlags |= QUEST_SPECIAL_FLAGS_REPEATABLE;
+ qinfo->_specialFlags |= QUEST_SPECIAL_FLAGS_REPEATABLE;
}
}
- if (qinfo->SpecialFlags & QUEST_SPECIAL_FLAGS_MONTHLY)
+ if (qinfo->_specialFlags & QUEST_SPECIAL_FLAGS_MONTHLY)
{
- if (!(qinfo->SpecialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE))
+ if (!(qinfo->_specialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE))
{
TC_LOG_DEBUG("sql.sql", "Monthly quest %u not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
- qinfo->SpecialFlags |= QUEST_SPECIAL_FLAGS_REPEATABLE;
+ qinfo->_specialFlags |= QUEST_SPECIAL_FLAGS_REPEATABLE;
}
}
- if (qinfo->Flags & QUEST_FLAGS_TRACKING)
+ if (qinfo->_flags & QUEST_FLAGS_TRACKING)
{
// at auto-reward can be rewarded only RewardChoiceItemId[0]
- for (int j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j )
+ for (uint32 j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j )
{
if (uint32 id = qinfo->RewardChoiceItemId[j])
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardChoiceItemId%d` = %u but item from `RewardChoiceItemId%d` can't be rewarded with quest flag QUEST_FLAGS_TRACKING.",
- qinfo->GetQuestId(), j+1, id, j+1);
+ qinfo->GetQuestId(), j + 1, id, j + 1);
// no changes, quest ignore this data
}
}
}
- if (qinfo->MinLevel == -1 || qinfo->MinLevel > DEFAULT_MAX_LEVEL)
+ if (qinfo->_minLevel == -1 || qinfo->_minLevel > DEFAULT_MAX_LEVEL)
{
- TC_LOG_ERROR("sql.sql", "Quest %u should be disabled because `MinLevel` = %i", qinfo->GetQuestId(), int32(qinfo->MinLevel));
+ TC_LOG_ERROR("sql.sql", "Quest %u should be disabled because `MinLevel` = %i", qinfo->GetQuestId(), int32(qinfo->_minLevel));
// no changes needed, sending -1 in SMSG_QUEST_QUERY_RESPONSE is valid
}
// client quest log visual (area case)
- if (qinfo->QuestSortID > 0)
+ if (qinfo->_questSortID > 0)
{
- if (!sAreaTableStore.LookupEntry(qinfo->QuestSortID))
+ if (!sAreaTableStore.LookupEntry(qinfo->_questSortID))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `QuestSortID` = %u (zone case) but zone with this id does not exist.",
- qinfo->GetQuestId(), qinfo->QuestSortID);
+ qinfo->GetQuestId(), qinfo->_questSortID);
// no changes, quest not dependent from this value but can have problems at client
}
}
// client quest log visual (sort case)
- if (qinfo->QuestSortID < 0)
+ if (qinfo->_questSortID < 0)
{
- QuestSortEntry const* qSort = sQuestSortStore.LookupEntry(-int32(qinfo->QuestSortID));
+ QuestSortEntry const* qSort = sQuestSortStore.LookupEntry(-int32(qinfo->_questSortID));
if (!qSort)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `QuestSortID` = %i (sort case) but quest sort with this id does not exist.",
- qinfo->GetQuestId(), qinfo->QuestSortID);
+ qinfo->GetQuestId(), qinfo->_questSortID);
// no changes, quest not dependent from this value but can have problems at client (note some may be 0, we must allow this so no check)
}
//check for proper RequiredSkillId value (skill case)
- if (uint32 skill_id = SkillByQuestSort(-int32(qinfo->QuestSortID)))
+ if (uint32 skill_id = SkillByQuestSort(-int32(qinfo->_questSortID)))
{
- if (qinfo->RequiredSkillId != skill_id)
+ if (qinfo->_requiredSkillId != skill_id)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `QuestSortID` = %i but `RequiredSkillId` does not have a corresponding value (%d).",
- qinfo->GetQuestId(), qinfo->QuestSortID, skill_id);
+ qinfo->GetQuestId(), qinfo->_questSortID, skill_id);
//override, and force proper value here?
}
}
}
// AllowableClasses, can be 0/CLASSMASK_ALL_PLAYABLE to allow any class
- if (qinfo->AllowableClasses)
+ if (qinfo->_allowableClasses)
{
- if (!(qinfo->AllowableClasses & CLASSMASK_ALL_PLAYABLE))
+ if (!(qinfo->_allowableClasses & CLASSMASK_ALL_PLAYABLE))
{
- TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable classes in `AllowableClasses` (%u), value set to 0 (all classes).", qinfo->GetQuestId(), qinfo->AllowableClasses);
- qinfo->AllowableClasses = 0;
+ TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable classes in `AllowableClasses` (%u), value set to 0 (all classes).", qinfo->GetQuestId(), qinfo->_allowableClasses);
+ qinfo->_allowableClasses = 0;
}
}
// AllowableRaces, can be -1/RACEMASK_ALL_PLAYABLE to allow any race
- if (qinfo->AllowableRaces.RawValue != uint64(-1))
+ if (qinfo->_allowableRaces.RawValue != uint64(-1))
{
- if (qinfo->AllowableRaces && !(qinfo->AllowableRaces.RawValue & RACEMASK_ALL_PLAYABLE))
+ if (qinfo->_allowableRaces && !(qinfo->_allowableRaces.RawValue & RACEMASK_ALL_PLAYABLE))
{
- TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `AllowableRaces` (" UI64FMTD "), value set to -1 (all races).", qinfo->GetQuestId(), qinfo->AllowableRaces.RawValue);
- qinfo->AllowableRaces.RawValue = uint64(-1);
+ TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `AllowableRaces` (" UI64FMTD "), value set to -1 (all races).", qinfo->GetQuestId(), qinfo->_allowableRaces.RawValue);
+ qinfo->_allowableRaces.RawValue = uint64(-1);
}
}
// RequiredSkillId, can be 0
- if (qinfo->RequiredSkillId)
+ if (qinfo->_requiredSkillId)
{
- if (!sSkillLineStore.LookupEntry(qinfo->RequiredSkillId))
+ if (!sSkillLineStore.LookupEntry(qinfo->_requiredSkillId))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSkillId` = %u but this skill does not exist",
- qinfo->GetQuestId(), qinfo->RequiredSkillId);
+ qinfo->GetQuestId(), qinfo->_requiredSkillId);
}
}
- if (qinfo->RequiredSkillPoints)
+ if (qinfo->_requiredSkillPoints)
{
- if (qinfo->RequiredSkillPoints > sWorld->GetConfigMaxSkillValue())
+ if (qinfo->_requiredSkillPoints > sWorld->GetConfigMaxSkillValue())
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSkillPoints` = %u but max possible skill is %u, quest can't be done.",
- qinfo->GetQuestId(), qinfo->RequiredSkillPoints, sWorld->GetConfigMaxSkillValue());
+ qinfo->GetQuestId(), qinfo->_requiredSkillPoints, sWorld->GetConfigMaxSkillValue());
// no changes, quest can't be done for this requirement
}
}
// else Skill quests can have 0 skill level, this is ok
- if (qinfo->RequiredMinRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMinRepFaction))
+ if (qinfo->_requiredMinRepFaction && !sFactionStore.LookupEntry(qinfo->_requiredMinRepFaction))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredMinRepFaction` = %u but faction template %u does not exist, quest can't be done.",
- qinfo->GetQuestId(), qinfo->RequiredMinRepFaction, qinfo->RequiredMinRepFaction);
+ qinfo->GetQuestId(), qinfo->_requiredMinRepFaction, qinfo->_requiredMinRepFaction);
// no changes, quest can't be done for this requirement
}
- if (qinfo->RequiredMaxRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMaxRepFaction))
+ if (qinfo->_requiredMaxRepFaction && !sFactionStore.LookupEntry(qinfo->_requiredMaxRepFaction))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredMaxRepFaction` = %u but faction template %u does not exist, quest can't be done.",
- qinfo->GetQuestId(), qinfo->RequiredMaxRepFaction, qinfo->RequiredMaxRepFaction);
+ qinfo->GetQuestId(), qinfo->_requiredMaxRepFaction, qinfo->_requiredMaxRepFaction);
// no changes, quest can't be done for this requirement
}
- if (qinfo->RequiredMinRepValue && qinfo->RequiredMinRepValue > ReputationMgr::Reputation_Cap)
+ if (qinfo->_requiredMinRepValue && qinfo->_requiredMinRepValue > ReputationMgr::Reputation_Cap)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredMinRepValue` = %d but max reputation is %u, quest can't be done.",
- qinfo->GetQuestId(), qinfo->RequiredMinRepValue, ReputationMgr::Reputation_Cap);
+ qinfo->GetQuestId(), qinfo->_requiredMinRepValue, ReputationMgr::Reputation_Cap);
// no changes, quest can't be done for this requirement
}
- if (qinfo->RequiredMinRepValue && qinfo->RequiredMaxRepValue && qinfo->RequiredMaxRepValue <= qinfo->RequiredMinRepValue)
+ if (qinfo->_requiredMinRepValue && qinfo->_requiredMaxRepValue && qinfo->_requiredMaxRepValue <= qinfo->_requiredMinRepValue)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredMaxRepValue` = %d and `RequiredMinRepValue` = %d, quest can't be done.",
- qinfo->GetQuestId(), qinfo->RequiredMaxRepValue, qinfo->RequiredMinRepValue);
+ qinfo->GetQuestId(), qinfo->_requiredMaxRepValue, qinfo->_requiredMinRepValue);
// no changes, quest can't be done for this requirement
}
- if (!qinfo->RequiredMinRepFaction && qinfo->RequiredMinRepValue != 0)
+ if (!qinfo->_requiredMinRepFaction && qinfo->_requiredMinRepValue != 0)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredMinRepValue` = %d but `RequiredMinRepFaction` is 0, value has no effect",
- qinfo->GetQuestId(), qinfo->RequiredMinRepValue);
+ qinfo->GetQuestId(), qinfo->_requiredMinRepValue);
// warning
}
- if (!qinfo->RequiredMaxRepFaction && qinfo->RequiredMaxRepValue != 0)
+ if (!qinfo->_requiredMaxRepFaction && qinfo->_requiredMaxRepValue != 0)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredMaxRepValue` = %d but `RequiredMaxRepFaction` is 0, value has no effect",
- qinfo->GetQuestId(), qinfo->RequiredMaxRepValue);
+ qinfo->GetQuestId(), qinfo->_requiredMaxRepValue);
// warning
}
- if (qinfo->RewardTitleId && !sCharTitlesStore.LookupEntry(qinfo->RewardTitleId))
+ if (qinfo->_rewardTitleId && !sCharTitlesStore.LookupEntry(qinfo->_rewardTitleId))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardTitleId` = %u but CharTitle Id %u does not exist, quest can't be rewarded with title.",
- qinfo->GetQuestId(), qinfo->RewardTitleId, qinfo->RewardTitleId);
- qinfo->RewardTitleId = 0;
+ qinfo->GetQuestId(), qinfo->_rewardTitleId, qinfo->_rewardTitleId);
+ qinfo->_rewardTitleId = 0;
// quest can't reward this title
}
- if (qinfo->SourceItemId)
+ if (qinfo->_sourceItemId)
{
- if (!sObjectMgr->GetItemTemplate(qinfo->SourceItemId))
+ if (!sObjectMgr->GetItemTemplate(qinfo->_sourceItemId))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `SourceItemId` = %u but item with entry %u does not exist, quest can't be done.",
- qinfo->GetQuestId(), qinfo->SourceItemId, qinfo->SourceItemId);
- qinfo->SourceItemId = 0; // quest can't be done for this requirement
+ qinfo->GetQuestId(), qinfo->_sourceItemId, qinfo->_sourceItemId);
+ qinfo->_sourceItemId = 0; // quest can't be done for this requirement
}
- else if (qinfo->SourceItemIdCount == 0)
+ else if (qinfo->_sourceItemIdCount == 0)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `StartItem` = %u but `ProvidedItemCount` = 0, set to 1 but need fix in DB.",
- qinfo->GetQuestId(), qinfo->SourceItemId);
- qinfo->SourceItemIdCount = 1; // update to 1 for allow quest work for backward compatibility with DB
+ qinfo->GetQuestId(), qinfo->_sourceItemId);
+ qinfo->_sourceItemIdCount = 1; // update to 1 for allow quest work for backward compatibility with DB
}
}
- else if (qinfo->SourceItemIdCount>0)
+ else if (qinfo->_sourceItemIdCount > 0)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `SourceItemId` = 0 but `SourceItemIdCount` = %u, useless value.",
- qinfo->GetQuestId(), qinfo->SourceItemIdCount);
- qinfo->SourceItemIdCount=0; // no quest work changes in fact
+ qinfo->GetQuestId(), qinfo->_sourceItemIdCount);
+ qinfo->_sourceItemIdCount = 0; // no quest work changes in fact
}
- if (qinfo->SourceSpellID)
+ if (qinfo->_sourceSpellID)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->SourceSpellID);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->_sourceSpellID);
if (!spellInfo)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `SourceSpellid` = %u but spell %u doesn't exist, quest can't be done.",
- qinfo->GetQuestId(), qinfo->SourceSpellID, qinfo->SourceSpellID);
- qinfo->SourceSpellID = 0; // quest can't be done for this requirement
+ qinfo->GetQuestId(), qinfo->_sourceSpellID, qinfo->_sourceSpellID);
+ qinfo->_sourceSpellID = 0; // quest can't be done for this requirement
}
else if (!SpellMgr::IsSpellValid(spellInfo))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `SourceSpellid` = %u but spell %u is broken, quest can't be done.",
- qinfo->GetQuestId(), qinfo->SourceSpellID, qinfo->SourceSpellID);
- qinfo->SourceSpellID = 0; // quest can't be done for this requirement
+ qinfo->GetQuestId(), qinfo->_sourceSpellID, qinfo->_sourceSpellID);
+ qinfo->_sourceSpellID = 0; // quest can't be done for this requirement
}
}
@@ -4501,7 +4437,7 @@ void ObjectMgr::LoadQuests()
{
if (qinfo->RewardFactionId[j])
{
- if (abs(qinfo->RewardFactionValue[j]) > 9)
+ if (std::abs(qinfo->RewardFactionValue[j]) > 9)
{
TC_LOG_ERROR("sql.sql", "Quest %u has RewardFactionValueId%d = %i. That is outside the range of valid values (-9 to 9).", qinfo->GetQuestId(), j+1, qinfo->RewardFactionValue[j]);
}
@@ -4542,59 +4478,59 @@ void ObjectMgr::LoadQuests()
}
}
- if (qinfo->RewardSpell > 0)
+ if (qinfo->_rewardSpell > 0)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpell);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->_rewardSpell);
if (!spellInfo)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpellCast` = %u but spell %u does not exist, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
- qinfo->RewardSpell = 0; // no spell will be cast on player
+ qinfo->GetQuestId(), qinfo->_rewardSpell, qinfo->_rewardSpell);
+ qinfo->_rewardSpell = 0; // no spell will be cast on player
}
else if (!SpellMgr::IsSpellValid(spellInfo))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpellCast` = %u but spell %u is broken, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
- qinfo->RewardSpell = 0; // no spell will be cast on player
+ qinfo->GetQuestId(), qinfo->_rewardSpell, qinfo->_rewardSpell);
+ qinfo->_rewardSpell = 0; // no spell will be cast on player
}
}
- if (qinfo->RewardMailTemplateId)
+ if (qinfo->_rewardMailTemplateId)
{
- if (!sMailTemplateStore.LookupEntry(qinfo->RewardMailTemplateId))
+ if (!sMailTemplateStore.LookupEntry(qinfo->_rewardMailTemplateId))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardMailTemplateId` = %u but mail template %u does not exist, quest will not have a mail reward.",
- qinfo->GetQuestId(), qinfo->RewardMailTemplateId, qinfo->RewardMailTemplateId);
- qinfo->RewardMailTemplateId = 0; // no mail will send to player
- qinfo->RewardMailDelay = 0; // no mail will send to player
- qinfo->RewardMailSenderEntry = 0;
+ qinfo->GetQuestId(), qinfo->_rewardMailTemplateId, qinfo->_rewardMailTemplateId);
+ qinfo->_rewardMailTemplateId = 0; // no mail will send to player
+ qinfo->_rewardMailDelay = 0; // no mail will send to player
+ qinfo->_rewardMailSenderEntry = 0;
}
- else if (usedMailTemplates.find(qinfo->RewardMailTemplateId) != usedMailTemplates.end())
+ else if (usedMailTemplates.find(qinfo->_rewardMailTemplateId) != usedMailTemplates.end())
{
- std::map<uint32, uint32>::const_iterator used_mt_itr = usedMailTemplates.find(qinfo->RewardMailTemplateId);
+ auto used_mt_itr = usedMailTemplates.find(qinfo->_rewardMailTemplateId);
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardMailTemplateId` = %u but mail template %u already used for quest %u, quest will not have a mail reward.",
- qinfo->GetQuestId(), qinfo->RewardMailTemplateId, qinfo->RewardMailTemplateId, used_mt_itr->second);
- qinfo->RewardMailTemplateId = 0; // no mail will send to player
- qinfo->RewardMailDelay = 0; // no mail will send to player
- qinfo->RewardMailSenderEntry = 0;
+ qinfo->GetQuestId(), qinfo->_rewardMailTemplateId, qinfo->_rewardMailTemplateId, used_mt_itr->second);
+ qinfo->_rewardMailTemplateId = 0; // no mail will send to player
+ qinfo->_rewardMailDelay = 0; // no mail will send to player
+ qinfo->_rewardMailSenderEntry = 0;
}
else
- usedMailTemplates[qinfo->RewardMailTemplateId] = qinfo->GetQuestId();
+ usedMailTemplates.emplace(qinfo->_rewardMailTemplateId, qinfo->GetQuestId());
}
- if (qinfo->NextQuestInChain)
+ if (qinfo->_nextQuestInChain)
{
- QuestMap::iterator qNextItr = _questTemplates.find(qinfo->NextQuestInChain);
+ auto qNextItr = _questTemplates.find(qinfo->_nextQuestInChain);
if (qNextItr == _questTemplates.end())
{
TC_LOG_ERROR("sql.sql", "Quest %u has `NextQuestInChain` = %u but quest %u does not exist, quest chain will not work.",
- qinfo->GetQuestId(), qinfo->NextQuestInChain, qinfo->NextQuestInChain);
- qinfo->NextQuestInChain = 0;
+ qinfo->GetQuestId(), qinfo->_nextQuestInChain, qinfo->_nextQuestInChain);
+ qinfo->_nextQuestInChain = 0;
}
else
- qNextItr->second->prevChainQuests.push_back(qinfo->GetQuestId());
+ qNextItr->second->PrevChainQuests.push_back(qinfo->GetQuestId());
}
for (uint8 j = 0; j < QUEST_REWARD_CURRENCY_COUNT; ++j)
@@ -4623,79 +4559,74 @@ void ObjectMgr::LoadQuests()
}
}
- if (qinfo->SoundAccept)
+ if (qinfo->_soundAccept)
{
- if (!sSoundKitStore.LookupEntry(qinfo->SoundAccept))
+ if (!sSoundKitStore.LookupEntry(qinfo->_soundAccept))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `SoundAccept` = %u but sound %u does not exist, set to 0.",
- qinfo->GetQuestId(), qinfo->SoundAccept, qinfo->SoundAccept);
- qinfo->SoundAccept = 0; // no sound will be played
+ qinfo->GetQuestId(), qinfo->_soundAccept, qinfo->_soundAccept);
+ qinfo->_soundAccept = 0; // no sound will be played
}
}
- if (qinfo->SoundTurnIn)
+ if (qinfo->_soundTurnIn)
{
- if (!sSoundKitStore.LookupEntry(qinfo->SoundTurnIn))
+ if (!sSoundKitStore.LookupEntry(qinfo->_soundTurnIn))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `SoundTurnIn` = %u but sound %u does not exist, set to 0.",
- qinfo->GetQuestId(), qinfo->SoundTurnIn, qinfo->SoundTurnIn);
- qinfo->SoundTurnIn = 0; // no sound will be played
+ qinfo->GetQuestId(), qinfo->_soundTurnIn, qinfo->_soundTurnIn);
+ qinfo->_soundTurnIn = 0; // no sound will be played
}
}
- if (qinfo->RewardSkillId)
+ if (qinfo->_rewardSkillId)
{
- if (!sSkillLineStore.LookupEntry(qinfo->RewardSkillId))
+ if (!sSkillLineStore.LookupEntry(qinfo->_rewardSkillId))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSkillId` = %u but this skill does not exist",
- qinfo->GetQuestId(), qinfo->RewardSkillId);
+ qinfo->GetQuestId(), qinfo->_rewardSkillId);
}
- if (!qinfo->RewardSkillPoints)
+ if (!qinfo->_rewardSkillPoints)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSkillId` = %u but `RewardSkillPoints` is 0",
- qinfo->GetQuestId(), qinfo->RewardSkillId);
+ qinfo->GetQuestId(), qinfo->_rewardSkillId);
}
}
- if (qinfo->RewardSkillPoints)
+ if (qinfo->_rewardSkillPoints)
{
- if (qinfo->RewardSkillPoints > sWorld->GetConfigMaxSkillValue())
+ if (qinfo->_rewardSkillPoints > sWorld->GetConfigMaxSkillValue())
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSkillPoints` = %u but max possible skill is %u, quest can't be done.",
- qinfo->GetQuestId(), qinfo->RewardSkillPoints, sWorld->GetConfigMaxSkillValue());
+ qinfo->GetQuestId(), qinfo->_rewardSkillPoints, sWorld->GetConfigMaxSkillValue());
// no changes, quest can't be done for this requirement
}
- if (!qinfo->RewardSkillId)
+ if (!qinfo->_rewardSkillId)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSkillPoints` = %u but `RewardSkillId` is 0",
- qinfo->GetQuestId(), qinfo->RewardSkillPoints);
+ qinfo->GetQuestId(), qinfo->_rewardSkillPoints);
}
}
// fill additional data stores
- if (qinfo->PrevQuestID)
+ if (qinfo->_prevQuestID)
{
if (_questTemplates.find(abs(qinfo->GetPrevQuestId())) == _questTemplates.end())
TC_LOG_ERROR("sql.sql", "Quest %d has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
- else
- qinfo->prevQuests.push_back(qinfo->PrevQuestID);
}
- if (qinfo->NextQuestID)
+ if (qinfo->_nextQuestID)
{
- QuestMap::iterator qNextItr = _questTemplates.find(abs(qinfo->GetNextQuestId()));
+ auto qNextItr = _questTemplates.find(qinfo->GetNextQuestId());
if (qNextItr == _questTemplates.end())
- TC_LOG_ERROR("sql.sql", "Quest %d has NextQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId());
+ TC_LOG_ERROR("sql.sql", "Quest %d has NextQuestId %u, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId());
else
- {
- int32 signedQuestId = qinfo->NextQuestID < 0 ? -int32(qinfo->GetQuestId()) : int32(qinfo->GetQuestId());
- qNextItr->second->prevQuests.push_back(signedQuestId);
- }
+ qNextItr->second->DependentPreviousQuests.push_back(qinfo->GetQuestId());
}
- if (qinfo->ExclusiveGroup)
- mExclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->ExclusiveGroup, qinfo->GetQuestId()));
- if (qinfo->LimitTime)
+ if (qinfo->_exclusiveGroup)
+ _exclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->_exclusiveGroup, qinfo->GetQuestId()));
+ if (qinfo->_limitTime)
qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED);
}
@@ -9223,6 +9154,8 @@ void ObjectMgr::LoadScriptNames()
return;
}
+ _scriptNamesStore.reserve(result->GetRowCount() + 1);
+
do
{
_scriptNamesStore.push_back((*result)[0].GetString());
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 7a2105cf346..6506eb3d80d 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -540,6 +540,9 @@ typedef std::multimap<uint32, uint32> QuestRelationsReverse; // quest -> unit/go
typedef std::pair<QuestRelations::const_iterator, QuestRelations::const_iterator> QuestRelationBounds;
typedef std::pair<QuestRelationsReverse::const_iterator, QuestRelationsReverse::const_iterator> QuestRelationReverseBounds;
+typedef std::multimap<int32, uint32> ExclusiveQuestGroups; // exclusiveGroupId -> quest
+typedef std::pair<ExclusiveQuestGroups::const_iterator, ExclusiveQuestGroups::const_iterator> ExclusiveQuestGroupsBounds;
+
struct PlayerCreateInfoItem
{
PlayerCreateInfoItem(uint32 id, uint32 amount) : item_id(id), item_amount(amount) { }
@@ -1206,6 +1209,11 @@ class TC_GAME_API ObjectMgr
return _creatureQuestInvolvedRelationsReverse.equal_range(questId);
}
+ ExclusiveQuestGroupsBounds GetExclusiveQuestGroupBounds(int32 exclusiveGroupId) const
+ {
+ return _exclusiveQuestGroups.equal_range(exclusiveGroupId);
+ }
+
bool LoadTrinityStrings();
void LoadEventScripts();
@@ -1344,11 +1352,6 @@ class TC_GAME_API ObjectMgr
uint64 GenerateCreatureSpawnId();
uint64 GenerateGameObjectSpawnId();
- typedef std::multimap<int32, uint32> ExclusiveQuestGroups;
- typedef std::pair<ExclusiveQuestGroups::const_iterator, ExclusiveQuestGroups::const_iterator> ExclusiveQuestGroupsBounds;
-
- ExclusiveQuestGroups mExclusiveQuestGroups;
-
MailLevelReward const* GetMailLevelReward(uint8 level, uint8 race)
{
MailLevelRewardContainer::const_iterator map_itr = _mailLevelRewardStore.find(level);
@@ -1677,6 +1680,8 @@ class TC_GAME_API ObjectMgr
QuestRelations _creatureQuestInvolvedRelations;
QuestRelationsReverse _creatureQuestInvolvedRelationsReverse;
+ ExclusiveQuestGroups _exclusiveQuestGroups;
+
//character reserved names
typedef std::set<std::wstring> ReservedNamesContainer;
ReservedNamesContainer _reservedNamesStore;
diff --git a/src/server/game/Grids/Cells/CellImpl.h b/src/server/game/Grids/Cells/CellImpl.h
index a06a84eaebc..3b343851bb2 100644
--- a/src/server/game/Grids/Cells/CellImpl.h
+++ b/src/server/game/Grids/Cells/CellImpl.h
@@ -64,7 +64,7 @@ inline void Cell::Visit(CellCoord const& standing_cell, TypeContainerVisitor<T,
{
//we should increase search radius by object's radius, otherwise
//we could have problems with huge creatures, which won't attack nearest players etc
- Visit(standing_cell, visitor, map, obj.GetPositionX(), obj.GetPositionY(), radius + obj.GetObjectSize());
+ Visit(standing_cell, visitor, map, obj.GetPositionX(), obj.GetPositionY(), radius + obj.GetCombatReach());
}
template<class T, class CONTAINER>
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index e786935b538..23f3cf2ddc0 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -944,14 +944,27 @@ namespace Trinity
class AnyFriendlyUnitInObjectRangeCheck
{
public:
- AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool playerOnly = false) : i_obj(obj), i_funit(funit), i_range(range), i_playerOnly(playerOnly) { }
+ AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool playerOnly = false, bool incOwnRadius = true, bool incTargetRadius = true)
+ : i_obj(obj), i_funit(funit), i_range(range), i_playerOnly(playerOnly), i_incOwnRadius(incOwnRadius), i_incTargetRadius(incTargetRadius) { }
bool operator()(Unit* u) const
{
- if (u->IsAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_funit->IsFriendlyTo(u) && (!i_playerOnly || u->GetTypeId() == TYPEID_PLAYER))
- return true;
- else
+ if (!u->IsAlive())
+ return false;
+
+ float searchRadius = i_range;
+ if (i_incOwnRadius)
+ searchRadius += i_obj->GetCombatReach();
+ if (i_incTargetRadius)
+ searchRadius += u->GetCombatReach();
+
+ if (!u->IsInMap(i_obj) || !u->IsInPhase(i_obj) || !u->IsWithinDoubleVerticalCylinder(i_obj, searchRadius, searchRadius))
return false;
+
+ if (!i_funit->IsFriendlyTo(u))
+ return false;
+
+ return !i_playerOnly || u->GetTypeId() == TYPEID_PLAYER;
}
private:
@@ -959,12 +972,15 @@ namespace Trinity
Unit const* i_funit;
float i_range;
bool i_playerOnly;
+ bool i_incOwnRadius;
+ bool i_incTargetRadius;
};
class AnyGroupedUnitInObjectRangeCheck
{
public:
- AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid, bool playerOnly = false) : _source(obj), _refUnit(funit), _range(range), _raid(raid), _playerOnly(playerOnly) { }
+ AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid, bool playerOnly = false, bool incOwnRadius = true, bool incTargetRadius = true)
+ : _source(obj), _refUnit(funit), _range(range), _raid(raid), _playerOnly(playerOnly), i_incOwnRadius(incOwnRadius), i_incTargetRadius(incTargetRadius) { }
bool operator()(Unit* u) const
{
@@ -979,7 +995,19 @@ namespace Trinity
else if (!_refUnit->IsInPartyWith(u))
return false;
- return !_refUnit->IsHostileTo(u) && u->IsAlive() && _source->IsWithinDistInMap(u, _range);
+ if (_refUnit->IsHostileTo(u))
+ return false;
+
+ if (!u->IsAlive())
+ return false;
+
+ float searchRadius = _range;
+ if (i_incOwnRadius)
+ searchRadius += _source->GetCombatReach();
+ if (i_incTargetRadius)
+ searchRadius += u->GetCombatReach();
+
+ return u->IsInMap(_source) && u->IsInPhase(_source) && u->IsWithinDoubleVerticalCylinder(_source, searchRadius, searchRadius);
}
private:
@@ -988,6 +1016,8 @@ namespace Trinity
float _range;
bool _raid;
bool _playerOnly;
+ bool i_incOwnRadius;
+ bool i_incTargetRadius;
};
class AnyUnitInObjectRangeCheck
@@ -1039,8 +1069,8 @@ namespace Trinity
class AnyAoETargetUnitInObjectRangeCheck
{
public:
- AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, SpellInfo const* spellInfo = nullptr)
- : i_obj(obj), i_funit(funit), _spellInfo(spellInfo), i_range(range)
+ AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, SpellInfo const* spellInfo = nullptr, bool incOwnRadius = true, bool incTargetRadius = true)
+ : i_obj(obj), i_funit(funit), _spellInfo(spellInfo), i_range(range), i_incOwnRadius(incOwnRadius), i_incTargetRadius(incTargetRadius)
{
if (!_spellInfo)
if (DynamicObject const* dynObj = i_obj->ToDynObject())
@@ -1056,7 +1086,16 @@ namespace Trinity
if (_spellInfo && _spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS) && u->GetTypeId() != TYPEID_PLAYER)
return false;
- return i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : nullptr) && i_obj->IsWithinDistInMap(u, i_range);
+ if (!i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : nullptr))
+ return false;
+
+ float searchRadius = i_range;
+ if (i_incOwnRadius)
+ searchRadius += i_obj->GetCombatReach();
+ if (i_incTargetRadius)
+ searchRadius += u->GetCombatReach();
+
+ return u->IsInMap(i_obj) && u->IsInPhase(i_obj) && u->IsWithinDoubleVerticalCylinder(i_obj, searchRadius, searchRadius);
}
private:
@@ -1064,6 +1103,8 @@ namespace Trinity
Unit const* i_funit;
SpellInfo const* _spellInfo;
float i_range;
+ bool i_incOwnRadius;
+ bool i_incTargetRadius;
};
// do attack at call of help to friendly crearture
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index bf2f9dc3cd5..1ae93079145 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -228,6 +228,7 @@ void WorldSession::HandleOpenWrappedItemCallback(uint16 pos, ObjectGuid itemGuid
item->SetGiftCreator(ObjectGuid::Empty);
item->SetEntry(entry);
item->SetItemFlags(ItemFieldFlags(flags));
+ item->SetMaxDurability(item->GetTemplate()->MaxDurability);
item->SetState(ITEM_CHANGED, GetPlayer());
GetPlayer()->SaveInventoryAndGoldToDB(trans);
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index 90582235948..4f124dd9567 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -145,7 +145,7 @@ void InstanceScript::LoadBossBoundaries(const BossBoundaryData& data)
{
for (BossBoundaryEntry const& entry : data)
if (entry.BossId < bosses.size())
- bosses[entry.BossId].boundary.insert(entry.Boundary);
+ bosses[entry.BossId].boundary.push_back(entry.Boundary);
}
void InstanceScript::LoadMinionData(const MinionData* data)
diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h
index 0fc37d470ec..a87779f7f22 100644
--- a/src/server/game/Instances/InstanceScript.h
+++ b/src/server/game/Instances/InstanceScript.h
@@ -119,7 +119,7 @@ struct ObjectData
uint32 type;
};
-typedef std::set<AreaBoundary const*> CreatureBoundary;
+typedef std::vector<AreaBoundary const*> CreatureBoundary;
struct BossInfo
{
diff --git a/src/server/game/Maps/AreaBoundary.cpp b/src/server/game/Maps/AreaBoundary.cpp
index f7ae5b4c9b6..407b5c27e53 100644
--- a/src/server/game/Maps/AreaBoundary.cpp
+++ b/src/server/game/Maps/AreaBoundary.cpp
@@ -21,7 +21,7 @@
// ---== RECTANGLE ==---
RectangleBoundary::RectangleBoundary(float southX, float northX, float eastY, float westY, bool isInverted) :
- AreaBoundary(BoundaryType::BOUNDARY_RECTANGLE, isInverted), _minX(southX), _maxX(northX), _minY(eastY), _maxY(westY) { }
+ AreaBoundary(isInverted), _minX(southX), _maxX(northX), _minY(eastY), _maxY(westY) { }
bool RectangleBoundary::IsWithinBoundaryArea(Position const* pos) const
{
if (!pos)
@@ -38,13 +38,9 @@ bool RectangleBoundary::IsWithinBoundaryArea(Position const* pos) const
// ---== CIRCLE ==---
CircleBoundary::CircleBoundary(Position const& center, double radius, bool isInverted) :
- CircleBoundary(DoublePosition(center), radius, isInverted) { }
-CircleBoundary::CircleBoundary(DoublePosition const& center, double radius, bool isInverted) :
- AreaBoundary(BoundaryType::BOUNDARY_CIRCLE, isInverted), _center(center), _radiusSq(radius*radius) { }
+ AreaBoundary(isInverted), _center(center), _radiusSq(radius*radius) { }
CircleBoundary::CircleBoundary(Position const& center, Position const& pointOnCircle, bool isInverted) :
- CircleBoundary(DoublePosition(center), DoublePosition(pointOnCircle), isInverted) { }
-CircleBoundary::CircleBoundary(DoublePosition const& center, DoublePosition const& pointOnCircle, bool isInverted) :
- AreaBoundary(BoundaryType::BOUNDARY_CIRCLE, isInverted), _center(center), _radiusSq(center.GetDoubleExactDist2dSq(pointOnCircle)) { }
+ AreaBoundary(isInverted), _center(center), _radiusSq(_center.GetDoubleExactDist2dSq(pointOnCircle)) { }
bool CircleBoundary::IsWithinBoundaryArea(Position const* pos) const
{
if (!pos)
@@ -58,9 +54,7 @@ bool CircleBoundary::IsWithinBoundaryArea(Position const* pos) const
// ---== ELLIPSE ==---
EllipseBoundary::EllipseBoundary(Position const& center, double radiusX, double radiusY, bool isInverted) :
- EllipseBoundary(DoublePosition(center), radiusX, radiusY, isInverted) { }
-EllipseBoundary::EllipseBoundary(DoublePosition const& center, double radiusX, double radiusY, bool isInverted) :
- AreaBoundary(BoundaryType::BOUNDARY_ELLIPSE, isInverted), _center(center), _radiusYSq(radiusY*radiusY), _scaleXSq(_radiusYSq / (radiusX*radiusX)) { }
+ AreaBoundary(isInverted), _center(center), _radiusYSq(radiusY*radiusY), _scaleXSq(_radiusYSq / (radiusX*radiusX)) { }
bool EllipseBoundary::IsWithinBoundaryArea(Position const* pos) const
{
if (!pos)
@@ -73,9 +67,7 @@ bool EllipseBoundary::IsWithinBoundaryArea(Position const* pos) const
// ---== TRIANGLE ==---
TriangleBoundary::TriangleBoundary(Position const& pointA, Position const& pointB, Position const& pointC, bool isInverted) :
- TriangleBoundary(DoublePosition(pointA), DoublePosition(pointB), DoublePosition(pointC), isInverted) { }
-TriangleBoundary::TriangleBoundary(DoublePosition const& pointA, DoublePosition const& pointB, DoublePosition const& pointC, bool isInverted) :
- AreaBoundary(BoundaryType::BOUNDARY_TRIANGLE, isInverted), _a(pointA), _b(pointB), _c(pointC), _abx(_b.GetDoublePositionX()-_a.GetDoublePositionX()), _bcx(_c.GetDoublePositionX()-_b.GetDoublePositionX()), _cax(_a.GetDoublePositionX() - _c.GetDoublePositionX()), _aby(_b.GetDoublePositionY()-_a.GetDoublePositionY()), _bcy(_c.GetDoublePositionY()-_b.GetDoublePositionY()), _cay(_a.GetDoublePositionY() - _c.GetDoublePositionY()) { }
+ AreaBoundary(isInverted), _a(pointA), _b(pointB), _c(pointC), _abx(_b.GetDoublePositionX()-_a.GetDoublePositionX()), _bcx(_c.GetDoublePositionX()-_b.GetDoublePositionX()), _cax(_a.GetDoublePositionX() - _c.GetDoublePositionX()), _aby(_b.GetDoublePositionY()-_a.GetDoublePositionY()), _bcy(_c.GetDoublePositionY()-_b.GetDoublePositionY()), _cay(_a.GetDoublePositionY() - _c.GetDoublePositionY()) { }
bool TriangleBoundary::IsWithinBoundaryArea(Position const* pos) const
{
if (!pos)
@@ -93,9 +85,7 @@ bool TriangleBoundary::IsWithinBoundaryArea(Position const* pos) const
// ---== PARALLELOGRAM ==---
ParallelogramBoundary::ParallelogramBoundary(Position const& cornerA, Position const& cornerB, Position const& cornerD, bool isInverted) :
- ParallelogramBoundary(DoublePosition(cornerA), DoublePosition(cornerB), DoublePosition(cornerD), isInverted) { }
-ParallelogramBoundary::ParallelogramBoundary(DoublePosition const& cornerA, DoublePosition const& cornerB, DoublePosition const& cornerD, bool isInverted) :
- AreaBoundary(BoundaryType::BOUNDARY_PARALLELOGRAM, isInverted), _a(cornerA), _b(cornerB), _d(cornerD), _c(DoublePosition(_d.GetDoublePositionX() + (_b.GetDoublePositionX() - _a.GetDoublePositionX()), _d.GetDoublePositionY() + (_b.GetDoublePositionY() - _a.GetDoublePositionY()))), _abx(_b.GetDoublePositionX() - _a.GetDoublePositionX()), _dax(_a.GetDoublePositionX() - _d.GetDoublePositionX()), _aby(_b.GetDoublePositionY() - _a.GetDoublePositionY()), _day(_a.GetDoublePositionY() - _d.GetDoublePositionY()) { }
+ AreaBoundary(isInverted), _a(cornerA), _b(cornerB), _d(cornerD), _c(DoublePosition(_d.GetDoublePositionX() + (_b.GetDoublePositionX() - _a.GetDoublePositionX()), _d.GetDoublePositionY() + (_b.GetDoublePositionY() - _a.GetDoublePositionY()))), _abx(_b.GetDoublePositionX() - _a.GetDoublePositionX()), _dax(_a.GetDoublePositionX() - _d.GetDoublePositionX()), _aby(_b.GetDoublePositionY() - _a.GetDoublePositionY()), _day(_a.GetDoublePositionY() - _d.GetDoublePositionY()) { }
bool ParallelogramBoundary::IsWithinBoundaryArea(Position const* pos) const
{
if (!pos)
@@ -114,7 +104,7 @@ bool ParallelogramBoundary::IsWithinBoundaryArea(Position const* pos) const
// ---== Z RANGE ==---
ZRangeBoundary::ZRangeBoundary(float minZ, float maxZ, bool isInverted) :
- AreaBoundary(BoundaryType::BOUNDARY_Z_RANGE, isInverted), _minZ(minZ), _maxZ(maxZ) { }
+ AreaBoundary(isInverted), _minZ(minZ), _maxZ(maxZ) { }
bool ZRangeBoundary::IsWithinBoundaryArea(Position const* pos) const
{
if (!pos)
diff --git a/src/server/game/Maps/AreaBoundary.h b/src/server/game/Maps/AreaBoundary.h
index 069701775eb..6aa7e4185cc 100644
--- a/src/server/game/Maps/AreaBoundary.h
+++ b/src/server/game/Maps/AreaBoundary.h
@@ -23,48 +23,52 @@
class TC_GAME_API AreaBoundary
{
public:
- enum BoundaryType
- {
- BOUNDARY_RECTANGLE, // Rectangle aligned with the coordinate axis
- BOUNDARY_CIRCLE,
- BOUNDARY_ELLIPSE,
- BOUNDARY_TRIANGLE,
- BOUNDARY_PARALLELOGRAM,
- BOUNDARY_Z_RANGE,
- };
- virtual ~AreaBoundary() { }
- BoundaryType GetBoundaryType() const { return m_boundaryType; }
- bool IsWithinBoundary(Position const* pos) const { return (IsWithinBoundaryArea(pos) != m_isInvertedBoundary); }
+ bool IsWithinBoundary(Position const* pos) const { return (IsWithinBoundaryArea(pos) != _isInvertedBoundary); }
bool IsWithinBoundary(Position const& pos) const { return IsWithinBoundary(&pos); }
+ virtual ~AreaBoundary() { }
+
+ protected:
+ explicit AreaBoundary(bool isInverted) : _isInvertedBoundary(isInverted) { }
+
struct DoublePosition : Position
{
- double d_positionX, d_positionY, d_positionZ;
DoublePosition(double x = 0.0, double y = 0.0, double z = 0.0, float o = 0.0f)
- : Position(float(x), float(y), float(z), o), d_positionX(x), d_positionY(y), d_positionZ(z) { }
+ : Position(float(x), float(y), float(z), o), DoublePosX(x), DoublePosY(y), DoublePosZ(z) { }
+
DoublePosition(float x, float y = 0.0f, float z = 0.0f, float o = 0.0f)
- : Position(x, y, z, o), d_positionX(x), d_positionY(y), d_positionZ(z) { }
+ : Position(x, y, z, o), DoublePosX(x), DoublePosY(y), DoublePosZ(z) { }
+
DoublePosition(Position const & pos)
- : DoublePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()) { }
+ : Position(pos), DoublePosX(pos.m_positionX), DoublePosY(pos.m_positionY), DoublePosZ(pos.m_positionZ) { }
- double GetDoublePositionX() const { return d_positionX; }
- double GetDoublePositionY() const { return d_positionY; }
- double GetDoublePositionZ() const { return d_positionZ; }
+ double GetDoublePositionX() const { return DoublePosX; }
+ double GetDoublePositionY() const { return DoublePosY; }
+ double GetDoublePositionZ() const { return DoublePosZ; }
double GetDoubleExactDist2dSq(DoublePosition const& pos) const {
- double offX = GetDoublePositionX() - pos.GetDoublePositionX();
- double offY = GetDoublePositionY() - pos.GetDoublePositionY();
- return (offX*offX) + (offY*offY);
+ double const offX = GetDoublePositionX() - pos.GetDoublePositionX();
+ double const offY = GetDoublePositionY() - pos.GetDoublePositionY();
+ return (offX * offX) + (offY * offY);
+ }
+
+ Position* sync()
+ {
+ m_positionX = float(DoublePosX);
+ m_positionY = float(DoublePosY);
+ m_positionZ = float(DoublePosZ);
+ return this;
}
- Position* sync() { m_positionX = (float)d_positionX; m_positionY = (float)d_positionY; m_positionZ = (float)d_positionZ; return this; }
+ double DoublePosX;
+ double DoublePosY;
+ double DoublePosZ;
};
- protected:
- AreaBoundary(BoundaryType bType, bool isInverted) : m_boundaryType(bType), m_isInvertedBoundary(isInverted) { }
virtual bool IsWithinBoundaryArea(Position const* pos) const = 0;
- const BoundaryType m_boundaryType;
- bool m_isInvertedBoundary;
+
+ private:
+ bool _isInvertedBoundary;
};
class TC_GAME_API RectangleBoundary : public AreaBoundary
@@ -77,51 +81,47 @@ class TC_GAME_API RectangleBoundary : public AreaBoundary
bool IsWithinBoundaryArea(Position const* pos) const override;
private:
- const float _minX, _maxX, _minY, _maxY;
+ float const _minX, _maxX, _minY, _maxY;
};
class TC_GAME_API CircleBoundary : public AreaBoundary
{
public:
CircleBoundary(Position const& center, double radius, bool isInverted = false);
- CircleBoundary(DoublePosition const& center, double radius, bool isInverted = false);
CircleBoundary(Position const& center, Position const& pointOnCircle, bool isInverted = false);
- CircleBoundary(DoublePosition const& center, DoublePosition const& pointOnCircle, bool isInverted = false);
protected:
bool IsWithinBoundaryArea(Position const* pos) const override;
private:
- const DoublePosition _center;
- const double _radiusSq;
+ DoublePosition const _center;
+ double const _radiusSq;
};
class TC_GAME_API EllipseBoundary : public AreaBoundary
{
public:
EllipseBoundary(Position const& center, double radiusX, double radiusY, bool isInverted = false);
- EllipseBoundary(DoublePosition const& center, double radiusX, double radiusY, bool isInverted = false);
protected:
bool IsWithinBoundaryArea(Position const* pos) const override;
private:
- const DoublePosition _center;
- const double _radiusYSq, _scaleXSq;
+ DoublePosition const _center;
+ double const _radiusYSq, _scaleXSq;
};
class TC_GAME_API TriangleBoundary : public AreaBoundary
{
public:
TriangleBoundary(Position const& pointA, Position const& pointB, Position const& pointC, bool isInverted = false);
- TriangleBoundary(DoublePosition const& pointA, DoublePosition const& pointB, DoublePosition const& pointC, bool isInverted = false);
protected:
bool IsWithinBoundaryArea(Position const* pos) const override;
private:
- const DoublePosition _a, _b, _c;
- const double _abx, _bcx, _cax, _aby, _bcy, _cay;
+ DoublePosition const _a, _b, _c;
+ double const _abx, _bcx, _cax, _aby, _bcy, _cay;
};
class TC_GAME_API ParallelogramBoundary : public AreaBoundary
@@ -129,14 +129,13 @@ class TC_GAME_API ParallelogramBoundary : public AreaBoundary
public:
// Note: AB must be orthogonal to AD
ParallelogramBoundary(Position const& cornerA, Position const& cornerB, Position const& cornerD, bool isInverted = false);
- ParallelogramBoundary(DoublePosition const& cornerA, DoublePosition const& cornerB, DoublePosition const& cornerD, bool isInverted = false);
protected:
bool IsWithinBoundaryArea(Position const* pos) const override;
private:
- const DoublePosition _a, _b, _d, _c;
- const double _abx, _dax, _aby, _day;
+ DoublePosition const _a, _b, _d, _c;
+ double const _abx, _dax, _aby, _day;
};
class TC_GAME_API ZRangeBoundary : public AreaBoundary
@@ -148,7 +147,7 @@ class TC_GAME_API ZRangeBoundary : public AreaBoundary
bool IsWithinBoundaryArea(Position const* pos) const override;
private:
- const float _minZ, _maxZ;
+ float const _minZ, _maxZ;
};
#endif //TRINITY_AREA_BOUNDARY_H
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index 283b0b42fc7..4355789458a 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -547,7 +547,7 @@ enum TrinityStrings
LANG_MOVEGENS_IDLE = 527,
LANG_MOVEGENS_RANDOM = 528,
LANG_MOVEGENS_WAYPOINT = 529,
- LANG_MOVEGENS_ANIMAL_RANDOM = 530,
+ // = 530, not used
LANG_MOVEGENS_CONFUSED = 531,
LANG_MOVEGENS_CHASE_PLAYER = 532,
LANG_MOVEGENS_CHASE_CREATURE = 533,
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 1edeb4218fe..1002ab50684 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -5392,6 +5392,14 @@ enum DiminishingLevels
DIMINISHING_LEVEL_TAUNT_IMMUNE = 4
};
+enum WeaponAttackType : uint8
+{
+ BASE_ATTACK = 0,
+ OFF_ATTACK = 1,
+ RANGED_ATTACK = 2,
+ MAX_ATTACK
+};
+
enum TokenResult
{
TOKEN_RESULT_SUCCESS = 0,
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index f4190f2520c..3e775d238a4 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -43,10 +43,16 @@ MotionMaster::~MotionMaster()
// clear ALL movement generators (including default)
while (!empty())
{
- MovementGenerator *curr = top();
+ MovementGenerator* movement = top();
pop();
- if (curr && !IsStatic(curr))
- delete curr; // Skip finalizing on delete, it might launch new movement
+ if (movement && !IsStatic(movement))
+ delete movement;
+ }
+
+ while (!_expireList.empty())
+ {
+ delete _expireList.back();
+ _expireList.pop_back();
}
}
@@ -89,13 +95,15 @@ void MotionMaster::UpdateMotion(uint32 diff)
ASSERT(!empty());
_cleanFlag |= MMCF_UPDATE;
- bool isMoveGenUpdateSuccess = top()->Update(_owner, diff);
- _cleanFlag &= ~MMCF_UPDATE;
-
- if (!isMoveGenUpdateSuccess)
+ if (!top()->Update(_owner, diff))
+ {
+ _cleanFlag &= ~MMCF_UPDATE;
MovementExpired();
+ }
+ else
+ _cleanFlag &= ~MMCF_UPDATE;
- if (_expireList)
+ if (!_expireList.empty())
ClearExpireList();
}
@@ -115,14 +123,10 @@ void MotionMaster::Clear(bool reset /*= true*/)
void MotionMaster::ClearExpireList()
{
- for (size_t i = 0; i < _expireList->size(); ++i)
- {
- MovementGenerator* mg = (*_expireList)[i];
- DirectDelete(mg);
- }
+ for (auto itr : _expireList)
+ DirectDelete(itr);
- delete _expireList;
- _expireList = nullptr;
+ _expireList.clear();
if (empty())
Initialize();
@@ -159,7 +163,7 @@ MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const
MovementGeneratorType MotionMaster::GetMotionSlotType(int slot) const
{
if (!_slot[slot])
- return NULL_MOTION_TYPE;
+ return MAX_MOTION_TYPE;
else
return _slot[slot]->GetMovementGeneratorType();
}
@@ -429,7 +433,7 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa
float dist = 2 * moveTimeHalf * speedXY;
float max_height = -Movement::computeFallElevation(moveTimeHalf, false, -speedZ);
- _owner->GetNearPoint(_owner, x, y, z, _owner->GetObjectSize(), dist, _owner->GetAngle(srcX, srcY) + float(M_PI));
+ _owner->GetNearPoint(_owner, x, y, z, _owner->GetCombatReach(), dist, _owner->GetAngle(srcX, srcY) + float(M_PI));
Movement::MoveSplineInit init(_owner);
init.MoveTo(x, y, z);
@@ -453,7 +457,7 @@ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ)
float moveTimeHalf = speedZ / Movement::gravity;
float dist = 2 * moveTimeHalf * speedXY;
- _owner->GetClosePoint(x, y, z, _owner->GetObjectSize(), dist, angle);
+ _owner->GetClosePoint(x, y, z, _owner->GetCombatReach(), dist, angle);
MoveJump(x, y, z, 0.0f, speedXY, speedZ);
}
@@ -835,7 +839,6 @@ void MotionMaster::DelayedDelete(MovementGenerator* curr)
TC_LOG_FATAL("misc", "Unit (Entry %u) is trying to delete its updating Movement Generator (Type %u)!", _owner->GetEntry(), curr->GetMovementGeneratorType());
if (IsStatic(curr))
return;
- if (!_expireList)
- _expireList = new ExpireList();
- _expireList->push_back(curr);
+
+ _expireList.push_back(curr);
}
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index f8dbe43306d..c496a0ec4ec 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -52,7 +52,6 @@ enum MovementGeneratorType : uint8
RANDOM_MOTION_TYPE = 1, // RandomMovementGenerator.h
WAYPOINT_MOTION_TYPE = 2, // WaypointMovementGenerator.h
MAX_DB_MOTION_TYPE = 3, // Below motion types can't be set in DB.
- ANIMAL_RANDOM_MOTION_TYPE = MAX_DB_MOTION_TYPE, // AnimalRandomMovementGenerator.h
CONFUSED_MOTION_TYPE = 4, // ConfusedMovementGenerator.h
CHASE_MOTION_TYPE = 5, // TargetedMovementGenerator.h
HOME_MOTION_TYPE = 6, // HomeMovementGenerator.h
@@ -60,14 +59,13 @@ enum MovementGeneratorType : uint8
POINT_MOTION_TYPE = 8, // PointMovementGenerator.h
FLEEING_MOTION_TYPE = 9, // FleeingMovementGenerator.h
DISTRACT_MOTION_TYPE = 10, // IdleMovementGenerator.h
- ASSISTANCE_MOTION_TYPE = 11, // PointMovementGenerator.h (first part of flee for assistance)
- ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h (second part of flee for assistance)
- TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance)
+ ASSISTANCE_MOTION_TYPE = 11, // PointMovementGenerator.h
+ ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h
+ TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h
FOLLOW_MOTION_TYPE = 14,
ROTATE_MOTION_TYPE = 15,
EFFECT_MOTION_TYPE = 16,
- NULL_MOTION_TYPE = 17,
- SPLINE_CHAIN_MOTION_TYPE = 18, // SplineChainMovementGenerator.h
+ SPLINE_CHAIN_MOTION_TYPE = 17, // SplineChainMovementGenerator.h
MAX_MOTION_TYPE // limit
};
@@ -100,11 +98,8 @@ struct JumpArrivalCastArgs
class TC_GAME_API MotionMaster
{
- private:
- typedef std::vector<MovementGenerator*> ExpireList;
-
public:
- explicit MotionMaster(Unit* unit) : _expireList(nullptr), _top(-1), _owner(unit), _cleanFlag(MMCF_NONE)
+ explicit MotionMaster(Unit* unit) : _owner(unit), _top(-1), _cleanFlag(MMCF_NONE)
{
for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i)
{
@@ -182,6 +177,8 @@ class TC_GAME_API MotionMaster
void MoveRotate(uint32 time, RotateDirection direction);
private:
+ typedef std::vector<MovementGenerator*> MovementList;
+
void pop();
bool NeedInitTop() const;
@@ -197,11 +194,11 @@ class TC_GAME_API MotionMaster
void DelayedDelete(MovementGenerator* curr);
void ClearExpireList();
- ExpireList* _expireList;
MovementGenerator* _slot[MAX_MOTION_SLOT];
- int _top;
- Unit* _owner;
bool _initialize[MAX_MOTION_SLOT];
+ MovementList _expireList;
+ Unit* _owner;
+ int _top;
uint8 _cleanFlag;
};
diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
index 51b9641661e..e8fa2ba6c53 100644
--- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
@@ -63,7 +63,7 @@ void HomeMovementGenerator<Creature>::_setTargetLocation(Creature* owner)
skipToHome = false;
arrived = false;
- owner->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_EVADE | UNIT_STATE_IGNORE_PATHFINDING)));
+ owner->ClearUnitState(UNIT_STATE_ALL_ERASABLE & ~UNIT_STATE_EVADE);
}
bool HomeMovementGenerator<Creature>::DoUpdate(Creature* owner, const uint32 /*time_diff*/)
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
index 6f3b34c0e4f..3cf0711dc41 100755
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
@@ -149,8 +149,6 @@ void EffectMovementGenerator::Finalize(Unit* unit)
{
if (Unit* victim = unit->GetVictim())
unit->GetMotionMaster()->MoveChase(victim);
- else
- unit->GetMotionMaster()->Initialize();
}
if (unit->ToCreature()->AI())
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
index 0a1206a8d48..54cc97ab418 100755
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
@@ -65,7 +65,7 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up
float size;
// Pets need special handling.
- // We need to subtract GetObjectSize() because it gets added back further down the chain
+ // We need to subtract GetCombatReach() because it gets added back further down the chain
// and that makes pets too far away. Subtracting it allows pets to properly
// be (GetCombatReach() + i_offset) away.
// Only applies when i_target is pet's owner otherwise pets and mobs end up
@@ -73,12 +73,12 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up
if (owner->IsPet() && i_target->GetTypeId() == TYPEID_PLAYER)
{
dist = 1.0f; //i_target->GetCombatReach();
- size = 1.0f; //i_target->GetCombatReach() - i_target->GetObjectSize();
+ size = 1.0f; //i_target->GetCombatReach() - i_target->GetCombatReach();
}
else
{
dist = i_offset + 1.0f;
- size = owner->GetObjectSize();
+ size = owner->GetCombatReach();
}
if (i_target->IsWithinDistInMap(owner, dist))
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 92a039344a5..28685dc58ec 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -27,43 +27,36 @@
Quest::Quest(Field* questRecord)
{
- EmoteOnIncomplete = 0;
- EmoteOnComplete = 0;
- _rewItemsCount = 0;
- _rewChoiceItemsCount = 0;
- _eventIdForQuest = 0;
- _rewCurrencyCount = 0;
-
- ID = questRecord[0].GetUInt32();
- Type = questRecord[1].GetUInt8();
- Level = questRecord[2].GetInt32();
- ScalingFactionGroup = questRecord[3].GetInt32();
- MaxScalingLevel = questRecord[4].GetInt32();
- PackageID = questRecord[5].GetUInt32();
- MinLevel = questRecord[6].GetInt32();
- QuestSortID = questRecord[7].GetInt16();
- QuestInfoID = questRecord[8].GetUInt16();
- SuggestedPlayers = questRecord[9].GetUInt8();
- NextQuestInChain = questRecord[10].GetUInt32();
- RewardXPDifficulty = questRecord[11].GetUInt32();
- RewardXPMultiplier = questRecord[12].GetFloat();
- RewardMoney = questRecord[13].GetUInt32();
- RewardMoneyDifficulty = questRecord[14].GetUInt32();
- RewardMoneyMultiplier = questRecord[15].GetFloat();
- RewardBonusMoney = questRecord[16].GetUInt32();
+ _id = questRecord[0].GetUInt32();
+ _type = questRecord[1].GetUInt8();
+ _level = questRecord[2].GetInt32();
+ _scalingFactionGroup = questRecord[3].GetInt32();
+ _maxScalingLevel = questRecord[4].GetInt32();
+ _packageID = questRecord[5].GetUInt32();
+ _minLevel = questRecord[6].GetInt32();
+ _questSortID = questRecord[7].GetInt16();
+ _questInfoID = questRecord[8].GetUInt16();
+ _suggestedPlayers = questRecord[9].GetUInt8();
+ _nextQuestInChain = questRecord[10].GetUInt32();
+ _rewardXPDifficulty = questRecord[11].GetUInt32();
+ _rewardXPMultiplier = questRecord[12].GetFloat();
+ _rewardMoney = questRecord[13].GetUInt32();
+ _rewardMoneyDifficulty = questRecord[14].GetUInt32();
+ _rewardMoneyMultiplier = questRecord[15].GetFloat();
+ _rewardBonusMoney = questRecord[16].GetUInt32();
for (uint32 i = 0; i < QUEST_REWARD_DISPLAY_SPELL_COUNT; ++i)
RewardDisplaySpell[i] = questRecord[17 + i].GetUInt32();
- RewardSpell = questRecord[20].GetUInt32();
- RewardHonor = questRecord[21].GetUInt32();
- RewardKillHonor = questRecord[22].GetUInt32();
- SourceItemId = questRecord[23].GetUInt32();
- RewardArtifactXPDifficulty = questRecord[24].GetUInt32();
- RewardArtifactXPMultiplier = questRecord[25].GetFloat();
- RewardArtifactCategoryID = questRecord[26].GetUInt32();
- Flags = questRecord[27].GetUInt32();
- FlagsEx = questRecord[28].GetUInt32();
- FlagsEx2 = questRecord[29].GetUInt32();
+ _rewardSpell = questRecord[20].GetUInt32();
+ _rewardHonor = questRecord[21].GetUInt32();
+ _rewardKillHonor = questRecord[22].GetUInt32();
+ _sourceItemId = questRecord[23].GetUInt32();
+ _rewardArtifactXPDifficulty = questRecord[24].GetUInt32();
+ _rewardArtifactXPMultiplier = questRecord[25].GetFloat();
+ _rewardArtifactCategoryID = questRecord[26].GetUInt32();
+ _flags = questRecord[27].GetUInt32();
+ _flagsEx = questRecord[28].GetUInt32();
+ _flagsEx2 = questRecord[29].GetUInt32();
for (uint32 i = 0; i < QUEST_ITEM_DROP_COUNT; ++i)
{
@@ -86,19 +79,19 @@ Quest::Quest(Field* questRecord)
++_rewChoiceItemsCount;
}
- POIContinent = questRecord[64].GetUInt32();
- POIx = questRecord[65].GetFloat();
- POIy = questRecord[66].GetFloat();
- POIPriority = questRecord[67].GetUInt32();
+ _poiContinent = questRecord[64].GetUInt32();
+ _poix = questRecord[65].GetFloat();
+ _poiy = questRecord[66].GetFloat();
+ _poiPriority = questRecord[67].GetUInt32();
- RewardTitleId = questRecord[68].GetUInt32();
- RewardArenaPoints = questRecord[69].GetUInt32();
- RewardSkillId = questRecord[70].GetUInt32();
- RewardSkillPoints = questRecord[71].GetUInt32();
+ _rewardTitleId = questRecord[68].GetUInt32();
+ _rewardArenaPoints = questRecord[69].GetUInt32();
+ _rewardSkillId = questRecord[70].GetUInt32();
+ _rewardSkillPoints = questRecord[71].GetUInt32();
- QuestGiverPortrait = questRecord[72].GetUInt32();
- QuestGiverPortraitMount = questRecord[73].GetUInt32();
- QuestTurnInPortrait = questRecord[74].GetUInt32();
+ _questGiverPortrait = questRecord[72].GetUInt32();
+ _questGiverPortraitMount = questRecord[73].GetUInt32();
+ _questTurnInPortrait = questRecord[74].GetUInt32();
for (uint32 i = 0; i < QUEST_REWARD_REPUTATIONS_COUNT; ++i)
{
@@ -108,7 +101,7 @@ Quest::Quest(Field* questRecord)
RewardFactionCapIn[i] = questRecord[78 + i * 4].GetUInt32();
}
- RewardReputationMask = questRecord[95].GetUInt32();
+ _rewardReputationMask = questRecord[95].GetUInt32();
for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
{
@@ -119,33 +112,25 @@ Quest::Quest(Field* questRecord)
++_rewCurrencyCount;
}
- SoundAccept = questRecord[104].GetUInt32();
- SoundTurnIn = questRecord[105].GetUInt32();
- AreaGroupID = questRecord[106].GetUInt32();
- LimitTime = questRecord[107].GetUInt32();
- AllowableRaces.RawValue = questRecord[108].GetUInt64();
- TreasurePickerID = questRecord[109].GetInt32();
- Expansion = questRecord[110].GetInt32();
- ManagedWorldStateID = questRecord[111].GetInt32();
- QuestSessionBonus = questRecord[112].GetInt32();
-
- LogTitle = questRecord[113].GetString();
- LogDescription = questRecord[114].GetString();
- QuestDescription = questRecord[115].GetString();
- AreaDescription = questRecord[116].GetString();
- PortraitGiverText = questRecord[117].GetString();
- PortraitGiverName = questRecord[118].GetString();
- PortraitTurnInText = questRecord[119].GetString();
- PortraitTurnInName = questRecord[120].GetString();
- QuestCompletionLog = questRecord[121].GetString();
-
- for (uint32 i = 0; i < QUEST_EMOTE_COUNT; ++i)
- {
- DetailsEmote[i] = 0;
- DetailsEmoteDelay[i] = 0;
- OfferRewardEmote[i] = 0;
- OfferRewardEmoteDelay[i] = 0;
- }
+ _soundAccept = questRecord[104].GetUInt32();
+ _soundTurnIn = questRecord[105].GetUInt32();
+ _areaGroupID = questRecord[106].GetUInt32();
+ _limitTime = questRecord[107].GetUInt32();
+ _allowableRaces.RawValue = questRecord[108].GetUInt64();
+ _treasurePickerID = questRecord[109].GetInt32();
+ _expansion = questRecord[110].GetInt32();
+ _managedWorldStateID = questRecord[111].GetInt32();
+ _questSessionBonus = questRecord[112].GetInt32();
+
+ _logTitle = questRecord[113].GetString();
+ _logDescription = questRecord[114].GetString();
+ _questDescription = questRecord[115].GetString();
+ _areaDescription = questRecord[116].GetString();
+ _portraitGiverText = questRecord[117].GetString();
+ _portraitGiverName = questRecord[118].GetString();
+ _portraitTurnInText = questRecord[119].GetString();
+ _portraitTurnInName = questRecord[120].GetString();
+ _questCompletionLog = questRecord[121].GetString();
}
void Quest::LoadQuestDetails(Field* fields)
@@ -167,18 +152,18 @@ void Quest::LoadQuestDetails(Field* fields)
void Quest::LoadQuestRequestItems(Field* fields)
{
- EmoteOnComplete = fields[1].GetUInt16();
- EmoteOnIncomplete = fields[2].GetUInt16();
+ _emoteOnComplete = fields[1].GetUInt16();
+ _emoteOnIncomplete = fields[2].GetUInt16();
- if (!sEmotesStore.LookupEntry(EmoteOnComplete))
- TC_LOG_ERROR("sql.sql", "Table `quest_request_items` has non-existing EmoteOnComplete (%u) set for quest %u.", EmoteOnComplete, fields[0].GetUInt32());
+ if (!sEmotesStore.LookupEntry(_emoteOnComplete))
+ TC_LOG_ERROR("sql.sql", "Table `quest_request_items` has non-existing EmoteOnComplete (%u) set for quest %u.", _emoteOnComplete, fields[0].GetUInt32());
- if (!sEmotesStore.LookupEntry(EmoteOnIncomplete))
- TC_LOG_ERROR("sql.sql", "Table `quest_request_items` has non-existing EmoteOnIncomplete (%u) set for quest %u.", EmoteOnIncomplete, fields[0].GetUInt32());
+ if (!sEmotesStore.LookupEntry(_emoteOnIncomplete))
+ TC_LOG_ERROR("sql.sql", "Table `quest_request_items` has non-existing EmoteOnIncomplete (%u) set for quest %u.", _emoteOnIncomplete, fields[0].GetUInt32());
- EmoteOnCompleteDelay = fields[3].GetUInt32();
- EmoteOnIncompleteDelay = fields[4].GetUInt32();
- RequestItemsText = fields[5].GetString();
+ _emoteOnCompleteDelay = fields[3].GetUInt32();
+ _emoteOnIncompleteDelay = fields[4].GetUInt32();
+ _requestItemsText = fields[5].GetString();
}
void Quest::LoadQuestOfferReward(Field* fields)
@@ -197,39 +182,43 @@ void Quest::LoadQuestOfferReward(Field* fields)
for (uint32 i = 0; i < QUEST_EMOTE_COUNT; ++i)
OfferRewardEmoteDelay[i] = fields[5 + i].GetUInt32();
- OfferRewardText = fields[9].GetString();
+ _offerRewardText = fields[9].GetString();
}
void Quest::LoadQuestTemplateAddon(Field* fields)
{
- MaxLevel = fields[1].GetUInt8();
- AllowableClasses = fields[2].GetUInt32();
- SourceSpellID = fields[3].GetUInt32();
- PrevQuestID = fields[4].GetInt32();
- NextQuestID = fields[5].GetInt32();
- ExclusiveGroup = fields[6].GetInt32();
- RewardMailTemplateId = fields[7].GetUInt32();
- RewardMailDelay = fields[8].GetUInt32();
- RequiredSkillId = fields[9].GetUInt16();
- RequiredSkillPoints = fields[10].GetUInt16();
- RequiredMinRepFaction = fields[11].GetUInt16();
- RequiredMaxRepFaction = fields[12].GetUInt16();
- RequiredMinRepValue = fields[13].GetInt32();
- RequiredMaxRepValue = fields[14].GetInt32();
- SourceItemIdCount = fields[15].GetUInt8();
- RewardMailSenderEntry = fields[16].GetUInt32();
- SpecialFlags = fields[17].GetUInt8();
- ScriptId = sObjectMgr->GetScriptId(fields[18].GetString());
-
- if (SpecialFlags & QUEST_SPECIAL_FLAGS_AUTO_ACCEPT)
- Flags |= QUEST_FLAGS_AUTO_ACCEPT;
+ _maxLevel = fields[1].GetUInt8();
+ _allowableClasses = fields[2].GetUInt32();
+ _sourceSpellID = fields[3].GetUInt32();
+ _prevQuestID = fields[4].GetInt32();
+ _nextQuestID = fields[5].GetUInt32();
+ _exclusiveGroup = fields[6].GetInt32();
+ _rewardMailTemplateId = fields[7].GetUInt32();
+ _rewardMailDelay = fields[8].GetUInt32();
+ _requiredSkillId = fields[9].GetUInt16();
+ _requiredSkillPoints = fields[10].GetUInt16();
+ _requiredMinRepFaction = fields[11].GetUInt16();
+ _requiredMaxRepFaction = fields[12].GetUInt16();
+ _requiredMinRepValue = fields[13].GetInt32();
+ _requiredMaxRepValue = fields[14].GetInt32();
+ _sourceItemIdCount = fields[15].GetUInt8();
+ _specialFlags = fields[16].GetUInt8();
+ _scriptId = sObjectMgr->GetScriptId(fields[17].GetString());
+
+ if (_specialFlags & QUEST_SPECIAL_FLAGS_AUTO_ACCEPT)
+ _flags |= QUEST_FLAGS_AUTO_ACCEPT;
+}
+
+void Quest::LoadQuestMailSender(Field* fields)
+{
+ _rewardMailSenderEntry = fields[1].GetUInt32();
}
void Quest::LoadQuestObjective(Field* fields)
{
QuestObjective obj;
- obj.ID = fields[0].GetUInt32();
- obj.QuestID = fields[1].GetUInt32();
+ obj.QuestID = fields[0].GetUInt32();
+ obj.ID = fields[1].GetUInt32();
obj.Type = fields[2].GetUInt8();
obj.StorageIndex = fields[3].GetInt8();
obj.ObjectID = fields[4].GetInt32();
@@ -252,7 +241,7 @@ void Quest::LoadQuestObjectiveVisualEffect(Field* fields)
{
uint8 effectIndex = fields[3].GetUInt8();
if (effectIndex >= obj.VisualEffects.size())
- obj.VisualEffects.resize(effectIndex+1, 0);
+ obj.VisualEffects.resize(effectIndex + 1, 0);
obj.VisualEffects[effectIndex] = fields[4].GetInt32();
break;
@@ -266,20 +255,20 @@ uint32 Quest::XPValue(Player const* player) const
{
uint32 questLevel = player->GetQuestLevel(this);
QuestXPEntry const* questXp = sQuestXPStore.LookupEntry(questLevel);
- if (!questXp || RewardXPDifficulty >= 10)
+ if (!questXp || _rewardXPDifficulty >= 10)
return 0;
float multiplier = 1.0f;
if (questLevel != player->getLevel())
multiplier = sXpGameTable.GetRow(std::min<int32>(player->getLevel(), questLevel))->Divisor / sXpGameTable.GetRow(player->getLevel())->Divisor;
- int32 diffFactor = 2 * (questLevel + (Level == -1 ? 0 : 5) - player->getLevel()) + 10;
+ int32 diffFactor = 2 * (questLevel + (_level == -1 ? 0 : 5) - player->getLevel()) + 10;
if (diffFactor < 1)
diffFactor = 1;
else if (diffFactor > 10)
diffFactor = 10;
- uint32 xp = diffFactor * questXp->Difficulty[RewardXPDifficulty] * RewardXPMultiplier / 10 * multiplier;
+ uint32 xp = diffFactor * questXp->Difficulty[_rewardXPDifficulty] * _rewardXPMultiplier / 10 * multiplier;
if (xp <= 100)
xp = 5 * ((xp + 2) / 5);
else if (xp <= 500)
@@ -354,7 +343,7 @@ uint32 Quest::GetRewMoneyMaxLevel() const
return 0;
// Else, return the rewarded copper sum modified by the rate
- return uint32(RewardBonusMoney * sWorld->getRate(RATE_MONEY_MAX_LEVEL_QUEST));
+ return uint32(_rewardBonusMoney * sWorld->getRate(RATE_MONEY_MAX_LEVEL_QUEST));
}
bool Quest::IsAutoAccept() const
@@ -364,12 +353,12 @@ bool Quest::IsAutoAccept() const
bool Quest::IsAutoComplete() const
{
- return !sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_COMPLETE) && Type == QUEST_TYPE_AUTOCOMPLETE;
+ return !sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_COMPLETE) && _type == QUEST_TYPE_AUTOCOMPLETE;
}
bool Quest::IsRaidQuest(Difficulty difficulty) const
{
- switch (QuestInfoID)
+ switch (_questInfoID)
{
case QUEST_INFO_RAID:
return true;
@@ -381,7 +370,7 @@ bool Quest::IsRaidQuest(Difficulty difficulty) const
break;
}
- if ((Flags & QUEST_FLAGS_RAID) != 0)
+ if ((_flags & QUEST_FLAGS_RAID) != 0)
return true;
return false;
@@ -481,7 +470,7 @@ WorldPacket Quest::BuildQueryData(LocaleConstant loc) const
response.Info.RewardXPMultiplier = GetXPMultiplier();
if (!HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
- response.Info.RewardMoney = RewardMoney;
+ response.Info.RewardMoney = GetRewMoney();
response.Info.RewardMoneyDifficulty = GetRewMoneyDifficulty();
response.Info.RewardMoneyMultiplier = GetMoneyMultiplier();
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index aefd9509f6b..2023a4de8e8 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -351,113 +351,138 @@ class TC_GAME_API Quest
void LoadQuestRequestItems(Field* fields);
void LoadQuestOfferReward(Field* fields);
void LoadQuestTemplateAddon(Field* fields);
+ void LoadQuestMailSender(Field* fields);
void LoadQuestObjective(Field* fields);
void LoadQuestObjectiveVisualEffect(Field* fields);
uint32 XPValue(Player const* player) const;
uint32 MoneyValue(Player const* player) const;
- bool HasFlag(QuestFlags flag) const { return (Flags & uint32(flag)) != 0; }
- bool HasFlagEx(QuestFlagsEx flag) const { return (FlagsEx & uint32(flag)) != 0; }
- bool HasFlagEx2(QuestFlagsEx2 flag) const { return (FlagsEx2 & uint32(flag)) != 0; }
+ bool HasFlag(QuestFlags flag) const { return (_flags & uint32(flag)) != 0; }
+ bool HasFlagEx(QuestFlagsEx flag) const { return (_flagsEx & uint32(flag)) != 0; }
+ bool HasFlagEx2(QuestFlagsEx2 flag) const { return (_flagsEx2 & uint32(flag)) != 0; }
- bool HasSpecialFlag(uint32 flag) const { return (SpecialFlags & flag) != 0; }
- void SetSpecialFlag(uint32 flag) { SpecialFlags |= flag; }
+ bool HasSpecialFlag(uint32 flag) const { return (_specialFlags & flag) != 0; }
+ void SetSpecialFlag(uint32 flag) { _specialFlags |= flag; }
// table data accessors:
- uint32 GetQuestId() const { return ID; }
- uint32 GetQuestType() const { return Type; }
- uint32 GetQuestPackageID() const { return PackageID; }
- int32 GetZoneOrSort() const { return QuestSortID; }
- int32 GetMinLevel() const { return MinLevel; }
- uint32 GetMaxLevel() const { return MaxLevel; }
- int32 GetQuestLevel() const { return Level; }
- int32 GetQuestScalingFactionGroup() const { return ScalingFactionGroup; }
- int32 GetQuestMaxScalingLevel() const { return MaxScalingLevel; }
- uint32 GetQuestInfoID() const { return QuestInfoID; }
- uint32 GetAllowableClasses() const { return AllowableClasses; }
- Trinity::RaceMask<uint64> GetAllowableRaces() const { return AllowableRaces; }
- uint32 GetRequiredSkill() const { return RequiredSkillId; }
- uint32 GetRequiredSkillValue() const { return RequiredSkillPoints; }
- uint32 GetRequiredMinRepFaction() const { return RequiredMinRepFaction; }
- int32 GetRequiredMinRepValue() const { return RequiredMinRepValue; }
- uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; }
- int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; }
- uint32 GetSuggestedPlayers() const { return SuggestedPlayers; }
- uint32 GetLimitTime() const { return LimitTime; }
- int32 GetPrevQuestId() const { return PrevQuestID; }
- int32 GetNextQuestId() const { return NextQuestID; }
- int32 GetExclusiveGroup() const { return ExclusiveGroup; }
- uint32 GetNextQuestInChain() const { return NextQuestInChain; }
- int32 GetRewArenaPoints() const {return RewardArenaPoints; }
- uint32 GetXPDifficulty() const { return RewardXPDifficulty; }
- float GetXPMultiplier() const { return RewardXPMultiplier; }
- float GetMoneyMultiplier() const { return RewardMoneyMultiplier; }
- uint32 GetSrcItemId() const { return SourceItemId; }
- uint32 GetSrcItemCount() const { return SourceItemIdCount; }
- uint32 GetSrcSpell() const { return SourceSpellID; }
- std::string const& GetLogTitle() const { return LogTitle; }
- std::string const& GetLogDescription() const { return LogDescription; }
- std::string const& GetQuestDescription() const { return QuestDescription; }
- std::string const& GetAreaDescription() const { return AreaDescription; }
- std::string const& GetOfferRewardText() const { return OfferRewardText; }
- std::string const& GetRequestItemsText() const { return RequestItemsText; }
- std::string const& GetQuestCompletionLog() const { return QuestCompletionLog; }
- std::string const& GetPortraitGiverText() const { return PortraitGiverText; }
- std::string const& GetPortraitGiverName() const { return PortraitGiverName; }
- std::string const& GetPortraitTurnInText() const { return PortraitTurnInText; }
- std::string const& GetPortraitTurnInName() const { return PortraitTurnInName; }
+ uint32 GetQuestId() const { return _id; }
+ uint32 GetQuestType() const { return _type; }
+ uint32 GetQuestPackageID() const { return _packageID; }
+ int32 GetZoneOrSort() const { return _questSortID; }
+ int32 GetMinLevel() const { return _minLevel; }
+ uint32 GetMaxLevel() const { return _maxLevel; }
+ int32 GetQuestLevel() const { return _level; }
+ int32 GetQuestScalingFactionGroup() const { return _scalingFactionGroup; }
+ int32 GetQuestMaxScalingLevel() const { return _maxScalingLevel; }
+ uint32 GetQuestInfoID() const { return _questInfoID; }
+ uint32 GetAllowableClasses() const { return _allowableClasses; }
+ Trinity::RaceMask<uint64> GetAllowableRaces() const { return _allowableRaces; }
+ uint32 GetRequiredSkill() const { return _requiredSkillId; }
+ uint32 GetRequiredSkillValue() const { return _requiredSkillPoints; }
+ uint32 GetRequiredMinRepFaction() const { return _requiredMinRepFaction; }
+ int32 GetRequiredMinRepValue() const { return _requiredMinRepValue; }
+ uint32 GetRequiredMaxRepFaction() const { return _requiredMaxRepFaction; }
+ int32 GetRequiredMaxRepValue() const { return _requiredMaxRepValue; }
+ uint32 GetSuggestedPlayers() const { return _suggestedPlayers; }
+ uint32 GetLimitTime() const { return _limitTime; }
+ int32 GetPrevQuestId() const { return _prevQuestID; }
+ uint32 GetNextQuestId() const { return _nextQuestID; }
+ int32 GetExclusiveGroup() const { return _exclusiveGroup; }
+ uint32 GetNextQuestInChain() const { return _nextQuestInChain; }
+ int32 GetRewArenaPoints() const {return _rewardArenaPoints; }
+ uint32 GetXPDifficulty() const { return _rewardXPDifficulty; }
+ float GetXPMultiplier() const { return _rewardXPMultiplier; }
+ float GetMoneyMultiplier() const { return _rewardMoneyMultiplier; }
+ uint32 GetSrcItemId() const { return _sourceItemId; }
+ uint32 GetSrcItemCount() const { return _sourceItemIdCount; }
+ uint32 GetSrcSpell() const { return _sourceSpellID; }
+ std::string const& GetLogTitle() const { return _logTitle; }
+ std::string const& GetLogDescription() const { return _logDescription; }
+ std::string const& GetQuestDescription() const { return _questDescription; }
+ std::string const& GetAreaDescription() const { return _areaDescription; }
+ std::string const& GetOfferRewardText() const { return _offerRewardText; }
+ std::string const& GetRequestItemsText() const { return _requestItemsText; }
+ std::string const& GetQuestCompletionLog() const { return _questCompletionLog; }
+ std::string const& GetPortraitGiverText() const { return _portraitGiverText; }
+ std::string const& GetPortraitGiverName() const { return _portraitGiverName; }
+ std::string const& GetPortraitTurnInText() const { return _portraitTurnInText; }
+ std::string const& GetPortraitTurnInName() const { return _portraitTurnInName; }
QuestObjectives const& GetObjectives() const { return Objectives; }
- uint32 GetRewMoneyDifficulty() const { return RewardMoneyDifficulty; }
- uint32 GetRewHonor() const { return RewardHonor; }
- uint32 GetRewKillHonor() const { return RewardKillHonor; }
- uint32 GetArtifactXPDifficulty() const { return RewardArtifactXPDifficulty; }
- float GetArtifactXPMultiplier() const { return RewardArtifactXPMultiplier; }
- uint32 GetArtifactCategoryId() const { return RewardArtifactCategoryID; }
+ uint32 GetRewMoney() const { return _rewardMoney; }
+ uint32 GetRewMoneyDifficulty() const { return _rewardMoneyDifficulty; }
+ uint32 GetRewHonor() const { return _rewardHonor; }
+ uint32 GetRewKillHonor() const { return _rewardKillHonor; }
+ uint32 GetArtifactXPDifficulty() const { return _rewardArtifactXPDifficulty; }
+ float GetArtifactXPMultiplier() const { return _rewardArtifactXPMultiplier; }
+ uint32 GetArtifactCategoryId() const { return _rewardArtifactCategoryID; }
uint32 GetRewMoneyMaxLevel() const; // use in XP calculation at client
- uint32 GetRewSpell() const { return RewardSpell; }
- uint32 GetRewMailTemplateId() const { return RewardMailTemplateId; }
- uint32 GetRewMailDelaySecs() const { return RewardMailDelay; }
- uint32 GetRewMailSenderEntry() const { return RewardMailSenderEntry; }
- uint32 GetRewTitle() const { return RewardTitleId; }
- uint32 GetPOIContinent() const { return POIContinent; }
- float GetPOIx() const { return POIx; }
- float GetPOIy() const { return POIy; }
- uint32 GetPOIPriority() const { return POIPriority; }
- uint32 GetSoundAccept() const { return SoundAccept; }
- uint32 GetSoundTurnIn() const { return SoundTurnIn; }
- uint32 GetIncompleteEmote() const { return EmoteOnIncomplete; }
- uint32 GetCompleteEmote() const { return EmoteOnComplete; }
- bool IsRepeatable() const { return SpecialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE; }
+ uint32 GetRewSpell() const { return _rewardSpell; }
+ uint32 GetRewMailTemplateId() const { return _rewardMailTemplateId; }
+ uint32 GetRewMailDelaySecs() const { return _rewardMailDelay; }
+ uint32 GetRewMailSenderEntry() const { return _rewardMailSenderEntry; }
+ uint32 GetRewTitle() const { return _rewardTitleId; }
+ uint32 GetPOIContinent() const { return _poiContinent; }
+ float GetPOIx() const { return _poix; }
+ float GetPOIy() const { return _poiy; }
+ uint32 GetPOIPriority() const { return _poiPriority; }
+ uint32 GetSoundAccept() const { return _soundAccept; }
+ uint32 GetSoundTurnIn() const { return _soundTurnIn; }
+ uint32 GetIncompleteEmote() const { return _emoteOnIncomplete; }
+ uint32 GetCompleteEmote() const { return _emoteOnComplete; }
+ uint32 GetIncompleteEmoteDelay() const { return _emoteOnIncompleteDelay; }
+ uint32 GetCompleteEmoteDelay() const { return _emoteOnCompleteDelay; }
+ bool IsRepeatable() const { return _specialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE; }
bool IsAutoAccept() const;
bool IsAutoComplete() const;
- uint32 GetFlags() const { return Flags; }
- uint32 GetFlagsEx() const { return FlagsEx; }
- uint32 GetFlagsEx2() const { return FlagsEx2; }
- uint32 GetSpecialFlags() const { return SpecialFlags; }
- uint32 GetScriptId() const { return ScriptId; }
- uint32 GetAreaGroupID() const { return AreaGroupID; }
- uint32 GetRewardSkillId() const { return RewardSkillId; }
- uint32 GetRewardSkillPoints() const { return RewardSkillPoints; }
- uint32 GetRewardReputationMask() const { return RewardReputationMask; }
- int32 GetTreasurePickerId() const { return TreasurePickerID; }
- int32 GetExpansion() const { return Expansion; }
- int32 GetManagedWorldStateId() const { return ManagedWorldStateID; }
- int32 GetQuestSessionBonus() const { return QuestSessionBonus; }
- uint32 GetQuestGiverPortrait() const { return QuestGiverPortrait; }
- int32 GetQuestGiverPortraitMount() const { return QuestGiverPortraitMount; }
- uint32 GetQuestTurnInPortrait() const { return QuestTurnInPortrait; }
- bool IsDaily() const { return (Flags & QUEST_FLAGS_DAILY) != 0; }
- bool IsWeekly() const { return (Flags & QUEST_FLAGS_WEEKLY) != 0; }
- bool IsMonthly() const { return (SpecialFlags & QUEST_SPECIAL_FLAGS_MONTHLY) != 0; }
- bool IsSeasonal() const { return (QuestSortID == -QUEST_SORT_SEASONAL || QuestSortID == -QUEST_SORT_SPECIAL || QuestSortID == -QUEST_SORT_LUNAR_FESTIVAL || QuestSortID == -QUEST_SORT_MIDSUMMER || QuestSortID == -QUEST_SORT_BREWFEST || QuestSortID == -QUEST_SORT_LOVE_IS_IN_THE_AIR || QuestSortID == -QUEST_SORT_NOBLEGARDEN) && !IsRepeatable(); }
- bool IsDailyOrWeekly() const { return (Flags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY)) != 0; }
+ uint32 GetFlags() const { return _flags; }
+ uint32 GetFlagsEx() const { return _flagsEx; }
+ uint32 GetFlagsEx2() const { return _flagsEx2; }
+ uint32 GetSpecialFlags() const { return _specialFlags; }
+ uint32 GetScriptId() const { return _scriptId; }
+ uint32 GetAreaGroupID() const { return _areaGroupID; }
+ uint32 GetRewardSkillId() const { return _rewardSkillId; }
+ uint32 GetRewardSkillPoints() const { return _rewardSkillPoints; }
+ uint32 GetRewardReputationMask() const { return _rewardReputationMask; }
+ int32 GetTreasurePickerId() const { return _treasurePickerID; }
+ int32 GetExpansion() const { return _expansion; }
+ int32 GetManagedWorldStateId() const { return _managedWorldStateID; }
+ int32 GetQuestSessionBonus() const { return _questSessionBonus; }
+ uint32 GetQuestGiverPortrait() const { return _questGiverPortrait; }
+ int32 GetQuestGiverPortraitMount() const { return _questGiverPortraitMount; }
+ uint32 GetQuestTurnInPortrait() const { return _questTurnInPortrait; }
+ bool IsDaily() const { return (_flags & QUEST_FLAGS_DAILY) != 0; }
+ bool IsWeekly() const { return (_flags & QUEST_FLAGS_WEEKLY) != 0; }
+ bool IsMonthly() const { return (_specialFlags & QUEST_SPECIAL_FLAGS_MONTHLY) != 0; }
+ bool IsSeasonal() const { return (_questSortID == -QUEST_SORT_SEASONAL || _questSortID == -QUEST_SORT_SPECIAL || _questSortID == -QUEST_SORT_LUNAR_FESTIVAL || _questSortID == -QUEST_SORT_MIDSUMMER || _questSortID == -QUEST_SORT_BREWFEST || _questSortID == -QUEST_SORT_LOVE_IS_IN_THE_AIR || _questSortID == -QUEST_SORT_NOBLEGARDEN) && !IsRepeatable(); }
+ bool IsDailyOrWeekly() const { return (_flags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY)) != 0; }
bool IsRaidQuest(Difficulty difficulty) const;
bool IsAllowedInRaid(Difficulty difficulty) const;
- bool IsDFQuest() const { return (SpecialFlags & QUEST_SPECIAL_FLAGS_DF_QUEST) != 0; }
+ bool IsDFQuest() const { return (_specialFlags & QUEST_SPECIAL_FLAGS_DF_QUEST) != 0; }
uint32 CalculateHonorGain(uint8 level) const;
bool CanIncreaseRewardedQuestCounters() const;
+ // multiple values
+ uint32 RewardDisplaySpell[QUEST_REWARD_DISPLAY_SPELL_COUNT] = { };
+ uint32 RewardItemId[QUEST_REWARD_ITEM_COUNT] = { };
+ uint32 RewardItemCount[QUEST_REWARD_ITEM_COUNT] = { };
+ uint32 ItemDrop[QUEST_ITEM_DROP_COUNT] = { };
+ uint32 ItemDropQuantity[QUEST_ITEM_DROP_COUNT] = { };
+ uint32 RewardChoiceItemId[QUEST_REWARD_CHOICES_COUNT] = { };
+ uint32 RewardChoiceItemCount[QUEST_REWARD_CHOICES_COUNT] = { };
+ uint32 RewardChoiceItemDisplayId[QUEST_REWARD_CHOICES_COUNT] = { };
+ uint32 RewardFactionId[QUEST_REWARD_REPUTATIONS_COUNT] = { };
+ int32 RewardFactionValue[QUEST_REWARD_REPUTATIONS_COUNT] = { };
+ int32 RewardFactionOverride[QUEST_REWARD_REPUTATIONS_COUNT] = { };
+ uint32 RewardFactionCapIn[QUEST_REWARD_REPUTATIONS_COUNT] = { };
+ uint32 RewardCurrencyId[QUEST_REWARD_CURRENCY_COUNT] = { };
+ uint32 RewardCurrencyCount[QUEST_REWARD_CURRENCY_COUNT] = { };
+ QuestObjectives Objectives = { };
+ uint32 DetailsEmote[QUEST_EMOTE_COUNT] = { };
+ uint32 DetailsEmoteDelay[QUEST_EMOTE_COUNT] = { };
+ uint32 OfferRewardEmote[QUEST_EMOTE_COUNT] = { };
+ uint32 OfferRewardEmoteDelay[QUEST_EMOTE_COUNT] = { };
+
uint32 GetRewChoiceItemsCount() const { return _rewChoiceItemsCount; }
uint32 GetRewItemsCount() const { return _rewItemsCount; }
uint32 GetRewCurrencyCount() const { return _rewCurrencyCount; }
@@ -471,141 +496,111 @@ class TC_GAME_API Quest
void BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player* player) const;
- typedef std::vector<int32> PrevQuests;
- PrevQuests prevQuests;
- typedef std::vector<uint32> PrevChainQuests;
- PrevChainQuests prevChainQuests;
+ std::vector<uint32> DependentPreviousQuests;
+ std::vector<uint32> PrevChainQuests;
WorldPacket QueryData[TOTAL_LOCALES];
private:
- uint32 _rewChoiceItemsCount;
- uint32 _rewItemsCount;
- uint16 _eventIdForQuest;
- uint32 _rewCurrencyCount;
+ uint32 _rewChoiceItemsCount = 0;
+ uint32 _rewItemsCount = 0;
+ uint16 _eventIdForQuest = 0;
+ uint32 _rewCurrencyCount = 0;
- public:
// wdb data (quest query response)
- uint32 ID;
- uint32 Type;
- int32 Level;
- int32 ScalingFactionGroup;
- int32 MaxScalingLevel;
- uint32 PackageID;
- int32 MinLevel;
- int32 QuestSortID;
- uint32 QuestInfoID;
- uint32 SuggestedPlayers;
- uint32 NextQuestInChain;
- uint32 RewardXPDifficulty;
- float RewardXPMultiplier;
- int32 RewardMoney;
- uint32 RewardMoneyDifficulty;
- float RewardMoneyMultiplier;
- uint32 RewardBonusMoney;
- uint32 RewardDisplaySpell[QUEST_REWARD_DISPLAY_SPELL_COUNT];
- uint32 RewardSpell;
- uint32 RewardHonor;
- uint32 RewardKillHonor;
- uint32 RewardArtifactXPDifficulty;
- float RewardArtifactXPMultiplier;
- uint32 RewardArtifactCategoryID;
- uint32 SourceItemId;
- uint32 Flags;
- uint32 FlagsEx;
- uint32 FlagsEx2;
- uint32 RewardItemId[QUEST_REWARD_ITEM_COUNT];
- uint32 RewardItemCount[QUEST_REWARD_ITEM_COUNT];
- uint32 ItemDrop[QUEST_ITEM_DROP_COUNT];
- uint32 ItemDropQuantity[QUEST_ITEM_DROP_COUNT];
- uint32 RewardChoiceItemId[QUEST_REWARD_CHOICES_COUNT];
- uint32 RewardChoiceItemCount[QUEST_REWARD_CHOICES_COUNT];
- uint32 RewardChoiceItemDisplayId[QUEST_REWARD_CHOICES_COUNT];
- uint32 POIContinent;
- float POIx;
- float POIy;
- uint32 POIPriority;
- uint32 RewardTitleId;
- int32 RewardArenaPoints;
- uint32 RewardSkillId;
- uint32 RewardSkillPoints;
- uint32 QuestGiverPortrait;
- int32 QuestGiverPortraitMount;
- uint32 QuestTurnInPortrait;
- uint32 RewardFactionId[QUEST_REWARD_REPUTATIONS_COUNT];
- int32 RewardFactionValue[QUEST_REWARD_REPUTATIONS_COUNT];
- int32 RewardFactionOverride[QUEST_REWARD_REPUTATIONS_COUNT];
- uint32 RewardFactionCapIn[QUEST_REWARD_REPUTATIONS_COUNT];
- uint32 RewardReputationMask;
- uint32 RewardCurrencyId[QUEST_REWARD_CURRENCY_COUNT];
- uint32 RewardCurrencyCount[QUEST_REWARD_CURRENCY_COUNT];
- uint32 SoundAccept;
- uint32 SoundTurnIn;
- uint32 AreaGroupID;
- uint32 LimitTime;
- Trinity::RaceMask<uint64> AllowableRaces;
- int32 TreasurePickerID;
- int32 Expansion;
- int32 ManagedWorldStateID;
- int32 QuestSessionBonus;
- QuestObjectives Objectives;
- std::string LogTitle;
- std::string LogDescription;
- std::string QuestDescription;
- std::string AreaDescription;
- std::string PortraitGiverText;
- std::string PortraitGiverName;
- std::string PortraitTurnInText;
- std::string PortraitTurnInName;
- std::string QuestCompletionLog;
-
- protected:
-
- // quest_detais table
- uint32 DetailsEmote[QUEST_EMOTE_COUNT] = { };
- uint32 DetailsEmoteDelay[QUEST_EMOTE_COUNT] = { };
+ uint32 _id = 0;
+ uint32 _type = 0;
+ int32 _level = 0;
+ int32 _scalingFactionGroup = 0;
+ int32 _maxScalingLevel = 0;
+ uint32 _packageID = 0;
+ int32 _minLevel = 0;
+ int32 _questSortID = 0;
+ uint32 _questInfoID = 0;
+ uint32 _suggestedPlayers = 0;
+ uint32 _nextQuestInChain = 0;
+ uint32 _rewardXPDifficulty = 0;
+ float _rewardXPMultiplier = 0.f;
+ int32 _rewardMoney = 0;
+ uint32 _rewardMoneyDifficulty = 0;
+ float _rewardMoneyMultiplier = 0.f;
+ uint32 _rewardBonusMoney = 0;
+ uint32 _rewardSpell = 0;
+ uint32 _rewardHonor = 0;
+ uint32 _rewardKillHonor = 0;
+ uint32 _rewardArtifactXPDifficulty = 0;
+ float _rewardArtifactXPMultiplier = 0.f;
+ uint32 _rewardArtifactCategoryID = 0;
+ uint32 _sourceItemId = 0;
+ uint32 _flags = 0;
+ uint32 _flagsEx = 0;
+ uint32 _flagsEx2 = 0;
+ uint32 _poiContinent = 0;
+ float _poix = 0.f;
+ float _poiy = 0.f;
+ uint32 _poiPriority = 0;
+ uint32 _rewardTitleId = 0;
+ int32 _rewardArenaPoints = 0;
+ uint32 _rewardSkillId = 0;
+ uint32 _rewardSkillPoints = 0;
+ uint32 _questGiverPortrait = 0;
+ int32 _questGiverPortraitMount = 0;
+ uint32 _questTurnInPortrait = 0;
+ uint32 _rewardReputationMask;
+ uint32 _soundAccept = 0;
+ uint32 _soundTurnIn = 0;
+ uint32 _areaGroupID = 0;
+ uint32 _limitTime = 0;
+ Trinity::RaceMask<uint64> _allowableRaces;
+ int32 _treasurePickerID = 0;
+ int32 _expansion = 0;
+ int32 _managedWorldStateID = 0;
+ int32 _questSessionBonus = 0;
+ std::string _logTitle;
+ std::string _logDescription;
+ std::string _questDescription;
+ std::string _areaDescription;
+ std::string _portraitGiverText;
+ std::string _portraitGiverName;
+ std::string _portraitTurnInText;
+ std::string _portraitTurnInName;
+ std::string _questCompletionLog;
// quest_request_items table
- uint32 EmoteOnComplete = 0;
- uint32 EmoteOnIncomplete = 0;
- uint32 EmoteOnCompleteDelay = 0;
- uint32 EmoteOnIncompleteDelay = 0;
- std::string RequestItemsText;
+ uint32 _emoteOnComplete = 0;
+ uint32 _emoteOnIncomplete = 0;
+ uint32 _emoteOnCompleteDelay = 0;
+ uint32 _emoteOnIncompleteDelay = 0;
+ std::string _requestItemsText;
// quest_offer_reward table
- uint32 OfferRewardEmote[QUEST_EMOTE_COUNT] = { };
- uint32 OfferRewardEmoteDelay[QUEST_EMOTE_COUNT] = { };
- std::string OfferRewardText;
+ std::string _offerRewardText;
// quest_template_addon table (custom data)
- uint32 MaxLevel = 0;
- uint32 AllowableClasses = 0;
- uint32 SourceSpellID = 0;
- int32 PrevQuestID = 0;
- int32 NextQuestID = 0;
- int32 ExclusiveGroup = 0;
- uint32 RewardMailTemplateId = 0;
- uint32 RewardMailDelay = 0;
- uint32 RequiredSkillId = 0;
- uint32 RequiredSkillPoints = 0;
- uint32 RequiredMinRepFaction = 0;
- int32 RequiredMinRepValue = 0;
- uint32 RequiredMaxRepFaction = 0;
- int32 RequiredMaxRepValue = 0;
- uint32 SourceItemIdCount = 0;
- uint32 RewardMailSenderEntry = 0;
- uint32 SpecialFlags = 0; // custom flags, not sniffed/WDB
- uint32 ScriptId = 0;
+ uint32 _maxLevel = 0;
+ uint32 _allowableClasses = 0;
+ uint32 _sourceSpellID = 0;
+ int32 _prevQuestID = 0;
+ uint32 _nextQuestID = 0;
+ int32 _exclusiveGroup = 0;
+ uint32 _rewardMailTemplateId = 0;
+ uint32 _rewardMailDelay = 0;
+ uint32 _requiredSkillId = 0;
+ uint32 _requiredSkillPoints = 0;
+ uint32 _requiredMinRepFaction = 0;
+ int32 _requiredMinRepValue = 0;
+ uint32 _requiredMaxRepFaction = 0;
+ int32 _requiredMaxRepValue = 0;
+ uint32 _sourceItemIdCount = 0;
+ uint32 _rewardMailSenderEntry = 0;
+ uint32 _specialFlags = 0; // custom flags, not sniffed/WDB
+ uint32 _scriptId = 0;
};
struct QuestStatusData
{
- QuestStatusData(): Status(QUEST_STATUS_NONE), Timer(0)
- {
- }
-
- QuestStatus Status;
- uint32 Timer;
- std::vector<int32> ObjectiveData;
+ QuestStatus Status = QUEST_STATUS_NONE;
+ uint32 Timer = 0;
+ std::vector<int32> ObjectiveData = { };
};
#endif
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 14db03c5b92..566ecfd9df8 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -215,7 +215,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleModMechanicImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
&AuraEffect::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
&AuraEffect::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
- &AuraEffect::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
+ &AuraEffect::HandleShieldBlockValuePercent, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
&AuraEffect::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
&AuraEffect::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
&AuraEffect::HandleUnused, //153 Unused (4.3.4) old SPELL_AURA_SPLIT_DAMAGE_FLAT
@@ -347,7 +347,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNoImmediateEffect, //279 SPELL_AURA_INITIALIZE_IMAGES
&AuraEffect::HandleUnused, //280 unused (4.3.4) old SPELL_AURA_MOD_ARMOR_PENETRATION_PCT
&AuraEffect::HandleNULL, //281 SPELL_AURA_MOD_GUILD_REPUTATION_GAIN_PCT
- &AuraEffect::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
+ &AuraEffect::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_MOD_BASE_HEALTH_PCT
&AuraEffect::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
&AuraEffect::HandleAuraLinked, //284 SPELL_AURA_LINKED
&AuraEffect::HandleAuraLinked, //285 SPELL_AURA_LINKED_2
@@ -790,6 +790,9 @@ void AuraEffect::ChangeAmount(int32 newAmount, bool mark, bool onStackOrReapply)
for (AuraApplication* aurApp : effectApplications)
{
+ if (aurApp->GetRemoveMode() != AURA_REMOVE_NONE)
+ continue;
+
aurApp->GetTarget()->_RegisterAuraEffect(this, true);
HandleEffect(aurApp, handleMask, true);
}
@@ -2038,7 +2041,7 @@ void AuraEffect::HandleAuraModScale(AuraApplication const* aurApp, uint8 mode, b
Unit* target = aurApp->GetTarget();
float scale = target->GetObjectScale();
- ApplyPercentModFloatVar(scale, float(GetAmount()), apply);
+ scale += CalculatePct(1.0f, apply ? GetAmount() : -GetAmount());
target->SetObjectScale(scale);
}
@@ -2223,11 +2226,15 @@ void AuraEffect::HandleAuraModDisarm(AuraApplication const* aurApp, uint8 mode,
Player* player = target->ToPlayer();
if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
{
- uint8 attacktype = Player::GetAttackBySlot(slot, item->GetTemplate()->GetInventoryType());
+ WeaponAttackType const attackType = Player::GetAttackBySlot(slot, item->GetTemplate()->GetInventoryType());
player->ApplyItemDependentAuras(item, !apply);
- if (attacktype < MAX_ATTACK)
+ if (attackType != MAX_ATTACK)
+ {
player->_ApplyWeaponDamage(slot, item, !apply);
+ if (!apply) // apply case already handled on item dependent aura removal (if any)
+ player->UpdateWeaponDependentAuras(attackType);
+ }
}
}
@@ -2719,9 +2726,19 @@ void AuraEffect::HandleModThreat(AuraApplication const* aurApp, uint8 mode, bool
return;
Unit* target = aurApp->GetTarget();
- for (int8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
+ for (uint8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
+ {
if (GetMiscValue() & (1 << i))
- ApplyPercentModFloatVar(target->m_threatModifier[i], float(GetAmount()), apply);
+ {
+ if (apply)
+ AddPct(target->m_threatModifier[i], GetAmount());
+ else
+ {
+ float amount = target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_THREAT, 1 << i);
+ target->m_threatModifier[i] = amount;
+ }
+ }
+ }
}
void AuraEffect::HandleAuraModTotalThreat(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -3210,9 +3227,9 @@ void AuraEffect::HandleAuraModResistance(AuraApplication const* aurApp, uint8 mo
Unit* target = aurApp->GetTarget();
- for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
- if (GetMiscValue() & int32(1<<x))
- target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(GetAmount()), apply);
+ for (uint8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; ++x)
+ if (GetMiscValue() & (1 << x))
+ target->HandleStatFlatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(GetAmount()), apply);
}
void AuraEffect::HandleAuraModBaseResistancePCT(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -3227,36 +3244,50 @@ void AuraEffect::HandleAuraModBaseResistancePCT(AuraApplication const* aurApp, u
{
//pets only have base armor
if (target->IsPet() && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
- target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(GetAmount()), apply);
+ {
+ if (apply)
+ target->ApplyStatPctModifier(UNIT_MOD_ARMOR, BASE_PCT, float(GetAmount()));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_BASE_RESISTANCE_PCT, SPELL_SCHOOL_MASK_NORMAL);
+ target->SetStatPctModifier(UNIT_MOD_ARMOR, BASE_PCT, amount);
+ }
+ }
}
else
{
- for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
+ for (uint8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; ++x)
{
- if (GetMiscValue() & int32(1<<x))
- target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(GetAmount()), apply);
+ if (GetMiscValue() & (1 << x))
+ {
+ if (apply)
+ target->ApplyStatPctModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(GetAmount()));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_BASE_RESISTANCE_PCT, 1 << x);
+ target->SetStatPctModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, amount);
+ }
+ }
}
}
}
-void AuraEffect::HandleModResistancePercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
+void AuraEffect::HandleModResistancePercent(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
{
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
return;
Unit* target = aurApp->GetTarget();
- int32 spellGroupVal = target->GetHighestExclusiveSameEffectSpellGroupValue(this, SPELL_AURA_MOD_RESISTANCE_PCT);
- if (abs(spellGroupVal) >= abs(GetAmount()))
- return;
- for (int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
+ for (uint8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
{
- if (GetMiscValue() & int32(1<<i))
+ if (GetMiscValue() & (1 << i))
{
- if (spellGroupVal)
- target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, (float)spellGroupVal, !apply);
+ float amount = target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_RESISTANCE_PCT, 1 << i);
+ if (target->GetPctModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT) == amount)
+ continue;
- target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(GetAmount()), apply);
+ target->SetStatPctModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, amount);
}
}
}
@@ -3271,15 +3302,15 @@ void AuraEffect::HandleModBaseResistance(AuraApplication const* aurApp, uint8 mo
// only players have base stats
if (target->GetTypeId() != TYPEID_PLAYER)
{
- //only pets have base stats
+ //pets only have base armor
if (target->IsPet() && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
- target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatFlatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(GetAmount()), apply);
}
else
{
- for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
- if (GetMiscValue() & (1<<i))
- target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(GetAmount()), apply);
+ for (uint8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
+ if (GetMiscValue() & (1 << i))
+ target->HandleStatFlatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(GetAmount()), apply);
}
}
@@ -3323,22 +3354,21 @@ void AuraEffect::HandleAuraModStat(AuraApplication const* aurApp, uint8 mode, bo
if (abs(spellGroupVal) >= abs(GetAmount()))
return;
- for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
+ for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
{
// -1 or -2 is all stats (misc < -2 checked in function beginning)
if (GetMiscValue() < 0 || GetMiscValue() == i)
{
if (spellGroupVal)
{
- target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(spellGroupVal), !apply);
+ target->HandleStatFlatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(spellGroupVal), !apply);
if (target->GetTypeId() == TYPEID_PLAYER || target->IsPet())
- target->ApplyStatBuffMod(Stats(i), float(spellGroupVal), !apply);
+ target->UpdateStatBuffMod(Stats(i));
}
- //target->ApplyStatMod(Stats(i), m_amount, apply);
- target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatFlatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(GetAmount()), apply);
if (target->GetTypeId() == TYPEID_PLAYER || target->IsPet())
- target->ApplyStatBuffMod(Stats(i), (float)GetAmount(), apply);
+ target->UpdateStatBuffMod(Stats(i));
}
}
}
@@ -3363,7 +3393,20 @@ void AuraEffect::HandleModPercentStat(AuraApplication const* aurApp, uint8 mode,
for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
{
if (GetMiscValue() == i || GetMiscValue() == -1)
- target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_amount), apply);
+ {
+ if (apply)
+ target->ApplyStatPctModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_amount));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_PERCENT_STAT, [i](AuraEffect const* aurEff) -> bool
+ {
+ if (aurEff->GetMiscValue() == i || aurEff->GetMiscValue() == -1)
+ return true;
+ return false;
+ });
+ target->SetStatPctModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, amount);
+ }
+ }
}
}
@@ -3450,28 +3493,12 @@ void AuraEffect::HandleModHealingDonePct(AuraApplication const* aurApp, uint8 mo
player->UpdateHealingDonePercentMod();
}
-void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8 mode, bool apply) const
+void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
{
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
return;
Unit* target = aurApp->GetTarget();
- int32 spellGroupVal = target->GetHighestExclusiveSameEffectSpellGroupValue(this, SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, true, -1);
- if (abs(spellGroupVal) >= abs(GetAmount()))
- return;
-
- if (spellGroupVal)
- {
- for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
- {
- if (GetMiscValue() == i || GetMiscValue() == -1) // affect the same stats
- {
- target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(spellGroupVal), !apply);
- if (target->GetTypeId() == TYPEID_PLAYER || target->IsPet())
- target->ApplyStatPercentBuffMod(Stats(i), float(spellGroupVal), !apply);
- }
- }
- }
// save current health state
float healthPct = target->GetHealthPct();
@@ -3483,30 +3510,29 @@ void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8
if (target->getDeathState() == CORPSE)
zeroHealth = (target->GetHealth() == 0);
- for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
+ for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
{
if (GetMiscValueB() & 1 << i || !GetMiscValueB()) // 0 is also used for all stats
{
- int32 spellGroupVal2 = target->GetHighestExclusiveSameEffectSpellGroupValue(this, SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, true, i);
- if (abs(spellGroupVal2) >= abs(GetAmount()))
- continue;
-
- if (spellGroupVal2)
+ float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, [i](AuraEffect const* aurEff) -> bool
{
- target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(spellGroupVal2), !apply);
- if (target->GetTypeId() == TYPEID_PLAYER || target->IsPet())
- target->ApplyStatPercentBuffMod(Stats(i), float(spellGroupVal2), !apply);
- }
+ if (aurEff->GetMiscValueB() & 1 << i || !aurEff->GetMiscValueB())
+ return true;
+ return false;
+ });
- target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(GetAmount()), apply);
+ if (target->GetPctModifierValue(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT) == amount)
+ continue;
+
+ target->SetStatPctModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, amount);
if (target->GetTypeId() == TYPEID_PLAYER || target->IsPet())
- target->ApplyStatPercentBuffMod(Stats(i), float(GetAmount()), apply);
+ target->UpdateStatBuffMod(Stats(i));
}
}
- // recalculate current HP/MP after applying aura modifications (only for spells with SPELL_ATTR0_UNK4 0x00000010 flag)
+ // recalculate current HP/MP after applying aura modifications (only for spells with SPELL_ATTR0_ABILITY 0x00000010 flag)
// this check is total bullshit i think
- if (GetMiscValueB() & 1 << STAT_STAMINA && (m_spellInfo->HasAttribute(SPELL_ATTR0_ABILITY)))
+ if ((GetMiscValueB() & 1 << STAT_STAMINA || !GetMiscValueB()) && (m_spellInfo->HasAttribute(SPELL_ATTR0_ABILITY)))
target->SetHealth(std::max<uint32>(CalculatePct(target->GetMaxHealth(), healthPct), (zeroHealth ? 0 : 1)));
}
@@ -3567,8 +3593,8 @@ void AuraEffect::HandleModStatBonusPercent(AuraApplication const* aurApp, uint8
{
if (GetMiscValue() == i || GetMiscValue() == -1)
{
- target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT_EXCLUDE_CREATE, float(m_amount), apply);
- target->ApplyStatPercentBuffMod(Stats(i), float(m_amount), apply);
+ target->HandleStatFlatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT_EXCLUDE_CREATE, float(m_amount), apply);
+ target->UpdateStatBuffMod(Stats(i));
}
}
}
@@ -3623,7 +3649,7 @@ void AuraEffect::HandleAuraModMaxPower(AuraApplication const* aurApp, uint8 mode
Powers power = Powers(GetMiscValue());
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power);
- target->HandleStatModifier(unitMod, TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatFlatModifier(unitMod, TOTAL_VALUE, float(GetAmount()), apply);
}
/********************************/
@@ -3688,7 +3714,7 @@ void AuraEffect::HandleAuraModIncreaseHealth(AuraApplication const* aurApp, uint
if (apply)
{
- target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatFlatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
target->ModifyHealth(GetAmount());
}
else
@@ -3698,7 +3724,7 @@ void AuraEffect::HandleAuraModIncreaseHealth(AuraApplication const* aurApp, uint
int32 value = std::min<int32>(target->GetHealth() - 1, GetAmount());
target->ModifyHealth(-value);
}
- target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatFlatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
}
}
@@ -3711,7 +3737,7 @@ void AuraEffect::HandleAuraModIncreaseMaxHealth(AuraApplication const* aurApp, u
float percent = target->GetHealthPct();
- target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatFlatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
// refresh percentage
if (target->GetHealth() > 0)
@@ -3730,7 +3756,7 @@ void AuraEffect::HandleAuraModIncreaseEnergy(AuraApplication const* aurApp, uint
Powers powerType = Powers(GetMiscValue());
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
- target->HandleStatModifier(unitMod, TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatFlatModifier(unitMod, TOTAL_VALUE, float(GetAmount()), apply);
}
void AuraEffect::HandleAuraModIncreaseEnergyPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -3748,7 +3774,26 @@ void AuraEffect::HandleAuraModIncreaseEnergyPercent(AuraApplication const* aurAp
int32 oldMaxPower = target->GetMaxPower(powerType);
// Handle aura effect for max power
- target->HandleStatModifier(unitMod, TOTAL_PCT, float(GetAmount()), apply);
+ if (apply)
+ target->ApplyStatPctModifier(unitMod, TOTAL_PCT, float(GetAmount()));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT, [powerType](AuraEffect const* aurEff) -> bool
+ {
+ if (aurEff->GetMiscValue() == powerType)
+ return true;
+ return false;
+ });
+
+ amount *= target->GetTotalAuraMultiplier(SPELL_AURA_MOD_MAX_POWER_PCT, [powerType](AuraEffect const* aurEff) -> bool
+ {
+ if (aurEff->GetMiscValue() == powerType)
+ return true;
+ return false;
+ });
+
+ target->SetStatPctModifier(unitMod, TOTAL_PCT, amount);
+ }
// Calculate the current power change
int32 change = target->GetMaxPower(powerType) - oldMaxPower;
@@ -3765,11 +3810,17 @@ void AuraEffect::HandleAuraModIncreaseHealthPercent(AuraApplication const* aurAp
// Unit will keep hp% after MaxHealth being modified if unit is alive.
float percent = target->GetHealthPct();
- target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(GetAmount()), apply);
+ if (apply)
+ target->ApplyStatPctModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(GetAmount()));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT);
+ target->SetStatPctModifier(UNIT_MOD_HEALTH, TOTAL_PCT, amount);
+ }
if (target->GetHealth() > 0)
{
- uint32 newHealth = std::max<uint32>(target->CountPctFromMaxHealth(int32(percent)), 1);
+ uint32 newHealth = std::max<uint32>(CalculatePct(target->GetMaxHealth(), percent), 1);
target->SetHealth(newHealth);
}
}
@@ -3781,7 +3832,13 @@ void AuraEffect::HandleAuraIncreaseBaseHealthPercent(AuraApplication const* aurA
Unit* target = aurApp->GetTarget();
- target->HandleStatModifier(UNIT_MOD_HEALTH, BASE_PCT, float(GetAmount()), apply);
+ if (apply)
+ target->ApplyStatPctModifier(UNIT_MOD_HEALTH, BASE_PCT, float(GetAmount()));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_BASE_HEALTH_PCT);
+ target->SetStatPctModifier(UNIT_MOD_HEALTH, BASE_PCT, amount);
+ }
}
void AuraEffect::HandleAuraModIncreaseBaseManaPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -3789,7 +3846,15 @@ void AuraEffect::HandleAuraModIncreaseBaseManaPercent(AuraApplication const* aur
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
return;
- aurApp->GetTarget()->HandleStatModifier(UNIT_MOD_MANA, BASE_PCT, float(GetAmount()), apply);
+ Unit* target = aurApp->GetTarget();
+
+ if (apply)
+ target->ApplyStatPctModifier(UNIT_MOD_MANA, BASE_PCT, float(GetAmount()));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_BASE_MANA_PCT);
+ target->SetStatPctModifier(UNIT_MOD_MANA, BASE_PCT, amount);
+ }
}
void AuraEffect::HandleAuraModPowerDisplay(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -3845,7 +3910,26 @@ void AuraEffect::HandleAuraModMaxPowerPct(AuraApplication const* aurApp, uint8 m
int32 oldMaxPower = target->GetMaxPower(powerType);
// Handle aura effect for max power
- target->HandleStatModifier(unitMod, TOTAL_PCT, float(GetAmount()), apply);
+ if (apply)
+ target->ApplyStatPctModifier(unitMod, TOTAL_PCT, float(GetAmount()));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_MAX_POWER_PCT, [powerType](AuraEffect const* aurEff) -> bool
+ {
+ if (aurEff->GetMiscValue() == powerType)
+ return true;
+ return false;
+ });
+
+ amount *= target->GetTotalAuraMultiplier(SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT, [powerType](AuraEffect const* aurEff) -> bool
+ {
+ if (aurEff->GetMiscValue() == powerType)
+ return true;
+ return false;
+ });
+
+ target->SetStatPctModifier(unitMod, TOTAL_PCT, amount);
+ }
// Calculate the current power change
int32 change = target->GetMaxPower(powerType) - oldMaxPower;
@@ -3901,19 +3985,16 @@ void AuraEffect::HandleAuraModRegenInterrupt(AuraApplication const* aurApp, uint
HandleModManaRegen(aurApp, mode, apply);
}
-void AuraEffect::HandleAuraModWeaponCritPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
+void AuraEffect::HandleAuraModWeaponCritPercent(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
{
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
return;
Player* target = aurApp->GetTarget()->ToPlayer();
-
if (!target)
return;
- target->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float(GetAmount()), apply);
- target->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float(GetAmount()), apply);
- target->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float(GetAmount()), apply);
+ target->UpdateAllWeaponDependentCritAuras();
}
void AuraEffect::HandleModHitChance(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -3945,7 +4026,7 @@ void AuraEffect::HandleModSpellHitChance(AuraApplication const* aurApp, uint8 mo
if (target->GetTypeId() == TYPEID_PLAYER)
target->ToPlayer()->UpdateSpellHitChances();
else
- target->m_modSpellHitChance += (apply) ? GetAmount(): (-GetAmount());
+ target->m_modSpellHitChance += (apply) ? GetAmount() : (-GetAmount());
}
void AuraEffect::HandleModSpellCritChance(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -3958,7 +4039,7 @@ void AuraEffect::HandleModSpellCritChance(AuraApplication const* aurApp, uint8 m
if (target->GetTypeId() == TYPEID_PLAYER)
target->ToPlayer()->UpdateSpellCritChance();
else
- target->m_baseSpellCritChance += (apply) ? GetAmount():-GetAmount();
+ target->m_baseSpellCritChance += (apply) ? GetAmount() : -GetAmount();
}
void AuraEffect::HandleAuraModCritPct(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -3970,13 +4051,11 @@ void AuraEffect::HandleAuraModCritPct(AuraApplication const* aurApp, uint8 mode,
if (target->GetTypeId() != TYPEID_PLAYER)
{
- target->m_baseSpellCritChance += (apply) ? GetAmount():-GetAmount();
+ target->m_baseSpellCritChance += (apply) ? GetAmount() : -GetAmount();
return;
}
- target->ToPlayer()->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
- target->ToPlayer()->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
- target->ToPlayer()->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
+ target->ToPlayer()->UpdateAllWeaponDependentCritAuras();
// included in Player::UpdateSpellCritChance calculation
target->ToPlayer()->UpdateSpellCritChance();
@@ -4136,7 +4215,7 @@ void AuraEffect::HandleAuraModAttackPower(AuraApplication const* aurApp, uint8 m
Unit* target = aurApp->GetTarget();
- target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(GetAmount()), apply);
}
void AuraEffect::HandleAuraModRangedAttackPower(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -4149,7 +4228,7 @@ void AuraEffect::HandleAuraModRangedAttackPower(AuraApplication const* aurApp, u
if ((target->getClassMask() & CLASSMASK_WAND_USERS) != 0)
return;
- target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(GetAmount()), apply);
}
void AuraEffect::HandleAuraModAttackPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -4160,7 +4239,13 @@ void AuraEffect::HandleAuraModAttackPowerPercent(AuraApplication const* aurApp,
Unit* target = aurApp->GetTarget();
//UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
- target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(GetAmount()), apply);
+ if (apply)
+ target->ApplyStatPctModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(GetAmount()));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_ATTACK_POWER_PCT);
+ target->SetStatPctModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, amount);
+ }
}
void AuraEffect::HandleAuraModRangedAttackPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -4174,7 +4259,13 @@ void AuraEffect::HandleAuraModRangedAttackPowerPercent(AuraApplication const* au
return;
//UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
- target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(GetAmount()), apply);
+ if (apply)
+ target->ApplyStatPctModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(GetAmount()));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT);
+ target->SetStatPctModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, amount);
+ }
}
/********************************/
@@ -4188,11 +4279,7 @@ void AuraEffect::HandleModDamageDone(AuraApplication const* aurApp, uint8 mode,
Unit* target = aurApp->GetTarget();
if (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
- {
- target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(GetAmount()), apply);
- target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(GetAmount()), apply);
- target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(GetAmount()), apply);
- }
+ target->UpdateAllDamageDoneMods();
// Magic damage modifiers implemented in Unit::SpellBaseDamageBonusDone
// This information for client side use only
@@ -4212,53 +4299,40 @@ void AuraEffect::HandleModDamageDone(AuraApplication const* aurApp, uint8 mode,
}
}
-void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8 mode, bool apply) const
+void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
{
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
return;
Unit* target = aurApp->GetTarget();
- int32 spellGroupVal = target->GetHighestExclusiveSameEffectSpellGroupValue(this, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
- if (abs(spellGroupVal) >= abs(GetAmount()))
- return;
+ // also handles spell group stacks
if (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
- {
- if (spellGroupVal)
- {
- target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(spellGroupVal), !apply);
- target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(spellGroupVal), !apply);
- target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(spellGroupVal), !apply);
- }
-
- target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(GetAmount()), apply);
- target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetAmount()), apply);
- target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(GetAmount()), apply);
- }
+ target->UpdateAllDamagePctDoneMods();
if (Player* thisPlayer = target->ToPlayer())
{
- for (uint16 i = 0; i < MAX_SPELL_SCHOOL; ++i)
+ for (uint8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
{
if (GetMiscValue() & (1 << i))
{
- if (spellGroupVal)
- thisPlayer->ApplyModDamageDonePercent(SpellSchools(i), float(spellGroupVal), !apply);
-
- thisPlayer->ApplyModDamageDonePercent(SpellSchools(i), float(GetAmount()), apply);
+ // only aura type modifying PLAYER_FIELD_MOD_DAMAGE_DONE_PCT
+ float amount = thisPlayer->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, 1 << i);
+ thisPlayer->SetModDamageDonePercent(i, amount);
}
}
}
}
-void AuraEffect::HandleModOffhandDamagePercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
+void AuraEffect::HandleModOffhandDamagePercent(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
{
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
return;
Unit* target = aurApp->GetTarget();
- target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetAmount()), apply);
+ // also handles spell group stacks
+ target->UpdateDamagePctDoneMods(OFF_ATTACK);
}
void AuraEffect::HandleShieldBlockValue(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -4267,7 +4341,25 @@ void AuraEffect::HandleShieldBlockValue(AuraApplication const* aurApp, uint8 mod
return;
if (Player* player = aurApp->GetTarget()->ToPlayer())
- player->HandleBaseModValue(SHIELD_BLOCK_VALUE, PCT_MOD, float(GetAmount()), apply);
+ player->HandleBaseModFlatValue(SHIELD_BLOCK_VALUE, float(GetAmount()), apply);
+}
+
+void AuraEffect::HandleShieldBlockValuePercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Player* target = aurApp->GetTarget()->ToPlayer();
+ if (!target)
+ return;
+
+ if (apply)
+ target->ApplyBaseModPctValue(SHIELD_BLOCK_VALUE, float(GetAmount()));
+ else
+ {
+ float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT);
+ target->SetBaseModPctValue(SHIELD_BLOCK_VALUE, amount);
+ }
}
/********************************/
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 138ea474e31..7b74320bdef 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -290,6 +290,7 @@ class TC_GAME_API AuraEffect
void HandleModDamagePercentDone(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleModOffhandDamagePercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleShieldBlockValue(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleShieldBlockValuePercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// power cost
void HandleModPowerCostPCT(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleModPowerCost(AuraApplication const* aurApp, uint8 mode, bool apply) const;
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 074da315ad3..175959a15d4 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -2312,7 +2312,7 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* c
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
{
units.push_back(GetUnitOwner());
- Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS), false, true);
Trinity::UnitListSearcher<Trinity::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
break;
@@ -2320,14 +2320,14 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* c
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
{
units.push_back(GetUnitOwner());
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS), false, true);
Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
{
- Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo); // No GetCharmer in searcher
+ Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo, false, true); // No GetCharmer in searcher
Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
break;
@@ -2396,13 +2396,13 @@ void DynObjAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit*
if (effect->TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY
|| effect->TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY)
{
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS), false, true);
Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), units, u_check);
Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius);
}
else
{
- Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
+ Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius, nullptr, false, true);
Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetDynobjOwner(), units, u_check);
Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius);
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 8ef877e6881..779b0d0495c 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1245,6 +1245,11 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
if (!effect)
return;
float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod;
+
+ // if this is a proximity based aoe (Frost Nova, Psychic Scream, ...), include the caster's own combat reach
+ if (targetType.IsProximityBasedAoe())
+ radius += GetCaster()->GetCombatReach();
+
SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), effect->ImplicitTargetConditions);
CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
@@ -1300,7 +1305,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
float dist = frand(minDist, maxDist);
float x, y, z;
float angle = float(rand_norm()) * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
- m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dist, angle);
+ m_caster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS, dist, angle);
float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhaseShift(), x, y, z, true, 50.0f);
float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
@@ -1333,7 +1338,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
{
float dist = effect->CalcRadius(m_caster);
float angle = targetType.CalcDirectionAngle();
- float objSize = m_caster->GetObjectSize();
+ float objSize = m_caster->GetCombatReach();
switch (targetType.GetTarget())
{
@@ -1391,7 +1396,7 @@ void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplici
if (SpellEffectInfo const* effect = GetEffect(effIndex))
{
float angle = targetType.CalcDirectionAngle();
- float objSize = target->GetObjectSize();
+ float objSize = target->GetCombatReach();
float dist = effect->CalcRadius(m_caster);
if (dist < objSize)
dist = objSize;
@@ -1615,7 +1620,7 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTarge
}
}
- const float size = std::max((*itr)->GetObjectSize(), 1.0f);
+ const float size = std::max((*itr)->GetCombatReach(), 1.0f);
const float objDist2d = srcPos.GetExactDist2d(*itr);
const float dz = (*itr)->GetPositionZ() - srcPos.m_positionZ;
@@ -5300,13 +5305,13 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
return SPELL_FAILED_LINE_OF_SIGHT;
- float objSize = target->GetObjectSize();
+ float objSize = target->GetCombatReach();
float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
m_preGeneratedPath = Trinity::make_unique<PathGenerator>(m_caster);
m_preGeneratedPath->SetPathLengthLimit(range);
// first try with raycast, if it fails fall back to normal path
- float targetObjectSize = std::min(target->GetObjectSize(), 4.0f);
+ float targetObjectSize = std::min(target->GetCombatReach(), 4.0f);
bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, true);
if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
return SPELL_FAILED_OUT_OF_RANGE;
@@ -7895,8 +7900,20 @@ WorldObjectSpellAreaTargetCheck::WorldObjectSpellAreaTargetCheck(float range, Po
bool WorldObjectSpellAreaTargetCheck::operator()(WorldObject* target)
{
- if (!target->IsWithinDist3d(_position, _range) && !(target->ToGameObject() && target->ToGameObject()->IsInRange(_position->GetPositionX(), _position->GetPositionY(), _position->GetPositionZ(), _range)))
- return false;
+ if (target->ToGameObject())
+ {
+ // isInRange including the dimension of the GO
+ bool isInRange = target->ToGameObject()->IsInRange(_position->GetPositionX(), _position->GetPositionY(), _position->GetPositionZ(), _range);
+ if (!isInRange)
+ return false;
+ }
+ else
+ {
+ bool isInsideCylinder = target->IsWithinDist2d(_position, _range) && std::abs(target->GetPositionZ() - _position->GetPositionZ()) <= _range;
+ if (!isInsideCylinder)
+ return false;
+ }
+
return WorldObjectSpellTargetCheck::operator ()(target);
}
@@ -7913,7 +7930,7 @@ bool WorldObjectSpellConeTargetCheck::operator()(WorldObject* target)
}
else if (_spellInfo->HasAttribute(SPELL_ATTR0_CU_CONE_LINE))
{
- if (!_caster->HasInLine(target, target->GetObjectSize(), _caster->GetObjectSize()))
+ if (!_caster->HasInLine(target, target->GetCombatReach(), _caster->GetCombatReach()))
return false;
}
else
@@ -7933,7 +7950,7 @@ WorldObjectSpellTrajTargetCheck::WorldObjectSpellTrajTargetCheck(float range, Po
bool WorldObjectSpellTrajTargetCheck::operator()(WorldObject* target)
{
// return all targets on missile trajectory (0 - size of a missile)
- if (!_caster->HasInLine(target, target->GetObjectSize(), TRAJECTORY_MISSILE_SIZE))
+ if (!_caster->HasInLine(target, target->GetCombatReach(), TRAJECTORY_MISSILE_SIZE))
return false;
if (target->GetExactDist2d(_position) > _range)
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 6acb790d8e8..56a050eea65 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2306,7 +2306,7 @@ void Spell::EffectTeleUnitsFaceCaster(SpellEffIndex /*effIndex*/)
float dis = effectInfo->CalcRadius(m_caster);
float fx, fy, fz;
- m_caster->GetClosePoint(fx, fy, fz, unitTarget->GetObjectSize(), dis);
+ m_caster->GetClosePoint(fx, fy, fz, unitTarget->GetCombatReach(), dis);
unitTarget->NearTeleportTo(fx, fy, fz, -m_caster->GetOrientation(), unitTarget == m_caster);
}
@@ -2659,7 +2659,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex)
//OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
float px, py, pz;
- owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
+ owner->GetClosePoint(px, py, pz, OldSummon->GetCombatReach());
OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
//OldSummon->Relocate(px, py, pz, OldSummon->GetOrientation());
@@ -2679,7 +2679,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex)
}
float x, y, z;
- owner->GetClosePoint(x, y, z, owner->GetObjectSize());
+ owner->GetClosePoint(x, y, z, owner->GetCombatReach());
Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET, 0);
if (!pet)
return;
@@ -2912,7 +2912,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break;
}
- float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
+ float weapon_total_pct = m_caster->GetPctModifierValue(unitMod, TOTAL_PCT);
if (fixed_bonus)
fixed_bonus = int32(fixed_bonus * weapon_total_pct);
if (spell_bonus)
@@ -3041,7 +3041,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
if (m_targets.HasDst())
destTarget->GetPosition(x, y, z);
else
- m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
+ m_caster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS);
Map* map = target->GetMap();
Position pos = Position(x, y, z, target->GetOrientation());
@@ -3922,7 +3922,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)
destTarget->GetPosition(x, y, z);
// Summon in random point all other units if location present
else
- m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
+ m_caster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS);
Map* map = m_caster->GetMap();
Position pos = Position(x, y, z, m_caster->GetOrientation());
@@ -4219,7 +4219,7 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/)
if (m_preGeneratedPath->GetPathType() == PATHFIND_BLANK)
{
//unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
- Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetObjectSize(), unitTarget->GetRelativeAngle(m_caster));
+ Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetCombatReach(), unitTarget->GetRelativeAngle(m_caster));
if (G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) && m_spellInfo->HasAttribute(SPELL_ATTR9_SPECIAL_DELAY_CALCULATION))
speed = pos.GetExactDist(m_caster) / speed;
@@ -4493,7 +4493,7 @@ void Spell::EffectResurrectPet(SpellEffIndex /*effIndex*/)
// Reposition the pet's corpse before reviving so as not to grab aggro
// We can use a different, more accurate version of GetClosePoint() since we have a pet
float x, y, z; // Will be used later to reposition the pet if we have one
- player->GetClosePoint(x, y, z, pet->GetObjectSize(), PET_FOLLOW_DIST, pet->GetFollowAngle());
+ player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
pet->NearTeleportTo(x, y, z, player->GetOrientation());
pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
}
@@ -4501,7 +4501,7 @@ void Spell::EffectResurrectPet(SpellEffIndex /*effIndex*/)
pet->SetDynamicFlags(UNIT_DYNFLAG_NONE);
pet->RemoveUnitFlag(UNIT_FLAG_SKINNABLE);
pet->setDeathState(ALIVE);
- pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE));
+ pet->ClearUnitState(UNIT_STATE_ALL_ERASABLE);
pet->SetHealth(pet->CountPctFromMaxHealth(damage));
// Reset things for when the AI to takes over
@@ -4656,7 +4656,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
else if (effectInfo->HasRadius() && m_spellInfo->Speed == 0)
{
float dis = effectInfo->CalcRadius(m_originalCaster);
- m_caster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis);
+ m_caster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis);
}
else
{
@@ -4665,7 +4665,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
float max_dis = m_spellInfo->GetMaxRange(true);
float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
- m_caster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis);
+ m_caster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis);
}
Map* cMap = m_caster->GetMap();
@@ -5076,7 +5076,7 @@ void Spell::EffectCreateTamedPet(SpellEffIndex /*effIndex*/)
// relocate
float px, py, pz;
- unitTarget->GetClosePoint(px, py, pz, pet->GetObjectSize(), PET_FOLLOW_DIST, pet->GetFollowAngle());
+ unitTarget->GetClosePoint(px, py, pz, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
pet->Relocate(px, py, pz, unitTarget->GetOrientation());
// add to world
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 3266343d8b3..12eb37b6861 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -75,6 +75,35 @@ bool SpellImplicitTargetInfo::IsArea() const
return GetSelectionCategory() == TARGET_SELECT_CATEGORY_AREA || GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE;
}
+bool SpellImplicitTargetInfo::IsProximityBasedAoe() const
+{
+ switch (_target)
+ {
+ case TARGET_UNIT_SRC_AREA_ENTRY:
+ case TARGET_UNIT_SRC_AREA_ENEMY:
+ case TARGET_UNIT_CASTER_AREA_PARTY:
+ case TARGET_UNIT_SRC_AREA_ALLY:
+ case TARGET_UNIT_SRC_AREA_PARTY:
+ case TARGET_UNIT_LASTTARGET_AREA_PARTY:
+ case TARGET_GAMEOBJECT_SRC_AREA:
+ case TARGET_UNIT_CASTER_AREA_RAID:
+ case TARGET_CORPSE_SRC_AREA_ENEMY:
+ return true;
+
+ case TARGET_UNIT_DEST_AREA_ENTRY:
+ case TARGET_UNIT_DEST_AREA_ENEMY:
+ case TARGET_UNIT_DEST_AREA_ALLY:
+ case TARGET_UNIT_DEST_AREA_PARTY:
+ case TARGET_GAMEOBJECT_DEST_AREA:
+ case TARGET_UNIT_TARGET_AREA_RAID_CLASS:
+ return false;
+
+ default:
+ TC_LOG_WARN("spells", "SpellImplicitTargetInfo::IsProximityBasedAoe called a non-aoe spell");
+ return false;
+ }
+}
+
SpellTargetSelectionCategories SpellImplicitTargetInfo::GetSelectionCategory() const
{
return _data[_target].SelectionCategory;
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index d663c2359f0..e4b8709308b 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -286,6 +286,7 @@ public:
SpellImplicitTargetInfo(uint32 target);
bool IsArea() const;
+ bool IsProximityBasedAoe() const;
SpellTargetSelectionCategories GetSelectionCategory() const;
SpellTargetReferenceTypes GetReferenceType() const;
SpellTargetObjectTypes GetObjectType() const;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 5bb9d23c7db..3c15a374d1b 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -369,10 +369,14 @@ bool SpellMgr::AddSameEffectStackRuleSpellGroups(SpellInfo const* spellInfo, int
SpellGroupStackRule SpellMgr::CheckSpellGroupStackRules(SpellInfo const* spellInfo1, SpellInfo const* spellInfo2) const
{
+ ASSERT(spellInfo1);
+ ASSERT(spellInfo2);
+
uint32 spellid_1 = spellInfo1->GetFirstRankSpell()->Id;
uint32 spellid_2 = spellInfo2->GetFirstRankSpell()->Id;
if (spellid_1 == spellid_2)
return SPELL_GROUP_STACK_RULE_DEFAULT;
+
// find SpellGroups which are common for both spells
SpellSpellGroupMapBounds spellGroup1 = GetSpellSpellGroupMapBounds(spellid_1);
std::set<SpellGroup> groups;
@@ -3363,6 +3367,12 @@ void SpellMgr::LoadSpellInfoCorrections()
const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
});
+ // Val'kyr Target Search
+ ApplySpellFix({ 69030 }, [](SpellInfo* spellInfo)
+ {
+ spellInfo->Attributes |= SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY;
+ });
+
// Raging Spirit Visual
ApplySpellFix({ 69198 }, [](SpellInfo* spellInfo)
{
@@ -3408,14 +3418,16 @@ void SpellMgr::LoadSpellInfoCorrections()
// Jump
ApplySpellFix({ 71809 }, [](SpellInfo* spellInfo)
{
- spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(3); // 20yd
- const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
+ spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->MiscValue = 190;
});
// Broken Frostmourne
ApplySpellFix({ 72405 }, [](SpellInfo* spellInfo)
{
- const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd
+ spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
});
// ENDOF ICECROWN CITADEL SPELLS
@@ -3631,6 +3643,10 @@ void SpellMgr::LoadSpellInfoCorrections()
if (spellInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_SPELL_MAGNET))
spellInfo->ProcFlags = 0;
+ // due to the way spell system works, unit would change orientation in Spell::_cast
+ if (spellInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_CONTROL_VEHICLE))
+ spellInfo->AttributesEx5 |= SPELL_ATTR5_DONT_TURN_DURING_CAST;
+
if (spellInfo->ActiveIconFileDataId == 135754) // flight
spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
}
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 3cd797d5e00..11417b305a5 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -918,7 +918,7 @@ public:
uint32 entry = atoul(e);
float x, y, z, o = handler->GetSession()->GetPlayer()->GetOrientation();
- handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, handler->GetSession()->GetPlayer()->GetObjectSize());
+ handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, handler->GetSession()->GetPlayer()->GetCombatReach());
if (!i)
return handler->GetSession()->GetPlayer()->SummonCreature(entry, x, y, z, o) != nullptr;
diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp
index afe3b3c2645..f6866734a7c 100644
--- a/src/server/scripts/Commands/cs_group.cpp
+++ b/src/server/scripts/Commands/cs_group.cpp
@@ -143,7 +143,7 @@ public:
// before GM
float x, y, z;
- gmPlayer->GetClosePoint(x, y, z, player->GetObjectSize());
+ gmPlayer->GetClosePoint(x, y, z, player->GetCombatReach());
player->TeleportTo(gmPlayer->GetMapId(), x, y, z, player->GetOrientation());
}
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 1067283431d..23dbd8e3d1a 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -591,7 +591,7 @@ public:
// before GM
float x, y, z;
- handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize());
+ handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetCombatReach());
target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation());
PhasingHandler::InheritPhaseShift(target, handler->GetSession()->GetPlayer());
target->UpdateObjectVisibility();
@@ -2201,9 +2201,6 @@ public:
case WAYPOINT_MOTION_TYPE:
handler->SendSysMessage(LANG_MOVEGENS_WAYPOINT);
break;
- case ANIMAL_RANDOM_MOTION_TYPE:
- handler->SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM);
- break;
case CONFUSED_MOTION_TYPE:
handler->SendSysMessage(LANG_MOVEGENS_CONFUSED);
break;
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index ac4d8abb366..7a2e6cff30e 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -1457,7 +1457,7 @@ public:
// place pet before player
float x, y, z;
- player->GetClosePoint (x, y, z, creatureTarget->GetObjectSize(), CONTACT_DISTANCE);
+ player->GetClosePoint (x, y, z, creatureTarget->GetCombatReach(), CONTACT_DISTANCE);
pet->Relocate(x, y, z, float(M_PI) - player->GetOrientation());
// set pet to defensive mode by default (some classes can't control controlled pets in fact).
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
index 22efdea4071..c0ae774c5f1 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
@@ -126,7 +126,7 @@ class boss_selin_fireheart : public CreatureScript
Crystals.remove(CrystalChosen);
float x, y, z;
- CrystalChosen->GetClosePoint(x, y, z, me->GetObjectSize(), CONTACT_DISTANCE);
+ CrystalChosen->GetClosePoint(x, y, z, me->GetCombatReach(), CONTACT_DISTANCE);
events.SetPhase(PHASE_DRAIN);
me->SetWalk(false);
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 d47bf3c7862..fea8c330b9c 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
@@ -101,7 +101,7 @@ public:
FlyBackTimer = 500;
break;
case 1:
- player->GetClosePoint(x, y, z, me->GetObjectSize());
+ player->GetClosePoint(x, y, z, me->GetCombatReach());
z += 2.5f;
x -= 2.0f;
y -= 1.5f;
diff --git a/src/server/scripts/EasternKingdoms/SunkenTemple/sunken_temple.h b/src/server/scripts/EasternKingdoms/SunkenTemple/sunken_temple.h
index 9f72ffe8183..c905702d3bc 100644
--- a/src/server/scripts/EasternKingdoms/SunkenTemple/sunken_temple.h
+++ b/src/server/scripts/EasternKingdoms/SunkenTemple/sunken_temple.h
@@ -20,17 +20,9 @@
#define DataHeader "ST"
-#define TROLLBOSS1_DEATH 1
-#define TROLLBOSS2_DEATH 2
-#define TROLLBOSS3_DEATH 3
-#define TROLLBOSS4_DEATH 4
-#define TROLLBOSS5_DEATH 5
-#define TROLLBOSS6_DEATH 6
-#define JAMMALAN_DEATH 7
-#define MORPHAZ_DEATH 8
-#define HAZZAS_DEATH 9
-#define ERANIKUS_DEATH 10
-#define ATALALARION_DEATH 11 //optional
+enum STEvents
+{
+ EVENT_STATE = 1
+};
-#define EVENT_STATE 1
#endif
diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp
index 58690c3a171..71784911f34 100644
--- a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp
+++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp
@@ -539,7 +539,7 @@ public:
/// TODO: Remove this once we find a general rule for WorldObject::MovePosition (this spell shouldn't take the Z change into consideration)
Unit* caster = GetCaster();
float angle = float(rand_norm()) * static_cast<float>(2 * M_PI);
- uint32 dist = caster->GetObjectSize() + GetSpellInfo()->GetEffect(EFFECT_0)->CalcRadius(caster) * (float)rand_norm();
+ uint32 dist = caster->GetCombatReach() + GetSpellInfo()->GetEffect(EFFECT_0)->CalcRadius(caster) * (float)rand_norm();
float x = caster->GetPositionX() + dist * std::cos(angle);
float y = caster->GetPositionY() + dist * std::sin(angle);
diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
index f00f96660a8..9112fd9ccd2 100644
--- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
@@ -483,15 +483,6 @@ class npc_anubarak_anub_ar_assassin : public CreatureScript
{
npc_anubarak_anub_ar_assassinAI(Creature* creature) : npc_anubarak_pet_template(creature, false), _backstabTimer(6 * IN_MILLISECONDS) { }
- bool IsInBounds(Position const& jumpTo, CreatureBoundary const* boundary)
- {
- if (!boundary)
- return true;
- for (AreaBoundary const* it : *boundary)
- if (!it->IsWithinBoundary(&jumpTo))
- return false;
- return true;
- }
Position GetRandomPositionAround(Creature* anubarak)
{
static float DISTANCE_MIN = 10.0f;
@@ -508,7 +499,7 @@ class npc_anubarak_anub_ar_assassin : public CreatureScript
Position jumpTo;
do
jumpTo = GetRandomPositionAround(anubarak);
- while (!IsInBounds(jumpTo, boundary));
+ while (!CreatureAI::IsInBounds(boundary, &jumpTo));
me->GetMotionMaster()->MoveJump(jumpTo, 40.0f, 40.0f);
DoCastSelf(SPELL_ASSASSIN_VISUAL, true);
}
diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_king_dred.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_king_dred.cpp
index 1df68607625..ff4343f31fd 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/boss_king_dred.cpp
+++ b/src/server/scripts/Northrend/DraktharonKeep/boss_king_dred.cpp
@@ -146,7 +146,7 @@ class boss_king_dred : public CreatureScript
float x, y, z;
- me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 10.0f);
+ me->GetClosePoint(x, y, z, me->GetCombatReach() / 3, 10.0f);
me->SummonCreature(RAND(NPC_DRAKKARI_GUTRIPPER, NPC_DRAKKARI_SCYTHECLAW), x, y, z, 0, TEMPSUMMON_DEAD_DESPAWN, 1000);
events.ScheduleEvent(EVENT_RAPTOR_CALL, urand(20000, 25000));
break;
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
index c67179d67eb..c78424c0078 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
@@ -131,7 +131,7 @@ class boss_bronjahm : public CreatureScript
{
summons.Summon(summon);
summon->SetReactState(REACT_PASSIVE);
- summon->GetMotionMaster()->MoveFollow(me, me->GetObjectSize(), 0.0f);
+ summon->GetMotionMaster()->MoveFollow(me, me->GetCombatReach(), 0.0f);
summon->CastSpell(summon, SPELL_PURPLE_BANISH_VISUAL, true);
}
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index 98ee4e6194e..80ab44fe32a 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -790,7 +790,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
{
float x, y, z;
- deathbringer->GetClosePoint(x, y, z, deathbringer->GetObjectSize());
+ deathbringer->GetClosePoint(x, y, z, deathbringer->GetCombatReach());
me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_CORPSE, x, y, z);
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
index 99060220471..1ab35165e5a 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
@@ -387,7 +387,7 @@ class npc_coldflame : public CreatureScript
{
float ang = Position::NormalizeOrientation(pos.GetAngle(me));
me->SetOrientation(ang);
- owner->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 5.0f - owner->GetObjectSize(), ang);
+ owner->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 5.0f - owner->GetCombatReach(), ang);
}
else
{
@@ -400,7 +400,7 @@ class npc_coldflame : public CreatureScript
float ang = Position::NormalizeOrientation(pos.GetAngle(target));
me->SetOrientation(ang);
- owner->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 15.0f - owner->GetObjectSize(), ang);
+ owner->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 15.0f - owner->GetCombatReach(), ang);
}
me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), me->GetPositionZ(), me->GetOrientation());
@@ -518,7 +518,7 @@ class spell_marrowgar_coldflame : public SpellScriptLoader
{
targets.clear();
// select any unit but not the tank (by owners threatlist)
- Unit* target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 1, -GetCaster()->GetObjectSize(), true, -SPELL_IMPALED);
+ Unit* target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 1, -GetCaster()->GetCombatReach(), true, -SPELL_IMPALED);
if (!target)
target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); // or the tank if its solo
if (!target)
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 e525c2efa45..94bf769b771 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -197,77 +197,80 @@ enum Events
{
// The Lich King
// intro events
- EVENT_INTRO_MOVE_1 = 1,
- EVENT_INTRO_MOVE_2 = 2,
- EVENT_INTRO_MOVE_3 = 3,
- EVENT_INTRO_TALK_1 = 4,
- EVENT_EMOTE_CAST_SHOUT = 5,
- EVENT_INTRO_EMOTE_1 = 6,
- EVENT_INTRO_CHARGE = 7,
- EVENT_INTRO_CAST_FREEZE = 8,
- EVENT_FINISH_INTRO = 9,
+ EVENT_INTRO_MOVE_1 = 1,
+ EVENT_INTRO_MOVE_2,
+ EVENT_INTRO_MOVE_3,
+ EVENT_INTRO_TALK_1,
+ EVENT_EMOTE_CAST_SHOUT,
+ EVENT_INTRO_EMOTE_1,
+ EVENT_INTRO_CHARGE,
+ EVENT_INTRO_CAST_FREEZE,
+ EVENT_FINISH_INTRO,
// combat events
- EVENT_SUMMON_SHAMBLING_HORROR = 10,
- EVENT_SUMMON_DRUDGE_GHOUL = 11,
- EVENT_INFEST = 12,
- EVENT_NECROTIC_PLAGUE = 13,
- EVENT_SHADOW_TRAP = 14, // heroic only
- EVENT_SOUL_REAPER = 15,
- EVENT_DEFILE = 16,
- EVENT_HARVEST_SOUL = 17, // normal mode only
- EVENT_PAIN_AND_SUFFERING = 18,
- EVENT_SUMMON_ICE_SPHERE = 19,
- EVENT_SUMMON_RAGING_SPIRIT = 20,
- EVENT_QUAKE = 21,
- EVENT_SUMMON_VALKYR = 22,
- EVENT_GRAB_PLAYER = 23,
- EVENT_MOVE_TO_DROP_POS = 24,
- EVENT_LIFE_SIPHON = 25, // heroic only
- EVENT_START_ATTACK = 26,
- EVENT_QUAKE_2 = 27,
- EVENT_VILE_SPIRITS = 28,
- EVENT_HARVEST_SOULS = 29, // heroic only
- EVENT_BERSERK = 30,
- EVENT_SOUL_RIP = 31,
- EVENT_DESTROY_SOUL = 32,
- EVENT_FROSTMOURNE_TALK_1 = 33,
- EVENT_FROSTMOURNE_TALK_2 = 34,
- EVENT_FROSTMOURNE_TALK_3 = 35,
- EVENT_TELEPORT_BACK = 36,
- EVENT_FROSTMOURNE_HEROIC = 37,
- EVENT_OUTRO_TALK_1 = 38,
- EVENT_OUTRO_TALK_2 = 39,
- EVENT_OUTRO_EMOTE_TALK = 40,
- EVENT_OUTRO_TALK_3 = 41,
- EVENT_OUTRO_MOVE_CENTER = 42,
- EVENT_OUTRO_TALK_4 = 43,
- EVENT_OUTRO_RAISE_DEAD = 44,
- EVENT_OUTRO_TALK_5 = 45,
- EVENT_OUTRO_BLESS = 46,
- EVENT_OUTRO_REMOVE_ICE = 47,
- EVENT_OUTRO_MOVE_1 = 48,
- EVENT_OUTRO_JUMP = 49,
- EVENT_OUTRO_TALK_6 = 50,
- EVENT_OUTRO_KNOCK_BACK = 51,
- EVENT_OUTRO_SOUL_BARRAGE = 52,
- EVENT_OUTRO_SUMMON_TERENAS = 53,
- EVENT_OUTRO_TERENAS_TALK_1 = 54,
- EVENT_OUTRO_TERENAS_TALK_2 = 55,
- EVENT_OUTRO_TALK_7 = 56,
- EVENT_OUTRO_TALK_8 = 57,
+ EVENT_SUMMON_SHAMBLING_HORROR,
+ EVENT_SUMMON_DRUDGE_GHOUL,
+ EVENT_INFEST,
+ EVENT_NECROTIC_PLAGUE,
+ EVENT_SHADOW_TRAP, // heroic only
+ EVENT_SOUL_REAPER,
+ EVENT_DEFILE,
+ EVENT_HARVEST_SOUL, // normal mode only
+ EVENT_PAIN_AND_SUFFERING,
+ EVENT_SUMMON_ICE_SPHERE,
+ EVENT_SUMMON_RAGING_SPIRIT,
+ EVENT_QUAKE,
+ EVENT_SUMMON_VALKYR,
+ EVENT_GRAB_PLAYER,
+ EVENT_MOVE_TO_DROP_POS,
+ EVENT_LIFE_SIPHON, // heroic only
+ EVENT_MOVE_TO_CENTER, // heroic only
+ EVENT_START_ATTACK,
+ EVENT_SUMMON_RAGING_SPIRIT_2,
+ EVENT_QUAKE_2,
+ EVENT_VILE_SPIRITS,
+ EVENT_HARVEST_SOULS, // heroic only
+ EVENT_BERSERK,
+ EVENT_SOUL_RIP,
+ EVENT_DESTROY_SOUL,
+ EVENT_FROSTMOURNE_TALK_1,
+ EVENT_FROSTMOURNE_TALK_2,
+ EVENT_FROSTMOURNE_TALK_3,
+ EVENT_TELEPORT_BACK,
+ EVENT_FROSTMOURNE_HEROIC,
+ EVENT_OUTRO_TALK_1,
+ EVENT_OUTRO_TALK_2,
+ EVENT_OUTRO_EMOTE_TALK,
+ EVENT_OUTRO_TALK_3,
+ EVENT_OUTRO_MOVE_CENTER,
+ EVENT_OUTRO_TALK_4,
+ EVENT_OUTRO_RAISE_DEAD,
+ EVENT_OUTRO_TALK_5,
+ EVENT_OUTRO_BLESS,
+ EVENT_OUTRO_REMOVE_ICE,
+ EVENT_OUTRO_MOVE_1,
+ EVENT_OUTRO_JUMP,
+ EVENT_OUTRO_TALK_6,
+ EVENT_OUTRO_KNOCK_BACK,
+ EVENT_OUTRO_SOUL_BARRAGE,
+ EVENT_OUTRO_SUMMON_TERENAS,
+ EVENT_OUTRO_TERENAS_TALK_1,
+ EVENT_OUTRO_TERENAS_TALK_2,
+ EVENT_OUTRO_TALK_7,
+ EVENT_OUTRO_TALK_8,
// Shambling Horror
- EVENT_SHOCKWAVE = 58,
- EVENT_ENRAGE = 59,
+ EVENT_SHOCKWAVE,
+ EVENT_ENRAGE,
// Raging Spirit
- EVENT_SOUL_SHRIEK = 60,
+ EVENT_SOUL_SHRIEK,
+ EVENT_SET_AGRESSIVE,
// Strangulate Vehicle (Harvest Soul)
- EVENT_TELEPORT = 61,
- EVENT_MOVE_TO_LICH_KING = 62,
- EVENT_DESPAWN_SELF = 63,
+ EVENT_TELEPORT,
+ EVENT_MOVE_TO_LICH_KING,
+ EVENT_DESPAWN_SELF,
};
enum EventGroups
@@ -320,6 +323,7 @@ enum MovePoints
POINT_OUTRO_JUMP = 11,
POINT_LK_OUTRO_2 = 12,
POINT_GROUND = 13,
+ POINT_SIPHON = 14,
POINT_CHARGE = 1003, // globally used number for charge spell effects
};
@@ -334,12 +338,14 @@ enum EncounterActions
ACTION_SUMMON_TERENAS = 6,
ACTION_FINISH_OUTRO = 7,
ACTION_TELEPORT_BACK = 8,
+ ACTION_DISABLE_RAGING = 9
};
enum MiscData
{
LIGHT_SNOWSTORM = 2490,
LIGHT_SOULSTORM = 2508,
+ LIGHT_FOG = 2509,
MUSIC_FROZEN_THRONE = 17457,
MUSIC_SPECIAL = 17458, // Summon Shambling Horror, Remorseless Winter, Quake, Summon Val'kyr Periodic, Harvest Soul, Vile Spirits
@@ -499,17 +505,7 @@ class boss_the_lich_king : public CreatureScript
_vileSpiritExplosions = 0;
}
- void InitializeAI() override
- {
- SetupEncounter();
- }
-
- void JustRespawned() override
- {
- SetupEncounter();
- }
-
- void SetupEncounter()
+ void Reset() override
{
_Reset();
me->AddUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
@@ -524,9 +520,10 @@ class boss_the_lich_king : public CreatureScript
Cell::VisitGridObjects(me, worker, 333.0f);
// Reset any light override
- me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, 0, 5000);
+ me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, 0, 5000);
- me->SummonCreature(NPC_HIGHLORD_TIRION_FORDRING_LK, TirionSpawn, TEMPSUMMON_MANUAL_DESPAWN);
+ if (!ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
+ me->SummonCreature(NPC_HIGHLORD_TIRION_FORDRING_LK, TirionSpawn, TEMPSUMMON_MANUAL_DESPAWN);
}
void JustDied(Unit* /*killer*/) override
@@ -538,6 +535,8 @@ class boss_the_lich_king : public CreatureScript
me->GetMotionMaster()->MoveFall();
if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f))
frostmourne->DespawnOrUnsummon();
+ me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_FOG, 5000);
+ me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_FOG, 0.0f);
}
void EnterCombat(Unit* target) override
@@ -550,6 +549,7 @@ class boss_the_lich_king : public CreatureScript
}
me->setActive(true);
+ me->SetCombatPulseDelay(5);
DoZoneInCombat();
events.SetPhase(PHASE_ONE);
@@ -592,7 +592,7 @@ class boss_the_lich_king : public CreatureScript
case ACTION_START_ENCOUNTER:
instance->SetBossState(DATA_THE_LICH_KING, IN_PROGRESS);
Talk(SAY_LK_INTRO_1);
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_FROZEN_THRONE);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FROZEN_THRONE);
// schedule talks
me->SetStandState(UNIT_STAND_STATE_STAND);
events.ScheduleEvent(EVENT_INTRO_MOVE_1, 4000);
@@ -601,10 +601,10 @@ class boss_the_lich_king : public CreatureScript
events.ScheduleEvent(EVENT_START_ATTACK, 5000);
break;
case ACTION_PLAY_MUSIC:
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_FINAL);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FINAL);
break;
case ACTION_RESTORE_LIGHT:
- me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, 0, 5000);
+ me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, 0, 5000);
break;
case ACTION_BREAK_FROSTMOURNE:
me->CastSpell((Unit*)NULL, SPELL_SUMMON_BROKEN_FROSTMOURNE, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
@@ -666,6 +666,7 @@ class boss_the_lich_king : public CreatureScript
events.SetPhase(PHASE_TRANSITION);
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
+ me->InterruptNonMeleeSpells(true);
me->GetMotionMaster()->MovePoint(POINT_CENTER_1, CenterPosition);
return;
}
@@ -675,6 +676,7 @@ class boss_the_lich_king : public CreatureScript
events.SetPhase(PHASE_TRANSITION);
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
+ me->InterruptNonMeleeSpells(true);
me->GetMotionMaster()->MovePoint(POINT_CENTER_2, CenterPosition);
return;
}
@@ -686,7 +688,7 @@ class boss_the_lich_king : public CreatureScript
events.Reset();
events.SetPhase(PHASE_OUTRO);
summons.DespawnAll();
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_FURY_OF_FROSTMOURNE);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FURY_OF_FROSTMOURNE);
me->InterruptNonMeleeSpells(true);
me->CastSpell((Unit*)NULL, SPELL_FURY_OF_FROSTMOURNE, TRIGGERED_NONE);
me->SetWalk(true);
@@ -738,8 +740,8 @@ class boss_the_lich_king : public CreatureScript
{
summon->CastSpell((Unit*)NULL, SPELL_BROKEN_FROSTMOURNE, true);
- me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, LIGHT_SOULSTORM, 10000);
- me->GetMap()->SetZoneWeather(AREA_THE_FROZEN_THRONE, WEATHER_STATE_BLACKSNOW, 0.5f);
+ me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_SOULSTORM, 10000);
+ me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_BLACKSNOW, 0.5f);
events.ScheduleEvent(EVENT_OUTRO_SOUL_BARRAGE, 5000, 0, PHASE_OUTRO);
return;
@@ -793,8 +795,8 @@ class boss_the_lich_king : public CreatureScript
{
if (spell->Id == REMORSELESS_WINTER_1 || spell->Id == REMORSELESS_WINTER_2)
{
- me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, LIGHT_SNOWSTORM, 5000);
- me->GetMap()->SetZoneWeather(AREA_THE_FROZEN_THRONE, WEATHER_STATE_LIGHT_SNOW, 0.5f);
+ me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_SNOWSTORM, 5000);
+ me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_LIGHT_SNOW, 0.5f);
}
}
@@ -820,13 +822,14 @@ class boss_the_lich_king : public CreatureScript
case POINT_CENTER_1:
me->SetFacingTo(0.0f, true);
Talk(SAY_LK_REMORSELESS_WINTER);
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
DoCast(me, SPELL_REMORSELESS_WINTER_1);
+ summons.DespawnEntry(NPC_SHADOW_TRAP);
events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions
events.ScheduleEvent(EVENT_QUAKE, 62500, 0, PHASE_TRANSITION);
events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 4000, 0, PHASE_TRANSITION);
events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8000, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 3000, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 6000, 0, PHASE_TRANSITION);
events.ScheduleEvent(EVENT_SUMMON_VALKYR, 78000, 0, PHASE_TWO);
events.ScheduleEvent(EVENT_INFEST, 70000, 0, PHASE_TWO);
events.ScheduleEvent(EVENT_DEFILE, 97000, 0, PHASE_TWO);
@@ -835,14 +838,14 @@ class boss_the_lich_king : public CreatureScript
case POINT_CENTER_2:
me->SetFacingTo(0.0f, true);
Talk(SAY_LK_REMORSELESS_WINTER);
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
DoCast(me, SPELL_REMORSELESS_WINTER_2);
summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD);
events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions
events.ScheduleEvent(EVENT_QUAKE_2, 62500, 0, PHASE_TRANSITION);
events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 6000, 0, PHASE_TRANSITION);
events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8000, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 5000, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT_2, 5000, 0, PHASE_TRANSITION);
events.ScheduleEvent(EVENT_DEFILE, 95500, 0, PHASE_THREE);
events.ScheduleEvent(EVENT_SOUL_REAPER, 99500, 0, PHASE_THREE);
events.ScheduleEvent(EVENT_VILE_SPIRITS, 79500, EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
@@ -921,7 +924,7 @@ class boss_the_lich_king : public CreatureScript
break;
case EVENT_SUMMON_SHAMBLING_HORROR:
DoCast(me, SPELL_SUMMON_SHAMBLING_HORROR);
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 60000, 0, PHASE_ONE);
break;
case EVENT_SUMMON_DRUDGE_GHOUL:
@@ -977,24 +980,29 @@ class boss_the_lich_king : public CreatureScript
me->CastSpell(target, SPELL_RAGING_SPIRIT, TRIGGERED_NONE);
events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, urand(22000, 23000), 0, PHASE_TRANSITION);
break;
+ case EVENT_SUMMON_RAGING_SPIRIT_2:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ me->CastSpell(target, SPELL_RAGING_SPIRIT, TRIGGERED_NONE);
+ events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 18000, 0, PHASE_TRANSITION);
+ break;
case EVENT_QUAKE:
events.SetPhase(PHASE_TWO);
me->ClearUnitState(UNIT_STATE_CASTING); // clear state to ensure check in DoCastAOE passes
DoCastAOE(SPELL_QUAKE);
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
Talk(SAY_LK_QUAKE);
break;
case EVENT_QUAKE_2:
events.SetPhase(PHASE_THREE);
me->ClearUnitState(UNIT_STATE_CASTING); // clear state to ensure check in DoCastAOE passes
DoCastAOE(SPELL_QUAKE);
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
Talk(SAY_LK_QUAKE);
break;
case EVENT_SUMMON_VALKYR:
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
Talk(SAY_LK_SUMMON_VALKYR);
- DoCastAOE(SUMMON_VALKYR);
+ DoCastAOE(SUMMON_VALKYR, true);
events.ScheduleEvent(EVENT_SUMMON_VALKYR, urand(45000, 50000), 0, PHASE_TWO);
break;
case EVENT_START_ATTACK:
@@ -1003,7 +1011,7 @@ class boss_the_lich_king : public CreatureScript
events.SetPhase(PHASE_THREE);
break;
case EVENT_VILE_SPIRITS:
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
DoCastAOE(SPELL_VILE_SPIRITS);
events.ScheduleEvent(EVENT_VILE_SPIRITS, urand(35000, 40000), EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
break;
@@ -1019,6 +1027,25 @@ class boss_the_lich_king : public CreatureScript
events.RescheduleEvent(EVENT_SOUL_REAPER, urand(57000, 62000), 0, PHASE_THREE);
events.ScheduleEvent(EVENT_START_ATTACK, 49000);
events.ScheduleEvent(EVENT_FROSTMOURNE_HEROIC, 6500);
+ for (ObjectGuid guid : summons)
+ {
+ if (Creature* summon = ObjectAccessor::GetCreature(*me, guid))
+ {
+ if (summon->GetEntry() == NPC_VILE_SPIRIT)
+ {
+ summon->m_Events.KillAllEvents(true);
+ summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(56500));
+ summon->SetReactState(REACT_PASSIVE);
+ summon->CombatStop(true);
+ summon->RemoveAurasDueToSpell(SPELL_VILE_SPIRIT_MOVE_SEARCH);
+ summon->RemoveAurasDueToSpell(SPELL_VILE_SPIRIT_DAMAGE_SEARCH);
+ summon->GetMotionMaster()->MoveTargetedHome();
+ summon->GetMotionMaster()->MoveRandom(10.0f);
+ }
+ else if (summon->GetEntry() == NPC_RAGING_SPIRIT)
+ summon->AI()->DoAction(ACTION_DISABLE_RAGING);
+ }
+ }
break;
case EVENT_FROSTMOURNE_HEROIC:
if (TempSummon* terenas = me->GetMap()->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE_H, TerenasSpawnHeroic, NULL, 50000))
@@ -1034,18 +1061,6 @@ class boss_the_lich_king : public CreatureScript
spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true); // summons bombs on players
spawner->m_Events.AddEvent(new TriggerWickedSpirit(spawner), spawner->m_Events.CalculateTime(3000));
}
-
- for (SummonList::iterator i = summons.begin(); i != summons.end(); ++i)
- {
- Creature* summon = ObjectAccessor::GetCreature(*me, *i);
- if (summon && summon->GetEntry() == NPC_VILE_SPIRIT)
- {
- summon->m_Events.KillAllEvents(true);
- summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(50000));
- summon->GetMotionMaster()->MoveRandom(10.0f);
- summon->SetReactState(REACT_PASSIVE);
- }
- }
}
break;
case EVENT_OUTRO_TALK_1:
@@ -1074,7 +1089,7 @@ class boss_the_lich_king : public CreatureScript
case EVENT_OUTRO_RAISE_DEAD:
DoCastAOE(SPELL_RAISE_DEAD);
me->ClearUnitState(UNIT_STATE_CASTING);
- me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_FINAL);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FINAL);
break;
case EVENT_OUTRO_TALK_5:
Talk(SAY_LK_OUTRO_5);
@@ -1189,7 +1204,7 @@ class npc_tirion_fordring_tft : public CreatureScript
if (spell->Id == SPELL_ICE_LOCK)
me->SetFacingTo(3.085098f);
else if (spell->Id == SPELL_BROKEN_FROSTMOURNE_KNOCK)
- SetEquipmentSlots(true); // remove glow on ashbringer
+ me->LoadEquipment(1); // remove glow on ashbringer
}
void sGossipSelect(Player* /*player*/, uint32 menuId, uint32 gossipListId) override
@@ -1357,7 +1372,9 @@ class npc_raging_spirit : public CreatureScript
void Reset() override
{
+ me->SetReactState(REACT_PASSIVE);
_events.Reset();
+ _events.ScheduleEvent(EVENT_SET_AGRESSIVE, 2000);
_events.ScheduleEvent(EVENT_SOUL_SHRIEK, urand(12000, 15000));
DoCast(me, SPELL_PLAGUE_AVOIDANCE, true);
DoCast(me, SPELL_RAGING_SPIRIT_VISUAL, true);
@@ -1367,6 +1384,19 @@ class npc_raging_spirit : public CreatureScript
DoCast(me, SPELL_BOSS_HITTIN_YA, true);
}
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_DISABLE_RAGING)
+ {
+ _events.Reset();
+ _events.SetPhase(PHASE_FROSTMOURNE);
+ _events.ScheduleEvent(EVENT_SET_AGRESSIVE, 52000);
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ me->InterruptNonMeleeSpells(true);
+ }
+ }
+
void IsSummonedBy(Unit* /*summoner*/) override
{
// player is the spellcaster so register summon manually
@@ -1384,7 +1414,7 @@ class npc_raging_spirit : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
+ if (!_events.IsInPhase(PHASE_FROSTMOURNE) && !UpdateVictim())
return;
_events.Update(diff);
@@ -1400,6 +1430,14 @@ class npc_raging_spirit : public CreatureScript
DoCastAOE(SPELL_SOUL_SHRIEK);
_events.ScheduleEvent(EVENT_SOUL_SHRIEK, urand(12000, 15000));
break;
+ case EVENT_SET_AGRESSIVE:
+ me->SetReactState(REACT_AGGRESSIVE);
+ if (_events.IsInPhase(PHASE_FROSTMOURNE))
+ {
+ _events.SetPhase(PHASE_THREE);
+ _events.ScheduleEvent(EVENT_SOUL_SHRIEK, urand(12000, 15000));
+ }
+ break;
default:
break;
}
@@ -1454,19 +1492,18 @@ class npc_valkyr_shadowguard : public CreatureScript
if (me->HealthBelowPctDamaged(50, damage))
{
- _events.Reset();
DoCastAOE(SPELL_EJECT_ALL_PASSENGERS);
- me->GetMotionMaster()->MoveTargetedHome();
- me->ClearUnitState(UNIT_STATE_EVADE);
+ ScheduleHeroicEvents();
}
}
- void JustReachedHome() override
+ void ScheduleHeroicEvents()
{
- // schedule siphon life event (heroic only)
DoZoneInCombat();
_events.Reset();
+ _events.ScheduleEvent(EVENT_MOVE_TO_CENTER, 1);
_events.ScheduleEvent(EVENT_LIFE_SIPHON, 2000);
+ me->ClearUnitState(UNIT_STATE_EVADE);
}
void AttackStart(Unit* /*target*/) override
@@ -1482,7 +1519,10 @@ class npc_valkyr_shadowguard : public CreatureScript
{
case POINT_DROP_PLAYER:
DoCastAOE(SPELL_EJECT_ALL_PASSENGERS);
- me->DespawnOrUnsummon(1000);
+ if (IsHeroic())
+ ScheduleHeroicEvents();
+ else
+ me->DespawnOrUnsummon(1000);
break;
case POINT_CHARGE:
if (Player* target = ObjectAccessor::GetPlayer(*me, _grabbedPlayer))
@@ -1545,6 +1585,13 @@ class npc_valkyr_shadowguard : public CreatureScript
DoCast(target, SPELL_LIFE_SIPHON);
_events.ScheduleEvent(EVENT_LIFE_SIPHON, 2500);
break;
+ case EVENT_MOVE_TO_CENTER:
+ {
+ Position pos = me->GetRandomPoint(CenterPosition, 4.0f);
+ pos.m_positionZ = me->GetHomePosition().m_positionZ;
+ me->GetMotionMaster()->MovePoint(POINT_SIPHON, pos);
+ break;
+ }
default:
break;
}
@@ -1607,6 +1654,7 @@ class npc_strangulate_vehicle : public CreatureScript
if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
lichKing->AI()->SummonedCreatureDespawn(me);
+ me->DespawnOrUnsummon();
}
void UpdateAI(uint32 diff) override
@@ -2099,7 +2147,7 @@ class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader
}
private:
- void SelectTarget(std::list<Unit*>& targets)
+ void SelectTarget(std::list<WorldObject*>& targets)
{
targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
if (targets.size() < 2)
@@ -2125,6 +2173,7 @@ class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader
void Register() override
{
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_necrotic_plague_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
BeforeHit += BeforeSpellHitFn(spell_the_lich_king_necrotic_plague_SpellScript::CheckAura);
OnHit += SpellHitFn(spell_the_lich_king_necrotic_plague_SpellScript::AddMissingStack);
}
@@ -2357,12 +2406,6 @@ class spell_the_lich_king_raging_spirit : public SpellScriptLoader
{
PrepareSpellScript(spell_the_lich_king_raging_spirit_SpellScript);
- bool Validate(SpellInfo const* spell) override
- {
- SpellEffectInfo const* effect0 = spell->GetEffect(EFFECT_0);
- return effect0 && ValidateSpellInfo({ uint32(effect0->CalcValue()) });
- }
-
void HandleScript(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
@@ -3134,6 +3177,34 @@ class spell_the_lich_king_jump_remove_aura : public SpellScriptLoader
}
};
+class spell_the_lich_king_harvest_souls_teleport : public SpellScriptLoader
+{
+public:
+ spell_the_lich_king_harvest_souls_teleport() : SpellScriptLoader("spell_the_lich_king_harvest_souls_teleport") { }
+
+ class spell_the_lich_king_harvest_souls_teleport_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_the_lich_king_harvest_souls_teleport_SpellScript);
+
+ void RelocateTransportOffset(SpellEffIndex /*effIndex*/)
+ {
+ float randCoordX = frand(-18.0f, 18.0f);
+ float randCoordY = frand(-18.0f, 18.0f);
+ GetHitDest()->RelocateOffset({ randCoordX, randCoordY, 0.0f, 0.0f });
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_harvest_souls_teleport_SpellScript::RelocateTransportOffset, EFFECT_1, SPELL_EFFECT_TELEPORT_UNITS);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_the_lich_king_harvest_souls_teleport_SpellScript();
+ }
+};
+
class achievement_been_waiting_long_time : public AchievementCriteriaScript
{
public:
@@ -3203,6 +3274,7 @@ void AddSC_boss_the_lich_king()
new spell_the_lich_king_jump();
new spell_the_lich_king_jump_remove_aura();
new spell_trigger_spell_from_caster("spell_the_lich_king_mass_resurrection", SPELL_MASS_RESURRECTION_REAL);
+ new spell_the_lich_king_harvest_souls_teleport();
new achievement_been_waiting_long_time();
new achievement_neck_deep_in_vile();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
index 1f9d88ea885..8fff8922983 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
@@ -321,6 +321,7 @@ enum ICCreaturesIds
NPC_WORLD_TRIGGER_INFINITE_AOI = 36171,
NPC_SPIRIT_BOMB = 39189,
NPC_FROSTMOURNE_TRIGGER = 38584,
+ NPC_SHADOW_TRAP = 39137,
// Generic
NPC_INVISIBLE_STALKER = 30298
@@ -524,8 +525,7 @@ enum ICWorldStatesICC
enum ICAreaIds
{
- AREA_ICECROWN_CITADEL = 4812,
- AREA_THE_FROZEN_THRONE = 4859
+ AREA_ICECROWN_CITADEL = 4812
};
class spell_trigger_spell_from_caster : public SpellScriptLoader
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
index 1d0ef4ccea0..d70f0d07c54 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
@@ -881,26 +881,20 @@ public:
{
PrepareAuraScript(spell_kelthuzad_chains_AuraScript);
- void HandleApply(AuraEffect const* /*eff*/, AuraEffectHandleModes /*mode*/)
+ void HandleApply(AuraEffect const* aurEff, AuraEffectHandleModes mode)
{
- Unit* target = GetTarget();
- float scale = target->GetObjectScale();
- ApplyPercentModFloatVar(scale, 200.0f, true);
- target->SetObjectScale(scale);
+ aurEff->HandleAuraModScale(GetTargetApplication(), mode, true);
}
- void HandleRemove(AuraEffect const* /*eff*/, AuraEffectHandleModes /*mode*/)
+ void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes mode)
{
- Unit* target = GetTarget();
- float scale = target->GetObjectScale();
- ApplyPercentModFloatVar(scale, 200.0f, false);
- target->SetObjectScale(scale);
+ aurEff->HandleAuraModScale(GetTargetApplication(), mode, false);
}
void Register() override
{
- AfterEffectApply += AuraEffectApplyFn(spell_kelthuzad_chains_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_AOE_CHARM, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectApplyFn(spell_kelthuzad_chains_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_AOE_CHARM, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectApply += AuraEffectApplyFn(spell_kelthuzad_chains_AuraScript::HandleApply, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectApplyFn(spell_kelthuzad_chains_AuraScript::HandleRemove, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
}
};
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index b61e42974ac..1569697c81c 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -43,7 +43,7 @@ BossBoundaryData const boundaries =
/* Military Quarter */
{ BOSS_RAZUVIOUS, new ZRangeBoundary(260.0f, 287.0f) }, // will not chase onto the upper floor
{ BOSS_GOTHIK, new RectangleBoundary(2627.0f, 2764.0f, -3440.0f, -3275.0f) },
- { BOSS_HORSEMEN, new ParallelogramBoundary(AreaBoundary::DoublePosition(2646.0, -2959.0), AreaBoundary::DoublePosition(2529.0, -3075.0), AreaBoundary::DoublePosition(2506.0, -2854.0)) },
+ { BOSS_HORSEMEN, new ParallelogramBoundary(Position(2646.0f, -2959.0f), Position(2529.0f, -3075.0f), Position(2506.0f, -2854.0f)) },
/* Construct Quarter */
{ BOSS_PATCHWERK, new CircleBoundary(Position(3204.0f, -3241.4f), 240.0f) },
@@ -51,9 +51,9 @@ BossBoundaryData const boundaries =
{ BOSS_GROBBULUS, new CircleBoundary(Position(3204.0f, -3241.4f), 240.0f) },
{ BOSS_GROBBULUS, new RectangleBoundary(3295.0f, 3340.0f, -3254.2f, -3230.18f, true) }, // entrance door blocker
{ BOSS_GLUTH, new CircleBoundary(Position(3293.0f, -3142.0f), 80.0) },
- { BOSS_GLUTH, new ParallelogramBoundary(AreaBoundary::DoublePosition(3401.0, -3149.0), AreaBoundary::DoublePosition(3261.0, -3028.0), AreaBoundary::DoublePosition(3320.0, -3267.0)) },
+ { BOSS_GLUTH, new ParallelogramBoundary(Position(3401.0f, -3149.0f), Position(3261.0f, -3028.0f), Position(3320.0f, -3267.0f)) },
{ BOSS_GLUTH, new ZRangeBoundary(285.0f, 310.0f) },
- { BOSS_THADDIUS, new ParallelogramBoundary(AreaBoundary::DoublePosition(3478.3, -3070.0), AreaBoundary::DoublePosition(3370.0, -2961.5), AreaBoundary::DoublePosition(3580.0, -2961.5)) },
+ { BOSS_THADDIUS, new ParallelogramBoundary(Position(3478.3f, -3070.0f), Position(3370.0f, -2961.5f), Position(3580.0f, -2961.5f)) },
/* Frostwyrm Lair */
{ BOSS_SAPPHIRON, new CircleBoundary(Position(3517.627f, -5255.5f), 110.0) },
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h
index b066eb59bea..4c3faf67b5a 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h
@@ -23,7 +23,7 @@
#define EoEScriptName "instance_eye_of_eternity"
#define DataHeader "EOE"
-enum InstanceData
+enum EOEInstanceData
{
DATA_MALYGOS_EVENT,
MAX_ENCOUNTER,
@@ -33,7 +33,7 @@ enum InstanceData
DATA_RESPAWN_IRIS
};
-enum InstanceData64
+enum EOEInstanceData64
{
DATA_TRIGGER,
DATA_MALYGOS,
@@ -44,7 +44,7 @@ enum InstanceData64
DATA_GIFT_BOX_BUNNY_GUID
};
-enum InstanceNpcs
+enum EOEInstanceNpcs
{
NPC_MALYGOS = 28859,
NPC_VORTEX_TRIGGER = 30090,
@@ -60,7 +60,7 @@ enum InstanceNpcs
NPC_SURGE_OF_POWER = 30334
};
-enum InstanceGameObjects
+enum EOEInstanceGameObjects
{
GO_NEXUS_RAID_PLATFORM = 193070,
GO_EXIT_PORTAL = 193908,
@@ -72,12 +72,12 @@ enum InstanceGameObjects
GO_HEART_OF_MAGIC_25 = 194159
};
-enum InstanceEvents
+enum EOEInstanceEvents
{
EVENT_FOCUSING_IRIS = 20711
};
-enum InstanceSpells
+enum EOEInstanceSpells
{
SPELL_VORTEX_4 = 55853, // damage | used to enter to the vehicle
SPELL_VORTEX_5 = 56263, // damage | used to enter to the vehicle
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 818485e4440..4e5019618ec 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
@@ -410,7 +410,7 @@ class boss_algalon_the_observer : public CreatureScript
{
_firstPull = false;
Talk(SAY_ALGALON_START_TIMER);
- if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRANN_BRONZEBEARD_ALG)))
+ if (Creature* brann = instance->GetCreature(DATA_BRANN_BRONZEBEARD_ALG))
brann->AI()->DoAction(ACTION_FINISH_INTRO);
me->setActive(true);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp
index b8f23964df6..fe01a917cd6 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp
@@ -393,8 +393,8 @@ class npc_sanctum_sentry : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* Auriaya = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_AURIAYA)))
- Auriaya->AI()->DoAction(ACTION_CRAZY_CAT_LADY);
+ if (Creature* auriaya = instance->GetCreature(BOSS_AURIAYA))
+ auriaya->AI()->DoAction(ACTION_CRAZY_CAT_LADY);
}
private:
@@ -472,8 +472,8 @@ class npc_feral_defender : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
DoCast(me, SPELL_SUMMON_ESSENCE);
- if (Creature* Auriaya = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_AURIAYA)))
- Auriaya->AI()->DoAction(ACTION_RESPAWN_DEFENDER);
+ if (Creature* auriaya = instance->GetCreature(BOSS_AURIAYA))
+ auriaya->AI()->DoAction(ACTION_RESPAWN_DEFENDER);
}
private:
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 b2958daf07c..8e734e6d3e7 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -974,11 +974,6 @@ class npc_mimirons_inferno : public CreatureScript
public:
npc_mimirons_inferno() : CreatureScript("npc_mimirons_inferno") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetUlduarAI<npc_mimirons_infernoAI>(creature);
- }
-
struct npc_mimirons_infernoAI : public npc_escortAI
{
npc_mimirons_infernoAI(Creature* creature) : npc_escortAI(creature)
@@ -1031,6 +1026,10 @@ public:
}
};
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_mimirons_infernoAI>(creature);
+ }
};
class npc_hodirs_fury : public CreatureScript
@@ -1247,7 +1246,7 @@ class npc_lorekeeper : public CreatureScript
CloseGossipMenuFor(player);
me->GetMap()->LoadGrid(364, -16); // make sure leviathan is loaded
- if (Creature* leviathan = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(BOSS_LEVIATHAN)))
+ if (Creature* leviathan = _instance->GetCreature(BOSS_LEVIATHAN))
{
leviathan->AI()->DoAction(ACTION_START_HARD_MODE);
me->SetVisible(false);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
index ad4b7c6413f..5cfc0d75481 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
@@ -1061,8 +1061,8 @@ class npc_ancient_water_spirit : public CreatureScript
{
Initialize();
instance = me->GetInstanceScript();
- if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_FREYA)))
- waveCount = ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->trioWaveCount;
+ if (Creature* freya = instance->GetCreature(BOSS_FREYA))
+ waveCount = ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->trioWaveCount;
else
waveCount = 0;
}
@@ -1099,10 +1099,10 @@ class npc_ancient_water_spirit : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_FREYA)))
+ if (Creature* freya = instance->GetCreature(BOSS_FREYA))
{
- ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->checkElementalAlive[waveCount] = false;
- ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->LasherDead(1);
+ ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->checkElementalAlive[waveCount] = false;
+ ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->LasherDead(1);
}
}
@@ -1129,8 +1129,8 @@ class npc_storm_lasher : public CreatureScript
{
Initialize();
instance = me->GetInstanceScript();
- if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_FREYA)))
- waveCount = ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->trioWaveCount;
+ if (Creature* freya = instance->GetCreature(BOSS_FREYA))
+ waveCount = ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->trioWaveCount;
else
waveCount = 0;
}
@@ -1173,10 +1173,10 @@ class npc_storm_lasher : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_FREYA)))
+ if (Creature* freya = instance->GetCreature(BOSS_FREYA))
{
- ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->checkElementalAlive[waveCount] = false;
- ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->LasherDead(2);
+ ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->checkElementalAlive[waveCount] = false;
+ ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->LasherDead(2);
}
}
@@ -1203,8 +1203,8 @@ class npc_snaplasher : public CreatureScript
npc_snaplasherAI(Creature* creature) : ScriptedAI(creature)
{
instance = me->GetInstanceScript();
- if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_FREYA)))
- waveCount = ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->trioWaveCount;
+ if (Creature* freya = instance->GetCreature(BOSS_FREYA))
+ waveCount = ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->trioWaveCount;
else
waveCount = 0;
}
@@ -1222,10 +1222,10 @@ class npc_snaplasher : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_FREYA)))
+ if (Creature* freya = instance->GetCreature(BOSS_FREYA))
{
- ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->checkElementalAlive[waveCount] = false;
- ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->LasherDead(4);
+ ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->checkElementalAlive[waveCount] = false;
+ ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->LasherDead(4);
}
}
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 9630f1ddbfe..6c03b9f5ecb 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp
@@ -336,8 +336,8 @@ class boss_saronite_animus : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* Vezax = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_VEZAX)))
- Vezax->AI()->DoAction(ACTION_ANIMUS_DIE);
+ if (Creature* vezax = instance->GetCreature(BOSS_VEZAX))
+ vezax->AI()->DoAction(ACTION_ANIMUS_DIE);
}
void UpdateAI(uint32 diff) override
@@ -434,8 +434,8 @@ class npc_saronite_vapors : public CreatureScript
DoCast(me, SPELL_SARONITE_VAPORS);
me->DespawnOrUnsummon(30000);
- if (Creature* Vezax = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_VEZAX)))
- Vezax->AI()->DoAction(ACTION_VAPORS_DIE);
+ if (Creature* vezax = instance->GetCreature(BOSS_VEZAX))
+ vezax->AI()->DoAction(ACTION_VAPORS_DIE);
}
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
index 57b96e26943..4d8a49160bc 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
@@ -242,8 +242,8 @@ class npc_flash_freeze : public CreatureScript
// Prevents to have Ice Block on other place than target is
me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation());
if (target->GetTypeId() == TYPEID_PLAYER)
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_HODIR)))
- Hodir->AI()->DoAction(ACTION_CHEESE_THE_FREEZE);
+ if (Creature* hodir = instance->GetCreature(BOSS_HODIR))
+ hodir->AI()->DoAction(ACTION_CHEESE_THE_FREEZE);
}
}
};
@@ -291,21 +291,21 @@ class npc_ice_block : public CreatureScript
void DamageTaken(Unit* who, uint32& /*damage*/) override
{
- if (Creature* Helper = ObjectAccessor::GetCreature(*me, targetGUID))
+ if (Creature* helper = ObjectAccessor::GetCreature(*me, targetGUID))
{
- Helper->RemoveUnitFlag(UnitFlags(UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED));
- Helper->SetControlled(false, UNIT_STATE_ROOT);
+ helper->RemoveUnitFlag(UnitFlags(UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED));
+ helper->SetControlled(false, UNIT_STATE_ROOT);
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_HODIR)))
+ if (Creature* hodir = instance->GetCreature(BOSS_HODIR))
{
- if (!Hodir->IsInCombat())
+ if (!hodir->IsInCombat())
{
- Hodir->SetReactState(REACT_AGGRESSIVE);
- Hodir->AI()->DoZoneInCombat();
- Hodir->AI()->AttackStart(who);
+ hodir->SetReactState(REACT_AGGRESSIVE);
+ hodir->AI()->DoZoneInCombat();
+ hodir->AI()->AttackStart(who);
}
- Helper->AI()->AttackStart(Hodir);
+ helper->AI()->AttackStart(hodir);
}
}
}
@@ -717,8 +717,8 @@ class npc_hodir_priest : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_HODIR)))
- Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
+ if (Creature* hodir = instance->GetCreature(BOSS_HODIR))
+ hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
}
private:
@@ -782,8 +782,8 @@ class npc_hodir_shaman : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_HODIR)))
- Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
+ if (Creature* hodir = instance->GetCreature(BOSS_HODIR))
+ hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
}
private:
@@ -846,8 +846,8 @@ class npc_hodir_druid : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_HODIR)))
- Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
+ if (Creature* hodir = instance->GetCreature(BOSS_HODIR))
+ hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
}
private:
@@ -929,8 +929,8 @@ class npc_hodir_mage : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_HODIR)))
- Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
+ if (Creature* hodir = instance->GetCreature(BOSS_HODIR))
+ hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
}
private:
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
index e4040a44a36..37141085731 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
@@ -328,7 +328,7 @@ class npc_iron_construct : public CreatureScript
if (me->HasAura(RAID_MODE(SPELL_BRITTLE, SPELL_BRITTLE_25)) && damage >= 5000)
{
DoCast(SPELL_SHATTER);
- if (Creature* ignis = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(BOSS_IGNIS)))
+ if (Creature* ignis = _instance->GetCreature(BOSS_IGNIS))
if (ignis->AI())
ignis->AI()->DoAction(ACTION_REMOVE_BUFF);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
index 5cf1cf67de8..fd4d7b02229 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
@@ -371,7 +371,7 @@ static bool IsEncounterFinished(Unit* who)
mkii->DespawnOrUnsummon(120000);
vx001->DespawnOrUnsummon(120000);
aerial->DespawnOrUnsummon(120000);
- if (Creature* mimiron = ObjectAccessor::GetCreature(*who, instance->GetGuidData(BOSS_MIMIRON)))
+ if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON))
mimiron->AI()->JustDied(who);
return true;
}
@@ -428,7 +428,7 @@ class boss_mimiron : public CreatureScript
me->RemoveAurasDueToSpell(SPELL_WELD);
DoCast(me->GetVehicleBase(), SPELL_SEAT_6);
- if (GameObject* button = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_MIMIRON_BUTTON)))
+ if (GameObject* button = instance->GetGameObject(DATA_MIMIRON_BUTTON))
button->AddFlag(GO_FLAG_NOT_SELECTABLE);
if (_fireFighter)
@@ -458,14 +458,14 @@ class boss_mimiron : public CreatureScript
_Reset();
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- if (GameObject* elevator = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_MIMIRON_ELEVATOR)))
+ if (GameObject* elevator = instance->GetGameObject(DATA_MIMIRON_ELEVATOR))
elevator->SetGoState(GO_STATE_ACTIVE);
if (_fireFighter)
- if (Creature* computer = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_COMPUTER)))
+ if (Creature* computer = instance->GetCreature(DATA_COMPUTER))
computer->AI()->DoAction(DO_DEACTIVATE_COMPUTER);
- if (GameObject* button = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_MIMIRON_BUTTON)))
+ if (GameObject* button = instance->GetGameObject(DATA_MIMIRON_BUTTON))
{
button->SetGoState(GO_STATE_READY);
button->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
@@ -493,7 +493,7 @@ class boss_mimiron : public CreatureScript
switch (eventId)
{
case EVENT_SUMMON_FLAMES:
- if (Unit* worldtrigger = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_MIMIRON_WORLD_TRIGGER)))
+ if (Creature* worldtrigger = instance->GetCreature(DATA_MIMIRON_WORLD_TRIGGER))
worldtrigger->CastCustomSpell(SPELL_SCRIPT_EFFECT_SUMMON_FLAMES_INITIAL, SPELLVALUE_MAX_TARGETS, 3, NULL, true, NULL, NULL, me->GetGUID());
events.RescheduleEvent(EVENT_SUMMON_FLAMES, 28000);
break;
@@ -529,14 +529,14 @@ class boss_mimiron : public CreatureScript
events.ScheduleEvent(EVENT_VX001_ACTIVATION_4, 5000);
break;
case EVENT_VX001_ACTIVATION_4:
- if (GameObject* elevator = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_MIMIRON_ELEVATOR)))
+ if (GameObject* elevator = instance->GetGameObject(DATA_MIMIRON_ELEVATOR))
elevator->SetGoState(GO_STATE_READY);
- if (Unit* worldtrigger = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_MIMIRON_WORLD_TRIGGER)))
+ if (Creature* worldtrigger = instance->GetCreature(DATA_MIMIRON_WORLD_TRIGGER))
worldtrigger->CastSpell(worldtrigger, SPELL_ELEVATOR_KNOCKBACK);
events.ScheduleEvent(EVENT_VX001_ACTIVATION_5, 6000);
break;
case EVENT_VX001_ACTIVATION_5:
- if (GameObject* elevator = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_MIMIRON_ELEVATOR)))
+ if (GameObject* elevator = instance->GetGameObject(DATA_MIMIRON_ELEVATOR))
elevator->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
if (Creature* vx001 = me->SummonCreature(NPC_VX_001, VX001SummonPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000))
vx001->CastSpell(vx001, SPELL_FREEZE_ANIM);
@@ -644,7 +644,7 @@ class boss_mimiron : public CreatureScript
Talk(SAY_V07TRON_DEATH);
if (_fireFighter)
{
- if (Creature* computer = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_COMPUTER)))
+ if (Creature* computer = instance->GetCreature(DATA_COMPUTER))
computer->AI()->DoAction(DO_DEACTIVATE_COMPUTER);
me->SummonGameObject(RAID_MODE(GO_CACHE_OF_INNOVATION_FIREFIGHTER, GO_CACHE_OF_INNOVATION_FIREFIGHTER_HERO), 2744.040f, 2569.352f, 364.3135f, 3.124123f, QuaternionData(0.f, 0.f, 0.9999619f, 0.008734641f), 604800);
}
@@ -783,7 +783,7 @@ class boss_leviathan_mk_ii : public CreatureScript
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
- if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MIMIRON)))
+ if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON))
mimiron->AI()->Talk(events.IsInPhase(PHASE_LEVIATHAN_MK_II) ? SAY_MKII_SLAY : SAY_V07TRON_SLAY);
}
@@ -798,7 +798,7 @@ class boss_leviathan_mk_ii : public CreatureScript
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
DoCast(me, SPELL_HALF_HEAL);
- if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MIMIRON)))
+ if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON))
mimiron->AI()->DoAction(DO_ACTIVATE_VX001);
break;
case WP_MKII_P4_POS_1:
@@ -808,7 +808,7 @@ class boss_leviathan_mk_ii : public CreatureScript
events.ScheduleEvent(EVENT_MOVE_POINT_3, 1);
break;
case WP_MKII_P4_POS_3:
- if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MIMIRON)))
+ if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON))
mimiron->AI()->DoAction(DO_ACTIVATE_V0L7R0N_2);
break;
case WP_MKII_P4_POS_4:
@@ -951,7 +951,7 @@ class boss_vx_001 : public CreatureScript
me->AddUnitFlag(UNIT_FLAG_NON_ATTACKABLE); // | UNIT_FLAG_NOT_SELECTABLE);
DoCast(me, SPELL_HALF_HEAL); // has no effect, wat
DoCast(me, SPELL_TORSO_DISABLED);
- if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MIMIRON)))
+ if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON))
mimiron->AI()->DoAction(DO_ACTIVATE_AERIAL);
}
else if (events.IsInPhase(PHASE_VOL7RON))
@@ -1022,7 +1022,7 @@ class boss_vx_001 : public CreatureScript
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
- if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MIMIRON)))
+ if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON))
mimiron->AI()->Talk(events.IsInPhase(PHASE_VX_001) ? SAY_VX001_SLAY : SAY_V07TRON_SLAY);
}
@@ -1201,7 +1201,7 @@ class boss_aerial_command_unit : public CreatureScript
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
- if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MIMIRON)))
+ if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON))
mimiron->AI()->Talk(events.IsInPhase(PHASE_AERIAL_COMMAND_UNIT) ? SAY_AERIAL_SLAY : SAY_V07TRON_SLAY);
}
@@ -1211,7 +1211,7 @@ class boss_aerial_command_unit : public CreatureScript
{
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MIMIRON)))
+ if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON))
mimiron->AI()->DoAction(DO_ACTIVATE_V0L7R0N_1);
}
}
@@ -1435,7 +1435,7 @@ class npc_mimiron_computer : public CreatureScript
{
case EVENT_SELF_DESTRUCT_10:
Talk(SAY_SELF_DESTRUCT_10);
- if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MIMIRON)))
+ if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON))
mimiron->AI()->DoAction(DO_ACTIVATE_HARD_MODE);
events.ScheduleEvent(EVENT_SELF_DESTRUCT_9, 60000);
break;
@@ -1477,7 +1477,7 @@ class npc_mimiron_computer : public CreatureScript
break;
case EVENT_SELF_DESTRUCT_FINALIZED:
Talk(SAY_SELF_DESTRUCT_FINALIZED);
- if (Creature* mimiron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MIMIRON)))
+ if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON))
mimiron->AI()->DoAction(DO_ACTIVATE_SELF_DESTRUCT);
DoCast(me, SPELL_SELF_DESTRUCTION_AURA);
DoCast(me, SPELL_SELF_DESTRUCTION_VISUAL);
@@ -1658,7 +1658,7 @@ class go_mimiron_hardmode_button : public GameObjectScript
if (!instance)
return false;
- if (Creature* computer = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_COMPUTER)))
+ if (Creature* computer = instance->GetCreature(DATA_COMPUTER))
computer->AI()->DoAction(DO_ACTIVATE_COMPUTER);
go->SetGoState(GO_STATE_ACTIVE);
go->AddFlag(GO_FLAG_NOT_SELECTABLE);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
index 8a1bbfe712c..3f56f4523cc 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
@@ -189,16 +189,22 @@ class boss_razorscale_controller : public CreatureScript
public:
boss_razorscale_controller() : CreatureScript("boss_razorscale_controller") { }
- struct boss_razorscale_controllerAI : public BossAI
+ struct boss_razorscale_controllerAI : public ScriptedAI
{
- boss_razorscale_controllerAI(Creature* creature) : BossAI(creature, DATA_RAZORSCALE_CONTROL)
+ boss_razorscale_controllerAI(Creature* creature) : ScriptedAI(creature), summons(me)
{
+ instance = creature->GetInstanceScript();
me->SetDisplayFromModel(1);
}
+ InstanceScript* instance;
+ EventMap events;
+ SummonList summons;
+
void Reset() override
{
- _Reset();
+ events.Reset();
+ summons.DespawnAll();
me->SetReactState(REACT_PASSIVE);
}
@@ -207,14 +213,14 @@ class boss_razorscale_controller : public CreatureScript
switch (spell->Id)
{
case SPELL_FLAMED:
- if (GameObject* Harpoon1 = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(GO_RAZOR_HARPOON_1)))
- Harpoon1->RemoveFromWorld();
- if (GameObject* Harpoon2 = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(GO_RAZOR_HARPOON_2)))
- Harpoon2->RemoveFromWorld();
- if (GameObject* Harpoon3 = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(GO_RAZOR_HARPOON_3)))
- Harpoon3->RemoveFromWorld();
- if (GameObject* Harpoon4 = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(GO_RAZOR_HARPOON_4)))
- Harpoon4->RemoveFromWorld();
+ if (GameObject* harpoon = instance->GetGameObject(GO_RAZOR_HARPOON_1))
+ harpoon->RemoveFromWorld();
+ if (GameObject* harpoon = instance->GetGameObject(GO_RAZOR_HARPOON_2))
+ harpoon->RemoveFromWorld();
+ if (GameObject* harpoon = instance->GetGameObject(GO_RAZOR_HARPOON_3))
+ harpoon->RemoveFromWorld();
+ if (GameObject* harpoon = instance->GetGameObject(GO_RAZOR_HARPOON_4))
+ harpoon->RemoveFromWorld();
DoAction(ACTION_HARPOON_BUILD);
DoAction(ACTION_PLACE_BROKEN_HARPOON);
break;
@@ -229,7 +235,8 @@ class boss_razorscale_controller : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- _JustDied();
+ events.Reset();
+ summons.DespawnAll();
}
void DoAction(int32 action) override
@@ -261,39 +268,39 @@ class boss_razorscale_controller : public CreatureScript
{
case EVENT_BUILD_HARPOON_1:
Talk(EMOTE_HARPOON);
- if (GameObject* Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_1, PosHarpoon[0].GetPositionX(), PosHarpoon[0].GetPositionY(), PosHarpoon[0].GetPositionZ(), 4.790f, QuaternionData::fromEulerAnglesZYX(4.790f, 0.0f, 0.0f), uint32(me->GetRespawnTime())))
+ if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_1, PosHarpoon[0].GetPositionX(), PosHarpoon[0].GetPositionY(), PosHarpoon[0].GetPositionZ(), 4.790f, QuaternionData::fromEulerAnglesZYX(4.790f, 0.0f, 0.0f), uint32(me->GetRespawnTime())))
{
- if (GameObject* BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f)) //only nearest broken harpoon
- BrokenHarpoon->RemoveFromWorld();
+ if (GameObject* brokenHarpoon = harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f)) //only nearest broken harpoon
+ brokenHarpoon->RemoveFromWorld();
events.ScheduleEvent(EVENT_BUILD_HARPOON_2, 20000);
events.CancelEvent(EVENT_BUILD_HARPOON_1);
}
return;
case EVENT_BUILD_HARPOON_2:
Talk(EMOTE_HARPOON);
- if (GameObject* Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_2, PosHarpoon[1].GetPositionX(), PosHarpoon[1].GetPositionY(), PosHarpoon[1].GetPositionZ(), 4.659f, QuaternionData::fromEulerAnglesZYX(4.659f, 0.0f, 0.0f), uint32(me->GetRespawnTime())))
+ if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_2, PosHarpoon[1].GetPositionX(), PosHarpoon[1].GetPositionY(), PosHarpoon[1].GetPositionZ(), 4.659f, QuaternionData::fromEulerAnglesZYX(4.659f, 0.0f, 0.0f), uint32(me->GetRespawnTime())))
{
- if (GameObject* BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
- BrokenHarpoon->RemoveFromWorld();
+ if (GameObject* brokenHarpoon = harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
+ brokenHarpoon->RemoveFromWorld();
events.CancelEvent(EVENT_BUILD_HARPOON_2);
}
return;
case EVENT_BUILD_HARPOON_3:
Talk(EMOTE_HARPOON);
- if (GameObject* Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_3, PosHarpoon[2].GetPositionX(), PosHarpoon[2].GetPositionY(), PosHarpoon[2].GetPositionZ(), 5.382f, QuaternionData::fromEulerAnglesZYX(5.382f, 0.0f, 0.0f), uint32(me->GetRespawnTime())))
+ if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_3, PosHarpoon[2].GetPositionX(), PosHarpoon[2].GetPositionY(), PosHarpoon[2].GetPositionZ(), 5.382f, QuaternionData::fromEulerAnglesZYX(5.382f, 0.0f, 0.0f), uint32(me->GetRespawnTime())))
{
- if (GameObject* BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
- BrokenHarpoon->RemoveFromWorld();
+ if (GameObject* brokenHarpoon = harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
+ brokenHarpoon->RemoveFromWorld();
events.ScheduleEvent(EVENT_BUILD_HARPOON_4, 20000);
events.CancelEvent(EVENT_BUILD_HARPOON_3);
}
return;
case EVENT_BUILD_HARPOON_4:
Talk(EMOTE_HARPOON);
- if (GameObject* Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_4, PosHarpoon[3].GetPositionX(), PosHarpoon[3].GetPositionY(), PosHarpoon[3].GetPositionZ(), 4.266f, QuaternionData::fromEulerAnglesZYX(4.266f, 0.0f, 0.0f), uint32(me->GetRespawnTime())))
+ if (GameObject* harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_4, PosHarpoon[3].GetPositionX(), PosHarpoon[3].GetPositionY(), PosHarpoon[3].GetPositionZ(), 4.266f, QuaternionData::fromEulerAnglesZYX(4.266f, 0.0f, 0.0f), uint32(me->GetRespawnTime())))
{
- if (GameObject* BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
- BrokenHarpoon->RemoveFromWorld();
+ if (GameObject* brokenHarpoon = harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
+ brokenHarpoon->RemoveFromWorld();
events.CancelEvent(EVENT_BUILD_HARPOON_4);
}
return;
@@ -315,9 +322,9 @@ class go_razorscale_harpoon : public GameObjectScript
bool OnGossipHello(Player* /*player*/, GameObject* go) override
{
- InstanceScript* instance = go->GetInstanceScript();
- if (ObjectAccessor::GetCreature(*go, instance->GetGuidData(BOSS_RAZORSCALE)))
- go->AddFlag(GO_FLAG_NOT_SELECTABLE);
+ if (InstanceScript* instance = go->GetInstanceScript())
+ if (instance->GetCreature(BOSS_RAZORSCALE))
+ go->AddFlag(GO_FLAG_NOT_SELECTABLE);
return false;
}
};
@@ -361,14 +368,14 @@ class boss_razorscale : public CreatureScript
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_PASSIVE);
Initialize();
- if (Creature* commander = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EXPEDITION_COMMANDER)))
+ if (Creature* commander = instance->GetCreature(DATA_EXPEDITION_COMMANDER))
commander->AI()->DoAction(ACTION_COMMANDER_RESET);
}
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RAZORSCALE_CONTROL)))
+ if (Creature* controller = instance->GetCreature(DATA_RAZORSCALE_CONTROL))
controller->AI()->DoAction(ACTION_HARPOON_BUILD);
me->SetSpeedRate(MOVE_FLIGHT, 3.0f);
me->SetReactState(REACT_PASSIVE);
@@ -383,7 +390,7 @@ class boss_razorscale : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
_JustDied();
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RAZORSCALE_CONTROL)))
+ if (Creature* controller = instance->GetCreature(DATA_RAZORSCALE_CONTROL))
controller->AI()->Reset();
}
@@ -459,7 +466,7 @@ class boss_razorscale : public CreatureScript
me->SetCanFly(false);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->AddUnitFlag(UnitFlags(UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED));
- if (Creature* commander = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EXPEDITION_COMMANDER)))
+ if (Creature* commander = instance->GetCreature(DATA_EXPEDITION_COMMANDER))
commander->AI()->DoAction(ACTION_GROUND_PHASE);
events.ScheduleEvent(EVENT_BREATH, 30000, 0, PHASE_GROUND);
events.ScheduleEvent(EVENT_BUFFET, 33000, 0, PHASE_GROUND);
@@ -475,7 +482,7 @@ class boss_razorscale : public CreatureScript
return;
case EVENT_BUFFET:
DoCastAOE(SPELL_WINGBUFFET);
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RAZORSCALE_CONTROL)))
+ if (Creature* controller = instance->GetCreature(DATA_RAZORSCALE_CONTROL))
controller->CastSpell(controller, SPELL_FLAMED, true);
events.CancelEvent(EVENT_BUFFET);
return;
@@ -717,10 +724,10 @@ class npc_expedition_commander : public CreatureScript
Phase = 5;
break;
case 5:
- if (Creature* Razorscale = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_RAZORSCALE)))
+ if (Creature* razorscale = instance->GetCreature(BOSS_RAZORSCALE))
{
- Razorscale->AI()->DoAction(ACTION_EVENT_START);
- me->SetInCombatWith(Razorscale);
+ razorscale->AI()->DoAction(ACTION_EVENT_START);
+ me->SetInCombatWith(razorscale);
}
if (Creature* firstEngineer = ObjectAccessor::GetCreature(*me, Engineer[0]))
firstEngineer->AI()->Talk(SAY_AGGRO_1);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
index 0366f1534ba..c6fc0925bf6 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
@@ -176,11 +176,6 @@ class boss_xt002 : public CreatureScript
public:
boss_xt002() : CreatureScript("boss_xt002") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetUlduarAI<boss_xt002_AI>(creature);
- }
-
struct boss_xt002_AI : public BossAI
{
boss_xt002_AI(Creature* creature) : BossAI(creature, BOSS_XT002)
@@ -441,6 +436,12 @@ class boss_xt002 : public CreatureScript
uint8 _heartExposed;
uint32 _transferHealth;
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<boss_xt002_AI>(creature);
+ }
+
};
/*-------------------------------------------------------
@@ -460,7 +461,7 @@ class npc_xt002_heart : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* xt002 = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(BOSS_XT002)))
+ if (Creature* xt002 = _instance->GetCreature(BOSS_XT002))
{
xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetHealth());
xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE);
@@ -487,11 +488,6 @@ class npc_scrapbot : public CreatureScript
public:
npc_scrapbot() : CreatureScript("npc_scrapbot") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetUlduarAI<npc_scrapbotAI>(creature);
- }
-
struct npc_scrapbotAI : public ScriptedAI
{
npc_scrapbotAI(Creature* creature) : ScriptedAI(creature)
@@ -511,15 +507,15 @@ class npc_scrapbot : public CreatureScript
Initialize();
- if (Creature* pXT002 = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(BOSS_XT002)))
- me->GetMotionMaster()->MoveFollow(pXT002, 0.0f, 0.0f);
+ if (Creature* xt002 = _instance->GetCreature(BOSS_XT002))
+ me->GetMotionMaster()->MoveFollow(xt002, 0.0f, 0.0f);
}
void UpdateAI(uint32 diff) override
{
if (_rangeCheckTimer <= diff)
{
- if (Creature* xt002 = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(BOSS_XT002)))
+ if (Creature* xt002 = _instance->GetCreature(BOSS_XT002))
{
if (me->IsWithinMeleeRange(xt002))
{
@@ -538,6 +534,12 @@ class npc_scrapbot : public CreatureScript
InstanceScript* _instance;
uint32 _rangeCheckTimer;
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_scrapbotAI>(creature);
+ }
+
};
/*-------------------------------------------------------
@@ -550,11 +552,6 @@ class npc_pummeller : public CreatureScript
public:
npc_pummeller() : CreatureScript("npc_pummeller") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetUlduarAI<npc_pummellerAI>(creature);
- }
-
struct npc_pummellerAI : public ScriptedAI
{
npc_pummellerAI(Creature* creature) : ScriptedAI(creature)
@@ -574,7 +571,7 @@ class npc_pummeller : public CreatureScript
{
Initialize();
- if (Creature* xt002 = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(BOSS_XT002)))
+ if (Creature* xt002 = _instance->GetCreature(BOSS_XT002))
{
Position pos = xt002->GetPosition();
me->GetMotionMaster()->MovePoint(0, pos);
@@ -622,6 +619,12 @@ class npc_pummeller : public CreatureScript
uint32 _trampleTimer;
uint32 _uppercutTimer;
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_pummellerAI>(creature);
+ }
+
};
/*-------------------------------------------------------
@@ -657,11 +660,6 @@ class npc_boombot : public CreatureScript
public:
npc_boombot() : CreatureScript("npc_boombot") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetUlduarAI<npc_boombotAI>(creature);
- }
-
struct npc_boombotAI : public ScriptedAI
{
npc_boombotAI(Creature* creature) : ScriptedAI(creature)
@@ -682,8 +680,8 @@ class npc_boombot : public CreatureScript
DoCast(SPELL_AURA_BOOMBOT); // For achievement
/// @todo proper waypoints?
- if (Creature* pXT002 = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(BOSS_XT002)))
- me->GetMotionMaster()->MoveFollow(pXT002, 0.0f, 0.0f);
+ if (Creature* xt002 = _instance->GetCreature(BOSS_XT002))
+ me->GetMotionMaster()->MoveFollow(xt002, 0.0f, 0.0f);
}
void DamageTaken(Unit* /*who*/, uint32& damage) override
@@ -723,6 +721,12 @@ class npc_boombot : public CreatureScript
InstanceScript* _instance;
bool _boomed;
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_boombotAI>(creature);
+ }
+
};
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 6c1101d433d..79214b5b0e1 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
@@ -511,7 +511,7 @@ class boss_voice_of_yogg_saron : public CreatureScript
void EnterCombat(Unit* /*who*/) override
{
- if (Creature* sara = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SARA)))
+ if (Creature* sara = instance->GetCreature(DATA_SARA))
sara->SetInCombatWith(me);
for (uint8 i = DATA_FREYA_YS; i <= DATA_MIMIRON_YS; ++i)
@@ -531,7 +531,7 @@ class boss_voice_of_yogg_saron : public CreatureScript
void JustDied(Unit* killer) override
{
// don't despawn Yogg-Saron's corpse, remove him from SummonList!
- if (Creature* yogg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_YOGG_SARON)))
+ if (Creature* yogg = instance->GetCreature(BOSS_YOGG_SARON))
summons.Despawn(yogg);
BossAI::JustDied(killer);
@@ -556,7 +556,7 @@ class boss_voice_of_yogg_saron : public CreatureScript
instance->SetBossState(BOSS_YOGG_SARON, IN_PROGRESS);
break;
case EVENT_EXTINGUISH_ALL_LIFE:
- if (Creature* yogg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_YOGG_SARON)))
+ if (Creature* yogg = instance->GetCreature(BOSS_YOGG_SARON))
{
yogg->AI()->Talk(EMOTE_YOGG_SARON_EXTINGUISH_ALL_LIFE, me);
yogg->CastSpell((Unit*)NULL, SPELL_EXTINGUISH_ALL_LIFE, true);
@@ -584,7 +584,7 @@ class boss_voice_of_yogg_saron : public CreatureScript
break;
case EVENT_ILLUSION:
{
- if (Creature* yogg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_YOGG_SARON)))
+ if (Creature* yogg = instance->GetCreature(BOSS_YOGG_SARON))
{
yogg->AI()->Talk(EMOTE_YOGG_SARON_MADNESS);
yogg->AI()->Talk(SAY_YOGG_SARON_MADNESS);
@@ -597,7 +597,7 @@ class boss_voice_of_yogg_saron : public CreatureScript
uint8 illusion = urand(CHAMBER_ILLUSION, STORMWIND_ILLUSION);
instance->SetData(DATA_ILLUSION, illusion);
- if (Creature* brain = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRAIN_OF_YOGG_SARON)))
+ if (Creature* brain = instance->GetCreature(DATA_BRAIN_OF_YOGG_SARON))
brain->AI()->DoAction(ACTION_INDUCE_MADNESS);
events.ScheduleEvent(EVENT_ILLUSION, 80000, 0, PHASE_TWO); // wowwiki says 80 secs, wowhead says something about 90 secs
break;
@@ -623,7 +623,7 @@ class boss_voice_of_yogg_saron : public CreatureScript
case ACTION_PHASE_TWO:
events.SetPhase(PHASE_TWO);
me->SummonCreature(NPC_YOGG_SARON, YoggSaronSpawnPos);
- if (Creature* brain = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRAIN_OF_YOGG_SARON)))
+ if (Creature* brain = instance->GetCreature(DATA_BRAIN_OF_YOGG_SARON))
brain->SetInCombatWithZone();
events.ScheduleEvent(EVENT_SUMMON_CORRUPTOR_TENTACLE, 1, EVENT_GROUP_SUMMON_TENTACLES, PHASE_TWO);
events.ScheduleEvent(EVENT_SUMMON_CONSTRICTOR_TENTACLE, 1, EVENT_GROUP_SUMMON_TENTACLES, PHASE_TWO);
@@ -722,7 +722,7 @@ class boss_sara : public CreatureScript
if (_events.IsInPhase(PHASE_ONE))
{
- if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VOICE_OF_YOGG_SARON)))
+ if (Creature* voice = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
voice->AI()->DoAction(ACTION_PHASE_TRANSFORM);
Talk(SAY_SARA_TRANSFORM_1);
@@ -818,14 +818,14 @@ class boss_sara : public CreatureScript
Talk(SAY_SARA_TRANSFORM_4);
DoCast(me, SPELL_FULL_HEAL);
me->setFaction(16);
- if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VOICE_OF_YOGG_SARON)))
+ if (Creature* voice = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
voice->AI()->DoAction(ACTION_PHASE_TWO);
if (Creature* mimiron = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_MIMIRON_YS)))
mimiron->AI()->DoAction(ACTION_PHASE_TWO);
break;
case EVENT_TRANSFORM_4:
DoCast(me, SPELL_PHASE_2_TRANSFORM);
- if (Creature* yogg = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(BOSS_YOGG_SARON)))
+ if (Creature* yogg = _instance->GetCreature(BOSS_YOGG_SARON))
DoCast(yogg, SPELL_RIDE_YOGG_SARON_VEHICLE);
DoCast(me, SPELL_SHADOWY_BARRIER_SARA);
_events.SetPhase(PHASE_TWO);
@@ -881,7 +881,7 @@ class boss_sara : public CreatureScript
break;
}
- if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VOICE_OF_YOGG_SARON)))
+ if (Creature* voice = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
voice->AI()->JustSummoned(summon);
}
@@ -948,7 +948,7 @@ class boss_yogg_saron : public CreatureScript
{
Talk(SAY_YOGG_SARON_DEATH);
- if (Creature* creature = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VOICE_OF_YOGG_SARON)))
+ if (Creature* creature = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
me->Kill(creature);
for (uint8 i = DATA_SARA; i <= DATA_BRAIN_OF_YOGG_SARON; ++i)
@@ -1065,11 +1065,11 @@ class boss_brain_of_yogg_saron : public CreatureScript
DoCast(me, SPELL_BRAIN_HURT_VISUAL, true);
me->AddUnitFlag(UnitFlags(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE));
- if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VOICE_OF_YOGG_SARON)))
+ if (Creature* voice = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
voice->AI()->DoAction(ACTION_PHASE_THREE);
- if (Creature* sara = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SARA)))
+ if (Creature* sara = _instance->GetCreature(DATA_SARA))
sara->AI()->DoAction(ACTION_PHASE_THREE);
- if (Creature* yogg = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(BOSS_YOGG_SARON)))
+ if (Creature* yogg = _instance->GetCreature(BOSS_YOGG_SARON))
yogg->AI()->DoAction(ACTION_PHASE_THREE);
for (uint8 i = DATA_THORIM_YS; i <= DATA_MIMIRON_YS; ++i)
@@ -1107,7 +1107,7 @@ class boss_brain_of_yogg_saron : public CreatureScript
DoCastAOE(SPELL_SHATTERED_ILLUSION, true);
_instance->HandleGameObject(_instance->GetGuidData(GO_BRAIN_ROOM_DOOR_1 + illusion), true);
- if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VOICE_OF_YOGG_SARON)))
+ if (Creature* voice = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
voice->AI()->DoAction(ACTION_TOGGLE_SHATTERED_ILLUSION);
}
break;
@@ -1214,7 +1214,7 @@ class npc_guardian_of_yogg_saron : public CreatureScript
return;
// Guardian can be summoned both by Voice of Yogg-Saron and by Ominous Cloud
- if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VOICE_OF_YOGG_SARON)))
+ if (Creature* voice = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
voice->AI()->JustSummoned(me);
}
@@ -1317,7 +1317,7 @@ class npc_constrictor_tentacle : public CreatureScript
void IsSummonedBy(Unit* /*summoner*/) override
{
- if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VOICE_OF_YOGG_SARON)))
+ if (Creature* voice = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
voice->AI()->JustSummoned(me);
}
@@ -1408,7 +1408,7 @@ class npc_influence_tentacle : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (Creature* brain = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_BRAIN_OF_YOGG_SARON)))
+ if (Creature* brain = _instance->GetCreature(DATA_BRAIN_OF_YOGG_SARON))
brain->AI()->DoAction(ACTION_TENTACLE_KILLED);
}
@@ -2779,7 +2779,7 @@ class spell_yogg_saron_induce_madness : public SpellScriptLoader // 64059
GetCaster()->CastSpell((Unit*)NULL, SPELL_SHATTERED_ILLUSION_REMOVE);
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
- if (Creature* voice = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_VOICE_OF_YOGG_SARON)))
+ if (Creature* voice = instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
voice->AI()->DoAction(ACTION_TOGGLE_SHATTERED_ILLUSION);
}
@@ -3053,7 +3053,9 @@ class spell_yogg_saron_in_the_maws_of_the_old_god : public SpellScriptLoader
SpellCastResult CheckRequirement()
{
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
- if (Creature* yogg = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(BOSS_YOGG_SARON)))
+ {
+ if (Creature* yogg = instance->GetCreature(BOSS_YOGG_SARON))
+ {
if (yogg->FindCurrentSpellBySpellId(SPELL_DEAFENING_ROAR))
{
if (GetCaster()->GetDistance(yogg) > 20.0f)
@@ -3061,6 +3063,8 @@ class spell_yogg_saron_in_the_maws_of_the_old_god : public SpellScriptLoader
else
return SPELL_CAST_OK;
}
+ }
+ }
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
index 3683e9f5ea3..d34a7ac516c 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
@@ -79,6 +79,28 @@ MinionData const minionData[] =
ObjectData const creatureData[] =
{
+ { NPC_FLAME_LEVIATHAN, BOSS_LEVIATHAN },
+ { NPC_IGNIS, BOSS_IGNIS },
+ { NPC_RAZORSCALE, BOSS_RAZORSCALE },
+ { NPC_XT002, BOSS_XT002 },
+ { NPC_KOLOGARN, BOSS_KOLOGARN },
+ { NPC_AURIAYA, BOSS_AURIAYA },
+ { NPC_HODIR, BOSS_HODIR },
+ { NPC_THORIM, BOSS_THORIM },
+ { NPC_FREYA, BOSS_FREYA },
+ { NPC_MIMIRON, BOSS_MIMIRON },
+ { NPC_VEZAX, BOSS_VEZAX },
+ { NPC_YOGG_SARON, BOSS_YOGG_SARON },
+ { NPC_ALGALON, BOSS_ALGALON },
+
+ { NPC_EXPEDITION_COMMANDER, DATA_EXPEDITION_COMMANDER },
+ { NPC_RAZORSCALE_CONTROLLER, DATA_RAZORSCALE_CONTROL },
+ { NPC_COMPUTER, DATA_COMPUTER },
+ { NPC_WORLD_TRIGGER_MIMIRON, DATA_MIMIRON_WORLD_TRIGGER },
+ { NPC_VOICE_OF_YOGG_SARON, DATA_VOICE_OF_YOGG_SARON },
+ { NPC_SARA, DATA_SARA },
+ { NPC_BRAIN_OF_YOGG_SARON, DATA_BRAIN_OF_YOGG_SARON },
+ { NPC_BRANN_BRONZBEARD_ALG, DATA_BRANN_BRONZEBEARD_ALG },
{ NPC_BRANN_BRONZEBEARD_INTRO, DATA_BRANN_BRONZEBEARD_INTRO },
{ NPC_LORE_KEEPER_OF_NORGANNON, DATA_LORE_KEEPER_OF_NORGANNON },
{ NPC_HIGH_EXPLORER_DELLORAH, DATA_DELLORAH },
@@ -86,6 +108,19 @@ ObjectData const creatureData[] =
{ 0, 0, }
};
+ObjectData const objectData[] =
+{
+ { GO_MIMIRON_ELEVATOR, DATA_MIMIRON_ELEVATOR },
+ { GO_MIMIRON_BUTTON, DATA_MIMIRON_BUTTON },
+ { GO_DOODAD_UL_UNIVERSEGLOBE01, DATA_UNIVERSE_GLOBE },
+ { GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, DATA_ALGALON_TRAPDOOR },
+ { GO_RAZOR_HARPOON_1, GO_RAZOR_HARPOON_1 },
+ { GO_RAZOR_HARPOON_2, GO_RAZOR_HARPOON_2 },
+ { GO_RAZOR_HARPOON_3, GO_RAZOR_HARPOON_3 },
+ { GO_RAZOR_HARPOON_4, GO_RAZOR_HARPOON_4 },
+ { 0, 0 }
+};
+
class instance_ulduar : public InstanceMapScript
{
public:
@@ -100,7 +135,7 @@ class instance_ulduar : public InstanceMapScript
LoadBossBoundaries(boundaries);
LoadDoorData(doorData);
LoadMinionData(minionData);
- LoadObjectData(creatureData, nullptr);
+ LoadObjectData(creatureData, objectData);
_algalonTimer = 61;
_maxArmorItemLevel = 0;
@@ -124,51 +159,29 @@ class instance_ulduar : public InstanceMapScript
}
// Creatures
- ObjectGuid LeviathanGUID;
GuidVector LeviathanVehicleGUIDs;
- ObjectGuid IgnisGUID;
- ObjectGuid RazorscaleGUID;
- ObjectGuid RazorscaleController;
- ObjectGuid ExpeditionCommanderGUID;
- ObjectGuid XT002GUID;
+
ObjectGuid XTToyPileGUIDs[4];
ObjectGuid AssemblyGUIDs[3];
- ObjectGuid KologarnGUID;
- ObjectGuid AuriayaGUID;
- ObjectGuid HodirGUID;
- ObjectGuid ThorimGUID;
- ObjectGuid FreyaGUID;
+
ObjectGuid ElderGUIDs[3];
ObjectGuid FreyaAchieveTriggerGUID;
- ObjectGuid MimironGUID;
ObjectGuid MimironVehicleGUIDs[3];
- ObjectGuid MimironComputerGUID;
- ObjectGuid MimironWorldTriggerGUID;
- ObjectGuid VezaxGUID;
- ObjectGuid YoggSaronGUID;
- ObjectGuid VoiceOfYoggSaronGUID;
- ObjectGuid SaraGUID;
- ObjectGuid BrainOfYoggSaronGUID;
ObjectGuid KeeperGUIDs[4];
- ObjectGuid AlgalonGUID;
- ObjectGuid BrannBronzebeardAlgGUID;
// GameObjects
ObjectGuid LeviathanGateGUID;
- ObjectGuid RazorHarpoonGUIDs[4];
ObjectGuid KologarnChestGUID;
ObjectGuid KologarnBridgeGUID;
ObjectGuid ThorimChestGUID;
ObjectGuid HodirRareCacheGUID;
ObjectGuid HodirChestGUID;
ObjectGuid MimironTramGUID;
- ObjectGuid MimironElevatorGUID;
- ObjectGuid MimironButtonGUID;
+
ObjectGuid BrainRoomDoorGUIDs[3];
ObjectGuid AlgalonSigilDoorGUID[3];
ObjectGuid AlgalonFloorGUID[2];
- ObjectGuid AlgalonUniverseGUID;
- ObjectGuid AlgalonTrapdoorGUID;
+
ObjectGuid GiftOfTheObserverGUID;
// Miscellaneous
@@ -239,6 +252,8 @@ class instance_ulduar : public InstanceMapScript
void OnCreatureCreate(Creature* creature) override
{
+ InstanceScript::OnCreatureCreate(creature);
+
if (!TeamInInstance)
{
Map::PlayerList const& Players = instance->GetPlayers();
@@ -249,40 +264,22 @@ class instance_ulduar : public InstanceMapScript
switch (creature->GetEntry())
{
- case NPC_LEVIATHAN:
- LeviathanGUID = creature->GetGUID();
- break;
case NPC_SALVAGED_DEMOLISHER:
case NPC_SALVAGED_SIEGE_ENGINE:
case NPC_SALVAGED_CHOPPER:
LeviathanVehicleGUIDs.push_back(creature->GetGUID());
break;
- case NPC_IGNIS:
- IgnisGUID = creature->GetGUID();
- break;
-
- // Razorscale
- case NPC_RAZORSCALE:
- RazorscaleGUID = creature->GetGUID();
- break;
- case NPC_RAZORSCALE_CONTROLLER:
- RazorscaleController = creature->GetGUID();
- break;
- case NPC_EXPEDITION_COMMANDER:
- ExpeditionCommanderGUID = creature->GetGUID();
- break;
// XT-002 Deconstructor
- case NPC_XT002:
- XT002GUID = creature->GetGUID();
- break;
case NPC_XT_TOY_PILE:
for (uint8 i = 0; i < 4; ++i)
+ {
if (!XTToyPileGUIDs[i])
{
XTToyPileGUIDs[i] = creature->GetGUID();
break;
}
+ }
break;
// Assembly of Iron
@@ -299,17 +296,7 @@ class instance_ulduar : public InstanceMapScript
AddMinion(creature, true);
break;
- case NPC_KOLOGARN:
- KologarnGUID = creature->GetGUID();
- break;
- case NPC_AURIAYA:
- AuriayaGUID = creature->GetGUID();
- break;
-
// Hodir
- case NPC_HODIR:
- HodirGUID = creature->GetGUID();
- break;
case NPC_EIVI_NIGHTFEATHER:
if (TeamInInstance == HORDE)
creature->UpdateEntry(NPC_TOR_GREYCLOUD);
@@ -343,14 +330,7 @@ class instance_ulduar : public InstanceMapScript
creature->UpdateEntry(NPC_BATTLE_PRIEST_GINA);
break;
- case NPC_THORIM:
- ThorimGUID = creature->GetGUID();
- break;
-
// Freya
- case NPC_FREYA:
- FreyaGUID = creature->GetGUID();
- break;
case NPC_IRONBRANCH:
ElderGUIDs[0] = creature->GetGUID();
if (GetBossState(BOSS_FREYA) == DONE)
@@ -371,9 +351,6 @@ class instance_ulduar : public InstanceMapScript
break;
// Mimiron
- case NPC_MIMIRON:
- MimironGUID = creature->GetGUID();
- break;
case NPC_LEVIATHAN_MKII:
MimironVehicleGUIDs[0] = creature->GetGUID();
break;
@@ -383,30 +360,8 @@ class instance_ulduar : public InstanceMapScript
case NPC_AERIAL_COMMAND_UNIT:
MimironVehicleGUIDs[2] = creature->GetGUID();
break;
- case NPC_COMPUTER:
- MimironComputerGUID = creature->GetGUID();
- break;
- case NPC_WORLD_TRIGGER_MIMIRON:
- MimironWorldTriggerGUID = creature->GetGUID();
- break;
-
- case NPC_VEZAX:
- VezaxGUID = creature->GetGUID();
- break;
// Yogg-Saron
- case NPC_YOGG_SARON:
- YoggSaronGUID = creature->GetGUID();
- break;
- case NPC_VOICE_OF_YOGG_SARON:
- VoiceOfYoggSaronGUID = creature->GetGUID();
- break;
- case NPC_BRAIN_OF_YOGG_SARON:
- BrainOfYoggSaronGUID = creature->GetGUID();
- break;
- case NPC_SARA:
- SaraGUID = creature->GetGUID();
- break;
case NPC_FREYA_YS:
KeeperGUIDs[0] = creature->GetGUID();
_summonYSKeeper[0] = false;
@@ -436,12 +391,6 @@ class instance_ulduar : public InstanceMapScript
break;
// Algalon
- case NPC_ALGALON:
- AlgalonGUID = creature->GetGUID();
- break;
- case NPC_BRANN_BRONZBEARD_ALG:
- BrannBronzebeardAlgGUID = creature->GetGUID();
- break;
//! These creatures are summoned by something else than Algalon
//! but need to be controlled/despawned by him - so they need to be
//! registered in his summon list
@@ -449,7 +398,7 @@ class instance_ulduar : public InstanceMapScript
case NPC_ALGALON_STALKER_ASTEROID_TARGET_01:
case NPC_ALGALON_STALKER_ASTEROID_TARGET_02:
case NPC_UNLEASHED_DARK_MATTER:
- if (Creature* algalon = instance->GetCreature(AlgalonGUID))
+ if (Creature* algalon = GetCreature(BOSS_ALGALON))
algalon->AI()->JustSummoned(creature);
break;
}
@@ -459,34 +408,34 @@ class instance_ulduar : public InstanceMapScript
void OnCreatureRemove(Creature* creature) override
{
+ InstanceScript::OnCreatureRemove(creature);
+
switch (creature->GetEntry())
{
case NPC_XT_TOY_PILE:
for (uint8 i = 0; i < 4; ++i)
+ {
if (XTToyPileGUIDs[i] == creature->GetGUID())
{
XTToyPileGUIDs[i].Clear();
break;
}
+ }
break;
case NPC_STEELBREAKER:
case NPC_MOLGEIM:
case NPC_BRUNDIR:
AddMinion(creature, false);
break;
- case NPC_BRANN_BRONZBEARD_ALG:
- if (BrannBronzebeardAlgGUID == creature->GetGUID())
- BrannBronzebeardAlgGUID.Clear();
- break;
default:
break;
}
-
- InstanceScript::OnCreatureRemove(creature);
}
void OnGameObjectCreate(GameObject* gameObject) override
{
+ InstanceScript::OnGameObjectCreate(gameObject);
+
switch (gameObject->GetEntry())
{
case GO_KOLOGARN_CHEST_HERO:
@@ -513,43 +462,11 @@ class instance_ulduar : public InstanceMapScript
case GO_MIMIRON_TRAM:
MimironTramGUID = gameObject->GetGUID();
break;
- case GO_MIMIRON_ELEVATOR:
- MimironElevatorGUID = gameObject->GetGUID();
- break;
- case GO_MIMIRON_BUTTON:
- MimironButtonGUID = gameObject->GetGUID();
- break;
case GO_LEVIATHAN_GATE:
LeviathanGateGUID = gameObject->GetGUID();
if (GetBossState(BOSS_LEVIATHAN) == DONE)
gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
break;
- case GO_LEVIATHAN_DOOR:
- case GO_XT_002_DOOR:
- case GO_IRON_COUNCIL_DOOR:
- case GO_ARCHIVUM_DOOR:
- case GO_HODIR_ENTRANCE:
- case GO_HODIR_DOOR:
- case GO_HODIR_ICE_DOOR:
- case GO_MIMIRON_DOOR_1:
- case GO_MIMIRON_DOOR_2:
- case GO_MIMIRON_DOOR_3:
- case GO_VEZAX_DOOR:
- case GO_YOGG_SARON_DOOR:
- AddDoor(gameObject, true);
- break;
- case GO_RAZOR_HARPOON_1:
- RazorHarpoonGUIDs[0] = gameObject->GetGUID();
- break;
- case GO_RAZOR_HARPOON_2:
- RazorHarpoonGUIDs[1] = gameObject->GetGUID();
- break;
- case GO_RAZOR_HARPOON_3:
- RazorHarpoonGUIDs[2] = gameObject->GetGUID();
- break;
- case GO_RAZOR_HARPOON_4:
- RazorHarpoonGUIDs[3] = gameObject->GetGUID();
- break;
case GO_MOLE_MACHINE:
if (GetBossState(BOSS_RAZORSCALE) == IN_PROGRESS)
gameObject->SetGoState(GO_STATE_ACTIVE);
@@ -580,23 +497,12 @@ class instance_ulduar : public InstanceMapScript
break;
case GO_DOODAD_UL_SIGILDOOR_03:
AlgalonSigilDoorGUID[2] = gameObject->GetGUID();
- AddDoor(gameObject, true);
break;
case GO_DOODAD_UL_UNIVERSEFLOOR_01:
AlgalonFloorGUID[0] = gameObject->GetGUID();
- AddDoor(gameObject, true);
break;
case GO_DOODAD_UL_UNIVERSEFLOOR_02:
AlgalonFloorGUID[1] = gameObject->GetGUID();
- AddDoor(gameObject, true);
- break;
- case GO_DOODAD_UL_UNIVERSEGLOBE01:
- AlgalonUniverseGUID = gameObject->GetGUID();
- AddDoor(gameObject, true);
- break;
- case GO_DOODAD_UL_ULDUAR_TRAPDOOR_03:
- AlgalonTrapdoorGUID = gameObject->GetGUID();
- AddDoor(gameObject, true);
break;
case GO_GIFT_OF_THE_OBSERVER_10:
case GO_GIFT_OF_THE_OBSERVER_25:
@@ -607,40 +513,12 @@ class instance_ulduar : public InstanceMapScript
}
}
- void OnGameObjectRemove(GameObject* gameObject) override
- {
- switch (gameObject->GetEntry())
- {
- case GO_LEVIATHAN_DOOR:
- case GO_XT_002_DOOR:
- case GO_IRON_COUNCIL_DOOR:
- case GO_ARCHIVUM_DOOR:
- case GO_HODIR_ENTRANCE:
- case GO_HODIR_DOOR:
- case GO_HODIR_ICE_DOOR:
- case GO_MIMIRON_DOOR_1:
- case GO_MIMIRON_DOOR_2:
- case GO_MIMIRON_DOOR_3:
- case GO_VEZAX_DOOR:
- case GO_YOGG_SARON_DOOR:
- case GO_DOODAD_UL_SIGILDOOR_03:
- case GO_DOODAD_UL_UNIVERSEFLOOR_01:
- case GO_DOODAD_UL_UNIVERSEFLOOR_02:
- case GO_DOODAD_UL_UNIVERSEGLOBE01:
- case GO_DOODAD_UL_ULDUAR_TRAPDOOR_03:
- AddDoor(gameObject, false);
- break;
- default:
- break;
- }
- }
-
void OnUnitDeath(Unit* unit) override
{
// Champion/Conqueror of Ulduar
if (unit->GetTypeId() == TYPEID_PLAYER)
{
- for (uint8 i = 0; i < BOSS_ALGALON; i++)
+ for (uint8 i = 0; i < BOSS_ALGALON; ++i)
{
if (GetBossState(i) == IN_PROGRESS)
{
@@ -686,27 +564,27 @@ class instance_ulduar : public InstanceMapScript
void ProcessEvent(WorldObject* /*gameObject*/, uint32 eventId) override
{
- // Flame Leviathan's Tower Event triggers
- Creature* FlameLeviathan = instance->GetCreature(LeviathanGUID);
-
switch (eventId)
{
+ // Flame Leviathan's Tower Event triggers
case EVENT_TOWER_OF_STORM_DESTROYED:
- if (FlameLeviathan && FlameLeviathan->IsAlive())
- FlameLeviathan->AI()->DoAction(ACTION_TOWER_OF_STORM_DESTROYED);
+ if (Creature* flameLeviathan = GetCreature(BOSS_LEVIATHAN))
+ flameLeviathan->AI()->DoAction(ACTION_TOWER_OF_STORM_DESTROYED);
break;
case EVENT_TOWER_OF_FROST_DESTROYED:
- if (FlameLeviathan && FlameLeviathan->IsAlive())
- FlameLeviathan->AI()->DoAction(ACTION_TOWER_OF_FROST_DESTROYED);
+ if (Creature* flameLeviathan = GetCreature(BOSS_LEVIATHAN))
+ flameLeviathan->AI()->DoAction(ACTION_TOWER_OF_FROST_DESTROYED);
break;
case EVENT_TOWER_OF_FLAMES_DESTROYED:
- if (FlameLeviathan && FlameLeviathan->IsAlive())
- FlameLeviathan->AI()->DoAction(ACTION_TOWER_OF_FLAMES_DESTROYED);
+ if (Creature* flameLeviathan = GetCreature(BOSS_LEVIATHAN))
+ flameLeviathan->AI()->DoAction(ACTION_TOWER_OF_FLAMES_DESTROYED);
break;
case EVENT_TOWER_OF_LIFE_DESTROYED:
- if (FlameLeviathan && FlameLeviathan->IsAlive())
- FlameLeviathan->AI()->DoAction(ACTION_TOWER_OF_LIFE_DESTROYED);
+ if (Creature* flameLeviathan = GetCreature(BOSS_LEVIATHAN))
+ flameLeviathan->AI()->DoAction(ACTION_TOWER_OF_LIFE_DESTROYED);
break;
+
+ // Yogg-Saron Event triggers
case EVENT_ACTIVATE_SANITY_WELL:
if (Creature* freya = instance->GetCreature(KeeperGUIDs[0]))
freya->AI()->DoAction(4/*ACTION_SANITY_WELLS*/);
@@ -851,9 +729,9 @@ class instance_ulduar : public InstanceMapScript
HodirRareCacheData = data;
if (!HodirRareCacheData)
{
- if (Creature* Hodir = instance->GetCreature(HodirGUID))
+ if (Creature* hodir = GetCreature(BOSS_HODIR))
if (GameObject* gameObject = instance->GetGameObject(HodirRareCacheGUID))
- Hodir->RemoveGameObject(gameObject, false);
+ hodir->RemoveGameObject(gameObject, false);
}
break;
case DATA_UNBROKEN:
@@ -888,30 +766,7 @@ class instance_ulduar : public InstanceMapScript
{
switch (data)
{
- case BOSS_LEVIATHAN:
- return LeviathanGUID;
- case BOSS_IGNIS:
- return IgnisGUID;
-
- // Razorscale
- case BOSS_RAZORSCALE:
- return RazorscaleGUID;
- case DATA_RAZORSCALE_CONTROL:
- return RazorscaleController;
- case DATA_EXPEDITION_COMMANDER:
- return ExpeditionCommanderGUID;
- case GO_RAZOR_HARPOON_1:
- return RazorHarpoonGUIDs[0];
- case GO_RAZOR_HARPOON_2:
- return RazorHarpoonGUIDs[1];
- case GO_RAZOR_HARPOON_3:
- return RazorHarpoonGUIDs[2];
- case GO_RAZOR_HARPOON_4:
- return RazorHarpoonGUIDs[3];
-
// XT-002 Deconstructor
- case BOSS_XT002:
- return XT002GUID;
case DATA_TOY_PILE_0:
case DATA_TOY_PILE_1:
case DATA_TOY_PILE_2:
@@ -926,18 +781,7 @@ class instance_ulduar : public InstanceMapScript
case DATA_BRUNDIR:
return AssemblyGUIDs[2];
- case BOSS_KOLOGARN:
- return KologarnGUID;
- case BOSS_AURIAYA:
- return AuriayaGUID;
- case BOSS_HODIR:
- return HodirGUID;
- case BOSS_THORIM:
- return ThorimGUID;
-
// Freya
- case BOSS_FREYA:
- return FreyaGUID;
case BOSS_BRIGHTLEAF:
return ElderGUIDs[0];
case BOSS_IRONBRANCH:
@@ -946,35 +790,14 @@ class instance_ulduar : public InstanceMapScript
return ElderGUIDs[2];
// Mimiron
- case BOSS_MIMIRON:
- return MimironGUID;
case DATA_LEVIATHAN_MK_II:
return MimironVehicleGUIDs[0];
case DATA_VX_001:
return MimironVehicleGUIDs[1];
case DATA_AERIAL_COMMAND_UNIT:
return MimironVehicleGUIDs[2];
- case DATA_COMPUTER:
- return MimironComputerGUID;
- case DATA_MIMIRON_WORLD_TRIGGER:
- return MimironWorldTriggerGUID;
- case DATA_MIMIRON_ELEVATOR:
- return MimironElevatorGUID;
- case DATA_MIMIRON_BUTTON:
- return MimironButtonGUID;
-
- case BOSS_VEZAX:
- return VezaxGUID;
// Yogg-Saron
- case BOSS_YOGG_SARON:
- return YoggSaronGUID;
- case DATA_VOICE_OF_YOGG_SARON:
- return VoiceOfYoggSaronGUID;
- case DATA_BRAIN_OF_YOGG_SARON:
- return BrainOfYoggSaronGUID;
- case DATA_SARA:
- return SaraGUID;
case GO_BRAIN_ROOM_DOOR_1:
return BrainRoomDoorGUIDs[0];
case GO_BRAIN_ROOM_DOOR_2:
@@ -991,8 +814,6 @@ class instance_ulduar : public InstanceMapScript
return KeeperGUIDs[3];
// Algalon
- case BOSS_ALGALON:
- return AlgalonGUID;
case DATA_SIGILDOOR_01:
return AlgalonSigilDoorGUID[0];
case DATA_SIGILDOOR_02:
@@ -1003,15 +824,9 @@ class instance_ulduar : public InstanceMapScript
return AlgalonFloorGUID[0];
case DATA_UNIVERSE_FLOOR_02:
return AlgalonFloorGUID[1];
- case DATA_UNIVERSE_GLOBE:
- return AlgalonUniverseGUID;
- case DATA_ALGALON_TRAPDOOR:
- return AlgalonTrapdoorGUID;
- case DATA_BRANN_BRONZEBEARD_ALG:
- return BrannBronzebeardAlgGUID;
}
- return ObjectGuid::Empty;
+ return InstanceScript::GetGuidData(data);
}
uint32 GetData(uint32 type) const override
@@ -1179,7 +994,7 @@ class instance_ulduar : public InstanceMapScript
{
DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 0);
_events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER);
- if (Creature* algalon = instance->GetCreature(AlgalonGUID))
+ if (Creature* algalon = GetCreature(BOSS_ALGALON))
algalon->AI()->DoAction(EVENT_DESPAWN_ALGALON);
}
break;
@@ -1200,8 +1015,8 @@ class instance_ulduar : public InstanceMapScript
}
break;
case EVENT_LEVIATHAN_BREAK_DOOR:
- if (Creature* Leviathan = instance->GetCreature(LeviathanGUID))
- Leviathan->AI()->DoAction(ACTION_MOVE_TO_CENTER_POSITION);
+ if (Creature* leviathan = GetCreature(BOSS_LEVIATHAN))
+ leviathan->AI()->DoAction(ACTION_MOVE_TO_CENTER_POSITION);
if (GameObject* gameObject = instance->GetGameObject(LeviathanGateGUID))
gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
break;
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
index 74adb6d1d13..a26b699b396 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
@@ -279,7 +279,7 @@ enum UlduarGameObjects
GO_GIFT_OF_THE_OBSERVER_25 = 194822,
};
-enum EventIds
+enum UUEventIds
{
EVENT_TOWER_OF_STORM_DESTROYED = 21031,
EVENT_TOWER_OF_FROST_DESTROYED = 21032,
diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp
index e7f17a1033b..0e42a431d93 100644
--- a/src/server/scripts/Northrend/zone_zuldrak.cpp
+++ b/src/server/scripts/Northrend/zone_zuldrak.cpp
@@ -58,7 +58,7 @@ public:
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
float x, y, z;
- me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 0.1f);
+ me->GetClosePoint(x, y, z, me->GetCombatReach() / 3, 0.1f);
if (Creature* summon = me->SummonCreature(NPC_RAGECLAW, x, y, z, 0, TEMPSUMMON_DEAD_DESPAWN, 1000))
{
@@ -183,7 +183,7 @@ public:
void Reset() override
{
float x, y, z;
- me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 25.0f);
+ me->GetClosePoint(x, y, z, me->GetCombatReach() / 3, 25.0f);
me->GetMotionMaster()->MovePoint(0, x, y, z);
}
diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
index e2e8a6bbef7..50fbd937d53 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
@@ -351,6 +351,8 @@ public:
Talk(SUFF_SAY_RECAP);
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
+ events.Reset();
+ me->InterruptNonMeleeSpells(false);
me->GetMotionMaster()->MovePoint(RELIQUARY_DESPAWN_WAYPOINT, DespawnPoint);
}
}
@@ -479,6 +481,8 @@ public:
Talk(DESI_SAY_RECAP);
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
+ events.Reset();
+ me->InterruptNonMeleeSpells(false);
me->GetMotionMaster()->MovePoint(RELIQUARY_DESPAWN_WAYPOINT, DespawnPoint);
}
}
@@ -743,7 +747,7 @@ class spell_reliquary_of_souls_aura_of_desire : public SpellScriptLoader
caster->CastCustomSpell(SPELL_AURA_OF_DESIRE_DAMAGE, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff);
}
- void UpdateAmount(AuraEffect const* /*effect*/)
+ void UpdateAmount(AuraEffect* /*aurEff*/)
{
if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1))
effect->ChangeAmount(effect->GetAmount() - 5);
@@ -752,7 +756,7 @@ class spell_reliquary_of_souls_aura_of_desire : public SpellScriptLoader
void Register() override
{
OnEffectProc += AuraEffectProcFn(spell_reliquary_of_souls_aura_of_desire_AuraScript::OnProcSpell, EFFECT_0, SPELL_AURA_MOD_HEALING_PCT);
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_reliquary_of_souls_aura_of_desire_AuraScript::UpdateAmount, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_reliquary_of_souls_aura_of_desire_AuraScript::UpdateAmount, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp
index 515039e987b..8cd4bbc9cf0 100644
--- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp
@@ -55,7 +55,7 @@ ObjectData const gameObjectData[] =
{ 0, 0 } //END
};
-static DataTypes const collapseObjectDatas[] =
+static MLDataTypes const collapseObjectDatas[] =
{
DATA_MAGTHERIDON_COLUMN_0,
DATA_MAGTHERIDON_COLUMN_1,
@@ -116,7 +116,7 @@ class instance_magtheridons_lair : public InstanceMapScript
HandleGameObject(ObjectGuid::Empty, value == ACTION_ENABLE ? true : false, hall);
break;
case DATA_COLLAPSE_2:
- for (DataTypes data : collapseObjectDatas)
+ for (MLDataTypes data : collapseObjectDatas)
if (GameObject* go = GetGameObject(data))
HandleGameObject(ObjectGuid::Empty, value == ACTION_ENABLE ? true : false, go);
break;
diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h
index 4e46ecd98e7..87190d446b0 100644
--- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h
+++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h
@@ -25,7 +25,7 @@
uint32 const EncounterCount = 1;
-enum DataTypes
+enum MLDataTypes
{
DATA_MAGTHERIDON = 0,
DATA_WORLD_TRIGGER = 1,
@@ -42,13 +42,13 @@ enum DataTypes
DATA_CALL_WARDERS = 12
};
-enum Actions
+enum MLActions
{
ACTION_ENABLE = 1,
ACTION_DISABLE = 2
};
-enum CreatureIds
+enum MLCreatureIds
{
NPC_MAGTHERIDON = 17257,
NPC_ABYSSAL = 17454,
@@ -61,7 +61,7 @@ enum CreatureIds
NPC_HELLFIRE_WARDER = 18829
};
-enum GameObjectIds
+enum MLGameObjectIds
{
GO_MAGTHERIDON_DOOR = 183847,
GO_MANTICRON_CUBE = 181713,
diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
index a482096ce7c..a8bd85023a2 100644
--- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
@@ -525,7 +525,7 @@ public:
Tapped = true;
float x, y, z;
- caster->GetClosePoint(x, y, z, me->GetObjectSize());
+ caster->GetClosePoint(x, y, z, me->GetCombatReach());
me->SetWalk(false);
me->GetMotionMaster()->MovePoint(1, x, y, z);
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 7adb0d0d4cf..eb800765b7c 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -4207,42 +4207,6 @@ class spell_gen_pony_mount_check : public SpellScriptLoader
}
};
-class spell_gen_shroud_of_death : public SpellScriptLoader
-{
-public:
- spell_gen_shroud_of_death() : SpellScriptLoader("spell_gen_shroud_of_death") { }
-
- class spell_gen_shroud_of_death_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_gen_shroud_of_death_AuraScript);
-
- void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- PreventDefaultAction();
- GetUnitOwner()->m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST);
- GetUnitOwner()->m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST);
- }
-
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- PreventDefaultAction();
- GetUnitOwner()->m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
- GetUnitOwner()->m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
- }
-
- void Register() override
- {
- OnEffectApply += AuraEffectApplyFn(spell_gen_shroud_of_death_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- OnEffectRemove += AuraEffectRemoveFn(spell_gen_shroud_of_death_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_gen_shroud_of_death_AuraScript();
- }
-};
-
// 169869 - Transformation Sickness
class spell_gen_decimatus_transformation_sickness : public SpellScriptLoader
{
@@ -4568,7 +4532,6 @@ void AddSC_generic_spell_scripts()
new spell_gen_landmine_knockback_achievement();
new spell_gen_clear_debuffs();
new spell_gen_pony_mount_check();
- new spell_gen_shroud_of_death();
new spell_gen_decimatus_transformation_sickness();
new spell_gen_anetheron_summon_towering_infernal();
new spell_gen_mark_of_kazrogal_hellfire();
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index 9836318f066..7461e52e1b4 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -1100,6 +1100,46 @@ class spell_item_gnomish_death_ray : public SpellScriptLoader
}
};
+// Item 10721: Gnomish Harm Prevention Belt
+// 13234 - Harm Prevention Belt
+enum HarmPreventionBelt
+{
+ SPELL_FORCEFIELD_COLLAPSE = 13235
+};
+
+class spell_item_harm_prevention_belt : public SpellScriptLoader
+{
+public:
+ spell_item_harm_prevention_belt() : SpellScriptLoader("spell_item_harm_prevention_belt") { }
+
+ class spell_item_harm_prevention_belt_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_item_harm_prevention_belt_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_FORCEFIELD_COLLAPSE))
+ return false;
+ return true;
+ }
+
+ void HandleProc(ProcEventInfo& /*eventInfo*/)
+ {
+ GetTarget()->CastSpell((Unit*)nullptr, SPELL_FORCEFIELD_COLLAPSE, true);
+ }
+
+ void Register() override
+ {
+ OnProc += AuraProcFn(spell_item_harm_prevention_belt_AuraScript::HandleProc);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_item_harm_prevention_belt_AuraScript();
+ }
+};
+
enum Heartpierce
{
SPELL_INVIGORATION_MANA = 71881,
@@ -4839,6 +4879,7 @@ void AddSC_item_spell_scripts()
new spell_item_flask_of_the_north();
new spell_item_frozen_shadoweave();
new spell_item_gnomish_death_ray();
+ new spell_item_harm_prevention_belt();
new spell_item_heartpierce<SPELL_INVIGORATION_ENERGY, SPELL_INVIGORATION_MANA, SPELL_INVIGORATION_RAGE, SPELL_INVIGORATION_RP>("spell_item_heartpierce");
new spell_item_heartpierce<SPELL_INVIGORATION_ENERGY_HERO, SPELL_INVIGORATION_MANA_HERO, SPELL_INVIGORATION_RAGE_HERO, SPELL_INVIGORATION_RP_HERO>("spell_item_heartpierce_hero");
new spell_item_crystal_spire_of_karabor();
diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp
index c0b570cbf46..7aaba87a2da 100644
--- a/src/server/scripts/Spells/spell_pet.cpp
+++ b/src/server/scripts/Spells/spell_pet.cpp
@@ -314,7 +314,7 @@ public:
{
if (AuraEffect* /* aurEff */ect = owner->GetAuraEffect(56246, EFFECT_0))
{
- float base_attPower = pet->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE) * pet->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_PCT);
+ float base_attPower = pet->GetFlatModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE) * pet->GetPctModifierValue(UNIT_MOD_ATTACK_POWER, BASE_PCT);
amount += CalculatePct(amount+base_attPower, /* aurEff */ect->GetAmount());
}
}
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index 98814128a34..c0e1fdaae33 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -361,7 +361,7 @@ public:
uint32 BirdEntry = 0;
float fX, fY, fZ;
- go->GetClosePoint(fX, fY, fZ, go->GetObjectSize(), INTERACTION_DISTANCE);
+ go->GetClosePoint(fX, fY, fZ, go->GetCombatReach(), INTERACTION_DISTANCE);
switch (go->GetEntry())
{
diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp
index 55b7d571d56..628ca0edcae 100644
--- a/src/server/scripts/World/item_scripts.cpp
+++ b/src/server/scripts/World/item_scripts.cpp
@@ -243,7 +243,7 @@ public:
return true;
float x, y, z;
- go->GetClosePoint(x, y, z, go->GetObjectSize() / 3, 7.0f);
+ go->GetClosePoint(x, y, z, go->GetCombatReach() / 3, 7.0f);
go->SummonGameObject(GO_HIGH_QUALITY_FUR, *go, QuaternionData::fromEulerAnglesZYX(go->GetOrientation(), 0.0f, 0.0f), 1);
if (TempSummon* summon = player->SummonCreature(NPC_NESINGWARY_TRAPPER, x, y, z, go->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 1000))
{