root/trunk/src/game/ObjectAccessor.h @ 120

Revision 120, 8.0 kB (checked in by yumileroy, 17 years ago)

[svn] * Allow WorldObjects? to keep the grid active, and prevent it from being unloaded. This can be done through calling WorldObject::setActive(bool) from the scripting library. Note that entire instances are still unloaded if no player is present on that map to save resources. This behavior can be changed if the need arises.

Original author: w12x
Date: 2008-10-27 08:41:55-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef TRINITY_OBJECTACCESSOR_H
22#define TRINITY_OBJECTACCESSOR_H
23
24#include "Platform/Define.h"
25#include "Policies/Singleton.h"
26#include "zthread/FastMutex.h"
27#include "Utilities/HashMap.h"
28#include "Policies/ThreadingModel.h"
29
30#include "ByteBuffer.h"
31#include "UpdateData.h"
32
33#include "GridDefines.h"
34#include "Object.h"
35#include "Player.h"
36
37#include <set>
38
39class Creature;
40class Corpse;
41class Unit;
42class GameObject;
43class DynamicObject;
44class WorldObject;
45class Map;
46
47template <class T>
48class HashMapHolder
49{
50    public:
51
52        typedef HM_NAMESPACE::hash_map< uint64, T* >   MapType;
53        typedef ZThread::FastMutex LockType;
54        typedef Trinity::GeneralLock<LockType > Guard;
55
56        static void Insert(T* o) { m_objectMap[o->GetGUID()] = o; }
57
58        static void Remove(T* o)
59        {
60            Guard guard(i_lock);
61            typename MapType::iterator itr = m_objectMap.find(o->GetGUID());
62            if (itr != m_objectMap.end())
63                m_objectMap.erase(itr);
64        }
65
66        static T* Find(uint64 guid)
67        {
68            typename MapType::iterator itr = m_objectMap.find(guid);
69            return (itr != m_objectMap.end()) ? itr->second : NULL;
70        }
71
72        static MapType& GetContainer() { return m_objectMap; }
73
74        static LockType* GetLock() { return &i_lock; }
75    private:
76
77        //Non instanciable only static
78        HashMapHolder() {}
79
80        static LockType i_lock;
81        static MapType  m_objectMap;
82};
83
84class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor, Trinity::ClassLevelLockable<ObjectAccessor, ZThread::FastMutex> >
85{
86
87    friend class Trinity::OperatorNew<ObjectAccessor>;
88    ObjectAccessor();
89    ~ObjectAccessor();
90    ObjectAccessor(const ObjectAccessor &);
91    ObjectAccessor& operator=(const ObjectAccessor &);
92
93    public:
94        typedef HM_NAMESPACE::hash_map<uint64, Corpse* >      Player2CorpsesMapType;
95        typedef HM_NAMESPACE::hash_map<Player*, UpdateData>::value_type UpdateDataValueType;
96
97        template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
98        {
99            return HashMapHolder<T>::Find(guid);
100        }
101
102        static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/)
103        {
104            if(!guid)
105                return NULL;
106
107            if (IS_PLAYER_GUID(guid))
108                return (Unit*)HashMapHolder<Player>::Find(guid);
109
110            if (Unit* u = (Unit*)HashMapHolder<Pet>::Find(guid))
111                return u;
112
113            return (Unit*)HashMapHolder<Creature>::Find(guid);
114        }
115
116        template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/)
117        {
118            T* obj = HashMapHolder<T>::Find(guid);
119            if(!obj || obj->GetMapId() != mapid) return NULL;
120
121            CellPair p = Trinity::ComputeCellPair(x,y);
122            if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
123            {
124                sLog.outError("ObjectAccessor::GetObjectInWorld: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x, y, p.x_coord, p.y_coord);
125                return NULL;
126            }
127
128            CellPair q = Trinity::ComputeCellPair(obj->GetPositionX(),obj->GetPositionY());
129            if(q.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || q.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
130            {
131                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                return NULL;
133            }
134
135            int32 dx = int32(p.x_coord) - int32(q.x_coord);
136            int32 dy = int32(p.y_coord) - int32(q.y_coord);
137
138            if (dx > -2 && dx < 2 && dy > -2 && dy < 2) return obj;
139            else return NULL;
140        }
141
142        static Object*   GetObjectByTypeMask(Player const &, uint64, uint32 typemask);
143        static Creature* GetNPCIfCanInteractWith(Player const &player, uint64 guid, uint32 npcflagmask);
144        static Creature* GetCreature(WorldObject const &, uint64);
145        static Creature* GetCreatureOrPet(WorldObject const &, uint64);
146        static Unit* GetUnit(WorldObject const &, uint64);
147        static Pet* GetPet(Unit const &, uint64 guid) { return GetPet(guid); }
148        static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); }
149        static GameObject* GetGameObject(WorldObject const &, uint64);
150        static DynamicObject* GetDynamicObject(Unit const &, uint64);
151        static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
152        static Pet* GetPet(uint64 guid);
153        static Player* FindPlayer(uint64);
154
155        Player* FindPlayerByName(const char *name) ;
156
157        HashMapHolder<Player>::MapType& GetPlayers()
158        {
159            return HashMapHolder<Player>::GetContainer();
160        }
161
162        template<class T> void AddObject(T *object)
163        {
164            HashMapHolder<T>::Insert(object);
165        }
166
167        template<class T> void RemoveObject(T *object)
168        {
169            HashMapHolder<T>::Remove(object);
170        }
171
172        void RemoveObject(Player *pl)
173        {
174            HashMapHolder<Player>::Remove(pl);
175
176            Guard guard(i_updateGuard);
177
178            std::set<Object *>::iterator iter2 = std::find(i_objects.begin(), i_objects.end(), (Object *)pl);
179            if( iter2 != i_objects.end() )
180                i_objects.erase(iter2);
181        }
182
183        void SaveAllPlayers();
184
185        void AddUpdateObject(Object *obj);
186        void RemoveUpdateObject(Object *obj);
187
188        void Update(uint32 diff);
189
190        Corpse* GetCorpseForPlayerGUID(uint64 guid);
191        void RemoveCorpse(Corpse *corpse);
192        void AddCorpse(Corpse* corpse);
193        void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
194        Corpse* ConvertCorpseForPlayer(uint64 player_guid);
195
196        bool ActiveObjectsNearGrid(uint32 x,uint32 y,uint32 m_id,uint32 i_id) const;
197
198        static void UpdateObject(Object* obj, Player* exceptPlayer);
199        static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
200
201        static void UpdateObjectVisibility(WorldObject* obj);
202        static void UpdateVisibilityForPlayer(Player* player);
203
204        void AddActiveObject(WorldObject*);
205        void RemoveActiveObject(WorldObject*);
206    private:
207        struct WorldObjectChangeAccumulator
208        {
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> &) {}
214        };
215
216        friend struct WorldObjectChangeAccumulator;
217        Player2CorpsesMapType   i_player2corpse;
218
219        typedef ZThread::FastMutex LockType;
220        typedef Trinity::GeneralLock<LockType > Guard;
221
222        static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &);
223        static void _buildPacket(Player *, Object *, UpdateDataMapType &);
224        void _update(void);
225        std::set<Object *> i_objects;
226        std::set<WorldObject *> i_activeobjects;
227        LockType i_playerGuard;
228        LockType i_updateGuard;
229        LockType i_corpseGuard;
230        LockType i_petGuard;
231};
232#endif
Note: See TracBrowser for help on using the browser.