[Spells] Fix to prevent Charmed Pets from continuing fight target if owner is dead. (#1600)

* Fix for charm break if pet owner dead

* fix, can't check hatelist it is already wiped.

* Update spell_effects.cpp
This commit is contained in:
KayenEQ 2021-10-16 00:22:07 -04:00 committed by GitHub
parent 5235dcee95
commit af5cfb9bed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 19 deletions

View File

@ -1684,11 +1684,17 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, EQ::skills::Skill
// #2: figure out things that affect the player dying and mark them dead
InterruptSpell();
Mob* m_pet = GetPet();
SetPet(0);
SetHorseId(0);
ShieldAbilityClearVariables();
dead = true;
if (m_pet && m_pet->IsCharmed()) {
m_pet->BuffFadeByEffect(SE_Charm);
}
if (GetMerc()) {
GetMerc()->Suspend();
}

View File

@ -4291,7 +4291,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
}
SendAppearancePacket(AT_Pet, 0, true, true);
Mob* tempmob = GetOwner();
Mob* owner = GetOwner();
SetOwnerID(0);
SetPetType(petNone);
SetHeld(false);
@ -4300,25 +4300,27 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
SetFocused(false);
SetPetStop(false);
SetPetRegroup(false);
if(tempmob)
if(owner)
{
tempmob->SetPet(0);
owner->SetPet(0);
}
if (IsAIControlled())
{
// clear the hate list of the mobs
//Remove damage over time effects on charmed pet and those applied by charmed pet.
if (RuleB(Spells, PreventFactionWarOnCharmBreak)) {
for (auto mob : hate_list.GetHateList()) {
auto tar = mob->entity_on_hatelist;
if (tar->IsCasting()) {
tar->InterruptSpell(tar->CastingSpellID());
}
uint32 buff_count = tar->GetMaxTotalSlots();
for (unsigned int j = 0; j < buff_count; j++) {
if (tar->GetBuffs()[j].spellid != SPELL_UNKNOWN) {
auto spell = spells[tar->GetBuffs()[j].spellid];
if (spell.goodEffect == 0 && IsEffectInSpell(spell.id, SE_CurrentHP) && tar->GetBuffs()[j].casterid == GetID()) {
tar->BuffFadeBySpellID(spell.id);
if (tar) {
if (tar->IsCasting()) {
tar->InterruptSpell(tar->CastingSpellID());
}
uint32 buff_count = tar->GetMaxTotalSlots();
for (unsigned int j = 0; j < buff_count; j++) {
if (IsValidSpell(tar->GetBuffs()[j].spellid)) {
auto spell = spells[tar->GetBuffs()[j].spellid];
if (spell.goodEffect == 0 && IsEffectInSpell(spell.id, SE_CurrentHP) && tar->GetBuffs()[j].casterid == GetID()) {
tar->BuffFadeBySpellID(spell.id);
}
}
}
}
@ -4328,7 +4330,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
}
uint32 buff_count = GetMaxTotalSlots();
for (unsigned int j = 0; j < buff_count; j++) {
if (GetBuffs()[j].spellid != SPELL_UNKNOWN) {
if (IsValidSpell(GetBuffs()[j].spellid )) {
auto spell = spells[this->GetBuffs()[j].spellid];
if (spell.goodEffect == 0 && IsEffectInSpell(spell.id, SE_CurrentHP)) {
BuffFadeBySpellID(spell.id);
@ -4336,17 +4338,43 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
}
}
}
entity_list.ReplaceWithTarget(this, tempmob);
// clear the hate list of the mobs
entity_list.ReplaceWithTarget(this, owner);
WipeHateList();
if(tempmob)
AddToHateList(tempmob, 1, 0);
if (owner) {
AddToHateList(owner, 1, 0);
}
//If owner dead, briefly setting Immmune Aggro while hatelists wipe for both pet and targets is needed to ensure no reaggroing.
else if (IsNPC()){
bool immune_aggro = GetSpecialAbility(IMMUNE_AGGRO); //check if already immune aggro
SetSpecialAbility(IMMUNE_AGGRO, 1);
WipeHateList();
if (IsCasting()) {
InterruptSpell(CastingSpellID());
}
entity_list.RemoveFromHateLists(this);
//If NPC targeting charmed pet are in process of casting on it after it is removed from hatelist, stop the cast to prevent reaggroing.
Mob *current_npc = nullptr;
for (auto &it : entity_list.GetNPCList()) {
current_npc = it.second;
if (current_npc && current_npc->IsCasting() && current_npc->GetTarget() == this) {
current_npc->InterruptSpell(current_npc->CastingSpellID());
}
}
if (!immune_aggro) {
SetSpecialAbility(IMMUNE_AGGRO, 0);
}
}
SendAppearancePacket(AT_Anim, ANIM_STAND);
}
if(tempmob && tempmob->IsClient())
if(owner && owner->IsClient())
{
auto app = new EQApplicationPacket(OP_Charm, sizeof(Charm_Struct));
Charm_Struct *ps = (Charm_Struct*)app->pBuffer;
ps->owner_id = tempmob->GetID();
ps->owner_id = owner->GetID();
ps->pet_id = GetID();
ps->command = 0;
entity_list.QueueClients(this, app);