diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index c30c7db0b..2c68bcf00 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -974,7 +974,7 @@ class WorldObject : public Object, public WorldLocation bool isActiveObject() const { return m_isActive; } void setActive(bool isActiveObject); - bool IsVisibilityOverridden() const { return m_isVisibilityDistanceOverride; } + bool IsVisibilityOverridden() const { return m_isVisibilityDistanceOverride || m_isActive; } void SetVisibilityDistanceOverride(bool isVisibilityDistanceOverride); void SetWorldObject(bool apply); bool IsPermanentWorldObject() const { return m_isWorldObject; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index fda40ae68..4dde7860c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -23040,9 +23040,12 @@ void Player::UpdateObjectVisibility(bool forced, bool fromUpdate) void Player::UpdateVisibilityForPlayer(bool mapChange) { - Trinity::VisibleNotifier notifier(*this, mapChange); - m_seer->VisitNearbyObject(GetSightRange()+VISIBILITY_INC_FOR_GOBJECTS, notifier); - notifier.SendToSelf(); + Trinity::VisibleNotifier notifierNoLarge(*this, mapChange, false); // visit only objects which are not large; default distance + m_seer->VisitNearbyObject(GetSightRange()+VISIBILITY_INC_FOR_GOBJECTS, notifierNoLarge); + notifierNoLarge.SendToSelf(); + Trinity::VisibleNotifier notifierLarge(*this, mapChange, true); // visit only large objects; maximum distance + m_seer->VisitNearbyObject(MAX_VISIBILITY_DISTANCE, notifierLarge); + notifierLarge.SendToSelf(); if (mapChange) m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 4db6faeec..1f4ab8341 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -19040,9 +19040,12 @@ void Unit::ExecuteDelayedUnitRelocationEvent() //active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ()); } - Trinity::PlayerRelocationNotifier relocate(*player); - viewPoint->VisitNearbyObject(player->GetSightRange()+VISIBILITY_INC_FOR_GOBJECTS, relocate); - relocate.SendToSelf(); + Trinity::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance + viewPoint->VisitNearbyObject(player->GetSightRange()+VISIBILITY_INC_FOR_GOBJECTS, relocateNoLarge); + relocateNoLarge.SendToSelf(); + Trinity::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance + viewPoint->VisitNearbyObject(MAX_VISIBILITY_DISTANCE, relocateLarge); + relocateLarge.SendToSelf(); } if (Player* player = this->ToPlayer()) @@ -19071,9 +19074,12 @@ void Unit::ExecuteDelayedUnitRelocationEvent() active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ()); } - Trinity::PlayerRelocationNotifier relocate(*player); - viewPoint->VisitNearbyObject(player->GetSightRange()+VISIBILITY_INC_FOR_GOBJECTS, relocate); - relocate.SendToSelf(); + Trinity::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance + viewPoint->VisitNearbyObject(player->GetSightRange()+VISIBILITY_INC_FOR_GOBJECTS, relocateNoLarge); + relocateNoLarge.SendToSelf(); + Trinity::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance + viewPoint->VisitNearbyObject(MAX_VISIBILITY_DISTANCE, relocateLarge); + relocateLarge.SendToSelf(); this->AddToNotify(NOTIFY_AI_RELOCATION); } @@ -19093,7 +19099,7 @@ void Unit::ExecuteDelayedUnitRelocationEvent() unit->m_last_notify_position.Relocate(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ()); Trinity::CreatureRelocationNotifier relocate(*unit); - unit->VisitNearbyObject(unit->GetMap()->GetVisibilityRange(), relocate); + unit->VisitNearbyObject(unit->GetVisibilityRange()+VISIBILITY_COMPENSATION, relocate); this->AddToNotify(NOTIFY_AI_RELOCATION); } diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index f0b57e196..d868e942c 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -23,6 +23,8 @@ void VisibleNotifier::Visit(GameObjectMapType &m) { for (GameObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { + if (i_largeOnly != iter->GetSource()->IsVisibilityOverridden()) + continue; vis_guids.erase(iter->GetSource()->GetGUID()); i_player.UpdateVisibilityOf(iter->GetSource(), i_data, i_visibleNow); } @@ -35,6 +37,9 @@ void VisibleNotifier::SendToSelf() if (Transport* transport = i_player.GetTransport()) for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end();++itr) { + if (i_largeOnly != (*itr)->IsVisibilityOverridden()) + continue; + if (vis_guids.find((*itr)->GetGUID()) != vis_guids.end()) { vis_guids.erase((*itr)->GetGUID()); @@ -59,6 +64,9 @@ void VisibleNotifier::SendToSelf() for (Player::ClientGUIDs::const_iterator it = vis_guids.begin();it != vis_guids.end(); ++it) { + if (i_largeOnly != ObjectAccessor::GetWorldObject(i_player, *it)->IsVisibilityOverridden()) + continue; + // pussywizard: static transports are removed only in RemovePlayerFromMap and here if can no longer detect (eg. phase changed) if (IS_TRANSPORT_GUID(*it)) if (GameObject* staticTrans = i_player.GetMap()->GetGameObject(*it)) @@ -84,7 +92,11 @@ void VisibleNotifier::SendToSelf() i_player.GetSession()->SendPacket(&packet); for (std::vector::const_iterator it = i_visibleNow.begin(); it != i_visibleNow.end(); ++it) + { + if (i_largeOnly != (*it)->IsVisibilityOverridden()) + continue; i_player.GetInitialVisiblePackets(*it); + } } void VisibleChangesNotifier::Visit(PlayerMapType &m) diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 4741428f9..f73b2b668 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -32,9 +32,10 @@ namespace Trinity Player::ClientGUIDs vis_guids; std::vector &i_visibleNow; bool i_gobjOnly; + bool i_largeOnly; UpdateData i_data; - VisibleNotifier(Player &player, bool gobjOnly) : i_player(player), vis_guids(player.m_clientGUIDs), i_visibleNow(player.m_newVisible), i_gobjOnly(gobjOnly) + VisibleNotifier(Player &player, bool gobjOnly, bool largeOnly) : i_player(player), vis_guids(player.m_clientGUIDs), i_visibleNow(player.m_newVisible), i_gobjOnly(gobjOnly), i_largeOnly(largeOnly) { i_visibleNow.clear(); } @@ -57,7 +58,7 @@ namespace Trinity struct PlayerRelocationNotifier : public VisibleNotifier { - PlayerRelocationNotifier(Player &player) : VisibleNotifier(player, false) {} + PlayerRelocationNotifier(Player &player, bool largeOnly) : VisibleNotifier(player, false, largeOnly) {} template void Visit(GridRefManager &m) { VisibleNotifier::Visit(m); } void Visit(PlayerMapType &); diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h index b77b0945a..711adaa07 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h +++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h @@ -25,6 +25,8 @@ inline void Trinity::VisibleNotifier::Visit(GridRefManager &m) for (typename GridRefManager::iterator iter = m.begin(); iter != m.end(); ++iter) { + if (i_largeOnly != iter->GetSource()->IsVisibilityOverridden()) + continue; vis_guids.erase(iter->GetSource()->GetGUID()); i_player.UpdateVisibilityOf(iter->GetSource(), i_data, i_visibleNow); }