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 "zthread/FastMutex.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 ZThread::FastMutex 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
, ZThread::FastMutex
> >
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 "I64FMTD
" has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj
->GetGUID(), 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
* GetNPCIfCanInteractWith(Player
const &player
, uint64 guid
, uint32 npcflagmask
);
141 static Creature
* GetCreature(WorldObject
const &, uint64
);
142 static Creature
* GetCreatureOrPetOrVehicle(WorldObject
const &, uint64
);
143 static Unit
* GetUnit(WorldObject
const &, uint64
);
144 static Pet
* GetPet(Unit
const &, uint64 guid
) { return GetPet(guid
); }
145 static Player
* GetPlayer(Unit
const &, uint64 guid
) { return FindPlayer(guid
); }
146 static GameObject
* GetGameObject(WorldObject
const &, uint64
);
147 static DynamicObject
* GetDynamicObject(WorldObject
const &, uint64
);
148 static Corpse
* GetCorpse(WorldObject
const &u
, uint64 guid
);
149 static Pet
* GetPet(uint64 guid
);
150 static Vehicle
* GetVehicle(uint64 guid
);
151 static Player
* FindPlayer(uint64
);
153 Player
* FindPlayerByName(const char *name
) ;
155 HashMapHolder
<Player
>::MapType
& GetPlayers()
157 return HashMapHolder
<Player
>::GetContainer();
160 template<class T
> void AddObject(T
*object
)
162 HashMapHolder
<T
>::Insert(object
);
165 template<class T
> void RemoveObject(T
*object
)
167 HashMapHolder
<T
>::Remove(object
);
170 void RemoveObject(Player
*pl
)
172 HashMapHolder
<Player
>::Remove(pl
);
174 Guard
guard(i_updateGuard
);
175 i_objects
.erase((Object
*)pl
);
178 void SaveAllPlayers();
180 void AddUpdateObject(Object
*obj
)
182 Guard
guard(i_updateGuard
);
183 i_objects
.insert(obj
);
186 void RemoveUpdateObject(Object
*obj
)
188 Guard
guard(i_updateGuard
);
189 i_objects
.erase( obj
);
192 void Update(uint32 diff
);
193 void UpdatePlayers(uint32 diff
);
195 Corpse
* GetCorpseForPlayerGUID(uint64 guid
);
196 void RemoveCorpse(Corpse
*corpse
);
197 void AddCorpse(Corpse
* corpse
);
198 void AddCorpsesToGrid(GridPair
const& gridpair
,GridType
& grid
,Map
* map
);
199 Corpse
* ConvertCorpseForPlayer(uint64 player_guid
, bool insignia
= false);
201 static void UpdateObject(Object
* obj
, Player
* exceptPlayer
);
202 static void _buildUpdateObject(Object
* obj
, UpdateDataMapType
&);
204 static void UpdateObjectVisibility(WorldObject
* obj
);
205 static void UpdateVisibilityForPlayer(Player
* player
);
207 struct WorldObjectChangeAccumulator
209 UpdateDataMapType
&i_updateDatas
;
210 WorldObject
&i_object
;
211 WorldObjectChangeAccumulator(WorldObject
&obj
, UpdateDataMapType
&d
) : i_updateDatas(d
), i_object(obj
) {}
212 void Visit(PlayerMapType
&);
213 template<class SKIP
> void Visit(GridRefManager
<SKIP
> &) {}
216 friend struct WorldObjectChangeAccumulator
;
217 Player2CorpsesMapType i_player2corpse
;
219 typedef ZThread::FastMutex LockType
;
220 typedef MaNGOS::GeneralLock
<LockType
> Guard
;
222 static void _buildChangeObjectForPlayer(WorldObject
*, UpdateDataMapType
&);
223 static void _buildPacket(Player
*, Object
*, UpdateDataMapType
&);
224 std::set
<Object
*> i_objects
;
225 LockType i_playerGuard
;
226 LockType i_updateGuard
;
227 LockType i_corpseGuard
;