Core/Players: Extend Player::SendInitialVisiblePackets to work with all WorldObject types

This commit is contained in:
Shauren
2024-03-08 21:02:29 +01:00
parent d397b636d4
commit 1439535c6a
4 changed files with 49 additions and 67 deletions

View File

@@ -23779,26 +23779,6 @@ bool Player::IsVisibleGloballyFor(Player const* u) const
return false;
}
template<class T>
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, T* target, std::set<Unit*>& /*v*/)
{
s64.insert(target->GetGUID());
}
template<>
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Creature* target, std::set<Unit*>& v)
{
s64.insert(target->GetGUID());
v.insert(target);
}
template<>
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Player* target, std::set<Unit*>& v)
{
s64.insert(target->GetGUID());
v.insert(target);
}
template<class T>
inline void BeforeVisibilityDestroy(T* /*t*/, Player* /*p*/) { }
@@ -23815,7 +23795,7 @@ void Player::UpdateVisibilityOf(Trinity::IteratorPair<WorldObject**> targets)
return;
UpdateData udata(GetMapId());
std::set<Unit*> newVisibleUnits;
std::set<WorldObject*> newVisibleObjects;
for (WorldObject* target : targets)
{
@@ -23825,28 +23805,28 @@ void Player::UpdateVisibilityOf(Trinity::IteratorPair<WorldObject**> targets)
switch (target->GetTypeId())
{
case TYPEID_UNIT:
UpdateVisibilityOf(target->ToCreature(), udata, newVisibleUnits);
UpdateVisibilityOf(target->ToCreature(), udata, newVisibleObjects);
break;
case TYPEID_PLAYER:
UpdateVisibilityOf(target->ToPlayer(), udata, newVisibleUnits);
UpdateVisibilityOf(target->ToPlayer(), udata, newVisibleObjects);
break;
case TYPEID_GAMEOBJECT:
UpdateVisibilityOf(target->ToGameObject(), udata, newVisibleUnits);
UpdateVisibilityOf(target->ToGameObject(), udata, newVisibleObjects);
break;
case TYPEID_DYNAMICOBJECT:
UpdateVisibilityOf(target->ToDynObject(), udata, newVisibleUnits);
UpdateVisibilityOf(target->ToDynObject(), udata, newVisibleObjects);
break;
case TYPEID_CORPSE:
UpdateVisibilityOf(target->ToCorpse(), udata, newVisibleUnits);
UpdateVisibilityOf(target->ToCorpse(), udata, newVisibleObjects);
break;
case TYPEID_AREATRIGGER:
UpdateVisibilityOf(target->ToAreaTrigger(), udata, newVisibleUnits);
UpdateVisibilityOf(target->ToAreaTrigger(), udata, newVisibleObjects);
break;
case TYPEID_SCENEOBJECT:
UpdateVisibilityOf(target->ToSceneObject(), udata, newVisibleUnits);
UpdateVisibilityOf(target->ToSceneObject(), udata, newVisibleObjects);
break;
case TYPEID_CONVERSATION:
UpdateVisibilityOf(target->ToConversation(), udata, newVisibleUnits);
UpdateVisibilityOf(target->ToConversation(), udata, newVisibleObjects);
break;
default:
break;
@@ -23860,7 +23840,7 @@ void Player::UpdateVisibilityOf(Trinity::IteratorPair<WorldObject**> targets)
udata.BuildPacket(&packet);
SendDirectMessage(&packet);
for (Unit* visibleUnit : newVisibleUnits)
for (WorldObject* visibleUnit : newVisibleObjects)
SendInitialVisiblePackets(visibleUnit);
}
@@ -23945,18 +23925,21 @@ void Player::UpdateTriggerVisibility()
SendDirectMessage(&packet);
}
void Player::SendInitialVisiblePackets(Unit* target) const
void Player::SendInitialVisiblePackets(WorldObject* target) const
{
SendAurasForTarget(target);
if (target->IsAlive())
if (Unit* targetUnit = target->ToUnit())
{
if (target->HasUnitState(UNIT_STATE_MELEE_ATTACKING) && target->GetVictim())
target->SendMeleeAttackStart(target->GetVictim());
SendAurasForTarget(targetUnit);
if (targetUnit->IsAlive())
{
if (targetUnit->HasUnitState(UNIT_STATE_MELEE_ATTACKING) && targetUnit->GetVictim())
targetUnit->SendMeleeAttackStart(targetUnit->GetVictim());
}
}
}
template<class T>
void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow)
void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<WorldObject*>& visibleNow)
{
if (HaveAtClient(target))
{
@@ -23981,7 +23964,8 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& vi
if (CanSeeOrDetect(target, false, true))
{
target->BuildCreateUpdateBlockForPlayer(&data, this);
UpdateVisibilityOf_helper(m_clientGUIDs, target, visibleNow);
m_clientGUIDs.insert(target->GetGUID());
visibleNow.insert(target);
#ifdef TRINITY_DEBUG
TC_LOG_DEBUG("maps", "Object {} is visible now for player {}. Distance = {}", target->GetGUID().ToString(), GetGUID().ToString(), GetDistance(target));
@@ -23990,14 +23974,14 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& vi
}
}
template void Player::UpdateVisibilityOf(Player* target, UpdateData& data, std::set<Unit*>& visibleNow);
template void Player::UpdateVisibilityOf(Creature* target, UpdateData& data, std::set<Unit*>& visibleNow);
template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data, std::set<Unit*>& visibleNow);
template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data, std::set<Unit*>& visibleNow);
template void Player::UpdateVisibilityOf(DynamicObject* target, UpdateData& data, std::set<Unit*>& visibleNow);
template void Player::UpdateVisibilityOf(AreaTrigger* target, UpdateData& data, std::set<Unit*>& visibleNow);
template void Player::UpdateVisibilityOf(SceneObject* target, UpdateData& data, std::set<Unit*>& visibleNow);
template void Player::UpdateVisibilityOf(Conversation* target, UpdateData& data, std::set<Unit*>& visibleNow);
template void Player::UpdateVisibilityOf(Player* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(Creature* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(DynamicObject* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(AreaTrigger* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(SceneObject* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(Conversation* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
void Player::UpdateObjectVisibility(bool forced)
{

View File

@@ -2515,7 +2515,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
bool IsVisibleGloballyFor(Player const* player) const;
void SendInitialVisiblePackets(Unit* target) const;
void SendInitialVisiblePackets(WorldObject* target) const;
void OnPhaseChange() override;
void UpdateObjectVisibility(bool forced = true) override;
void UpdateVisibilityForPlayer();
@@ -2524,7 +2524,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void UpdateTriggerVisibility();
template<class T>
void UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow);
void UpdateVisibilityOf(T* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
std::array<uint8, MAX_MOVE_TYPE> m_forced_speed_changes;
uint8 m_movementForceModMagnitudeChanges;

View File

@@ -32,30 +32,28 @@ void VisibleNotifier::SendToSelf()
// but exist one case when this possible and object not out of range: transports
if (Transport* transport = dynamic_cast<Transport*>(i_player.GetTransport()))
{
for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
for (WorldObject* passenger : transport->GetPassengers())
{
if (vis_guids.find((*itr)->GetGUID()) != vis_guids.end())
if (vis_guids.erase(passenger->GetGUID()) > 0)
{
vis_guids.erase((*itr)->GetGUID());
switch ((*itr)->GetTypeId())
switch (passenger->GetTypeId())
{
case TYPEID_GAMEOBJECT:
i_player.UpdateVisibilityOf((*itr)->ToGameObject(), i_data, i_visibleNow);
i_player.UpdateVisibilityOf(passenger->ToGameObject(), i_data, i_visibleNow);
break;
case TYPEID_PLAYER:
i_player.UpdateVisibilityOf((*itr)->ToPlayer(), i_data, i_visibleNow);
if (!(*itr)->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
(*itr)->ToPlayer()->UpdateVisibilityOf(&i_player);
i_player.UpdateVisibilityOf(passenger->ToPlayer(), i_data, i_visibleNow);
if (!passenger->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
passenger->ToPlayer()->UpdateVisibilityOf(&i_player);
break;
case TYPEID_UNIT:
i_player.UpdateVisibilityOf((*itr)->ToCreature(), i_data, i_visibleNow);
i_player.UpdateVisibilityOf(passenger->ToCreature(), i_data, i_visibleNow);
break;
case TYPEID_DYNAMICOBJECT:
i_player.UpdateVisibilityOf((*itr)->ToDynObject(), i_data, i_visibleNow);
i_player.UpdateVisibilityOf(passenger->ToDynObject(), i_data, i_visibleNow);
break;
case TYPEID_AREATRIGGER:
i_player.UpdateVisibilityOf((*itr)->ToAreaTrigger(), i_data, i_visibleNow);
i_player.UpdateVisibilityOf(passenger->ToAreaTrigger(), i_data, i_visibleNow);
break;
default:
break;
@@ -64,14 +62,14 @@ void VisibleNotifier::SendToSelf()
}
}
for (auto it = vis_guids.begin(); it != vis_guids.end(); ++it)
for (ObjectGuid const& outOfRangeGuid : vis_guids)
{
i_player.m_clientGUIDs.erase(*it);
i_data.AddOutOfRangeGUID(*it);
i_player.m_clientGUIDs.erase(outOfRangeGuid);
i_data.AddOutOfRangeGUID(outOfRangeGuid);
if (it->IsPlayer())
if (outOfRangeGuid.IsPlayer())
{
Player* player = ObjectAccessor::FindPlayer(*it);
Player* player = ObjectAccessor::GetPlayer(i_player, outOfRangeGuid);
if (player && !player->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
player->UpdateVisibilityOf(&i_player);
}
@@ -84,8 +82,8 @@ void VisibleNotifier::SendToSelf()
i_data.BuildPacket(&packet);
i_player.SendDirectMessage(&packet);
for (std::set<Unit*>::const_iterator it = i_visibleNow.begin(); it != i_visibleNow.end(); ++it)
i_player.SendInitialVisiblePackets(*it);
for (WorldObject* visibleObject : i_visibleNow)
i_player.SendInitialVisiblePackets(visibleObject);
}
void VisibleChangesNotifier::Visit(PlayerMapType &m)

View File

@@ -49,7 +49,7 @@ namespace Trinity
{
Player &i_player;
UpdateData i_data;
std::set<Unit*> i_visibleNow;
std::set<WorldObject*> i_visibleNow;
GuidUnorderedSet vis_guids;
VisibleNotifier(Player &player) : i_player(player), i_data(player.GetMapId()), vis_guids(player.m_clientGUIDs) { }