From 8573b651c8bb00612b161cc44664cbbb6dd16327 Mon Sep 17 00:00:00 2001 From: xinef1 Date: Sat, 21 Jan 2017 14:46:32 +0100 Subject: Core/Units: Drop hostile world references that are out of our sight (fixes combat bug) (#18591) (cherry-picked from ba6281bf429384a506aad5125bcc537eef5bfe77) --- src/server/game/AI/CoreAI/PetAI.cpp | 5 +++++ src/server/game/Combat/HostileRefManager.cpp | 20 ++++++++++++++++++++ src/server/game/Combat/HostileRefManager.h | 3 +++ src/server/game/Entities/Player/Player.cpp | 13 +++++++++++++ src/server/game/Entities/Player/Player.h | 1 + 5 files changed, 42 insertions(+) (limited to 'src') diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index f30b2369e91..cab622be0cb 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -50,6 +50,11 @@ bool PetAI::_needToStop() if (me->IsCharmed() && me->GetVictim() == me->GetCharmer()) return true; + // dont allow pets to follow targets far away from owner + if (Unit* owner = me->GetCharmerOrOwner()) + if (owner->GetExactDist(me) >= (owner->GetVisibilityRange()-10.0f)) + return true; + return !me->IsValidAttackTarget(me->GetVictim()); } diff --git a/src/server/game/Combat/HostileRefManager.cpp b/src/server/game/Combat/HostileRefManager.cpp index 98883f3ac70..bcea34d7e83 100644 --- a/src/server/game/Combat/HostileRefManager.cpp +++ b/src/server/game/Combat/HostileRefManager.cpp @@ -141,6 +141,26 @@ void HostileRefManager::deleteReferencesForFaction(uint32 faction) } } +//================================================= +// delete all references out of specified range + +void HostileRefManager::deleteReferencesOutOfRange(float range) +{ + HostileReference* ref = getFirst(); + range = range*range; + while (ref) + { + HostileReference* nextRef = ref->next(); + Unit* owner = ref->GetSource()->GetOwner(); + if (!owner->isActiveObject() && owner->GetExactDist2dSq(GetOwner()) > range) + { + ref->removeReference(); + delete ref; + } + ref = nextRef; + } +} + //================================================= // delete one reference, defined by Unit diff --git a/src/server/game/Combat/HostileRefManager.h b/src/server/game/Combat/HostileRefManager.h index fc26d950e67..585d96b7443 100644 --- a/src/server/game/Combat/HostileRefManager.h +++ b/src/server/game/Combat/HostileRefManager.h @@ -53,6 +53,9 @@ class TC_GAME_API HostileRefManager : public RefManager // Remove specific faction references void deleteReferencesForFaction(uint32 faction); + // for combat bugs + void deleteReferencesOutOfRange(float range); + HostileReference* getFirst() { return ((HostileReference*) RefManager::getFirst()); } void updateThreatTables(); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 01d6b9e2066..6131c40aca0 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -210,6 +210,7 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this) m_MirrorTimerFlags = UNDERWATER_NONE; m_MirrorTimerFlagsLast = UNDERWATER_NONE; m_isInWater = false; + m_hostileReferenceCheckTimer = 0; m_drunkTimer = 0; m_deathTimer = 0; m_deathExpireTime = 0; @@ -1348,6 +1349,18 @@ void Player::Update(uint32 p_time) //if (pet && !pet->IsWithinDistInMap(this, GetMap()->GetVisibilityDistance()) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID()))) RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); + if (IsAlive()) + { + if (m_hostileReferenceCheckTimer <= p_time) + { + m_hostileReferenceCheckTimer = 15 * IN_MILLISECONDS; + if (!GetMap()->IsDungeon()) + getHostileRefManager().deleteReferencesOutOfRange(GetVisibilityRange()); + } + else + m_hostileReferenceCheckTimer -= p_time; + } + //we should execute delayed teleports only for alive(!) players //because we don't want player's ghost teleported from graveyard if (IsHasDelayedTeleport() && IsAlive()) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index fd2b6e9a049..eb12abc021c 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2593,6 +2593,7 @@ class TC_GAME_API Player : public Unit, public GridObject bool m_SeasonalQuestChanged; time_t m_lastDailyQuestTime; + uint32 m_hostileReferenceCheckTimer; uint32 m_drunkTimer; uint32 m_weaponChangeTimer; -- cgit v1.2.3