2 * Copyright (C) 2005-2008 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"
50 typedef UNORDERED_MAP
< uint64
, T
* > MapType
;
51 typedef ZThread::FastMutex LockType
;
52 typedef MaNGOS::GeneralLock
<LockType
> Guard
;
54 static void Insert(T
* o
) { m_objectMap
[o
->GetGUID()] = o
; }
56 static void Remove(T
* o
)
59 typename
MapType::iterator itr
= m_objectMap
.find(o
->GetGUID());
60 if (itr
!= m_objectMap
.end())
61 m_objectMap
.erase(itr
);
64 static T
* Find(uint64 guid
)
66 typename
MapType::iterator itr
= m_objectMap
.find(guid
);
67 return (itr
!= m_objectMap
.end()) ? itr
->second
: NULL
;
70 static MapType
& GetContainer() { return m_objectMap
; }
72 static LockType
* GetLock() { return &i_lock
; }
75 //Non instanceable only static
78 static LockType i_lock
;
79 static MapType m_objectMap
;
82 class MANGOS_DLL_DECL ObjectAccessor
: public MaNGOS::Singleton
<ObjectAccessor
, MaNGOS::ClassLevelLockable
<ObjectAccessor
, ZThread::FastMutex
> >
85 friend class MaNGOS::OperatorNew
<ObjectAccessor
>;
88 ObjectAccessor(const ObjectAccessor
&);
89 ObjectAccessor
& operator=(const ObjectAccessor
&);
92 typedef UNORDERED_MAP
<uint64
, Corpse
* > Player2CorpsesMapType
;
93 typedef UNORDERED_MAP
<Player
*, UpdateData
>::value_type UpdateDataValueType
;
95 template<class T
> static T
* GetObjectInWorld(uint64 guid
, T
* /*fake*/)
97 return HashMapHolder
<T
>::Find(guid
);
100 static Unit
* GetObjectInWorld(uint64 guid
, Unit
* /*fake*/)
105 if (IS_PLAYER_GUID(guid
))
106 return (Unit
*)HashMapHolder
<Player
>::Find(guid
);
108 if (Unit
* u
= (Unit
*)HashMapHolder
<Pet
>::Find(guid
))
111 return (Unit
*)HashMapHolder
<Creature
>::Find(guid
);
114 template<class T
> static T
* GetObjectInWorld(uint32 mapid
, float x
, float y
, uint64 guid
, T
* /*fake*/)
116 T
* obj
= HashMapHolder
<T
>::Find(guid
);
117 if(!obj
|| obj
->GetMapId() != mapid
) return NULL
;
119 CellPair p
= MaNGOS::ComputeCellPair(x
,y
);
120 if(p
.x_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
|| p
.y_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
)
122 sLog
.outError("ObjectAccessor::GetObjectInWorld: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x
, y
, p
.x_coord
, p
.y_coord
);
126 CellPair q
= MaNGOS::ComputeCellPair(obj
->GetPositionX(),obj
->GetPositionY());
127 if(q
.x_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
|| q
.y_coord
>= TOTAL_NUMBER_OF_CELLS_PER_MAP
)
129 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
);
133 int32 dx
= int32(p
.x_coord
) - int32(q
.x_coord
);
134 int32 dy
= int32(p
.y_coord
) - int32(q
.y_coord
);
136 if (dx
> -2 && dx
< 2 && dy
> -2 && dy
< 2) return obj
;
140 static Object
* GetObjectByTypeMask(Player
const &, uint64
, uint32 typemask
);
141 static Creature
* GetNPCIfCanInteractWith(Player
const &player
, uint64 guid
, uint32 npcflagmask
);
142 static Creature
* GetCreature(WorldObject
const &, uint64
);
143 static Creature
* GetCreatureOrPet(WorldObject
const &, uint64
);
144 static Unit
* GetUnit(WorldObject
const &, uint64
);
145 static Pet
* GetPet(Unit
const &, uint64 guid
) { return GetPet(guid
); }
146 static Player
* GetPlayer(Unit
const &, uint64 guid
) { return FindPlayer(guid
); }
147 static GameObject
* GetGameObject(WorldObject
const &, uint64
);
148 static DynamicObject
* GetDynamicObject(Unit
const &, uint64
);
149 static Corpse
* GetCorpse(WorldObject
const &u
, uint64 guid
);
150 static Pet
* GetPet(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
);
176 std::set
<Object
*>::iterator iter2
= std::find(i_objects
.begin(), i_objects
.end(), (Object
*)pl
);
177 if( iter2
!= i_objects
.end() )
178 i_objects
.erase(iter2
);
181 void SaveAllPlayers();
183 void AddUpdateObject(Object
*obj
);
184 void RemoveUpdateObject(Object
*obj
);
186 void Update(uint32 diff
);
187 void UpdatePlayers(uint32 diff
);
189 Corpse
* GetCorpseForPlayerGUID(uint64 guid
);
190 void RemoveCorpse(Corpse
*corpse
);
191 void AddCorpse(Corpse
* corpse
);
192 void AddCorpsesToGrid(GridPair
const& gridpair
,GridType
& grid
,Map
* map
);
193 Corpse
* ConvertCorpseForPlayer(uint64 player_guid
);
195 static void UpdateObject(Object
* obj
, Player
* exceptPlayer
);
196 static void _buildUpdateObject(Object
* obj
, UpdateDataMapType
&);
198 static void UpdateObjectVisibility(WorldObject
* obj
);
199 static void UpdateVisibilityForPlayer(Player
* player
);
201 struct WorldObjectChangeAccumulator
203 UpdateDataMapType
&i_updateDatas
;
204 WorldObject
&i_object
;
205 WorldObjectChangeAccumulator(WorldObject
&obj
, UpdateDataMapType
&d
) : i_updateDatas(d
), i_object(obj
) {}
206 void Visit(PlayerMapType
&);
207 template<class SKIP
> void Visit(GridRefManager
<SKIP
> &) {}
210 friend struct WorldObjectChangeAccumulator
;
211 Player2CorpsesMapType i_player2corpse
;
213 typedef ZThread::FastMutex LockType
;
214 typedef MaNGOS::GeneralLock
<LockType
> Guard
;
216 static void _buildChangeObjectForPlayer(WorldObject
*, UpdateDataMapType
&);
217 static void _buildPacket(Player
*, Object
*, UpdateDataMapType
&);
218 std::set
<Object
*> i_objects
;
219 LockType i_playerGuard
;
220 LockType i_updateGuard
;
221 LockType i_corpseGuard
;