2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef MANGOS_OBJECTACCESSOR_H
20 #define MANGOS_OBJECTACCESSOR_H
22 #include "Platform/Define.h"
23 #include "Policies/Singleton.h"
24 #include <ace/Thread_Mutex.h>
25 #include "Utilities/UnorderedMap.h"
26 #include "Policies/ThreadingModel.h"
28 #include "ByteBuffer.h"
29 #include "UpdateData.h"
31 #include "GridDefines.h"
51 typedef UNORDERED_MAP
< uint64
, T
* > MapType
;
52 typedef ACE_Thread_Mutex LockType
;
53 typedef MaNGOS::GeneralLock
<LockType
> Guard
;
55 static void Insert(T
* o
) { m_objectMap
[o
->GetGUID()] = o
; }
57 static void Remove(T
* o
)
60 m_objectMap
.erase(o
->GetGUID());
63 static T
* Find(uint64 guid
)
65 typename
MapType::iterator itr
= m_objectMap
.find(guid
);
66 return (itr
!= m_objectMap
.end()) ? itr
->second
: NULL
;
69 static MapType
& GetContainer() { return m_objectMap
; }
71 static LockType
* GetLock() { return &i_lock
; }
74 //Non instanceable only static
77 static LockType i_lock
;
78 static MapType m_objectMap
;
81 class MANGOS_DLL_DECL ObjectAccessor
: public MaNGOS::Singleton
<ObjectAccessor
, MaNGOS::ClassLevelLockable
<ObjectAccessor
, ACE_Thread_Mutex
> >
84 friend class MaNGOS::OperatorNew
<ObjectAccessor
>;
87 ObjectAccessor(const ObjectAccessor
&);
88 ObjectAccessor
& operator=(const ObjectAccessor
&);
91 typedef UNORDERED_MAP
<uint64
, Corpse
* > Player2CorpsesMapType
;
92 typedef UNORDERED_MAP
<Player
*, UpdateData
>::value_type UpdateDataValueType
;
94 template<class T
> static T
* GetObjectInWorld(uint64 guid
, T
* /*fake*/)
96 return HashMapHolder
<T
>::Find(guid
);
99 static Unit
* GetObjectInWorld(uint64 guid
, Unit
* /*fake*/)
104 if (IS_PLAYER_GUID(guid
))
105 return (Unit
*)HashMapHolder
<Player
>::Find(guid
);
107 if (Unit
* u
= (Unit
*)HashMapHolder
<Pet
>::Find(guid
))
110 return (Unit
*)HashMapHolder
<Creature
>::Find(guid
);
113 template<class T
> static T
* GetObjectInWorld(uint32 mapid
, float x
, float y
, uint64 guid
, T
* /*fake*/)
115 T
* obj
= HashMapHolder
<T
>::Find(guid
);
116 if(!obj
|| obj
->GetMapId() != mapid
) return NULL
;
118 CellPair p
= MaNGOS::ComputeCellPair(x
,y
);
119 if(p
.x_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
|| p
.y_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
)
121 sLog
.outError("ObjectAccessor::GetObjectInWorld: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x
, y
, p
.x_coord
, p
.y_coord
);
125 CellPair q
= MaNGOS::ComputeCellPair(obj
->GetPositionX(),obj
->GetPositionY());
126 if(q
.x_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
|| q
.y_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
)
128 sLog
.outError("ObjectAccessor::GetObjecInWorld: object (GUID: %u TypeId: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj
->GetGUIDLow(), obj
->GetTypeId(), obj
->GetPositionX(), obj
->GetPositionY(), q
.x_coord
, q
.y_coord
);
132 int32 dx
= int32(p
.x_coord
) - int32(q
.x_coord
);
133 int32 dy
= int32(p
.y_coord
) - int32(q
.y_coord
);
135 if (dx
> -2 && dx
< 2 && dy
> -2 && dy
< 2) return obj
;
139 static Object
* GetObjectByTypeMask(WorldObject
const &, uint64
, uint32 typemask
);
140 static Creature
* GetCreatureOrPetOrVehicle(WorldObject
const &, uint64
);
141 static Unit
* GetUnit(WorldObject
const &, uint64
);
142 static Pet
* GetPet(Unit
const &, uint64 guid
) { return GetPet(guid
); }
143 static Player
* GetPlayer(Unit
const &, uint64 guid
) { return FindPlayer(guid
); }
144 static Corpse
* GetCorpse(WorldObject
const &u
, uint64 guid
);
145 static Pet
* GetPet(uint64 guid
);
146 static Vehicle
* GetVehicle(uint64 guid
);
147 static Player
* FindPlayer(uint64
);
149 Player
* FindPlayerByName(const char *name
) ;
151 HashMapHolder
<Player
>::MapType
& GetPlayers()
153 return HashMapHolder
<Player
>::GetContainer();
156 template<class T
> void AddObject(T
*object
)
158 HashMapHolder
<T
>::Insert(object
);
161 template<class T
> void RemoveObject(T
*object
)
163 HashMapHolder
<T
>::Remove(object
);
166 void RemoveObject(Player
*pl
)
168 HashMapHolder
<Player
>::Remove(pl
);
170 Guard
guard(i_updateGuard
);
171 i_objects
.erase((Object
*)pl
);
174 void SaveAllPlayers();
176 void AddUpdateObject(Object
*obj
)
178 Guard
guard(i_updateGuard
);
179 i_objects
.insert(obj
);
182 void RemoveUpdateObject(Object
*obj
)
184 Guard
guard(i_updateGuard
);
185 i_objects
.erase( obj
);
188 void Update(uint32 diff
);
189 void UpdatePlayers(uint32 diff
);
191 Corpse
* GetCorpseForPlayerGUID(uint64 guid
);
192 void RemoveCorpse(Corpse
*corpse
);
193 void AddCorpse(Corpse
* corpse
);
194 void AddCorpsesToGrid(GridPair
const& gridpair
,GridType
& grid
,Map
* map
);
195 Corpse
* ConvertCorpseForPlayer(uint64 player_guid
, bool insignia
= false);
197 static void UpdateObject(Object
* obj
, Player
* exceptPlayer
);
198 static void _buildUpdateObject(Object
* obj
, UpdateDataMapType
&);
200 static void UpdateObjectVisibility(WorldObject
* obj
);
201 static void UpdateVisibilityForPlayer(Player
* player
);
203 struct WorldObjectChangeAccumulator
205 UpdateDataMapType
&i_updateDatas
;
206 WorldObject
&i_object
;
207 WorldObjectChangeAccumulator(WorldObject
&obj
, UpdateDataMapType
&d
) : i_updateDatas(d
), i_object(obj
) {}
208 void Visit(PlayerMapType
&);
209 template<class SKIP
> void Visit(GridRefManager
<SKIP
> &) {}
212 friend struct WorldObjectChangeAccumulator
;
213 Player2CorpsesMapType i_player2corpse
;
215 typedef ACE_Thread_Mutex LockType
;
216 typedef MaNGOS::GeneralLock
<LockType
> Guard
;
218 static void _buildChangeObjectForPlayer(WorldObject
*, UpdateDataMapType
&);
219 static void _buildPacket(Player
*, Object
*, UpdateDataMapType
&);
220 std::set
<Object
*> i_objects
;
221 LockType i_playerGuard
;
222 LockType i_updateGuard
;
223 LockType i_corpseGuard
;