{"action":"created","issue":{"url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/6756","repository_url":"https://api.github.com/repos/TrinityCore/TrinityCore","labels_url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/6756/labels{/name}","comments_url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/6756/comments","events_url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/6756/events","html_url":"https://github.com/TrinityCore/TrinityCore/issues/6756","id":4989711,"number":6756,"title":"Combat Bug / fight in progress after wipe (15$ bounty)","user":{"login":"durrrr","id":1152437,"avatar_url":"https://avatars.githubusercontent.com/u/1152437?v=3","gravatar_id":"","url":"https://api.github.com/users/durrrr","html_url":"https://github.com/durrrr","followers_url":"https://api.github.com/users/durrrr/followers","following_url":"https://api.github.com/users/durrrr/following{/other_user}","gists_url":"https://api.github.com/users/durrrr/gists{/gist_id}","starred_url":"https://api.github.com/users/durrrr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/durrrr/subscriptions","organizations_url":"https://api.github.com/users/durrrr/orgs","repos_url":"https://api.github.com/users/durrrr/repos","events_url":"https://api.github.com/users/durrrr/events{/privacy}","received_events_url":"https://api.github.com/users/durrrr/received_events","type":"User","site_admin":false},"labels":[{"id":179342707,"url":"https://api.github.com/repos/TrinityCore/TrinityCore/labels/bounty","name":"bounty","color":"129e5e","default":false},{"id":26232644,"url":"https://api.github.com/repos/TrinityCore/TrinityCore/labels/Comp-Core","name":"Comp-Core","color":"FF6600","default":false},{"id":220407,"url":"https://api.github.com/repos/TrinityCore/TrinityCore/labels/Priority-High","name":"Priority-High","color":"e102d8","default":false},{"id":3421015,"url":"https://api.github.com/repos/TrinityCore/TrinityCore/labels/Sub-ScriptingEngine","name":"Sub-ScriptingEngine","color":"e10c02","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":18,"created_at":"2012-06-10T06:19:48Z","updated_at":"2016-12-22T23:52:11Z","closed_at":null,"body":"Hello,\nI have encountered a problem while playing in some game zones, such as \"Naxxaramas\", \"Trial of the Crusader\" and more.\n\nHow to reproduce the bug:\n1. Finish some of the encounters and stay in combat mode.\n\nWhat should happen, what happens instead:\nYou should finish the encounters and get out of Combat mode, what happens instead is you get stuck in combat mode with no ability to get out of combat unless you use cd's like \"Vanish\".\n\nThis issue is problematic in some places because it holds you back from summoning, getting loots, and more.\nAchievements like \"The Immortal\" are nearly impossible because if someone dc's or relogs he just dies, and then the achievement is just ruined by script.\n\nSome of the NPC's that keeps you in combat bug:\nhttp://www.wowhead.com/npc=15932 --> The NPC #1 (Gluth) (Old Wowhead)\nhttp://www.wowhead.com/npc=15928 --> The NPC #2 (Thaddius) (Old Wowhead)\nhttp://www.wowhead.com/npc=34564 --> The NPC #3 (Anub'arak) (Old Wowhead)\nhttp://www.wowhead.com/npc=31139 --> The NPC #4 (Pustulent Horror) (Old Wowhead)\nhttp://www.wowhead.com/npc=30330 --> The NPC #5 (Jotunheim Proto-Drake) (Old Wowhead)\n\nThese 3 are just a small example. I cant remember them all so i'll be glad of some other people will implement their NPC's which keeps them in combat.\n\nI'm running Unix on hash: 7e62c34 , TDB 335.11.46+\nAddons: AH bot and WG.\n\nRegards,\ndurrrr\n## <bountysource-plugin>\n\nWant to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/64527-zones-npc-s-combat-bug?utm_campaign=plugin&utm_content=tracker%2F1310&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F1310&utm_medium=issues&utm_source=github).\n</bountysource-plugin>\n"},"comment":{"url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/comments/268916245","html_url":"https://github.com/TrinityCore/TrinityCore/issues/6756#issuecomment-268916245","issue_url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/6756","id":268916245,"user":{"login":"xinef1","id":2781353,"avatar_url":"https://avatars.githubusercontent.com/u/2781353?v=3","gravatar_id":"","url":"https://api.github.com/users/xinef1","html_url":"https://github.com/xinef1","followers_url":"https://api.github.com/users/xinef1/followers","following_url":"https://api.github.com/users/xinef1/following{/other_user}","gists_url":"https://api.github.com/users/xinef1/gists{/gist_id}","starred_url":"https://api.github.com/users/xinef1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xinef1/subscriptions","organizations_url":"https://api.github.com/users/xinef1/orgs","repos_url":"https://api.github.com/users/xinef1/repos","events_url":"https://api.github.com/users/xinef1/events{/privacy}","received_events_url":"https://api.github.com/users/xinef1/received_events","type":"User","site_admin":false},"created_at":"2016-12-22T23:52:11Z","updated_at":"2016-12-22T23:52:11Z","body":"This will solve worldwide combat bugs. It basicly removes all hostile references that are out of our sight (the cause of combat bug). As for instance scripts, they need to be fixed separately.\r\n\r\n<details>\r\n\r\n```diff\r\n src/server/game/Entities/Player/Player.h | 1 +\r\n 1 file changed, 1 insertion(+)\r\n\r\ndiff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h\r\nindex dcaa219..1be2e75 100644\r\n--- a/src/server/game/Entities/Player/Player.h\r\n+++ b/src/server/game/Entities/Player/Player.h\r\n@@ -2467,6 +2467,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>\r\n         bool   m_SeasonalQuestChanged;\r\n         time_t m_lastDailyQuestTime;\r\n \r\n+        uint32 m_hostileReferenceCheckTimer;\r\n         uint32 m_drunkTimer;\r\n         uint32 m_weaponChangeTimer;\r\n \r\n src/server/game/Entities/Player/Player.cpp | 13 +++++++++++++\r\n 1 file changed, 13 insertions(+)\r\n\r\ndiff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp\r\nindex 21d1f25..c5f7727 100644\r\n--- a/src/server/game/Entities/Player/Player.cpp\r\n+++ b/src/server/game/Entities/Player/Player.cpp\r\n@@ -380,6 +380,7 @@ Player::Player(WorldSession* session): Unit(true)\r\n     m_MirrorTimerFlags = UNDERWATER_NONE;\r\n     m_MirrorTimerFlagsLast = UNDERWATER_NONE;\r\n     m_isInWater = false;\r\n+\tm_hostileReferenceCheckTimer = 0;\r\n     m_drunkTimer = 0;\r\n     m_deathTimer = 0;\r\n     m_deathExpireTime = 0;\r\n@@ -1550,6 +1551,18 @@ void Player::Update(uint32 p_time)\r\n     if (pet && !pet->IsWithinDistInMap(this, GetMap()->GetVisibilityRange()) && !pet->isPossessed())\r\n     //if (pet && !pet->IsWithinDistInMap(this, GetMap()->GetVisibilityDistance()) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID())))\r\n         RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);\r\n+\t\r\n+\tif (IsAlive())\r\n+    {\r\n+        if (m_hostileReferenceCheckTimer <= p_time)\r\n+        {\r\n+            m_hostileReferenceCheckTimer = 15 * IN_MILLISECONDS;\r\n+            if (!GetMap()->IsDungeon())\r\n+                getHostileRefManager().deleteReferencesOutOfRange(GetVisibilityRange());\r\n+        }\r\n+        else\r\n+            m_hostileReferenceCheckTimer -= p_time;\r\n+    }\r\n \r\n     //we should execute delayed teleports only for alive(!) players\r\n     //because we don't want player's ghost teleported from graveyard\r\n\r\n src/server/game/Combat/HostileRefManager.h | 3 +++\r\n 1 file changed, 3 insertions(+)\r\n\r\ndiff --git a/src/server/game/Combat/HostileRefManager.h b/src/server/game/Combat/HostileRefManager.h\r\nindex 859bee3..2f414fb 100644\r\n--- a/src/server/game/Combat/HostileRefManager.h\r\n+++ b/src/server/game/Combat/HostileRefManager.h\r\n@@ -53,6 +53,9 @@ class TC_GAME_API HostileRefManager : public RefManager<Unit, ThreatManager>\r\n         // Remove specific faction references\r\n         void deleteReferencesForFaction(uint32 faction);\r\n \r\n+        // for combat bugs\r\n+        void deleteReferencesOutOfRange(float range);\r\n+\r\n         HostileReference* getFirst() { return ((HostileReference*) RefManager<Unit, ThreatManager>::getFirst()); }\r\n \r\n         void updateThreatTables();\r\n\r\n src/server/game/Combat/HostileRefManager.cpp | 20 ++++++++++++++++++++\r\n 1 file changed, 20 insertions(+)\r\n\r\ndiff --git a/src/server/game/Combat/HostileRefManager.cpp b/src/server/game/Combat/HostileRefManager.cpp\r\nindex 965b910..3b3ea24 100644\r\n--- a/src/server/game/Combat/HostileRefManager.cpp\r\n+++ b/src/server/game/Combat/HostileRefManager.cpp\r\n@@ -142,6 +142,26 @@ void HostileRefManager::deleteReferencesForFaction(uint32 faction)\r\n }\r\n \r\n //=================================================\r\n+// delete all references out of specified range\r\n+\r\n+void HostileRefManager::deleteReferencesOutOfRange(float range)\r\n+{\r\n+    HostileReference* ref = getFirst();\r\n+    range = range*range;\r\n+    while (ref)\r\n+    {\r\n+        HostileReference* nextRef = ref->next();\r\n+        Unit* owner = ref->GetSource()->GetOwner();\r\n+        if (!owner->isActiveObject() && owner->GetExactDist2dSq(GetOwner()) > range)\r\n+        {\r\n+            ref->removeReference();\r\n+            delete ref;\r\n+        }\r\n+        ref = nextRef;\r\n+    }\r\n+}\r\n+\r\n+//=================================================\r\n // delete one reference, defined by Unit\r\n \r\n void HostileRefManager::deleteReference(Unit* creature)\r\n\r\n src/server/game/AI/CoreAI/PetAI.cpp | 5 +++++\r\n 1 file changed, 5 insertions(+)\r\n\r\ndiff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp\r\nindex 9ef589a..971067f 100644\r\n--- a/src/server/game/AI/CoreAI/PetAI.cpp\r\n+++ b/src/server/game/AI/CoreAI/PetAI.cpp\r\n@@ -48,6 +48,11 @@ bool PetAI::_needToStop()\r\n     if (me->IsCharmed() && me->GetVictim() == me->GetCharmer())\r\n         return true;\r\n \r\n+    // dont allow pets to follow targets far away from owner\r\n+    if (Unit* owner = me->GetCharmerOrOwner())\r\n+        if (owner->GetExactDist(me) >= (owner->GetVisibilityRange()-10.0f))\r\n+            return true;\r\n+\r\n     return !me->IsValidAttackTarget(me->GetVictim());\r\n }\r\n \r\n```\r\n\r\n</details>"}}
{"actor":{"display_login":"xinef1"}}