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
))
106 Unit
* u
= (Unit
*)HashMapHolder
<Player
>::Find(guid
);
107 if(!u
|| !u
->IsInWorld())
113 if (IS_PET_GUID(guid
))
114 return (Unit
*)HashMapHolder
<Pet
>::Find(guid
);
116 return (Unit
*)HashMapHolder
<Creature
>::Find(guid
);
119 template<class T
> static T
* GetObjectInWorld(uint32 mapid
, float x
, float y
, uint64 guid
, T
* /*fake*/)
121 T
* obj
= HashMapHolder
<T
>::Find(guid
);
122 if(!obj
|| obj
->GetMapId() != mapid
) return NULL
;
124 CellPair p
= MaNGOS::ComputeCellPair(x
,y
);
125 if(p
.x_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
|| p
.y_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
)
127 sLog
.outError("ObjectAccessor::GetObjectInWorld: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x
, y
, p
.x_coord
, p
.y_coord
);
131 CellPair q
= MaNGOS::ComputeCellPair(obj
->GetPositionX(),obj
->GetPositionY());
132 if(q
.x_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
|| q
.y_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
)
134 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
);
138 int32 dx
= int32(p
.x_coord
) - int32(q
.x_coord
);
139 int32 dy
= int32(p
.y_coord
) - int32(q
.y_coord
);
141 if (dx
> -2 && dx
< 2 && dy
> -2 && dy
< 2) return obj
;
145 static Object
* GetObjectByTypeMask(WorldObject
const &, uint64
, uint32 typemask
);
146 static Creature
* GetCreatureOrPetOrVehicle(WorldObject
const &, uint64
);
147 static Unit
* GetUnit(WorldObject
const &, uint64
);
148 static Pet
* GetPet(Unit
const &, uint64 guid
) { return GetPet(guid
); }
149 static Player
* GetPlayer(Unit
const &, uint64 guid
) { return FindPlayer(guid
); }
150 static Corpse
* GetCorpse(WorldObject
const &u
, uint64 guid
);
151 static Pet
* GetPet(uint64 guid
);
152 static Vehicle
* GetVehicle(uint64 guid
);
153 static Player
* FindPlayer(uint64
);
155 Player
* FindPlayerByName(const char *name
) ;
157 HashMapHolder
<Player
>::MapType
& GetPlayers()
159 return HashMapHolder
<Player
>::GetContainer();
162 template<class T
> void AddObject(T
*object
)
164 HashMapHolder
<T
>::Insert(object
);
167 template<class T
> void RemoveObject(T
*object
)
169 HashMapHolder
<T
>::Remove(object
);
172 void RemoveObject(Player
*pl
)
174 HashMapHolder
<Player
>::Remove(pl
);
176 Guard
guard(i_updateGuard
);
177 i_objects
.erase((Object
*)pl
);
180 void SaveAllPlayers();
182 void AddUpdateObject(Object
*obj
)
184 Guard
guard(i_updateGuard
);
185 i_objects
.insert(obj
);
188 void RemoveUpdateObject(Object
*obj
)
190 Guard
guard(i_updateGuard
);
191 i_objects
.erase( obj
);
194 void Update(uint32 diff
);
196 Corpse
* GetCorpseForPlayerGUID(uint64 guid
);
197 void RemoveCorpse(Corpse
*corpse
);
198 void AddCorpse(Corpse
* corpse
);
199 void AddCorpsesToGrid(GridPair
const& gridpair
,GridType
& grid
,Map
* map
);
200 Corpse
* ConvertCorpseForPlayer(uint64 player_guid
, bool insignia
= false);
202 static void UpdateObject(Object
* obj
, Player
* exceptPlayer
);
203 static void _buildUpdateObject(Object
* obj
, UpdateDataMapType
&);
205 static void UpdateObjectVisibility(WorldObject
* obj
);
206 static void UpdateVisibilityForPlayer(Player
* player
);
208 struct WorldObjectChangeAccumulator
210 UpdateDataMapType
&i_updateDatas
;
211 WorldObject
&i_object
;
212 WorldObjectChangeAccumulator(WorldObject
&obj
, UpdateDataMapType
&d
) : i_updateDatas(d
), i_object(obj
) {}
213 void Visit(PlayerMapType
&);
214 template<class SKIP
> void Visit(GridRefManager
<SKIP
> &) {}
217 friend struct WorldObjectChangeAccumulator
;
218 Player2CorpsesMapType i_player2corpse
;
220 typedef ACE_Thread_Mutex LockType
;
221 typedef MaNGOS::GeneralLock
<LockType
> Guard
;
223 static void _buildChangeObjectForPlayer(WorldObject
*, UpdateDataMapType
&);
224 static void _buildPacket(Player
*, Object
*, UpdateDataMapType
&);
225 std::set
<Object
*> i_objects
;
226 LockType i_playerGuard
;
227 LockType i_updateGuard
;
228 LockType i_corpseGuard
;