aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/HostilRefManager.cpp18
-rw-r--r--src/game/HostilRefManager.h3
-rw-r--r--src/game/SpellAuras.cpp8
-rw-r--r--src/game/Unit.cpp34
-rw-r--r--src/game/Unit.h1
5 files changed, 62 insertions, 2 deletions
diff --git a/src/game/HostilRefManager.cpp b/src/game/HostilRefManager.cpp
index 48938dff71b..1e1c70dd01c 100644
--- a/src/game/HostilRefManager.cpp
+++ b/src/game/HostilRefManager.cpp
@@ -110,6 +110,24 @@ void HostilRefManager::deleteReferences()
}
//=================================================
+// delete one reference, defined by faction
+
+void HostilRefManager::deleteReferencesForFaction(uint32 faction)
+{
+ HostilReference* ref = getFirst();
+ while(ref)
+ {
+ HostilReference* nextRef = ref->next();
+ if(ref->getSource()->getOwner()->getFactionTemplateEntry()->faction == faction)
+ {
+ ref->removeReference();
+ delete ref;
+ }
+ ref = nextRef;
+ }
+}
+
+//=================================================
// delete one reference, defined by Unit
void HostilRefManager::deleteReference(Unit *pCreature)
diff --git a/src/game/HostilRefManager.h b/src/game/HostilRefManager.h
index a25a6011575..403e66c0d7b 100644
--- a/src/game/HostilRefManager.h
+++ b/src/game/HostilRefManager.h
@@ -52,6 +52,9 @@ class HostilRefManager : public RefManager<Unit, ThreatManager>
// tell the source to remove them from the list and free the mem
void deleteReferences();
+ // Remove specific faction references
+ void deleteReferencesForFaction(uint32 faction);
+
HostilReference* getFirst() { return ((HostilReference* ) RefManager<Unit, ThreatManager>::getFirst()); }
void updateThreatTables();
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index faa8c3407dc..f3352d015a2 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -3925,10 +3925,14 @@ void AuraEffect::HandleForceReaction(bool apply, bool Real, bool changeAmount)
Player* player = (Player*)m_target;
uint32 faction_id = GetMiscValue();
- uint32 faction_rank = m_amount;
+ ReputationRank faction_rank = ReputationRank(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 AuraEffect::HandleAuraModSkill(bool apply, bool Real, bool /*changeAmount*/)
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 7ea832d2477..24cd4a71b16 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -15751,6 +15751,40 @@ void Unit::RewardRage( uint32 damage, uint32 weaponSpeedHitFactor, bool attacker
ModifyPower(POWER_RAGE, uint32(addRage*10));
}
+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;
+ }
+
+ getHostilRefManager().deleteReferencesForFaction(faction_id);
+
+ for(ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
+ (*itr)->StopAttackFaction(faction_id);
+}
+
void Unit::OutDebugInfo() const
{
sLog.outError("Unit::OutDebugInfo");
diff --git a/src/game/Unit.h b/src/game/Unit.h
index cef043be902..0abcbf8f017 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1152,6 +1152,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void CombatStop(bool includingCast = false);
void CombatStopWithPets(bool includingCast = false);
+ void StopAttackFaction(uint32 faction_id);
Unit* SelectNearbyTarget(float dist = NOMINAL_MELEE_RANGE) const;
bool hasNegativeAuraWithInterruptFlag(uint32 flag);
void SendMeleeAttackStop(Unit* victim);