diff options
-rw-r--r-- | src/game/HostilRefManager.cpp | 18 | ||||
-rw-r--r-- | src/game/HostilRefManager.h | 3 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 8 | ||||
-rw-r--r-- | src/game/Unit.cpp | 34 | ||||
-rw-r--r-- | src/game/Unit.h | 1 |
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); |