mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Entities: Handle partial state change for pets (#22014)
* handle partial state change
* range-based for loop
* fixes
* readability
* break
(cherry picked from commit ae22fd6d74)
This commit is contained in:
@@ -305,6 +305,28 @@ void Minion::RemoveFromWorld()
|
||||
TempSummon::RemoveFromWorld();
|
||||
}
|
||||
|
||||
void Minion::setDeathState(DeathState s)
|
||||
{
|
||||
Creature::setDeathState(s);
|
||||
if (s != JUST_DIED || !IsGuardianPet())
|
||||
return;
|
||||
|
||||
Unit* owner = GetOwner();
|
||||
if (!owner || owner->GetTypeId() != TYPEID_PLAYER || owner->GetMinionGUID() != GetGUID())
|
||||
return;
|
||||
|
||||
for (Unit* controlled : owner->m_Controlled)
|
||||
{
|
||||
if (controlled->GetEntry() == GetEntry() && controlled->IsAlive())
|
||||
{
|
||||
owner->SetMinionGUID(controlled->GetGUID());
|
||||
owner->SetPetGUID(controlled->GetGUID());
|
||||
owner->ToPlayer()->CharmSpellInitialize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Minion::IsGuardianPet() const
|
||||
{
|
||||
return IsPet() || (m_Properties && m_Properties->Control == SUMMON_CATEGORY_PET);
|
||||
|
||||
@@ -73,6 +73,7 @@ class TC_GAME_API Minion : public TempSummon
|
||||
Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
|
||||
void InitStats(uint32 duration) override;
|
||||
void RemoveFromWorld() override;
|
||||
void setDeathState(DeathState s) override;
|
||||
Unit* GetOwner() const { return m_owner; }
|
||||
float GetFollowAngle() const override { return m_followAngle; }
|
||||
void SetFollowAngle(float angle) { m_followAngle = angle; }
|
||||
|
||||
@@ -480,6 +480,11 @@ void WorldSession::HandlePetSetAction(WorldPackets::Pet::PetSetAction& packet)
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<Unit*> pets;
|
||||
for (Unit* controlled : _player->m_Controlled)
|
||||
if (controlled->GetEntry() == pet->GetEntry() && controlled->IsAlive())
|
||||
pets.push_back(controlled);
|
||||
|
||||
uint32 position = packet.Index;
|
||||
uint32 actionData = packet.Action;
|
||||
|
||||
@@ -489,34 +494,37 @@ void WorldSession::HandlePetSetAction(WorldPackets::Pet::PetSetAction& packet)
|
||||
TC_LOG_DEBUG("entities.pet", "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X",
|
||||
_player->GetName().c_str(), position, spell_id, uint32(act_state));
|
||||
|
||||
//if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
|
||||
if (!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))
|
||||
for (Unit* petControlled : pets)
|
||||
{
|
||||
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id, pet->GetMap()->GetDifficultyID()))
|
||||
//if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
|
||||
if (!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !petControlled->HasSpell(spell_id)))
|
||||
{
|
||||
//sign for autocast
|
||||
if (act_state == ACT_ENABLED)
|
||||
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id, petControlled->GetMap()->GetDifficultyID()))
|
||||
{
|
||||
if (pet->GetTypeId() == TYPEID_UNIT && pet->IsPet())
|
||||
((Pet*)pet)->ToggleAutocast(spellInfo, true);
|
||||
else
|
||||
for (Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr)
|
||||
if ((*itr)->GetEntry() == pet->GetEntry())
|
||||
(*itr)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, true);
|
||||
//sign for autocast
|
||||
if (act_state == ACT_ENABLED)
|
||||
{
|
||||
if (petControlled->GetTypeId() == TYPEID_UNIT && petControlled->IsPet())
|
||||
((Pet*)petControlled)->ToggleAutocast(spellInfo, true);
|
||||
else
|
||||
for (Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr)
|
||||
if ((*itr)->GetEntry() == petControlled->GetEntry())
|
||||
(*itr)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, true);
|
||||
}
|
||||
//sign for no/turn off autocast
|
||||
else if (act_state == ACT_DISABLED)
|
||||
{
|
||||
if (petControlled->GetTypeId() == TYPEID_UNIT && petControlled->IsPet())
|
||||
((Pet*)petControlled)->ToggleAutocast(spellInfo, false);
|
||||
else
|
||||
for (Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr)
|
||||
if ((*itr)->GetEntry() == petControlled->GetEntry())
|
||||
(*itr)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, false);
|
||||
}
|
||||
}
|
||||
//sign for no/turn off autocast
|
||||
else if (act_state == ACT_DISABLED)
|
||||
{
|
||||
if (pet->GetTypeId() == TYPEID_UNIT && pet->IsPet())
|
||||
((Pet*)pet)->ToggleAutocast(spellInfo, false);
|
||||
else
|
||||
for (Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr)
|
||||
if ((*itr)->GetEntry() == pet->GetEntry())
|
||||
(*itr)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, false);
|
||||
}
|
||||
}
|
||||
|
||||
charmInfo->SetActionBar(position, spell_id, ActiveStates(act_state));
|
||||
charmInfo->SetActionBar(position, spell_id, ActiveStates(act_state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,23 +638,31 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPackets::Pet::PetSpellAutoc
|
||||
return;
|
||||
}
|
||||
|
||||
// do not add not learned spells/ passive spells
|
||||
if (!pet->HasSpell(packet.SpellID) || !spellInfo->IsAutocastable())
|
||||
return;
|
||||
std::vector<Unit*> pets;
|
||||
for (Unit* controlled : _player->m_Controlled)
|
||||
if (controlled->GetEntry() == pet->GetEntry() && controlled->IsAlive())
|
||||
pets.push_back(controlled);
|
||||
|
||||
CharmInfo* charmInfo = pet->GetCharmInfo();
|
||||
if (!charmInfo)
|
||||
for (Unit* pet : pets)
|
||||
{
|
||||
TC_LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: object (%s) is considered pet-like but doesn't have a charminfo!", pet->GetGUID().ToString().c_str());
|
||||
return;
|
||||
// do not add not learned spells/ passive spells
|
||||
if (!pet->HasSpell(packet.SpellID) || !spellInfo->IsAutocastable())
|
||||
return;
|
||||
|
||||
CharmInfo* charmInfo = pet->GetCharmInfo();
|
||||
if (!charmInfo)
|
||||
{
|
||||
TC_LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: object (%s) is considered pet-like but doesn't have a charminfo!", pet->GetGUID().ToString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (pet->IsPet())
|
||||
pet->ToPet()->ToggleAutocast(spellInfo, packet.AutocastEnabled);
|
||||
else
|
||||
charmInfo->ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
|
||||
|
||||
charmInfo->SetSpellAutocast(spellInfo, packet.AutocastEnabled);
|
||||
}
|
||||
|
||||
if (pet->IsPet())
|
||||
pet->ToPet()->ToggleAutocast(spellInfo, packet.AutocastEnabled);
|
||||
else
|
||||
charmInfo->ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
|
||||
|
||||
charmInfo->SetSpellAutocast(spellInfo, packet.AutocastEnabled);
|
||||
}
|
||||
|
||||
void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& petCastSpell)
|
||||
|
||||
Reference in New Issue
Block a user