mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
[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:
parent
db1c9924a9
commit
45dd7140b5
28 changed files with 228 additions and 144 deletions
|
|
@ -141,7 +141,7 @@ bool
|
||||||
AggressorAI::IsVisible(Unit *pl) const
|
AggressorAI::IsVisible(Unit *pl) const
|
||||||
{
|
{
|
||||||
return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_MONSTER))
|
return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_MONSTER))
|
||||||
&& pl->isVisibleForOrDetect(m_creature,true);
|
&& pl->isVisibleForOrDetect(m_creature,m_creature,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Corpse::isVisibleForInState(Player const* u, bool inVisibleList) const
|
bool Corpse::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const
|
||||||
{
|
{
|
||||||
return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
|
return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(viewPoint, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ class Corpse : public WorldObject
|
||||||
GridPair const& GetGrid() const { return m_grid; }
|
GridPair const& GetGrid() const { return m_grid; }
|
||||||
void SetGrid(GridPair const& grid) { m_grid = grid; }
|
void SetGrid(GridPair const& grid) { m_grid = grid; }
|
||||||
|
|
||||||
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
|
bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const;
|
||||||
|
|
||||||
Loot loot; // remove insignia ONLY at BG
|
Loot loot; // remove insignia ONLY at BG
|
||||||
Player* lootRecipient;
|
Player* lootRecipient;
|
||||||
|
|
|
||||||
|
|
@ -681,7 +681,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
||||||
|
|
||||||
void SetDeadByDefault (bool death_state) { m_isDeadByDefault = death_state; }
|
void SetDeadByDefault (bool death_state) { m_isDeadByDefault = death_state; }
|
||||||
|
|
||||||
bool isActiveObject() const { return m_isActiveObject; }
|
bool isActiveObject() const { return m_isActiveObject || HasAuraType(SPELL_AURA_BIND_SIGHT) || HasAuraType(SPELL_AURA_FAR_SIGHT); }
|
||||||
void SetActiveObjectState(bool on);
|
void SetActiveObjectState(bool on);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -1116,7 +1116,7 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
|
||||||
bool CreatureEventAI::IsVisible(Unit *pl) const
|
bool CreatureEventAI::IsVisible(Unit *pl) const
|
||||||
{
|
{
|
||||||
return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_MONSTER))
|
return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_MONSTER))
|
||||||
&& pl->isVisibleForOrDetect(m_creature,true);
|
&& pl->isVisibleForOrDetect(m_creature,m_creature,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
|
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,9 @@
|
||||||
#include "GridNotifiers.h"
|
#include "GridNotifiers.h"
|
||||||
#include "CellImpl.h"
|
#include "CellImpl.h"
|
||||||
#include "GridNotifiersImpl.h"
|
#include "GridNotifiersImpl.h"
|
||||||
|
#include "SpellMgr.h"
|
||||||
|
|
||||||
DynamicObject::DynamicObject() : WorldObject()
|
DynamicObject::DynamicObject() : WorldObject(), m_isActiveObject(false)
|
||||||
{
|
{
|
||||||
m_objectType |= TYPEMASK_DYNAMICOBJECT;
|
m_objectType |= TYPEMASK_DYNAMICOBJECT;
|
||||||
m_objectTypeId = TYPEID_DYNAMICOBJECT;
|
m_objectTypeId = TYPEID_DYNAMICOBJECT;
|
||||||
|
|
@ -81,6 +82,11 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32
|
||||||
m_radius = radius;
|
m_radius = radius;
|
||||||
m_effIndex = effIndex;
|
m_effIndex = effIndex;
|
||||||
m_spellId = spellId;
|
m_spellId = spellId;
|
||||||
|
|
||||||
|
// set to active for far sight case
|
||||||
|
if(SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId))
|
||||||
|
m_isActiveObject = IsSpellHaveEffect(spellEntry,SPELL_EFFECT_ADD_FARSIGHT);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,20 +113,24 @@ void DynamicObject::Update(uint32 p_time)
|
||||||
else
|
else
|
||||||
deleteThis = true;
|
deleteThis = true;
|
||||||
|
|
||||||
// TODO: make a timer and update this in larger intervals
|
// have radius and work as persistent effect
|
||||||
CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()));
|
if(m_radius)
|
||||||
Cell cell(p);
|
{
|
||||||
cell.data.Part.reserved = ALL_DISTRICT;
|
// TODO: make a timer and update this in larger intervals
|
||||||
cell.SetNoCreate();
|
CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()));
|
||||||
|
Cell cell(p);
|
||||||
|
cell.data.Part.reserved = ALL_DISTRICT;
|
||||||
|
cell.SetNoCreate();
|
||||||
|
|
||||||
MaNGOS::DynamicObjectUpdater notifier(*this, caster);
|
MaNGOS::DynamicObjectUpdater notifier(*this, caster);
|
||||||
|
|
||||||
TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, WorldTypeMapContainer > world_object_notifier(notifier);
|
TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, WorldTypeMapContainer > world_object_notifier(notifier);
|
||||||
TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier);
|
TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier);
|
||||||
|
|
||||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||||
cell_lock->Visit(cell_lock, world_object_notifier, *GetMap());
|
cell_lock->Visit(cell_lock, world_object_notifier, *GetMap());
|
||||||
cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap());
|
cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap());
|
||||||
|
}
|
||||||
|
|
||||||
if(deleteThis)
|
if(deleteThis)
|
||||||
{
|
{
|
||||||
|
|
@ -143,7 +153,15 @@ void DynamicObject::Delay(int32 delaytime)
|
||||||
(*iunit)->DelayAura(m_spellId, m_effIndex, delaytime);
|
(*iunit)->DelayAura(m_spellId, m_effIndex, delaytime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const
|
bool DynamicObject::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const
|
||||||
{
|
{
|
||||||
return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
|
if(!IsInWorld() || !u->IsInWorld())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// always seen by owner
|
||||||
|
if(GetCasterGUID()==u->GetGUID())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// normal case
|
||||||
|
return IsWithinDistInMap(viewPoint, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class DynamicObject : public WorldObject
|
||||||
void AddAffected(Unit *unit) { m_affected.insert(unit); }
|
void AddAffected(Unit *unit) { m_affected.insert(unit); }
|
||||||
void RemoveAffected(Unit *unit) { m_affected.erase(unit); }
|
void RemoveAffected(Unit *unit) { m_affected.erase(unit); }
|
||||||
void Delay(int32 delaytime);
|
void Delay(int32 delaytime);
|
||||||
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
|
bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const;
|
||||||
|
|
||||||
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
|
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
|
||||||
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
|
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
|
||||||
|
|
@ -56,15 +56,16 @@ class DynamicObject : public WorldObject
|
||||||
|
|
||||||
GridReference<DynamicObject> &GetGridRef() { return m_gridRef; }
|
GridReference<DynamicObject> &GetGridRef() { return m_gridRef; }
|
||||||
|
|
||||||
bool isActiveObject() const { return false; }
|
bool isActiveObject() const { return m_isActiveObject; }
|
||||||
protected:
|
protected:
|
||||||
uint32 m_spellId;
|
uint32 m_spellId;
|
||||||
uint32 m_effIndex;
|
uint32 m_effIndex;
|
||||||
int32 m_aliveDuration;
|
int32 m_aliveDuration;
|
||||||
time_t m_nextThinkTime;
|
time_t m_nextThinkTime;
|
||||||
float m_radius;
|
float m_radius; // radius apply persistent effect, 0 = no persistent effect
|
||||||
AffectedSet m_affected;
|
AffectedSet m_affected;
|
||||||
private:
|
private:
|
||||||
GridReference<DynamicObject> m_gridRef;
|
GridReference<DynamicObject> m_gridRef;
|
||||||
|
bool m_isActiveObject;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -690,7 +690,7 @@ void GameObject::SaveRespawnTime()
|
||||||
objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime);
|
objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const
|
bool GameObject::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const
|
||||||
{
|
{
|
||||||
// Not in world
|
// Not in world
|
||||||
if(!IsInWorld() || !u->IsInWorld())
|
if(!IsInWorld() || !u->IsInWorld())
|
||||||
|
|
@ -717,7 +717,7 @@ bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// check distance
|
// check distance
|
||||||
return IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject() +
|
return IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForObject() +
|
||||||
(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
|
(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -670,7 +670,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
||||||
|
|
||||||
void TriggeringLinkedGameObject( uint32 trapEntry, Unit* target);
|
void TriggeringLinkedGameObject( uint32 trapEntry, Unit* target);
|
||||||
|
|
||||||
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
|
bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const;
|
||||||
|
|
||||||
GameObject* LookupFishingHoleAround(float range);
|
GameObject* LookupFishingHoleAround(float range);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,16 @@ using namespace MaNGOS;
|
||||||
void
|
void
|
||||||
MaNGOS::PlayerNotifier::Visit(PlayerMapType &m)
|
MaNGOS::PlayerNotifier::Visit(PlayerMapType &m)
|
||||||
{
|
{
|
||||||
|
WorldObject const* viewPoint = i_player.GetViewPoint();
|
||||||
|
|
||||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
if( iter->getSource() == &i_player )
|
Player* player = iter->getSource();
|
||||||
|
if( player == &i_player )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
iter->getSource()->UpdateVisibilityOf(&i_player);
|
player->UpdateVisibilityOf(player->GetViewPoint(),&i_player);
|
||||||
i_player.UpdateVisibilityOf(iter->getSource());
|
i_player.UpdateVisibilityOf(viewPoint,player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,24 +48,28 @@ VisibleChangesNotifier::Visit(PlayerMapType &m)
|
||||||
{
|
{
|
||||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
if(iter->getSource() == &i_object)
|
Player* player = iter->getSource();
|
||||||
|
if(player == &i_object)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
iter->getSource()->UpdateVisibilityOf(&i_object);
|
player->UpdateVisibilityOf(player->GetViewPoint(),&i_object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VisibleNotifier::Visit(PlayerMapType &m)
|
VisibleNotifier::Visit(PlayerMapType &m)
|
||||||
{
|
{
|
||||||
|
WorldObject const* viewPoint = i_player.GetViewPoint();
|
||||||
|
|
||||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
if( iter->getSource() == &i_player )
|
Player* player = iter->getSource();
|
||||||
|
if( player == &i_player )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
iter->getSource()->UpdateVisibilityOf(&i_player);
|
player->UpdateVisibilityOf(player->GetViewPoint(),&i_player);
|
||||||
i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_data_updates,i_visibleNow);
|
i_player.UpdateVisibilityOf(viewPoint,player,i_data,i_data_updates,i_visibleNow);
|
||||||
i_clientGUIDs.erase(iter->getSource()->GetGUID());
|
i_clientGUIDs.erase(player->GetGUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,8 +84,9 @@ VisibleNotifier::Notify()
|
||||||
{
|
{
|
||||||
if(i_clientGUIDs.find((*itr)->GetGUID())!=i_clientGUIDs.end())
|
if(i_clientGUIDs.find((*itr)->GetGUID())!=i_clientGUIDs.end())
|
||||||
{
|
{
|
||||||
(*itr)->UpdateVisibilityOf(&i_player);
|
// ignore far sight case
|
||||||
i_player.UpdateVisibilityOf((*itr),i_data,i_data_updates,i_visibleNow);
|
(*itr)->UpdateVisibilityOf((*itr),&i_player);
|
||||||
|
i_player.UpdateVisibilityOf(&i_player,(*itr),i_data,i_data_updates,i_visibleNow);
|
||||||
i_clientGUIDs.erase((*itr)->GetGUID());
|
i_clientGUIDs.erase((*itr)->GetGUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -121,9 +129,8 @@ VisibleNotifier::Notify()
|
||||||
if(!IS_PLAYER_GUID(*iter))
|
if(!IS_PLAYER_GUID(*iter))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Player* plr = ObjectAccessor::GetPlayer(i_player,*iter);
|
if (Player* plr = ObjectAccessor::GetPlayer(i_player,*iter))
|
||||||
if(plr)
|
plr->UpdateVisibilityOf(plr->GetViewPoint(),&i_player);
|
||||||
plr->UpdateVisibilityOf(&i_player);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -778,7 +778,7 @@ namespace MaNGOS
|
||||||
return u->isAlive()
|
return u->isAlive()
|
||||||
&& i_obj->IsWithinDistInMap(u, i_range)
|
&& i_obj->IsWithinDistInMap(u, i_range)
|
||||||
&& !i_funit->IsFriendlyTo(u)
|
&& !i_funit->IsFriendlyTo(u)
|
||||||
&& u->isVisibleForOrDetect(i_funit, false);
|
&& u->isVisibleForOrDetect(i_funit,i_funit,false);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
WorldObject const* i_obj;
|
WorldObject const* i_obj;
|
||||||
|
|
@ -827,7 +827,7 @@ namespace MaNGOS
|
||||||
bool operator()(Unit* u)
|
bool operator()(Unit* u)
|
||||||
{
|
{
|
||||||
if( u->isTargetableForAttack() && i_obj->IsWithinDistInMap(u, i_range) &&
|
if( u->isTargetableForAttack() && i_obj->IsWithinDistInMap(u, i_range) &&
|
||||||
!i_funit->IsFriendlyTo(u) && u->isVisibleForOrDetect(i_funit,false) )
|
!i_funit->IsFriendlyTo(u) && u->isVisibleForOrDetect(i_funit,i_funit,false) )
|
||||||
{
|
{
|
||||||
i_range = i_obj->GetDistance(u); // use found unit range as new range limit for next check
|
i_range = i_obj->GetDistance(u); // use found unit range as new range limit for next check
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -863,7 +863,7 @@ namespace MaNGOS
|
||||||
return false;
|
return false;
|
||||||
if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem())
|
if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem())
|
||||||
return false;
|
return false;
|
||||||
if (!i_hitHidden && !u->isVisibleForOrDetect(i_funit, false))
|
if (!i_hitHidden && !u->isVisibleForOrDetect(i_funit, i_funit, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(( i_targetForPlayer ? !i_funit->IsFriendlyTo(u) : i_funit->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range))
|
if(( i_targetForPlayer ? !i_funit->IsFriendlyTo(u) : i_funit->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range))
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,11 @@ template<class T>
|
||||||
inline void
|
inline void
|
||||||
MaNGOS::VisibleNotifier::Visit(GridRefManager<T> &m)
|
MaNGOS::VisibleNotifier::Visit(GridRefManager<T> &m)
|
||||||
{
|
{
|
||||||
|
WorldObject const* viewPoint = i_player.GetViewPoint();
|
||||||
|
|
||||||
for(typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
|
for(typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_data_updates,i_visibleNow);
|
i_player.UpdateVisibilityOf(viewPoint,iter->getSource(),i_data,i_data_updates,i_visibleNow);
|
||||||
i_clientGUIDs.erase(iter->getSource()->GetGUID());
|
i_clientGUIDs.erase(iter->getSource()->GetGUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,10 +66,10 @@ MaNGOS::PlayerRelocationNotifier::Visit(PlayerMapType &m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PlayerCreatureRelocationWorker(Player* pl, Creature* c)
|
inline void PlayerCreatureRelocationWorker(Player* pl, WorldObject const* viewPoint, Creature* c)
|
||||||
{
|
{
|
||||||
// update creature visibility at player/creature move
|
// update creature visibility at player/creature move
|
||||||
pl->UpdateVisibilityOf(c);
|
pl->UpdateVisibilityOf(viewPoint,c);
|
||||||
|
|
||||||
// Creature AI reaction
|
// Creature AI reaction
|
||||||
if(!c->hasUnitState(UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING))
|
if(!c->hasUnitState(UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING))
|
||||||
|
|
@ -98,9 +100,11 @@ MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType &m)
|
||||||
if(!i_player.isAlive() || i_player.isInFlight())
|
if(!i_player.isAlive() || i_player.isInFlight())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
WorldObject const* viewPoint = i_player.GetViewPoint();
|
||||||
|
|
||||||
for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||||
if( iter->getSource()->isAlive())
|
if (iter->getSource()->isAlive())
|
||||||
PlayerCreatureRelocationWorker(&i_player,iter->getSource());
|
PlayerCreatureRelocationWorker(&i_player,viewPoint,iter->getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -111,8 +115,9 @@ MaNGOS::CreatureRelocationNotifier::Visit(PlayerMapType &m)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||||
if( iter->getSource()->isAlive() && !iter->getSource()->isInFlight())
|
if (Player* player = iter->getSource())
|
||||||
PlayerCreatureRelocationWorker(iter->getSource(), &i_creature);
|
if (player->isAlive() && !player->isInFlight())
|
||||||
|
PlayerCreatureRelocationWorker(player, player->GetViewPoint(), &i_creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
||||||
|
|
@ -973,7 +973,7 @@ void Group::UpdatePlayerOutOfRange(Player* pPlayer)
|
||||||
for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
|
for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
|
||||||
{
|
{
|
||||||
player = itr->getSource();
|
player = itr->getSource();
|
||||||
if (player && player != pPlayer && !pPlayer->isVisibleFor(player))
|
if (player && player != pPlayer && !pPlayer->isVisibleFor(player,player->GetViewPoint()))
|
||||||
player->GetSession()->SendPacket(&data);
|
player->GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ void GuardAI::UpdateAI(const uint32 /*diff*/)
|
||||||
bool GuardAI::IsVisible(Unit *pl) const
|
bool GuardAI::IsVisible(Unit *pl) const
|
||||||
{
|
{
|
||||||
return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_GUARDER))
|
return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_GUARDER))
|
||||||
&& pl->isVisibleForOrDetect(m_creature,true);
|
&& pl->isVisibleForOrDetect(m_creature,m_creature,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuardAI::AttackStart(Unit *u)
|
void GuardAI::AttackStart(Unit *u)
|
||||||
|
|
|
||||||
|
|
@ -1456,13 +1456,15 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode( WorldPacket & recv_data )
|
||||||
sLog.outDebug("WORLD: CMSG_MOVE_SET_CAN_FLY_ACK");
|
sLog.outDebug("WORLD: CMSG_MOVE_SET_CAN_FLY_ACK");
|
||||||
//recv_data.hexlike();
|
//recv_data.hexlike();
|
||||||
|
|
||||||
uint64 guid;
|
recv_data.read_skip<uint64>(); // guid
|
||||||
uint32 unk;
|
recv_data.read_skip<uint32>(); // unk
|
||||||
uint32 flags;
|
|
||||||
|
|
||||||
recv_data >> guid >> unk >> flags;
|
MovementInfo movementInfo;
|
||||||
|
ReadMovementInfo(recv_data, &movementInfo);
|
||||||
|
|
||||||
_player->m_movementInfo.SetMovementFlags(MovementFlags(flags));
|
recv_data.read_skip<uint32>(); // unk2
|
||||||
|
|
||||||
|
_player->m_movementInfo.SetMovementFlags(movementInfo.GetMovementFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleRequestPetInfoOpcode( WorldPacket & /*recv_data */)
|
void WorldSession::HandleRequestPetInfoOpcode( WorldPacket & /*recv_data */)
|
||||||
|
|
|
||||||
|
|
@ -1359,6 +1359,16 @@ bool WorldObject::HasInArc(const float arcangle, const WorldObject* obj) const
|
||||||
return (( angle >= lborder ) && ( angle <= rborder ));
|
return (( angle >= lborder ) && ( angle <= rborder ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WorldObject::isInFrontInMap(WorldObject const* target, float distance, float arc) const
|
||||||
|
{
|
||||||
|
return IsWithinDistInMap(target, distance) && HasInArc( arc, target );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WorldObject::isInBackInMap(WorldObject const* target, float distance, float arc) const
|
||||||
|
{
|
||||||
|
return IsWithinDistInMap(target, distance) && !HasInArc( 2 * M_PI - arc, target );
|
||||||
|
}
|
||||||
|
|
||||||
void WorldObject::GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z) const
|
void WorldObject::GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z) const
|
||||||
{
|
{
|
||||||
if(distance == 0)
|
if(distance == 0)
|
||||||
|
|
|
||||||
|
|
@ -445,6 +445,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
||||||
float GetAngle( const WorldObject* obj ) const;
|
float GetAngle( const WorldObject* obj ) const;
|
||||||
float GetAngle( const float x, const float y ) const;
|
float GetAngle( const float x, const float y ) const;
|
||||||
bool HasInArc( const float arcangle, const WorldObject* obj ) const;
|
bool HasInArc( const float arcangle, const WorldObject* obj ) const;
|
||||||
|
bool isInFrontInMap(WorldObject const* target,float distance, float arc = M_PI) const;
|
||||||
|
bool isInBackInMap(WorldObject const* target, float distance, float arc = M_PI) const;
|
||||||
|
|
||||||
virtual void CleanupsBeforeDelete(); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
|
virtual void CleanupsBeforeDelete(); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
|
||||||
|
|
||||||
|
|
@ -471,10 +473,10 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
||||||
void AddObjectToRemoveList();
|
void AddObjectToRemoveList();
|
||||||
|
|
||||||
// main visibility check function in normal case (ignore grey zone distance check)
|
// main visibility check function in normal case (ignore grey zone distance check)
|
||||||
bool isVisibleFor(Player const* u) const { return isVisibleForInState(u,false); }
|
bool isVisibleFor(Player const* u, WorldObject const* viewPoint) const { return isVisibleForInState(u,viewPoint,false); }
|
||||||
|
|
||||||
// low level function for visibility change code, must be define in all main world object subclasses
|
// low level function for visibility change code, must be define in all main world object subclasses
|
||||||
virtual bool isVisibleForInState(Player const* u, bool inVisibleList) const = 0;
|
virtual bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const = 0;
|
||||||
|
|
||||||
void SetMap(Map * map);
|
void SetMap(Map * map);
|
||||||
Map * GetMap() const { ASSERT(m_currMap); return m_currMap; }
|
Map * GetMap() const { ASSERT(m_currMap); return m_currMap; }
|
||||||
|
|
|
||||||
|
|
@ -90,43 +90,61 @@ ObjectAccessor::GetCorpse(WorldObject const &u, uint64 guid)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorldObject* ObjectAccessor::GetWorldObject(WorldObject const &p, uint64 guid)
|
||||||
|
{
|
||||||
|
switch(GUID_HIPART(guid))
|
||||||
|
{
|
||||||
|
case HIGHGUID_PLAYER: return FindPlayer(guid);
|
||||||
|
case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid);
|
||||||
|
case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid);
|
||||||
|
case HIGHGUID_PET: return GetPet(guid);
|
||||||
|
case HIGHGUID_VEHICLE: return GetVehicle(guid);
|
||||||
|
case HIGHGUID_DYNAMICOBJECT:return p.GetMap()->GetDynamicObject(guid);
|
||||||
|
case HIGHGUID_TRANSPORT: return NULL;
|
||||||
|
case HIGHGUID_CORPSE: return GetCorpse(p,guid);
|
||||||
|
case HIGHGUID_MO_TRANSPORT: return NULL;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, uint32 typemask)
|
Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, uint32 typemask)
|
||||||
{
|
{
|
||||||
Object *obj = NULL;
|
switch(GUID_HIPART(guid))
|
||||||
|
|
||||||
if(typemask & TYPEMASK_PLAYER)
|
|
||||||
{
|
{
|
||||||
obj = FindPlayer(guid);
|
case HIGHGUID_ITEM:
|
||||||
if(obj)
|
if(typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER)
|
||||||
return obj;
|
return ((Player const &)p).GetItemByGuid( guid );
|
||||||
}
|
break;
|
||||||
|
case HIGHGUID_PLAYER:
|
||||||
if(typemask & TYPEMASK_UNIT)
|
if(typemask & TYPEMASK_PLAYER)
|
||||||
{
|
return FindPlayer(guid);
|
||||||
obj = GetCreatureOrPetOrVehicle(p,guid);
|
break;
|
||||||
if(obj)
|
case HIGHGUID_GAMEOBJECT:
|
||||||
return obj;
|
if(typemask & TYPEMASK_GAMEOBJECT)
|
||||||
}
|
return p.GetMap()->GetGameObject(guid);
|
||||||
|
break;
|
||||||
if(typemask & TYPEMASK_GAMEOBJECT)
|
case HIGHGUID_UNIT:
|
||||||
{
|
if(typemask & TYPEMASK_UNIT)
|
||||||
obj = p.GetMap()->GetGameObject(guid);
|
return p.GetMap()->GetCreature(guid);
|
||||||
if(obj)
|
break;
|
||||||
return obj;
|
case HIGHGUID_PET:
|
||||||
}
|
if(typemask & TYPEMASK_UNIT)
|
||||||
|
return GetPet(guid);
|
||||||
if(typemask & TYPEMASK_DYNAMICOBJECT)
|
break;
|
||||||
{
|
case HIGHGUID_VEHICLE:
|
||||||
obj = p.GetMap()->GetDynamicObject(guid);
|
if(typemask & TYPEMASK_UNIT)
|
||||||
if(obj)
|
return GetVehicle(guid);
|
||||||
return obj;
|
break;
|
||||||
}
|
case HIGHGUID_DYNAMICOBJECT:
|
||||||
|
if(typemask & TYPEMASK_DYNAMICOBJECT)
|
||||||
if(typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER)
|
return p.GetMap()->GetDynamicObject(guid);
|
||||||
{
|
break;
|
||||||
obj = ((Player const &)p).GetItemByGuid( guid );
|
case HIGHGUID_TRANSPORT:
|
||||||
if(obj)
|
case HIGHGUID_CORPSE:
|
||||||
return obj;
|
case HIGHGUID_MO_TRANSPORT:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
else return NULL;
|
else return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WorldObject* GetWorldObject(WorldObject const &, uint64);
|
||||||
static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask);
|
static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask);
|
||||||
static Creature* GetCreatureOrPetOrVehicle(WorldObject const &, uint64);
|
static Creature* GetCreatureOrPetOrVehicle(WorldObject const &, uint64);
|
||||||
static Unit* GetUnit(WorldObject const &, uint64);
|
static Unit* GetUnit(WorldObject const &, uint64);
|
||||||
|
|
|
||||||
|
|
@ -307,7 +307,7 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||||
bool PetAI::_isVisible(Unit *u) const
|
bool PetAI::_isVisible(Unit *u) const
|
||||||
{
|
{
|
||||||
return m_creature->IsWithinDist(u,sWorld.getConfig(CONFIG_SIGHT_GUARDER))
|
return m_creature->IsWithinDist(u,sWorld.getConfig(CONFIG_SIGHT_GUARDER))
|
||||||
&& u->isVisibleForOrDetect(m_creature,true);
|
&& u->isVisibleForOrDetect(m_creature,m_creature,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetAI::UpdateAllies()
|
void PetAI::UpdateAllies()
|
||||||
|
|
|
||||||
|
|
@ -16794,13 +16794,15 @@ void Player::HandleStealthedUnitsDetection()
|
||||||
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap());
|
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap());
|
||||||
cell_lock->Visit(cell_lock, grid_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)
|
for (std::list<Unit*>::const_iterator i = stealthedUnits.begin(); i != stealthedUnits.end(); ++i)
|
||||||
{
|
{
|
||||||
if((*i)==this)
|
if((*i)==this)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool hasAtClient = HaveAtClient((*i));
|
bool hasAtClient = HaveAtClient((*i));
|
||||||
bool hasDetected = (*i)->isVisibleForOrDetect(this, true);
|
bool hasDetected = (*i)->isVisibleForOrDetect(this, viewPoint, true);
|
||||||
|
|
||||||
if (hasDetected)
|
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
|
bool Player::IsVisibleInGridForPlayer( Player* pl ) const
|
||||||
{
|
{
|
||||||
// gamemaster in GM mode see all, including ghosts
|
// gamemaster in GM mode see all, including ghosts
|
||||||
|
|
@ -17949,11 +17962,11 @@ bool Player::IsVisibleGloballyFor( Player* u ) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::UpdateVisibilityOf(WorldObject* target)
|
void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* target)
|
||||||
{
|
{
|
||||||
if(HaveAtClient(target))
|
if(HaveAtClient(target))
|
||||||
{
|
{
|
||||||
if(!target->isVisibleForInState(this, true))
|
if(!target->isVisibleForInState(this, viewPoint, true))
|
||||||
{
|
{
|
||||||
target->DestroyForPlayer(this);
|
target->DestroyForPlayer(this);
|
||||||
m_clientGUIDs.erase(target->GetGUID());
|
m_clientGUIDs.erase(target->GetGUID());
|
||||||
|
|
@ -17966,7 +17979,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(target->isVisibleForInState(this,false))
|
if(target->isVisibleForInState(this, viewPoint, false))
|
||||||
{
|
{
|
||||||
target->SendUpdateToPlayer(this);
|
target->SendUpdateToPlayer(this);
|
||||||
if(target->GetTypeId()!=TYPEID_GAMEOBJECT||!((GameObject*)target)->IsTransport())
|
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>
|
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(HaveAtClient(target))
|
||||||
{
|
{
|
||||||
if(!target->isVisibleForInState(this,true))
|
if(!target->isVisibleForInState(this,viewPoint,true))
|
||||||
{
|
{
|
||||||
target->BuildOutOfRangeUpdateBlock(&data);
|
target->BuildOutOfRangeUpdateBlock(&data);
|
||||||
m_clientGUIDs.erase(target->GetGUID());
|
m_clientGUIDs.erase(target->GetGUID());
|
||||||
|
|
@ -18019,7 +18032,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, UpdateDataMapType&
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(target->isVisibleForInState(this,false))
|
if(target->isVisibleForInState(this,viewPoint,false))
|
||||||
{
|
{
|
||||||
visibleNow.insert(target);
|
visibleNow.insert(target);
|
||||||
target->BuildUpdate(data_updates);
|
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(WorldObject const* viewPoint, 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(WorldObject const* viewPoint, 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(WorldObject const* viewPoint, 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(WorldObject const* viewPoint, 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, DynamicObject* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
|
||||||
|
|
||||||
void Player::InitPrimaryProfessions()
|
void Player::InitPrimaryProfessions()
|
||||||
{
|
{
|
||||||
|
|
@ -20566,3 +20579,14 @@ bool Player::HasMovementFlag( MovementFlags f ) const
|
||||||
{
|
{
|
||||||
return m_movementInfo.HasMovementFlag(f);
|
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2084,7 +2084,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void ExitVehicle(Vehicle *vehicle);
|
void ExitVehicle(Vehicle *vehicle);
|
||||||
|
|
||||||
uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); }
|
uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); }
|
||||||
void SetFarSightGUID(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); }
|
void SetFarSightGUID(uint64 guid);
|
||||||
|
|
||||||
// Transports
|
// Transports
|
||||||
Transport * GetTransport() const { return m_transport; }
|
Transport * GetTransport() const { return m_transport; }
|
||||||
|
|
@ -2122,13 +2122,14 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
|
|
||||||
bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); }
|
bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); }
|
||||||
|
|
||||||
|
WorldObject const* GetViewPoint() const;
|
||||||
bool IsVisibleInGridForPlayer(Player* pl) const;
|
bool IsVisibleInGridForPlayer(Player* pl) const;
|
||||||
bool IsVisibleGloballyFor(Player* pl) const;
|
bool IsVisibleGloballyFor(Player* pl) const;
|
||||||
|
|
||||||
void UpdateVisibilityOf(WorldObject* target);
|
void UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* target);
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void UpdateVisibilityOf(T* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
|
void UpdateVisibilityOf(WorldObject const* viewPoint,T* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
|
||||||
|
|
||||||
// Stealth detection system
|
// Stealth detection system
|
||||||
void HandleStealthedUnitsDetection();
|
void HandleStealthedUnitsDetection();
|
||||||
|
|
|
||||||
|
|
@ -1194,7 +1194,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
||||||
{
|
{
|
||||||
// for delayed spells ignore not visible explicit target
|
// for delayed spells ignore not visible explicit target
|
||||||
if (m_spellInfo->speed > 0.0f && unit == m_targets.getUnitTarget() &&
|
if (m_spellInfo->speed > 0.0f && unit == m_targets.getUnitTarget() &&
|
||||||
!unit->isVisibleForOrDetect(m_caster,false))
|
!unit->isVisibleForOrDetect(m_caster,m_caster,false))
|
||||||
{
|
{
|
||||||
realCaster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
|
realCaster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
|
||||||
return;
|
return;
|
||||||
|
|
@ -1204,9 +1204,9 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
||||||
if (!(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH))
|
if (!(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH))
|
||||||
unit->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
unit->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||||
|
|
||||||
// can cause back attack (if detected)
|
// can cause back attack (if detected), stealth removed at Spell::cast if spell break it
|
||||||
if (!(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) && !IsPositiveSpell(m_spellInfo->Id) &&
|
if (!(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) && !IsPositiveSpell(m_spellInfo->Id) &&
|
||||||
m_caster->isVisibleForOrDetect(unit,false)) // stealth removed at Spell::cast if spell break it
|
m_caster->isVisibleForOrDetect(unit,unit,false))
|
||||||
{
|
{
|
||||||
// use speedup check to avoid re-remove after above lines
|
// use speedup check to avoid re-remove after above lines
|
||||||
if (m_spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH)
|
if (m_spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH)
|
||||||
|
|
|
||||||
|
|
@ -3634,10 +3634,14 @@ void Spell::EffectPickPocket(uint32 /*i*/)
|
||||||
|
|
||||||
void Spell::EffectAddFarsight(uint32 i)
|
void Spell::EffectAddFarsight(uint32 i)
|
||||||
{
|
{
|
||||||
float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
|
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
|
return;
|
||||||
|
|
||||||
int32 duration = GetSpellDuration(m_spellInfo);
|
int32 duration = GetSpellDuration(m_spellInfo);
|
||||||
DynamicObject* dynObj = new DynamicObject;
|
DynamicObject* dynObj = new DynamicObject;
|
||||||
if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius))
|
|
||||||
|
// set radius to 0: spell not expected to work as persistent aura
|
||||||
|
if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, 0))
|
||||||
{
|
{
|
||||||
delete dynObj;
|
delete dynObj;
|
||||||
return;
|
return;
|
||||||
|
|
@ -3646,8 +3650,7 @@ void Spell::EffectAddFarsight(uint32 i)
|
||||||
dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002);
|
dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002);
|
||||||
m_caster->AddDynObject(dynObj);
|
m_caster->AddDynObject(dynObj);
|
||||||
m_caster->GetMap()->Add(dynObj);
|
m_caster->GetMap()->Add(dynObj);
|
||||||
if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
((Player*)m_caster)->SetFarSightGUID(dynObj->GetGUID());
|
||||||
((Player*)m_caster)->SetFarSightGUID(dynObj->GetGUID());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectSummonWild(uint32 i)
|
void Spell::EffectSummonWild(uint32 i)
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
|
||||||
// Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
|
// Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
|
||||||
if( !victim ||
|
if( !victim ||
|
||||||
!victim->isTargetableForAttack() || !m_creature->IsWithinDistInMap(victim, max_range) ||
|
!victim->isTargetableForAttack() || !m_creature->IsWithinDistInMap(victim, max_range) ||
|
||||||
m_creature->IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(m_creature,false) )
|
m_creature->IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(m_creature,m_creature,false) )
|
||||||
{
|
{
|
||||||
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(),m_creature->GetPositionY()));
|
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(),m_creature->GetPositionY()));
|
||||||
Cell cell(p);
|
Cell cell(p);
|
||||||
|
|
|
||||||
|
|
@ -3193,21 +3193,11 @@ Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const
|
|
||||||
{
|
|
||||||
return IsWithinDistInMap(target, distance) && HasInArc( arc, target );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Unit::SetInFront(Unit const* target)
|
void Unit::SetInFront(Unit const* target)
|
||||||
{
|
{
|
||||||
SetOrientation(GetAngle(target));
|
SetOrientation(GetAngle(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const
|
|
||||||
{
|
|
||||||
return IsWithinDistInMap(target, distance) && !HasInArc( 2 * M_PI - arc, target );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Unit::isInAccessablePlaceFor(Creature const* c) const
|
bool Unit::isInAccessablePlaceFor(Creature const* c) const
|
||||||
{
|
{
|
||||||
if(IsInWater())
|
if(IsInWater())
|
||||||
|
|
@ -9272,7 +9262,7 @@ int32 Unit::ModifyPower(Powers power, int32 dVal)
|
||||||
return gain;
|
return gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, bool is3dDistance) const
|
bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, bool detect, bool inVisibleList, bool is3dDistance) const
|
||||||
{
|
{
|
||||||
if(!u)
|
if(!u)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -9319,16 +9309,20 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
|
||||||
if(GetCharmerOrOwnerGUID()==u->GetGUID())
|
if(GetCharmerOrOwnerGUID()==u->GetGUID())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// always seen by far sight caster
|
||||||
|
if( u->GetTypeId()==TYPEID_PLAYER && ((Player*)u)->GetFarSight()==GetGUID())
|
||||||
|
return true;
|
||||||
|
|
||||||
// different visible distance checks
|
// different visible distance checks
|
||||||
if(u->isInFlight()) // what see player in flight
|
if(u->isInFlight()) // what see player in flight
|
||||||
{
|
{
|
||||||
// use object grey distance for all (only see objects any way)
|
// use object grey distance for all (only see objects any way)
|
||||||
if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
|
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(!isAlive()) // distance for show body
|
else if(!isAlive()) // distance for show body
|
||||||
{
|
{
|
||||||
if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
|
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(GetTypeId()==TYPEID_PLAYER) // distance for show player
|
else if(GetTypeId()==TYPEID_PLAYER) // distance for show player
|
||||||
|
|
@ -9336,26 +9330,26 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
|
||||||
if(u->GetTypeId()==TYPEID_PLAYER)
|
if(u->GetTypeId()==TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
// Players far than max visible distance for player or not in our map are not visible too
|
// 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), is3dDistance))
|
if (!at_same_transport && !IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Units far than max visible distance for creature or not in our map are not visible too
|
// 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), is3dDistance))
|
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(GetCharmerOrOwnerGUID()) // distance for show pet/charmed
|
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
|
// 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), is3dDistance))
|
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else // distance for show creature
|
else // distance for show creature
|
||||||
{
|
{
|
||||||
// Units far than max visible distance for creature or not in our map are not visible too
|
// 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), is3dDistance))
|
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9463,7 +9457,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
|
||||||
float visibleDistance = (u->GetTypeId() == TYPEID_PLAYER) ? MAX_PLAYER_STEALTH_DETECT_RANGE : ((Creature const*)u)->GetAttackDistance(this);
|
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
|
//Always invisible from back (when stealth detection is on), also filter max distance cases
|
||||||
bool isInFront = u->isInFrontInMap(this, visibleDistance);
|
bool isInFront = viewPoint->isInFrontInMap(this, visibleDistance);
|
||||||
if(!isInFront)
|
if(!isInFront)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -9490,13 +9484,13 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
|
||||||
visibleDistance = visibleDistance > MAX_PLAYER_STEALTH_DETECT_RANGE ? MAX_PLAYER_STEALTH_DETECT_RANGE : visibleDistance;
|
visibleDistance = visibleDistance > MAX_PLAYER_STEALTH_DETECT_RANGE ? MAX_PLAYER_STEALTH_DETECT_RANGE : visibleDistance;
|
||||||
|
|
||||||
// recheck new distance
|
// recheck new distance
|
||||||
if(visibleDistance <= 0 || !IsWithinDist(u,visibleDistance))
|
if(visibleDistance <= 0 || !IsWithinDist(viewPoint,visibleDistance))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now check is target visible with LoS
|
// Now check is target visible with LoS
|
||||||
float ox,oy,oz;
|
float ox,oy,oz;
|
||||||
u->GetPosition(ox,oy,oz);
|
viewPoint->GetPosition(ox,oy,oz);
|
||||||
return IsWithinLOS(ox,oy,oz);
|
return IsWithinLOS(ox,oy,oz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10203,9 +10197,9 @@ Unit* Unit::GetUnit(WorldObject& object, uint64 guid)
|
||||||
return ObjectAccessor::GetUnit(object,guid);
|
return ObjectAccessor::GetUnit(object,guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unit::isVisibleForInState( Player const* u, bool inVisibleList ) const
|
bool Unit::isVisibleForInState( Player const* u, WorldObject const* viewPoint, bool inVisibleList ) const
|
||||||
{
|
{
|
||||||
return isVisibleForOrDetect(u, false, inVisibleList, false);
|
return isVisibleForOrDetect(u, viewPoint, false, inVisibleList, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Unit::GetCreatureType() const
|
uint32 Unit::GetCreatureType() const
|
||||||
|
|
|
||||||
|
|
@ -1310,21 +1310,19 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
float GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const;
|
float GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const;
|
||||||
void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }
|
void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }
|
||||||
|
|
||||||
bool isInFrontInMap(Unit const* target,float distance, float arc = M_PI) const;
|
|
||||||
void SetInFront(Unit const* target);
|
void SetInFront(Unit const* target);
|
||||||
bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const;
|
|
||||||
|
|
||||||
// Visibility system
|
// Visibility system
|
||||||
UnitVisibility GetVisibility() const { return m_Visibility; }
|
UnitVisibility GetVisibility() const { return m_Visibility; }
|
||||||
void SetVisibility(UnitVisibility x);
|
void SetVisibility(UnitVisibility x);
|
||||||
|
|
||||||
// common function for visibility checks for player/creatures with detection code
|
// common function for visibility checks for player/creatures with detection code
|
||||||
bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
|
bool isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
|
||||||
bool canDetectInvisibilityOf(Unit const* u) const;
|
bool canDetectInvisibilityOf(Unit const* u) const;
|
||||||
void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask
|
void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask
|
||||||
|
|
||||||
// virtual functions for all world objects types
|
// virtual functions for all world objects types
|
||||||
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
|
bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const;
|
||||||
// function for low level grid visibility checks in player/creature cases
|
// function for low level grid visibility checks in player/creature cases
|
||||||
virtual bool IsVisibleInGridForPlayer(Player* pl) const = 0;
|
virtual bool IsVisibleInGridForPlayer(Player* pl) const = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8421"
|
#define REVISION_NR "8422"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue