diff --git a/contrib/extractor/adt.cpp b/contrib/extractor/adt.cpp index b7f54f8ad..c8cd50e20 100644 --- a/contrib/extractor/adt.cpp +++ b/contrib/extractor/adt.cpp @@ -204,6 +204,7 @@ inline void LoadMapChunk(MPQFile & mf, chunk*_chunk) if(fourcc==0x4d435654) // MCVT { for (int j=0; j<17; ++j) + { for (int i=0; i<((j%2)?8:9); ++i) { mf.read(&h,4); @@ -226,6 +227,7 @@ inline void LoadMapChunk(MPQFile & mf, chunk*_chunk) if(z>zmax)zmax=z; //if(zIsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)); + return IsInWorld() && u->IsInWorld() && IsWithinDistInMap2d(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)); } diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index 21c689e57..31df66e94 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -148,5 +148,5 @@ void DynamicObject::Delay(int32 delaytime) bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const { - return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)); + return IsInWorld() && u->IsInWorld() && IsWithinDistInMap2d(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)); } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 866157571..fb14abb3b 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -738,7 +738,7 @@ bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const } // check distance - return IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject() + + return IsWithinDistInMap2d(u,World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f) ); } diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 1c8ad7bed..1ff78e3c0 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1119,6 +1119,19 @@ bool WorldObject::IsWithinDistInMap(const WorldObject* obj, const float dist2com return distsq < maxdist * maxdist; } +bool WorldObject::IsWithinDistInMap2d(const WorldObject* obj, const float dist2compare) const +{ + if (!obj || !IsInMap(obj)) return false; + + float dx = GetPositionX() - obj->GetPositionX(); + float dy = GetPositionY() - obj->GetPositionY(); + float distsq = dx*dx + dy*dy; + float sizefactor = GetObjectSize() + obj->GetObjectSize(); + float maxdist = dist2compare + sizefactor; + + return distsq < maxdist * maxdist; +} + bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const { if (!IsInMap(obj)) return false; diff --git a/src/game/Object.h b/src/game/Object.h index 974e6b0b3..5cb93a7de 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -418,6 +418,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object float GetDistanceZ(const WorldObject* obj) const; bool IsInMap(const WorldObject* obj) const { return GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId(); } bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare) const; + bool IsWithinDistInMap2d(const WorldObject* obj, const float dist2compare) const; bool IsWithinLOS(const float x, const float y, const float z ) const; bool IsWithinLOSInMap(const WorldObject* obj) const; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 30cf08c76..dd67be95f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8547,7 +8547,7 @@ int32 Unit::ModifyPower(Powers power, int32 dVal) return gain; } -bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList) const +bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, bool is2dDistance) const { if(!u) return false; @@ -8598,40 +8598,88 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList) if(u->isInFlight()) // what see player in flight { // use object grey distance for all (only see objects any way) - if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) - return false; + if(is2dDistance) + { + if (!IsWithinDistInMap2d(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) + return false; + } + else + { + if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) + return false; + } } else if(!isAlive()) // distance for show body { - if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) - return false; + if(is2dDistance) + { + if (!IsWithinDistInMap2d(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) + return false; + } + else + { + if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) + return false; + } } else if(GetTypeId()==TYPEID_PLAYER) // distance for show player { if(u->GetTypeId()==TYPEID_PLAYER) { // Players far than max visible distance for player or not in our map are not visible too - if (!at_same_transport && !IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) - return false; + if(is2dDistance) + { + if (!at_same_transport && !IsWithinDistInMap2d(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } + else + { + if (!at_same_transport && !IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } } else { // Units far than max visible distance for creature or not in our map are not visible too - if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) - return false; + if(is2dDistance) + { + if (!IsWithinDistInMap2d(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } + else + { + if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } } } else if(GetCharmerOrOwnerGUID()) // distance for show pet/charmed { // Pet/charmed far than max visible distance for player or not in our map are not visible too - if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) - return false; + if(is2dDistance) + { + if (!IsWithinDistInMap2d(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } + else + { + if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } } else // distance for show creature { // Units far than max visible distance for creature or not in our map are not visible too - if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) - return false; + if(is2dDistance) + { + if (!IsWithinDistInMap2d(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } + else + { + if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } } // Visible units, always are visible for all units, except for units under invisibility @@ -9444,7 +9492,7 @@ Unit* Unit::GetUnit(WorldObject& object, uint64 guid) bool Unit::isVisibleForInState( Player const* u, bool inVisibleList ) const { - return isVisibleForOrDetect(u,false,inVisibleList); + return isVisibleForOrDetect(u, false, inVisibleList, true); } uint32 Unit::GetCreatureType() const diff --git a/src/game/Unit.h b/src/game/Unit.h index 365e50554..3f3191eea 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1139,7 +1139,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void SetVisibility(UnitVisibility x); // common function for visibility checks for player/creatures with detection code - bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false) const; + bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is2dDistance = false) const; bool canDetectInvisibilityOf(Unit const* u) const; // virtual functions for all world objects types diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index 0bda27130..e2ce71475 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -869,9 +869,9 @@ GM.StartLevel = 1 # Visibility.Distance.Creature # Visibility.Distance.Player # Visibility distance for different in game object -# Max limited by active player zone: ~ 166 +# Max limited by active player zone: ~ 333 # Min limit dependent from objects -# Default: 66 (cell size) +# Default: 132 (cell size) # Min limit is max aggro radius (45) * Rate.Creature.Aggro # # Visibility.Distance.Object @@ -897,10 +897,10 @@ GM.StartLevel = 1 ################################################################################################################### Visibility.GroupMode = 0 -Visibility.Distance.Creature = 66 -Visibility.Distance.Player = 66 -Visibility.Distance.Object = 66 -Visibility.Distance.InFlight = 66 +Visibility.Distance.Creature = 132 +Visibility.Distance.Player = 132 +Visibility.Distance.Object = 132 +Visibility.Distance.InFlight = 132 Visibility.Distance.Grey.Unit = 1 Visibility.Distance.Grey.Object = 10