diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 9673a226e..f9874ae61 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1274,8 +1274,8 @@ void Player::Update( uint32 p_time ) { if (p_time >= m_DetectInvTimer) { - m_DetectInvTimer = 3000; HandleStealthedUnitsDetection(); + m_DetectInvTimer = 3000; } else m_DetectInvTimer -= p_time; @@ -16876,35 +16876,40 @@ void Player::HandleStealthedUnitsDetection() cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap()); cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap()); - for (std::list::iterator i = stealthedUnits.begin(); i != stealthedUnits.end();) + for (std::list::const_iterator i = stealthedUnits.begin(); i != stealthedUnits.end(); ++i) { if((*i)==this) - { - i = stealthedUnits.erase(i); continue; - } - if ((*i)->isVisibleForOrDetect(this,true)) + bool hasAtClient = HaveAtClient((*i)); + bool hasDetected = (*i)->isVisibleForOrDetect(this, true); + + if (hasDetected) { + if(!hasAtClient) + { + (*i)->SendUpdateToPlayer(this); + m_clientGUIDs.insert((*i)->GetGUID()); - (*i)->SendUpdateToPlayer(this); - m_clientGUIDs.insert((*i)->GetGUID()); + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) + sLog.outDebug("Object %u (Type: %u) is detected in stealth by player %u. Distance = %f",(*i)->GetGUIDLow(),(*i)->GetTypeId(),GetGUIDLow(),GetDistance(*i)); + #endif - #ifdef MANGOS_DEBUG - if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) - sLog.outDebug("Object %u (Type: %u) is detected in stealth by player %u. Distance = %f",(*i)->GetGUIDLow(),(*i)->GetTypeId(),GetGUIDLow(),GetDistance(*i)); - #endif - - // target aura duration for caster show only if target exist at caster client - // send data at target visibility change (adding to client) - if((*i)!=this && (*i)->isType(TYPEMASK_UNIT)) - SendAurasForTarget(*i); - - i = stealthedUnits.erase(i); - continue; + // target aura duration for caster show only if target exist at caster client + // send data at target visibility change (adding to client) + if((*i)!=this && (*i)->isType(TYPEMASK_UNIT)) + SendAurasForTarget(*i); + } + } + else + { + if(hasAtClient) + { + (*i)->DestroyForPlayer(this); + m_clientGUIDs.erase((*i)->GetGUID()); + } } - - ++i; } } diff --git a/src/game/Player.h b/src/game/Player.h index 96a08f202..9d5d1c7a8 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2101,7 +2101,6 @@ class MANGOS_DLL_SPEC Player : public Unit void UpdateVisibilityOf(T* target, UpdateData& data, UpdateDataMapType& data_updates, std::set& visibleNow); // Stealth detection system - uint32 m_DetectInvTimer; void HandleStealthedUnitsDetection(); uint8 m_forced_speed_changes[MAX_MOVE_TYPE]; @@ -2455,6 +2454,8 @@ class MANGOS_DLL_SPEC Player : public Unit bool m_bCanDelayTeleport; bool m_bHasDelayedTeleport; + uint32 m_DetectInvTimer; + // Temporary removed pet cache uint32 m_temporaryUnsummonedPetNumber; uint32 m_oldpetspell; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c41542438..39ba61708 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9232,13 +9232,11 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, // NOW ONLY STEALTH CASE - // stealth and detected and visible for some seconds - if (u->GetTypeId() == TYPEID_PLAYER && ((Player*)u)->m_DetectInvTimer > 300 && ((Player*)u)->HaveAtClient(this)) - return true; - //if in non-detect mode then invisible for unit + //mobs always detect players (detect == true)... return 'false' for those mobs which have (detect == false) + //players detect players only in Player::HandleStealthedUnitsDetection() if (!detect) - return false; + return (u->GetTypeId() == TYPEID_PLAYER) ? ((Player*)u)->HaveAtClient(this) : false; // Special cases @@ -9254,21 +9252,13 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, if (u->hasUnitState(UNIT_STAT_STUNNED) && (u != this)) return false; - // Creature can detect target only in aggro radius - if(u->GetTypeId() != TYPEID_PLAYER) - { - //Always invisible from back and out of aggro range - bool isInFront = u->isInFrontInMap(this,((Creature const*)u)->GetAttackDistance(this)); - if(!isInFront) - return false; - } - else - { - //Always invisible from back - bool isInFront = u->isInFrontInMap(this,(GetTypeId()==TYPEID_PLAYER || GetCharmerOrOwnerGUID()) ? World::GetMaxVisibleDistanceForPlayer() : World::GetMaxVisibleDistanceForCreature()); - if(!isInFront) - return false; - } + // set max ditance + float visibleDistance = (u->GetTypeId() == TYPEID_PLAYER) ? MAX_PLAYER_STEALTH_DETECT_RANGE : ((Creature const*)u)->GetAttackDistance(this); + + //Always invisible from back (when stealth detection is on), also filter max distance cases + bool isInFront = u->isInFrontInMap(this, visibleDistance); + if(!isInFront) + return false; // if doesn't have stealth detection (Shadow Sight), then check how stealthy the unit is, otherwise just check los if(!u->HasAuraType(SPELL_AURA_DETECT_STEALTH)) @@ -9276,7 +9266,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, //Calculation if target is in front //Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5) - float visibleDistance = 10.5f - (GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/100.0f); + visibleDistance = 10.5f - (GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/100.0f); //Visible distance is modified by //-Level Diff (every level diff = 1.0f in visible distance) @@ -9290,7 +9280,9 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, //-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia) //based on wowwiki every 5 mod we have 1 more level diff in calculation visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f; + visibleDistance = visibleDistance > MAX_PLAYER_STEALTH_DETECT_RANGE ? MAX_PLAYER_STEALTH_DETECT_RANGE : visibleDistance; + // recheck new distance if(visibleDistance <= 0 || !IsWithinDist(u,visibleDistance)) return false; } diff --git a/src/game/Unit.h b/src/game/Unit.h index 14dfb82e0..0dd34089b 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -851,6 +851,7 @@ typedef std::set GuardianPetList; // delay time next attack to prevent client attack animation problems #define ATTACK_DISPLAY_DELAY 200 +#define MAX_PLAYER_STEALTH_DETECT_RANGE 45.0f // max distance for detection targets by player struct SpellProcEventEntry; // used only privately diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7f6e801c5..23835f479 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 "8228" + #define REVISION_NR "8229" #endif // __REVISION_NR_H__