mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 10:37:02 +00:00
[8677] Move most client update data functions to object itself from ObjectAccessor.
Also use virtual function BuildUpdateData (old ObjectAccessor::_buildUpdateObject) that different for world objects and items.
This commit is contained in:
parent
a2ff999fd3
commit
abb77cfdbf
7 changed files with 73 additions and 79 deletions
|
|
@ -996,6 +996,14 @@ bool Item::IsBindedNotWith( Player const* player ) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Item::BuildUpdateData(UpdateDataMapType& update_players)
|
||||||
|
{
|
||||||
|
if (Player* pl = GetOwner())
|
||||||
|
BuildUpdateDataForPlayer(pl, update_players);
|
||||||
|
|
||||||
|
ClearUpdateMask(false);
|
||||||
|
}
|
||||||
|
|
||||||
bool ItemRequiredTarget::IsFitToRequirements( Unit* pUnitTarget ) const
|
bool ItemRequiredTarget::IsFitToRequirements( Unit* pUnitTarget ) const
|
||||||
{
|
{
|
||||||
if(pUnitTarget->GetTypeId() != TYPEID_UNIT)
|
if(pUnitTarget->GetTypeId() != TYPEID_UNIT)
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,7 @@ class MANGOS_DLL_SPEC Item : public Object
|
||||||
bool IsPotion() const { return GetProto()->IsPotion(); }
|
bool IsPotion() const { return GetProto()->IsPotion(); }
|
||||||
bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
|
bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
|
||||||
|
|
||||||
|
void BuildUpdateData(UpdateDataMapType& update_players);
|
||||||
private:
|
private:
|
||||||
uint8 m_slot;
|
uint8 m_slot;
|
||||||
Bag *m_container;
|
Bag *m_container;
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ void Object::BuildMovementUpdateBlock(UpdateData * data, uint32 flags ) const
|
||||||
buf << uint8( UPDATETYPE_MOVEMENT );
|
buf << uint8( UPDATETYPE_MOVEMENT );
|
||||||
buf.append(GetPackGUID());
|
buf.append(GetPackGUID());
|
||||||
|
|
||||||
_BuildMovementUpdate(&buf, flags, 0x00000000);
|
BuildMovementUpdate(&buf, flags, 0x00000000);
|
||||||
|
|
||||||
data->AddUpdateBlock(buf);
|
data->AddUpdateBlock(buf);
|
||||||
}
|
}
|
||||||
|
|
@ -189,12 +189,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
|
||||||
buf.append(GetPackGUID());
|
buf.append(GetPackGUID());
|
||||||
buf << (uint8)m_objectTypeId;
|
buf << (uint8)m_objectTypeId;
|
||||||
|
|
||||||
_BuildMovementUpdate(&buf, flags, flags2);
|
BuildMovementUpdate(&buf, flags, flags2);
|
||||||
|
|
||||||
UpdateMask updateMask;
|
UpdateMask updateMask;
|
||||||
updateMask.SetCount( m_valuesCount );
|
updateMask.SetCount( m_valuesCount );
|
||||||
_SetCreateBits( &updateMask, target );
|
_SetCreateBits( &updateMask, target );
|
||||||
_BuildValuesUpdate(updatetype, &buf, &updateMask, target);
|
BuildValuesUpdate(updatetype, &buf, &updateMask, target);
|
||||||
data->AddUpdateBlock(buf);
|
data->AddUpdateBlock(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,7 +220,7 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) c
|
||||||
updateMask.SetCount( m_valuesCount );
|
updateMask.SetCount( m_valuesCount );
|
||||||
|
|
||||||
_SetUpdateBits( &updateMask, target );
|
_SetUpdateBits( &updateMask, target );
|
||||||
_BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target);
|
BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target);
|
||||||
|
|
||||||
data->AddUpdateBlock(buf);
|
data->AddUpdateBlock(buf);
|
||||||
}
|
}
|
||||||
|
|
@ -240,7 +240,7 @@ void Object::DestroyForPlayer( Player *target, bool anim ) const
|
||||||
target->GetSession()->SendPacket( &data );
|
target->GetSession()->SendPacket( &data );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2) const
|
void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2) const
|
||||||
{
|
{
|
||||||
uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0);
|
uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0);
|
||||||
|
|
||||||
|
|
@ -567,7 +567,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const
|
void Object::BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const
|
||||||
{
|
{
|
||||||
if(!target)
|
if(!target)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1065,6 +1065,20 @@ bool Object::PrintIndexError(uint32 index, bool set) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Object::BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players)
|
||||||
|
{
|
||||||
|
UpdateDataMapType::iterator iter = update_players.find(pl);
|
||||||
|
|
||||||
|
if (iter == update_players.end())
|
||||||
|
{
|
||||||
|
std::pair<UpdateDataMapType::iterator, bool> p = update_players.insert( UpdateDataMapType::value_type(pl, UpdateData()) );
|
||||||
|
assert(p.second);
|
||||||
|
iter = p.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
|
||||||
|
}
|
||||||
|
|
||||||
WorldObject::WorldObject()
|
WorldObject::WorldObject()
|
||||||
: m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
|
: m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
|
||||||
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), m_currMap(NULL)
|
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), m_currMap(NULL)
|
||||||
|
|
@ -1857,3 +1871,33 @@ void WorldObject::UpdateObjectVisibility()
|
||||||
GetMap()->UpdateObjectVisibility(this, cell, p);
|
GetMap()->UpdateObjectVisibility(this, cell, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct WorldObjectChangeAccumulator
|
||||||
|
{
|
||||||
|
UpdateDataMapType &i_updateDatas;
|
||||||
|
WorldObject &i_object;
|
||||||
|
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {}
|
||||||
|
void Visit(PlayerMapType &m)
|
||||||
|
{
|
||||||
|
for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||||
|
if(iter->getSource()->HaveAtClient(&i_object))
|
||||||
|
i_object.BuildUpdateDataForPlayer(iter->getSource(), i_updateDatas);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void WorldObject::BuildUpdateData( UpdateDataMapType & update_players)
|
||||||
|
{
|
||||||
|
CellPair p = MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY());
|
||||||
|
Cell cell(p);
|
||||||
|
cell.data.Part.reserved = ALL_DISTRICT;
|
||||||
|
cell.SetNoCreate();
|
||||||
|
WorldObjectChangeAccumulator notifier(*this, update_players);
|
||||||
|
TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier);
|
||||||
|
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||||
|
Map* aMap = GetMap();
|
||||||
|
//we must build packets for all visible players
|
||||||
|
cell_lock->Visit(cell_lock, player_notifier, *aMap, *this, aMap->GetVisibilityDistance());
|
||||||
|
|
||||||
|
ClearUpdateMask(false);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,7 @@ class MANGOS_DLL_SPEC Object
|
||||||
virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
|
virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
|
||||||
void SendCreateUpdateToPlayer(Player* player);
|
void SendCreateUpdateToPlayer(Player* player);
|
||||||
|
|
||||||
|
virtual void BuildUpdateData(UpdateDataMapType& update_players) =0;
|
||||||
void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
|
void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
|
||||||
void BuildOutOfRangeUpdateBlock( UpdateData *data ) const;
|
void BuildOutOfRangeUpdateBlock( UpdateData *data ) const;
|
||||||
void BuildMovementUpdateBlock( UpdateData * data, uint32 flags = 0 ) const;
|
void BuildMovementUpdateBlock( UpdateData * data, uint32 flags = 0 ) const;
|
||||||
|
|
@ -307,8 +308,9 @@ class MANGOS_DLL_SPEC Object
|
||||||
virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
|
virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
|
||||||
|
|
||||||
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
|
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
|
||||||
void _BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 ) const;
|
void BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 ) const;
|
||||||
void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
|
void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
|
||||||
|
void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players);
|
||||||
|
|
||||||
uint16 m_objectType;
|
uint16 m_objectType;
|
||||||
|
|
||||||
|
|
@ -339,8 +341,12 @@ class MANGOS_DLL_SPEC Object
|
||||||
Object& operator=(Object const&); // prevent generation assigment operator
|
Object& operator=(Object const&); // prevent generation assigment operator
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct WorldObjectChangeAccumulator;
|
||||||
|
|
||||||
class MANGOS_DLL_SPEC WorldObject : public Object
|
class MANGOS_DLL_SPEC WorldObject : public Object
|
||||||
{
|
{
|
||||||
|
friend struct WorldObjectChangeAccumulator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~WorldObject ( ) {}
|
virtual ~WorldObject ( ) {}
|
||||||
|
|
||||||
|
|
@ -488,11 +494,11 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
||||||
//this function should be removed in nearest time...
|
//this function should be removed in nearest time...
|
||||||
Map const* GetBaseMap() const;
|
Map const* GetBaseMap() const;
|
||||||
|
|
||||||
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
|
void BuildUpdateData(UpdateDataMapType &);
|
||||||
|
|
||||||
|
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
|
||||||
protected:
|
protected:
|
||||||
explicit WorldObject();
|
explicit WorldObject();
|
||||||
std::string m_name;
|
|
||||||
|
|
||||||
//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
|
//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
|
||||||
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
|
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
|
||||||
|
|
@ -500,6 +506,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
||||||
void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
|
void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
|
||||||
void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }
|
void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Map * m_currMap; //current object's Map location
|
Map * m_currMap; //current object's Map location
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,49 +182,6 @@ ObjectAccessor::SaveAllPlayers()
|
||||||
itr->second->SaveToDB();
|
itr->second->SaveToDB();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ObjectAccessor::_buildUpdateObject(Object *obj, UpdateDataMapType &update_players)
|
|
||||||
{
|
|
||||||
if(obj->isType(TYPEMASK_ITEM))
|
|
||||||
{
|
|
||||||
Item *item = static_cast<Item *>(obj);
|
|
||||||
if (Player* pl = item->GetOwner())
|
|
||||||
_buildPacket(pl, obj, update_players);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_buildChangeObjectForPlayer(static_cast<WorldObject*>(obj), update_players);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ObjectAccessor::_buildPacket(Player *pl, Object *obj, UpdateDataMapType &update_players)
|
|
||||||
{
|
|
||||||
UpdateDataMapType::iterator iter = update_players.find(pl);
|
|
||||||
|
|
||||||
if( iter == update_players.end() )
|
|
||||||
{
|
|
||||||
std::pair<UpdateDataMapType::iterator, bool> p = update_players.insert( UpdateDataValueType(pl, UpdateData()) );
|
|
||||||
assert(p.second);
|
|
||||||
iter = p.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ObjectAccessor::_buildChangeObjectForPlayer(WorldObject *obj, UpdateDataMapType &update_players)
|
|
||||||
{
|
|
||||||
CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
|
|
||||||
Cell cell(p);
|
|
||||||
cell.data.Part.reserved = ALL_DISTRICT;
|
|
||||||
cell.SetNoCreate();
|
|
||||||
WorldObjectChangeAccumulator notifier(*obj, update_players);
|
|
||||||
TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier);
|
|
||||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
|
||||||
Map& map = *obj->GetMap();
|
|
||||||
//we must build packets for all visible players
|
|
||||||
cell_lock->Visit(cell_lock, player_notifier, map, *obj, map.GetVisibilityDistance());
|
|
||||||
}
|
|
||||||
|
|
||||||
Pet*
|
Pet*
|
||||||
ObjectAccessor::GetPet(uint64 guid)
|
ObjectAccessor::GetPet(uint64 guid)
|
||||||
{
|
{
|
||||||
|
|
@ -386,8 +343,7 @@ ObjectAccessor::Update(uint32 diff)
|
||||||
i_objects.erase(i_objects.begin());
|
i_objects.erase(i_objects.begin());
|
||||||
if (!obj)
|
if (!obj)
|
||||||
continue;
|
continue;
|
||||||
_buildUpdateObject(obj, update_players);
|
obj->BuildUpdateData(update_players);
|
||||||
obj->ClearUpdateMask(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -400,14 +356,6 @@ ObjectAccessor::Update(uint32 diff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ObjectAccessor::WorldObjectChangeAccumulator::Visit(PlayerMapType &m)
|
|
||||||
{
|
|
||||||
for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
|
||||||
if(iter->getSource()->HaveAtClient(&i_object))
|
|
||||||
ObjectAccessor::_buildPacket(iter->getSource(), &i_object, i_updateDatas);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Define the static member of HashMapHolder
|
/// Define the static member of HashMapHolder
|
||||||
|
|
||||||
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;
|
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,6 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef UNORDERED_MAP<uint64, Corpse* > Player2CorpsesMapType;
|
typedef UNORDERED_MAP<uint64, Corpse* > Player2CorpsesMapType;
|
||||||
typedef UNORDERED_MAP<Player*, UpdateData>::value_type UpdateDataValueType;
|
|
||||||
|
|
||||||
template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
|
template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
|
||||||
{
|
{
|
||||||
|
|
@ -180,21 +179,10 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
|
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
|
||||||
Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false);
|
Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false);
|
||||||
|
|
||||||
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
|
|
||||||
|
|
||||||
// TODO: This methods will need lock in MT environment
|
// TODO: This methods will need lock in MT environment
|
||||||
static void LinkMap(Map* map) { i_mapList.push_back(map); }
|
static void LinkMap(Map* map) { i_mapList.push_back(map); }
|
||||||
static void DelinkMap(Map* map) { i_mapList.remove(map); }
|
static void DelinkMap(Map* map) { i_mapList.remove(map); }
|
||||||
private:
|
private:
|
||||||
struct WorldObjectChangeAccumulator
|
|
||||||
{
|
|
||||||
UpdateDataMapType &i_updateDatas;
|
|
||||||
WorldObject &i_object;
|
|
||||||
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {}
|
|
||||||
void Visit(PlayerMapType &);
|
|
||||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: This methods will need lock in MT environment
|
// TODO: This methods will need lock in MT environment
|
||||||
// Theoreticaly multiple threads can enter and search in this method but
|
// Theoreticaly multiple threads can enter and search in this method but
|
||||||
// in that case linking/delinking other map should be guarded
|
// in that case linking/delinking other map should be guarded
|
||||||
|
|
@ -213,14 +201,11 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
|
|
||||||
static std::list<Map*> i_mapList;
|
static std::list<Map*> i_mapList;
|
||||||
|
|
||||||
friend struct WorldObjectChangeAccumulator;
|
|
||||||
Player2CorpsesMapType i_player2corpse;
|
Player2CorpsesMapType i_player2corpse;
|
||||||
|
|
||||||
typedef ACE_Thread_Mutex LockType;
|
typedef ACE_Thread_Mutex LockType;
|
||||||
typedef MaNGOS::GeneralLock<LockType > Guard;
|
typedef MaNGOS::GeneralLock<LockType > Guard;
|
||||||
|
|
||||||
static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &);
|
|
||||||
static void _buildPacket(Player *, Object *, UpdateDataMapType &);
|
|
||||||
std::set<Object *> i_objects;
|
std::set<Object *> i_objects;
|
||||||
LockType i_playerGuard;
|
LockType i_playerGuard;
|
||||||
LockType i_updateGuard;
|
LockType i_updateGuard;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8676"
|
#define REVISION_NR "8677"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue