Updated Copyright year to 2013
[getmangos.git] / src / game / Map.h
blob7a77e285d4cc846dbaa4173ee02e3fa743f98d26
1 /*
2 * Copyright (C) 2005-2013 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_MAP_H
20 #define MANGOS_MAP_H
22 #include "Common.h"
23 #include "Platform/Define.h"
24 #include "Policies/ThreadingModel.h"
25 #include "ace/RW_Thread_Mutex.h"
26 #include "ace/Thread_Mutex.h"
28 #include "DBCStructure.h"
29 #include "GridDefines.h"
30 #include "Cell.h"
31 #include "Object.h"
32 #include "Timer.h"
33 #include "SharedDefines.h"
34 #include "GridMap.h"
35 #include "GameSystem/GridRefManager.h"
36 #include "MapRefManager.h"
37 #include "Utilities/TypeList.h"
38 #include "ScriptMgr.h"
39 #include "CreatureLinkingMgr.h"
41 #include <bitset>
42 #include <list>
44 struct CreatureInfo;
45 class Creature;
46 class Unit;
47 class WorldPacket;
48 class InstanceData;
49 class Group;
50 class MapPersistentState;
51 class WorldPersistentState;
52 class DungeonPersistentState;
53 class BattleGroundPersistentState;
54 struct ScriptInfo;
55 class BattleGround;
56 class GridMap;
58 // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
59 #if defined( __GNUC__ )
60 #pragma pack(1)
61 #else
62 #pragma pack(push,1)
63 #endif
65 struct InstanceTemplate
67 uint32 map; // instance map
68 uint32 parent; // non-continent parent instance (for instance with entrance in another instances)
69 // or 0 (not related to continent 0 map id)
70 uint32 levelMin;
71 uint32 levelMax;
72 uint32 script_id;
75 struct WorldTemplate
77 uint32 map; // non-instance map
78 uint32 script_id;
81 enum LevelRequirementVsMode
83 LEVELREQUIREMENT_HEROIC = 70
86 #if defined( __GNUC__ )
87 #pragma pack()
88 #else
89 #pragma pack(pop)
90 #endif
92 #define MIN_UNLOAD_DELAY 1 // immediate unload
94 class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>
96 friend class MapReference;
97 friend class ObjectGridLoader;
98 friend class ObjectWorldLoader;
100 protected:
101 Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode);
103 public:
104 virtual ~Map();
106 // currently unused for normal maps
107 bool CanUnload(uint32 diff)
109 if (!m_unloadTimer) return false;
110 if (m_unloadTimer <= diff) return true;
111 m_unloadTimer -= diff;
112 return false;
115 virtual bool Add(Player*);
116 virtual void Remove(Player*, bool);
117 template<class T> void Add(T*);
118 template<class T> void Remove(T*, bool);
120 static void DeleteFromWorld(Player* player); // player object will deleted at call
122 virtual void Update(const uint32&);
124 void MessageBroadcast(Player*, WorldPacket*, bool to_self);
125 void MessageBroadcast(WorldObject*, WorldPacket*);
126 void MessageDistBroadcast(Player*, WorldPacket*, float dist, bool to_self, bool own_team_only = false);
127 void MessageDistBroadcast(WorldObject*, WorldPacket*, float dist);
129 float GetVisibilityDistance() const { return m_VisibleDistance; }
130 // function for setting up visibility distance for maps on per-type/per-Id basis
131 virtual void InitVisibilityDistance();
133 void PlayerRelocation(Player*, float x, float y, float z, float angl);
134 void CreatureRelocation(Creature* creature, float x, float y, float z, float orientation);
136 template<class T, class CONTAINER> void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER>& visitor);
138 bool IsRemovalGrid(float x, float y) const
140 GridPair p = MaNGOS::ComputeGridPair(x, y);
141 return(!getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL);
144 bool IsLoaded(float x, float y) const
146 GridPair p = MaNGOS::ComputeGridPair(x, y);
147 return loaded(p);
150 bool GetUnloadLock(const GridPair& p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); }
151 void SetUnloadLock(const GridPair& p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); }
152 void LoadGrid(const Cell& cell, bool no_unload = false);
153 bool UnloadGrid(const uint32& x, const uint32& y, bool pForce);
154 virtual void UnloadAll(bool pForce);
156 void ResetGridExpiry(NGridType& grid, float factor = 1) const
158 grid.ResetTimeTracker((time_t)((float)i_gridExpiry * factor));
161 time_t GetGridExpiry(void) const { return i_gridExpiry; }
162 uint32 GetId(void) const { return i_id; }
164 // some calls like isInWater should not use vmaps due to processor power
165 // can return INVALID_HEIGHT if under z+2 z coord not found height
167 virtual void RemoveAllObjectsInRemoveList();
169 bool CreatureRespawnRelocation(Creature* c); // used only in CreatureRelocation and ObjectGridUnloader
171 bool CheckGridIntegrity(Creature* c, bool moved) const;
173 uint32 GetInstanceId() const { return i_InstanceId; }
174 virtual bool CanEnter(Player* player);
175 const char* GetMapName() const;
177 // have meaning only for instanced map (that have set real difficulty), NOT USE its for BaseMap
178 // _currently_ spawnmode == difficulty, but this can be changes later, so use appropriate spawmmode/difficult functions
179 // for simplify later code support
180 // regular difficulty = continent/dungeon normal/first raid normal difficulty
181 uint8 GetSpawnMode() const { return (i_spawnMode); }
182 Difficulty GetDifficulty() const { return Difficulty(GetSpawnMode()); }
183 bool IsRegularDifficulty() const { return GetDifficulty() == REGULAR_DIFFICULTY; }
184 uint32 GetMaxPlayers() const; // dependent from map difficulty
185 uint32 GetMaxResetDelay() const; // dependent from map difficulty
186 MapDifficultyEntry const* GetMapDifficulty() const; // dependent from map difficulty
188 bool Instanceable() const { return i_mapEntry && i_mapEntry->Instanceable(); }
189 // NOTE: this duplicate of Instanceable(), but Instanceable() can be changed when BG also will be instanceable
190 bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); }
191 bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); }
192 bool IsNonRaidDungeon() const { return i_mapEntry && i_mapEntry->IsNonRaidDungeon(); }
193 bool IsRaidOrHeroicDungeon() const { return IsRaid() || GetDifficulty() > DUNGEON_DIFFICULTY_NORMAL; }
194 bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); }
195 bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); }
196 bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); }
198 // can't be NULL for loaded map
199 MapPersistentState* GetPersistentState() const { return m_persistentState; }
201 void AddObjectToRemoveList(WorldObject* obj);
203 void UpdateObjectVisibility(WorldObject* obj, Cell cell, CellPair cellpair);
205 void resetMarkedCells() { marked_cells.reset(); }
206 bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
207 void markCell(uint32 pCellId) { marked_cells.set(pCellId); }
209 bool HavePlayers() const { return !m_mapRefManager.isEmpty(); }
210 uint32 GetPlayersCountExceptGMs() const;
211 bool ActiveObjectsNearGrid(uint32 x, uint32 y) const;
213 void SendToPlayers(WorldPacket const* data) const;
215 typedef MapRefManager PlayerList;
216 PlayerList const& GetPlayers() const { return m_mapRefManager; }
218 // per-map script storage
219 bool ScriptsStart(ScriptMapMapName const& scripts, uint32 id, Object* source, Object* target);
220 void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
222 // must called with AddToWorld
223 void AddToActive(WorldObject* obj);
224 // must called with RemoveFromWorld
225 void RemoveFromActive(WorldObject* obj);
227 Player* GetPlayer(ObjectGuid guid);
228 Creature* GetCreature(ObjectGuid guid);
229 Pet* GetPet(ObjectGuid guid);
230 Creature* GetAnyTypeCreature(ObjectGuid guid); // normal creature or pet or vehicle
231 GameObject* GetGameObject(ObjectGuid guid);
232 DynamicObject* GetDynamicObject(ObjectGuid guid);
233 Corpse* GetCorpse(ObjectGuid guid); // !!! find corpse can be not in world
234 Unit* GetUnit(ObjectGuid guid); // only use if sure that need objects at current map, specially for player case
235 WorldObject* GetWorldObject(ObjectGuid guid); // only use if sure that need objects at current map, specially for player case
237 typedef TypeUnorderedMapContainer<AllMapStoredObjectTypes, ObjectGuid> MapStoredObjectTypesContainer;
238 MapStoredObjectTypesContainer& GetObjectsStore() { return m_objectsStore; }
240 void AddUpdateObject(Object* obj)
242 i_objectsToClientUpdate.insert(obj);
245 void RemoveUpdateObject(Object* obj)
247 i_objectsToClientUpdate.erase(obj);
250 // DynObjects currently
251 uint32 GenerateLocalLowGuid(HighGuid guidhigh);
253 // get corresponding TerrainData object for this particular map
254 const TerrainInfo* GetTerrain() const { return m_TerrainData; }
256 void CreateInstanceData(bool load);
257 InstanceData* GetInstanceData() { return i_data; }
258 uint32 GetScriptId() const { return i_script_id; }
260 void MonsterYellToMap(ObjectGuid guid, int32 textId, uint32 language, Unit* target);
261 void MonsterYellToMap(CreatureInfo const* cinfo, int32 textId, uint32 language, Unit* target, uint32 senderLowGuid = 0);
262 void PlayDirectSoundToMap(uint32 soundId, uint32 zoneId = 0);
264 // VMap System
265 bool IsInLineOfSight(float srcX, float srcY, float srcZ, float destX, float destY, float destZ);
266 bool GetObjectHitPos(float srcX, float srcY, float srcZ, float destX, float destY, float destZ, float& resX, float& resY, float& resZ, float pModifyDist);
268 // Get Holder for Creature Linking
269 CreatureLinkingHolder* GetCreatureLinkingHolder() { return &m_creatureLinkingHolder; }
271 private:
272 void LoadMapAndVMap(int gx, int gy);
274 void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; }
276 void SendInitSelf(Player* player);
278 void SendInitTransports(Player* player);
279 void SendRemoveTransports(Player* player);
281 bool CreatureCellRelocation(Creature* creature, Cell new_cell);
283 bool loaded(const GridPair&) const;
284 void EnsureGridCreated(const GridPair&);
285 bool EnsureGridLoaded(Cell const&);
286 void EnsureGridLoadedAtEnter(Cell const&, Player* player = NULL);
288 void buildNGridLinkage(NGridType* pNGridType) { pNGridType->link(this); }
290 template<class T> void AddType(T* obj);
291 template<class T> void RemoveType(T* obj, bool);
293 NGridType* getNGrid(uint32 x, uint32 y) const
295 MANGOS_ASSERT(x < MAX_NUMBER_OF_GRIDS);
296 MANGOS_ASSERT(y < MAX_NUMBER_OF_GRIDS);
297 return i_grids[x][y];
300 bool isGridObjectDataLoaded(uint32 x, uint32 y) const { return getNGrid(x, y)->isGridObjectDataLoaded(); }
301 void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y) { getNGrid(x, y)->setGridObjectDataLoaded(pLoaded); }
303 void setNGrid(NGridType* grid, uint32 x, uint32 y);
304 void ScriptsProcess();
306 void SendObjectUpdates();
307 std::set<Object*> i_objectsToClientUpdate;
309 protected:
310 MapEntry const* i_mapEntry;
311 uint8 i_spawnMode;
312 uint32 i_id;
313 uint32 i_InstanceId;
314 uint32 m_unloadTimer;
315 float m_VisibleDistance;
316 MapPersistentState* m_persistentState;
318 MapRefManager m_mapRefManager;
319 MapRefManager::iterator m_mapRefIter;
321 typedef std::set<WorldObject*> ActiveNonPlayers;
322 ActiveNonPlayers m_activeNonPlayers;
323 ActiveNonPlayers::iterator m_activeNonPlayersIter;
324 MapStoredObjectTypesContainer m_objectsStore;
326 private:
327 time_t i_gridExpiry;
329 NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
331 // Shared geodata object with map coord info...
332 TerrainInfo* const m_TerrainData;
333 bool m_bLoadedGrids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
335 std::bitset<TOTAL_NUMBER_OF_CELLS_PER_MAP* TOTAL_NUMBER_OF_CELLS_PER_MAP> marked_cells;
337 std::set<WorldObject*> i_objectsToRemove;
339 typedef std::multimap<time_t, ScriptAction> ScriptScheduleMap;
340 ScriptScheduleMap m_scriptSchedule;
342 InstanceData* i_data;
343 uint32 i_script_id;
345 // Map local low guid counters
346 ObjectGuidGenerator<HIGHGUID_UNIT> m_CreatureGuids;
347 ObjectGuidGenerator<HIGHGUID_GAMEOBJECT> m_GameObjectGuids;
348 ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT> m_DynObjectGuids;
349 ObjectGuidGenerator<HIGHGUID_PET> m_PetGuids;
350 ObjectGuidGenerator<HIGHGUID_VEHICLE> m_VehicleGuids;
352 // Type specific code for add/remove to/from grid
353 template<class T>
354 void AddToGrid(T*, NGridType*, Cell const&);
356 template<class T>
357 void RemoveFromGrid(T*, NGridType*, Cell const&);
359 // Holder for information about linked mobs
360 CreatureLinkingHolder m_creatureLinkingHolder;
363 class MANGOS_DLL_SPEC WorldMap : public Map
365 private:
366 using Map::GetPersistentState; // hide in subclass for overwrite
367 public:
368 WorldMap(uint32 id, time_t expiry) : Map(id, expiry, 0, REGULAR_DIFFICULTY) {}
369 ~WorldMap() {}
371 // can't be NULL for loaded map
372 WorldPersistentState* GetPersistanceState() const;
375 class MANGOS_DLL_SPEC DungeonMap : public Map
377 private:
378 using Map::GetPersistentState; // hide in subclass for overwrite
379 public:
380 DungeonMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode);
381 ~DungeonMap();
382 bool Add(Player*) override;
383 void Remove(Player*, bool) override;
384 void Update(const uint32&) override;
385 bool Reset(InstanceResetMethod method);
386 void PermBindAllPlayers(Player* player);
387 void UnloadAll(bool pForce) override;
388 void SendResetWarnings(uint32 timeLeft) const;
389 void SetResetSchedule(bool on);
391 // can't be NULL for loaded map
392 DungeonPersistentState* GetPersistanceState() const;
394 virtual void InitVisibilityDistance() override;
395 private:
396 bool m_resetAfterUnload;
397 bool m_unloadWhenEmpty;
400 class MANGOS_DLL_SPEC BattleGroundMap : public Map
402 private:
403 using Map::GetPersistentState; // hide in subclass for overwrite
404 public:
405 BattleGroundMap(uint32 id, time_t, uint32 InstanceId, uint8 spawnMode);
406 ~BattleGroundMap();
408 void Update(const uint32&) override;
409 bool Add(Player*) override;
410 void Remove(Player*, bool) override;
411 bool CanEnter(Player* player) override;
412 void SetUnload();
413 void UnloadAll(bool pForce) override;
415 virtual void InitVisibilityDistance() override;
416 BattleGround* GetBG() { return m_bg; }
417 void SetBG(BattleGround* bg) { m_bg = bg; }
419 // can't be NULL for loaded map
420 BattleGroundPersistentState* GetPersistanceState() const;
422 private:
423 BattleGround* m_bg;
426 template<class T, class CONTAINER>
427 inline void
428 Map::Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER>& visitor)
430 const uint32 x = cell.GridX();
431 const uint32 y = cell.GridY();
432 const uint32 cell_x = cell.CellX();
433 const uint32 cell_y = cell.CellY();
435 if (!cell.NoCreate() || loaded(GridPair(x, y)))
437 EnsureGridLoaded(cell);
438 getNGrid(x, y)->Visit(cell_x, cell_y, visitor);
441 #endif