diff --git a/src/game/Spells/SpellAuras.cpp b/src/game/Spells/SpellAuras.cpp index 27fb025a..833ebffc 100644 --- a/src/game/Spells/SpellAuras.cpp +++ b/src/game/Spells/SpellAuras.cpp @@ -3057,6 +3057,8 @@ void Aura::HandleModCharm(bool apply, bool Real) target->CastStop(target == caster ? GetId() : 0); caster->SetCharm(target); + // Clear threat list to prevent previously hostile enemies attacking, + // and allow combat to drop target->CombatStop(true); target->DeleteThreatList(); target->getHostileRefManager().deleteReferences(); @@ -3108,28 +3110,22 @@ void Aura::HandleModCharm(bool apply, bool Real) } else if (Player* pPlayer = target->ToPlayer()) { - if (caster->GetTypeId() == TYPEID_UNIT) - { - pPlayer->SetControlledBy(caster); - if (pPlayer->i_AI && m_spellAuraHolder->GetId() == 28410) - pPlayer->i_AI->enablePositiveSpells = true; - } - else - { - PlayerAI *oldAi = pPlayer->i_AI; - delete oldAi; - pPlayer->i_AI = new PlayerControlledAI(pPlayer, caster); - } + pPlayer->SetControlledBy(caster); + if (pPlayer->i_AI && m_spellAuraHolder->GetId() == 28410) + pPlayer->i_AI->enablePositiveSpells = true; } + target->UpdateControl(); if (caster->GetTypeId() == TYPEID_PLAYER) ((Player*)caster)->CharmSpellInitialize(); } else { + Creature *pCasterCreature = caster ? caster->ToCreature() : nullptr; + target->SetCharmerGuid(ObjectGuid()); - if(target->GetTypeId() != TYPEID_PLAYER) + if (target->GetTypeId() != TYPEID_PLAYER) { CreatureInfo const *cinfo = ((Creature*)target)->GetCreatureInfo(); @@ -3166,46 +3162,37 @@ void Aura::HandleModCharm(bool apply, bool Real) target->UpdateControl(); - if (target->GetTypeId() == TYPEID_PLAYER) + if (Player* pPlayer = target->ToPlayer()) { - Player* pPlayer = target->ToPlayer(); - ((Player*)target)->setFactionForRace(target->getRace()); + pPlayer->setFactionForRace(target->getRace()); + pPlayer->SendAttackSwingCancelAttack(); + + pPlayer->RemoveAI(); + + // Charmed players are seen as hostile and not in the group for other clients, restore + // group upon charm end + if (pPlayer->GetGroup()) + pPlayer->GetGroup()->BroadcastGroupUpdate(); } - // this should possibly be the case for other spells too... - // why on earth remove player from combat if, for example, its a boss casting it - if (m_spellAuraHolder->GetId() == 28410 && target->GetTypeId() == TYPEID_PLAYER) - { - if (caster->isAlive() && caster->isInCombat()) - { - if (target->GetTypeId() == TYPEID_PLAYER) - ((Player*)target)->SendAttackSwingCancelAttack(); - if (target->IsNonMeleeSpellCasted(false)) - target->InterruptNonMeleeSpells(false); + if (target->IsNonMeleeSpellCasted(false)) + target->InterruptNonMeleeSpells(false); - target->AttackStop(); - target->RemoveAllAttackers(); - target->DeleteThreatList(); - target->getHostileRefManager().deleteReferences(); + // Clear threat list for targets engaged while charmed + target->DeleteThreatList(); + target->getHostileRefManager().deleteReferences(); + target->AttackStop(); - caster->SetInCombatWith(target); - target->SetInCombatWith(caster); - - target->SetInCombatState(false, caster); - } - else - { - target->CombatStop(true); - target->DeleteThreatList(); - target->getHostileRefManager().deleteReferences(); - } - } - else + // Re-add the target to the caster's hated list to prevent combat dropping. + // Combat reset timer kicks in once the hated list is empty. If the caster is + // a creature and combat ended, remove the target (likely player) from combat too. + if (pCasterCreature && pCasterCreature->isAlive() && pCasterCreature->isInCombat()) { - target->CombatStop(true); - target->DeleteThreatList(); - target->getHostileRefManager().deleteReferences(); + pCasterCreature->SetInCombatWith(target); + pCasterCreature->AddThreat(target); } + else + target->CombatStop(false); target->SetUnitMovementFlags(MOVEFLAG_NONE); target->StopMoving(); @@ -3219,16 +3206,6 @@ void Aura::HandleModCharm(bool apply, bool Real) if (caster) pTargetCrea->AttackedBy(caster); } - else if (Player* pPlayer = target->ToPlayer()) - { - pPlayer->RemoveAI(); - - // Charmed players are seen as hostile and not in the group for other clients, restore - // group upon charm end - pPlayer->setFactionForRace(target->getRace()); - if(pPlayer->GetGroup()) - pPlayer->GetGroup()->BroadcastGroupUpdate(); - } } } diff --git a/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_kelthuzad.cpp b/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_kelthuzad.cpp index f08ed954..d817d53f 100644 --- a/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_kelthuzad.cpp +++ b/src/scripts/eastern_kingdoms/eastern_plaguelands/naxxramas/boss_kelthuzad.cpp @@ -521,6 +521,7 @@ struct boss_kelthuzadAI : public ScriptedAI break; case EVENT_PUT_IN_COMBAT: m_creature->SetInCombatState(false); + m_creature->UpdateCombatState(true); m_creature->SetInCombatWithZone(); hasPutInCombat = true; break;