diff --git a/src/game/HostileRefManager.cpp b/src/game/HostileRefManager.cpp index 12accb7cf..b173f7706 100644 --- a/src/game/HostileRefManager.cpp +++ b/src/game/HostileRefManager.cpp @@ -107,6 +107,24 @@ void HostileRefManager::deleteReferences() } } +//================================================= +// delete one reference, defined by faction + +void HostileRefManager::deleteReferencesForFaction(uint32 faction) +{ + HostileReference* ref = getFirst(); + while(ref) + { + HostileReference* nextRef = ref->next(); + if(ref->getSource()->getOwner()->getFactionTemplateEntry()->faction == faction) + { + ref->removeReference(); + delete ref; + } + ref = nextRef; + } +} + //================================================= // delete one reference, defined by Unit diff --git a/src/game/HostileRefManager.h b/src/game/HostileRefManager.h index 93945e669..a2555858d 100644 --- a/src/game/HostileRefManager.h +++ b/src/game/HostileRefManager.h @@ -50,6 +50,9 @@ class HostileRefManager : public RefManager // tell the source to remove them from the list and free the mem void deleteReferences(); + // Remove specific faction references + void deleteReferencesForFaction(uint32 faction); + HostileReference* getFirst() { return ((HostileReference* ) RefManager::getFirst()); } void updateThreatTables(); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 2ef6b4a98..662cd5a54 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3242,10 +3242,14 @@ void Aura::HandleForceReaction(bool apply, bool Real) Player* player = (Player*)m_target; uint32 faction_id = m_modifier.m_miscvalue; - uint32 faction_rank = m_modifier.m_amount; + ReputationRank faction_rank = ReputationRank(m_modifier.m_amount); - player->GetReputationMgr().ApplyForceReaction(faction_id, ReputationRank(faction_rank), apply); + player->GetReputationMgr().ApplyForceReaction(faction_id, faction_rank, apply); player->GetReputationMgr().SendForceReactions(); + + // stop fighting if at apply forced rank friendly or at remove real rank friendly + if (apply && faction_rank >= REP_FRIENDLY || !apply && player->GetReputationRank(faction_id) >= REP_FRIENDLY) + player->StopAttackFaction(faction_id); } void Aura::HandleAuraModSkill(bool apply, bool /*Real*/) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 1b3820498..83e839cc5 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -12822,3 +12822,43 @@ void Unit::SendThreatRemove(HostileReference* pHostileReference) data.appendPackGUID(pHostileReference->getUnitGuid()); SendMessageToSet(&data, false); } + +void Unit::StopAttackFaction(uint32 faction_id) +{ + if (Unit* victim = getVictim()) + { + if (victim->getFactionTemplateEntry()->faction==faction_id) + { + AttackStop(); + if (IsNonMeleeSpellCasted(false)) + InterruptNonMeleeSpells(false); + + // melee and ranged forced attack cancel + if (GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->SendAttackSwingCancelAttack(); + } + } + + AttackerSet const& attackers = getAttackers(); + for(AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end();) + { + if ((*itr)->getFactionTemplateEntry()->faction==faction_id) + { + (*itr)->AttackStop(); + itr = attackers.begin(); + } + else + ++itr; + } + + getHostileRefManager().deleteReferencesForFaction(faction_id); + + if(Pet* pet = GetPet()) + pet->StopAttackFaction(faction_id); + if(Unit* charm = GetCharm()) + charm->StopAttackFaction(faction_id); + + for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr) + if(Unit* guardian = Unit::GetUnit(*this,*itr)) + guardian->StopAttackFaction(faction_id); +} diff --git a/src/game/Unit.h b/src/game/Unit.h index 1a0ac3861..0d5fea3d5 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -929,6 +929,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject Unit* getVictim() const { return m_attacking; } void CombatStop(bool includingCast = false); void CombatStopWithPets(bool includingCast = false); + void StopAttackFaction(uint32 faction_id); Unit* SelectNearbyTarget(Unit* except = NULL) const; bool hasNegativeAuraWithInterruptFlag(uint32 flag); void SendMeleeAttackStop(Unit* victim); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 927240b0c..e58483c71 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8866" + #define REVISION_NR "8867" #endif // __REVISION_NR_H__