fix(Core/Combat): safe StopAttackFaction and restore escort evade (#25516)
Co-authored-by: blinkysc <blinkysc@users.noreply.github.com>
This commit is contained in:
parent
ad3b5a29e1
commit
37b60cd0bc
4 changed files with 25 additions and 11 deletions
|
|
@ -309,12 +309,9 @@ void CreatureAI::EngagementOver()
|
|||
|
||||
void CreatureAI::JustExitedCombat()
|
||||
{
|
||||
EngagementOver();
|
||||
|
||||
// If creature is alive, in world, and not already evading, trigger evade to return home
|
||||
// Check IsInWorld to avoid evade during server shutdown/cleanup
|
||||
if (me->IsAlive() && me->IsInWorld() && !me->IsInEvadeMode())
|
||||
EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
|
||||
// No-op: synchronous EnterEvadeMode cascades via MemberEvaded and frees
|
||||
// refs held by upstream iterators (StopAttackFaction crash). EngagementOver
|
||||
// here also resets scripted fights on brief combat gaps (Valithria).
|
||||
}
|
||||
|
||||
/*void CreatureAI::AttackedBy(Unit* attacker)
|
||||
|
|
|
|||
|
|
@ -189,6 +189,15 @@ void npc_escortAI::ReturnToLastPoint()
|
|||
me->GetMotionMaster()->MovePoint(POINT_LAST_POINT, x, y, z, FORCED_MOVEMENT_RUN);
|
||||
}
|
||||
|
||||
void npc_escortAI::JustExitedCombat()
|
||||
{
|
||||
// Evade synchronously so UpdateAI does not push a waypoint spline before
|
||||
// SelectVictim's evade fallback fires; stacked motion intents twitch.
|
||||
EngagementOver();
|
||||
if (me->IsAlive() && me->IsInWorld() && !me->IsInEvadeMode())
|
||||
EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
|
||||
}
|
||||
|
||||
void npc_escortAI::EnterEvadeMode(EvadeReason /*why*/)
|
||||
{
|
||||
me->GetThreatMgr().ClearAllThreat();
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ public:
|
|||
|
||||
void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override;
|
||||
|
||||
void JustExitedCombat() override;
|
||||
|
||||
void UpdateAI(uint32 diff) override; //the "internal" update, calls UpdateEscortAI()
|
||||
virtual void UpdateEscortAI(uint32 diff); //used when it's needed to add code in update (abilities, scripted events, etc)
|
||||
|
||||
|
|
|
|||
|
|
@ -16105,13 +16105,19 @@ void Unit::StopAttackFaction(uint32 faction_id)
|
|||
++itr;
|
||||
}
|
||||
|
||||
// End combat and threat references with creatures in this faction
|
||||
std::vector<CombatReference*> refsToEnd;
|
||||
// Collect GUIDs, not pointers: EndCombat can cascade through AI callbacks
|
||||
// (formation MemberEvaded -> CombatStop) and free other refs in the list.
|
||||
std::vector<ObjectGuid> guidsToEnd;
|
||||
for (auto const& pair : m_combatManager.GetPvECombatRefs())
|
||||
if (pair.second->GetOther(this)->GetFactionTemplateEntry()->faction == faction_id)
|
||||
refsToEnd.push_back(pair.second);
|
||||
for (CombatReference* ref : refsToEnd)
|
||||
ref->EndCombat();
|
||||
guidsToEnd.push_back(pair.first);
|
||||
for (ObjectGuid const& guid : guidsToEnd)
|
||||
{
|
||||
auto const& refs = m_combatManager.GetPvECombatRefs();
|
||||
auto it = refs.find(guid);
|
||||
if (it != refs.end())
|
||||
it->second->EndCombat();
|
||||
}
|
||||
|
||||
for (ControlSet::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
||||
(*itr)->StopAttackFaction(faction_id);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue