[8422] Implement far sight like spells work for long distance.

* Added basic infrastructure for visibility update in case difference player and current view point.
  Just for note: seletect additional arg way beacuse repeatable search object will slow but store pointer will not safe,
  so use middle case: get view point pointer early as possible at visibility updates.
* Implement dynamic object and creature activisation while it's target of far sight spell effect
* Use this for SPELL_AURA_BIND_SIGHT, SPELL_AURA_FAR_SIGHT and SPELL_EFFECT_ADD_FARSIGHT.
* Note2: some spyglass like spells let look _around_ at long distance, this hard implement in current grid loading system
  Without additional changes and not implemented (you will see empty area without creatures in likes case)

* Also fixed warning spam at CMSG_MOVE_SET_CAN_FLY_ACK receive by use proper packet sructure reading.
This commit is contained in:
VladimirMangos 2009-08-26 08:18:30 +04:00
parent db1c9924a9
commit 45dd7140b5
28 changed files with 228 additions and 144 deletions

View file

@ -16794,13 +16794,15 @@ void Player::HandleStealthedUnitsDetection()
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap());
cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap());
WorldObject const* viewPoint = GetViewPoint();
for (std::list<Unit*>::const_iterator i = stealthedUnits.begin(); i != stealthedUnits.end(); ++i)
{
if((*i)==this)
continue;
bool hasAtClient = HaveAtClient((*i));
bool hasDetected = (*i)->isVisibleForOrDetect(this, true);
bool hasDetected = (*i)->isVisibleForOrDetect(this, viewPoint, true);
if (hasDetected)
{
@ -17884,6 +17886,17 @@ void Player::ReportedAfkBy(Player* reporter)
}
}
WorldObject const* Player::GetViewPoint() const
{
if(uint64 far_sight = GetFarSight())
{
WorldObject const* viewPoint = ObjectAccessor::GetWorldObject(*this,far_sight);
return viewPoint ? viewPoint : this; // always expected not NULL
}
else
return this;
}
bool Player::IsVisibleInGridForPlayer( Player* pl ) const
{
// gamemaster in GM mode see all, including ghosts
@ -17949,11 +17962,11 @@ bool Player::IsVisibleGloballyFor( Player* u ) const
return true;
}
void Player::UpdateVisibilityOf(WorldObject* target)
void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* target)
{
if(HaveAtClient(target))
{
if(!target->isVisibleForInState(this, true))
if(!target->isVisibleForInState(this, viewPoint, true))
{
target->DestroyForPlayer(this);
m_clientGUIDs.erase(target->GetGUID());
@ -17966,7 +17979,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
}
else
{
if(target->isVisibleForInState(this,false))
if(target->isVisibleForInState(this, viewPoint, false))
{
target->SendUpdateToPlayer(this);
if(target->GetTypeId()!=TYPEID_GAMEOBJECT||!((GameObject*)target)->IsTransport())
@ -18002,11 +18015,11 @@ inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, GameObject* target)
}
template<class T>
void Player::UpdateVisibilityOf(T* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow)
void Player::UpdateVisibilityOf(WorldObject const* viewPoint, T* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow)
{
if(HaveAtClient(target))
{
if(!target->isVisibleForInState(this,true))
if(!target->isVisibleForInState(this,viewPoint,true))
{
target->BuildOutOfRangeUpdateBlock(&data);
m_clientGUIDs.erase(target->GetGUID());
@ -18019,7 +18032,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, UpdateDataMapType&
}
else
{
if(target->isVisibleForInState(this,false))
if(target->isVisibleForInState(this,viewPoint,false))
{
visibleNow.insert(target);
target->BuildUpdate(data_updates);
@ -18034,11 +18047,11 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, UpdateDataMapType&
}
}
template void Player::UpdateVisibilityOf(Player* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(Creature* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(DynamicObject* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(WorldObject const* viewPoint, Player* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(WorldObject const* viewPoint, Creature* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(WorldObject const* viewPoint, Corpse* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(WorldObject const* viewPoint, GameObject* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
template void Player::UpdateVisibilityOf(WorldObject const* viewPoint, DynamicObject* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
void Player::InitPrimaryProfessions()
{
@ -20566,3 +20579,14 @@ bool Player::HasMovementFlag( MovementFlags f ) const
{
return m_movementInfo.HasMovementFlag(f);
}
void Player::SetFarSightGUID( uint64 guid )
{
if(GetFarSight()==guid)
return;
SetUInt64Value(PLAYER_FARSIGHT, guid);
// need triggering load grids around new view point
ObjectAccessor::UpdateVisibilityForPlayer(this);
}