diff options
| author | Giacomo Pozzoni <giacomopoz@gmail.com> | 2021-12-27 13:33:37 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-27 13:33:37 +0100 |
| commit | 19e99db821ba5975e88ec160df3f4ff78ed562b0 (patch) | |
| tree | 00d21b3b614c385f56858b81005616c29c0d2f37 /src/server/game/Entities | |
| parent | a9c80e4402a8b6b3a8a2fb478b700c16fc5ddbb4 (diff) | |
Core/AI: Fix crashes caused by charmed Creatures having null AI for 1 map update tick (#27434)
Implement using ScheduledChangeAI instead of nullptr to signal a required AI change
Diffstat (limited to 'src/server/game/Entities')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 25 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 |
2 files changed, 23 insertions, 4 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index eda7b604fe6..278087e4890 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -60,6 +60,7 @@ #include "PlayerAI.h" #include "QuestDef.h" #include "ReputationMgr.h" +#include "ScheduledChangeAI.h" #include "SpellAuraEffects.h" #include "SpellAuras.h" #include "Spell.h" @@ -491,7 +492,7 @@ void Unit::Update(uint32 p_time) // All position info based actions have been executed, reset info _positionUpdateInfo.Reset(); - if (!GetAI() && (GetTypeId() != TYPEID_PLAYER || (IsCharmed() && GetCharmerGUID().IsCreature()))) + if (HasScheduledAIChange() && (GetTypeId() != TYPEID_PLAYER || (IsCharmed() && GetCharmerGUID().IsCreature()))) UpdateCharmAI(); RefreshAI(); } @@ -9524,11 +9525,11 @@ void Unit::ScheduleAIChange() bool const charmed = IsCharmed(); if (charmed) - PushAI(nullptr); + PushAI(GetScheduledChangeAI()); else { RestoreDisabledAI(); - PushAI(nullptr); //This could actually be PopAI() to get the previous AI but it's required atm to trigger UpdateCharmAI() + PushAI(GetScheduledChangeAI()); //This could actually be PopAI() to get the previous AI but it's required atm to trigger UpdateCharmAI() } } @@ -9536,10 +9537,26 @@ void Unit::RestoreDisabledAI() { // Keep popping the stack until we either reach the bottom or find a valid AI while (PopAI()) - if (GetTopAI()) + if (GetTopAI() && dynamic_cast<ScheduledChangeAI*>(GetTopAI()) == nullptr) return; } +UnitAI* Unit::GetScheduledChangeAI() +{ + if (Creature* creature = ToCreature()) + return new ScheduledChangeAI(creature); + else + return nullptr; +} + +bool Unit::HasScheduledAIChange() const +{ + if (UnitAI* ai = GetAI()) + return dynamic_cast<ScheduledChangeAI*>(ai) != nullptr; + else + return true; +} + void Unit::AddToWorld() { if (IsInWorld()) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index ea63c22ea3a..07f46b6a7c7 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -804,6 +804,8 @@ class TC_GAME_API Unit : public WorldObject void SetAI(UnitAI* newAI); UnitAI* GetTopAI() const { return i_AIs.empty() ? nullptr : i_AIs.top().get(); } void RefreshAI(); + UnitAI* GetScheduledChangeAI(); + bool HasScheduledAIChange() const; public: void AddToWorld() override; |
