fix(Core/Pets): Fix crash when pet tries to attack deleted object (#17034)

This situation occurs when, during a fight, a pet receives a command to apply a positive spell to an ally and then resume attacking its previous target.
This commit is contained in:
Anton Popovichenko
2023-08-19 22:27:51 +02:00
committed by GitHub
parent 7529994a5c
commit f6b77f9d64
3 changed files with 22 additions and 14 deletions

View File

@@ -48,7 +48,7 @@ Pet::Pet(Player* owner, PetType type) : Guardian(nullptr, owner ? owner->GetGUID
m_loading(false), m_loading(false),
m_petRegenTimer(PET_FOCUS_REGEN_INTERVAL), m_petRegenTimer(PET_FOCUS_REGEN_INTERVAL),
m_tempspellTarget(nullptr), m_tempspellTarget(nullptr),
m_tempoldTarget(nullptr), m_tempoldTarget(),
m_tempspellIsPositive(false), m_tempspellIsPositive(false),
m_tempspell(0) m_tempspell(0)
{ {
@@ -710,7 +710,11 @@ void Pet::Update(uint32 diff)
if (m_tempspell) if (m_tempspell)
{ {
Unit* tempspellTarget = m_tempspellTarget; Unit* tempspellTarget = m_tempspellTarget;
Unit* tempoldTarget = m_tempoldTarget; Unit* tempoldTarget = nullptr;
if (!m_tempoldTarget.IsEmpty())
tempoldTarget = ObjectAccessor::GetUnit(*this, m_tempoldTarget);
bool tempspellIsPositive = m_tempspellIsPositive; bool tempspellIsPositive = m_tempspellIsPositive;
uint32 tempspell = m_tempspell; uint32 tempspell = m_tempspell;
Unit* charmer = GetCharmerOrOwner(); Unit* charmer = GetCharmerOrOwner();
@@ -783,7 +787,7 @@ void Pet::Update(uint32 diff)
} }
} }
m_tempoldTarget = nullptr; m_tempoldTarget = ObjectGuid::Empty;
m_tempspellIsPositive = false; m_tempspellIsPositive = false;
} }
} }
@@ -793,7 +797,7 @@ void Pet::Update(uint32 diff)
{ {
m_tempspell = 0; m_tempspell = 0;
m_tempspellTarget = nullptr; m_tempspellTarget = nullptr;
m_tempoldTarget = nullptr; m_tempoldTarget = ObjectGuid::Empty;
m_tempspellIsPositive = false; m_tempspellIsPositive = false;
Unit* victim = charmer->GetVictim(); Unit* victim = charmer->GetVictim();
@@ -2414,7 +2418,7 @@ void Pet::SetDisplayId(uint32 modelId)
player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID); player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID);
} }
void Pet::CastWhenWillAvailable(uint32 spellid, Unit* spellTarget, Unit* oldTarget, bool spellIsPositive) void Pet::CastWhenWillAvailable(uint32 spellid, Unit* spellTarget, ObjectGuid oldTarget, bool spellIsPositive)
{ {
if (!spellid) if (!spellid)
return; return;
@@ -2426,7 +2430,7 @@ void Pet::CastWhenWillAvailable(uint32 spellid, Unit* spellTarget, Unit* oldTarg
m_tempspell = spellid; m_tempspell = spellid;
m_tempspellIsPositive = spellIsPositive; m_tempspellIsPositive = spellIsPositive;
if (oldTarget) if (!oldTarget.IsEmpty())
m_tempoldTarget = oldTarget; m_tempoldTarget = oldTarget;
} }
@@ -2435,7 +2439,7 @@ void Pet::ClearCastWhenWillAvailable()
m_tempspellIsPositive = false; m_tempspellIsPositive = false;
m_tempspell = 0; m_tempspell = 0;
m_tempspellTarget = nullptr; m_tempspellTarget = nullptr;
m_tempoldTarget = nullptr; m_tempoldTarget = ObjectGuid::Empty;
} }
void Pet::RemoveSpellCooldown(uint32 spell_id, bool update /* = false */) void Pet::RemoveSpellCooldown(uint32 spell_id, bool update /* = false */)

View File

@@ -96,7 +96,7 @@ public:
void LearnPetPassives(); void LearnPetPassives();
void CastPetAuras(bool current); void CastPetAuras(bool current);
void CastWhenWillAvailable(uint32 spellid, Unit* spellTarget, Unit* oldTarget, bool spellIsPositive = false); void CastWhenWillAvailable(uint32 spellid, Unit* spellTarget, ObjectGuid oldTarget, bool spellIsPositive = false);
void ClearCastWhenWillAvailable(); void ClearCastWhenWillAvailable();
void RemoveSpellCooldown(uint32 spell_id, bool update /* = false */); void RemoveSpellCooldown(uint32 spell_id, bool update /* = false */);
@@ -157,10 +157,10 @@ protected:
std::unique_ptr<DeclinedName> m_declinedname; std::unique_ptr<DeclinedName> m_declinedname;
Unit* m_tempspellTarget; Unit* m_tempspellTarget;
Unit* m_tempoldTarget; ObjectGuid m_tempoldTarget;
bool m_tempspellIsPositive; bool m_tempspellIsPositive;
uint32 m_tempspell; uint32 m_tempspell;
private: private:
void SaveToDB(uint32, uint8, uint32) override // override of Creature::SaveToDB - must not be called void SaveToDB(uint32, uint8, uint32) override // override of Creature::SaveToDB - must not be called

View File

@@ -530,7 +530,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
pet->SendPetAIReaction(guid1); pet->SendPetAIReaction(guid1);
} }
pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, nullptr, tempspellIsPositive); pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, ObjectGuid::Empty, tempspellIsPositive);
} }
} }
else if (haspositiveeffect) else if (haspositiveeffect)
@@ -566,7 +566,11 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
pet->SendPetAIReaction(guid1); pet->SendPetAIReaction(guid1);
} }
pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, victim, tmpSpellIsPositive); ObjectGuid oldTarget = ObjectGuid::Empty;
if (victim)
oldTarget = victim->GetGUID();
pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, oldTarget, tmpSpellIsPositive);
} }
} }
} }