fix(Core/Combat): drop dangling current victim on phase change crash (#26020)
Co-authored-by: blinkysc <blinkysc@users.noreply.github.com>
This commit is contained in:
@@ -15321,30 +15321,10 @@ void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
|
|||||||
|
|
||||||
if (!sScriptMgr->CanSetPhaseMask(this, newPhaseMask, update))
|
if (!sScriptMgr->CanSetPhaseMask(this, newPhaseMask, update))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Phase-related threat updates are done AFTER the phase change below
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldObject::SetPhaseMask(newPhaseMask, false);
|
WorldObject::SetPhaseMask(newPhaseMask, false);
|
||||||
|
|
||||||
// Now update threat online states with the new phase mask applied
|
|
||||||
if (IsCreature() || (IsPlayer() && !ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout()))
|
|
||||||
{
|
|
||||||
// Update online state for units that have me on their threat list
|
|
||||||
for (auto const& pair : GetThreatMgr().GetThreatenedByMeList())
|
|
||||||
{
|
|
||||||
if (ThreatReference* ref = pair.second)
|
|
||||||
ref->UpdateOffline();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update online state for units on my threat list
|
|
||||||
if (!IsPlayer())
|
|
||||||
{
|
|
||||||
for (ThreatReference* ref : GetThreatMgr().GetModifiableThreatList())
|
|
||||||
ref->UpdateOffline();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsInWorld())
|
if (!IsInWorld())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -734,7 +734,7 @@ TEST_F(ThreatManagerIntegrationTest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Phase Change + Threat Offline State Tests (SetPhaseMask order fix)
|
// Phase Change + Threat Offline State Tests
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
TEST_F(ThreatManagerIntegrationTest,
|
TEST_F(ThreatManagerIntegrationTest,
|
||||||
@@ -748,6 +748,10 @@ TEST_F(ThreatManagerIntegrationTest,
|
|||||||
// Move B to a different phase
|
// Move B to a different phase
|
||||||
_creatureB->SetPhase(2);
|
_creatureB->SetPhase(2);
|
||||||
|
|
||||||
|
// Online state is refreshed lazily on the next threat update tick (matches
|
||||||
|
// TrinityCore - SetPhaseMask itself does not touch threat)
|
||||||
|
_creatureA->TestGetThreatMgr().Update(ThreatManager::THREAT_UPDATE_INTERVAL);
|
||||||
|
|
||||||
// B should now be offline on A's threat list (different phases)
|
// B should now be offline on A's threat list (different phases)
|
||||||
// The list is not empty if we include offline, but empty if we don't
|
// The list is not empty if we include offline, but empty if we don't
|
||||||
EXPECT_TRUE(_creatureA->TestGetThreatMgr().IsThreatenedBy(_creatureB, true)); // includeOffline
|
EXPECT_TRUE(_creatureA->TestGetThreatMgr().IsThreatenedBy(_creatureB, true)); // includeOffline
|
||||||
|
|||||||
Reference in New Issue
Block a user