diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 644c13dfa..ba6381cb7 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -996,6 +996,18 @@ bool Item::IsBindedNotWith( Player const* player ) const } } +void Item::AddToClientUpdateList() +{ + if (Player* pl = GetOwner()) + pl->GetMap()->AddUpdateObject(this); +} + +void Item::RemoveFromClientUpdateList() +{ + if (Player* pl = GetOwner()) + pl->GetMap()->RemoveUpdateObject(this); +} + void Item::BuildUpdateData(UpdateDataMapType& update_players) { if (Player* pl = GetOwner()) diff --git a/src/game/Item.h b/src/game/Item.h index a1b444007..59aa86f6d 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -313,6 +313,8 @@ class MANGOS_DLL_SPEC Item : public Object bool IsPotion() const { return GetProto()->IsPotion(); } bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); } + void AddToClientUpdateList(); + void RemoveFromClientUpdateList(); void BuildUpdateData(UpdateDataMapType& update_players); private: uint8 m_slot; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 4abed7b57..51d9cddb8 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -697,6 +697,9 @@ void Map::Update(const uint32 &t_diff) } } + // Send world objects and item update field changes + SendObjectUpdates(); + // Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load ! // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended if (!IsBattleGroundOrArena()) @@ -3415,3 +3418,25 @@ DynamicObject* Map::GetDynamicObject(uint64 guid) { return m_objectsStore.find(guid, (DynamicObject*)NULL); } + +void Map::SendObjectUpdates() +{ + UpdateDataMapType update_players; + + while(!i_objectsToClientUpdate.empty()) + { + Object* obj = *i_objectsToClientUpdate.begin(); + i_objectsToClientUpdate.erase(i_objectsToClientUpdate.begin()); + if (!obj) + continue; + obj->BuildUpdateData(update_players); + } + + WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 + for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) + { + iter->second.BuildPacket(&packet); + iter->first->GetSession()->SendPacket(&packet); + packet.clear(); // clean the string + } +} \ No newline at end of file diff --git a/src/game/Map.h b/src/game/Map.h index a50a3e1f4..af5b94cd6 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -428,6 +428,16 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj DynamicObject* GetDynamicObject(uint64 guid); TypeUnorderedMapContainer& GetObjectsStore() { return m_objectsStore; } + + void AddUpdateObject(Object *obj) + { + i_objectsToClientUpdate.insert(obj); + } + + void RemoveUpdateObject(Object *obj) + { + i_objectsToClientUpdate.erase( obj ); + } private: void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); @@ -472,6 +482,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj void setNGrid(NGridType* grid, uint32 x, uint32 y); void ScriptsProcess(); + void SendObjectUpdates(); + std::set i_objectsToClientUpdate; protected: void SetUnloadReferenceLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 624e3b884..f129e6db9 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -268,7 +268,6 @@ MapManager::Update(uint32 diff) iter->second->Update(i_timer.GetCurrent()); } - ObjectAccessor::Instance().Update(i_timer.GetCurrent()); for (TransportSet::iterator iter = m_Transports.begin(); iter != m_Transports.end(); ++iter) (*iter)->Update(i_timer.GetCurrent()); diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 08fcee5b4..b795475aa 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -80,9 +80,6 @@ Object::Object( ) : m_PackGUID(sizeof(uint64)+1) Object::~Object( ) { - if(m_objectUpdated) - ObjectAccessor::Instance().RemoveUpdateObject(this); - if(m_uint32Values) { if(IsInWorld()) @@ -744,10 +741,11 @@ void Object::ClearUpdateMask(bool remove) if(m_uint32Values_mirror[index]!= m_uint32Values[index]) m_uint32Values_mirror[index] = m_uint32Values[index]; } + if(m_objectUpdated) { if(remove) - ObjectAccessor::Instance().RemoveUpdateObject(this); + RemoveFromClientUpdateList(); m_objectUpdated = false; } } @@ -801,7 +799,7 @@ void Object::SetInt32Value( uint16 index, int32 value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -820,7 +818,7 @@ void Object::SetUInt32Value( uint16 index, uint32 value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -839,7 +837,7 @@ void Object::SetUInt64Value( uint16 index, const uint64 &value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -858,7 +856,7 @@ void Object::SetFloatValue( uint16 index, float value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -884,7 +882,7 @@ void Object::SetByteValue( uint16 index, uint8 offset, uint8 value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -910,7 +908,7 @@ void Object::SetUInt16Value( uint16 index, uint8 offset, uint16 value ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -979,7 +977,7 @@ void Object::SetFlag( uint16 index, uint32 newFlag ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -1000,7 +998,7 @@ void Object::RemoveFlag( uint16 index, uint32 oldFlag ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -1025,7 +1023,7 @@ void Object::SetByteFlag( uint16 index, uint8 offset, uint8 newFlag ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -1050,7 +1048,7 @@ void Object::RemoveByteFlag( uint16 index, uint8 offset, uint8 oldFlag ) { if(!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + AddToClientUpdateList(); m_objectUpdated = true; } } @@ -1871,6 +1869,16 @@ void WorldObject::UpdateObjectVisibility() GetMap()->UpdateObjectVisibility(this, cell, p); } +void WorldObject::AddToClientUpdateList() +{ + GetMap()->AddUpdateObject(this); +} + +void WorldObject::RemoveFromClientUpdateList() +{ + GetMap()->RemoveUpdateObject(this); +} + struct WorldObjectChangeAccumulator { UpdateDataMapType &i_updateDatas; diff --git a/src/game/Object.h b/src/game/Object.h index 20b543eab..d515af136 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -124,7 +124,7 @@ class MANGOS_DLL_SPEC Object m_inWorld = true; // synchronize values mirror with values array (changes will send in updatecreate opcode any way - ClearUpdateMask(true); + ClearUpdateMask(false); // false - we can't have update dat in update queue before adding to world } virtual void RemoveFromWorld() { @@ -148,6 +148,8 @@ class MANGOS_DLL_SPEC Object virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const; void SendCreateUpdateToPlayer(Player* player); + virtual void AddToClientUpdateList() =0; + virtual void RemoveFromClientUpdateList() =0; virtual void BuildUpdateData(UpdateDataMapType& update_players) =0; void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const; void BuildOutOfRangeUpdateBlock( UpdateData *data ) const; @@ -308,6 +310,7 @@ class MANGOS_DLL_SPEC Object virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const; virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const; + void BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 ) const; void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const; void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players); @@ -494,6 +497,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object //this function should be removed in nearest time... Map const* GetBaseMap() const; + void AddToClientUpdateList(); + void RemoveFromClientUpdateList(); void BuildUpdateData(UpdateDataMapType &); Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime); diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index dc377cd12..7cc289104 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -331,31 +331,6 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia) return bones; } -void -ObjectAccessor::Update(uint32 diff) -{ - UpdateDataMapType update_players; - { - Guard guard(i_updateGuard); - while(!i_objects.empty()) - { - Object* obj = *i_objects.begin(); - i_objects.erase(i_objects.begin()); - if (!obj) - continue; - obj->BuildUpdateData(update_players); - } - } - - WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 - for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) - { - iter->second.BuildPacket(&packet); - iter->first->GetSession()->SendPacket(&packet); - packet.clear(); // clean the string - } -} - /// Define the static member of HashMapHolder template UNORDERED_MAP< uint64, T* > HashMapHolder::m_objectMap; diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index 5778732c7..c562f5e74 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -152,27 +152,10 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton::Remove(pl); - - Guard guard(i_updateGuard); - i_objects.erase((Object *)pl); } void SaveAllPlayers(); - void AddUpdateObject(Object *obj) - { - Guard guard(i_updateGuard); - i_objects.insert(obj); - } - - void RemoveUpdateObject(Object *obj) - { - Guard guard(i_updateGuard); - i_objects.erase( obj ); - } - - void Update(uint32 diff); - Corpse* GetCorpseForPlayerGUID(uint64 guid); void RemoveCorpse(Corpse *corpse); void AddCorpse(Corpse* corpse); @@ -206,9 +189,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton Guard; - std::set i_objects; LockType i_playerGuard; - LockType i_updateGuard; LockType i_corpseGuard; }; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d993e1e04..74aa52fe4 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8677" + #define REVISION_NR "8678" #endif // __REVISION_NR_H__