Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
VMapManager2.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include <iostream>
7#include <iomanip>
8#include <mutex>
9#include <string>
10#include <sstream>
11#include "VMapManager2.h"
12#include "MapTree.h"
13#include "ModelInstance.h"
14#include "WorldModel.h"
15#include <G3D/Vector3.h>
16#include "DisableMgr.h"
17#include "DBCStores.h"
18#include "Log.h"
19#include "VMapDefinitions.h"
20
21using G3D::Vector3;
22
23namespace VMAP
24{
28
30 {
31 for (InstanceTreeMap::iterator i = iInstanceMapTrees.begin(); i != iInstanceMapTrees.end(); ++i)
32 {
33 delete i->second;
34 }
35 for (ModelFileMap::iterator i = iLoadedModelFiles.begin(); i != iLoadedModelFiles.end(); ++i)
36 {
37 delete i->second.getModel();
38 }
39 }
40
41 Vector3 VMapManager2::convertPositionToInternalRep(float x, float y, float z) const
42 {
43 Vector3 pos;
44 const float mid = 0.5f * 64.0f * 533.33333333f;
45 pos.x = mid - x;
46 pos.y = mid - y;
47 pos.z = z;
48
49 return pos;
50 }
51
52 // move to MapTree too?
53 std::string VMapManager2::getMapFileName(unsigned int mapId)
54 {
55 std::stringstream fname;
56 fname.width(4);
57 fname << std::setfill('0') << mapId << std::string(MAP_FILENAME_EXTENSION2);
58
59 return fname.str();
60 }
61
62 int VMapManager2::loadMap(const char* basePath, unsigned int mapId, int x, int y)
63 {
64 int result = VMAP_LOAD_RESULT_IGNORED;
66 {
67 if (_loadMap(mapId, basePath, x, y))
68 result = VMAP_LOAD_RESULT_OK;
69 else
71 }
72
73 return result;
74 }
75
76 // load one tile (internal use only)
77 bool VMapManager2::_loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY)
78 {
79 InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
80 if (instanceTree == iInstanceMapTrees.end())
81 {
82 std::string mapFileName = getMapFileName(mapId);
83 StaticMapTree* newTree = new StaticMapTree(mapId, basePath);
84 if (!newTree->InitMap(mapFileName, this))
85 {
86 delete newTree;
87 return false;
88 }
89 instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, newTree)).first;
90 }
91
92 return instanceTree->second->LoadMapTile(tileX, tileY, this);
93 }
94
95 void VMapManager2::unloadMap(unsigned int mapId)
96 {
97 InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
98 if (instanceTree != iInstanceMapTrees.end())
99 {
100 instanceTree->second->UnloadMap(this);
101 if (instanceTree->second->numLoadedTiles() == 0)
102 {
103 delete instanceTree->second;
104 iInstanceMapTrees.erase(mapId);
105 }
106 }
107 }
108
109 void VMapManager2::unloadMap(unsigned int mapId, int x, int y)
110 {
111 InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
112 if (instanceTree != iInstanceMapTrees.end())
113 {
114 instanceTree->second->UnloadMapTile(x, y, this);
115 if (instanceTree->second->numLoadedTiles() == 0)
116 {
117 delete instanceTree->second;
118 iInstanceMapTrees.erase(mapId);
119 }
120 }
121 }
122
123 bool VMapManager2::isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2)
124 {
126 return true;
127
128 InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
129 if (instanceTree != iInstanceMapTrees.end())
130 {
131 Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
132 Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
133 if (pos1 != pos2)
134 {
135 return instanceTree->second->isInLineOfSight(pos1, pos2);
136 }
137 }
138
139 return true;
140 }
141
146 bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist)
147 {
149 {
150 InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
151 if (instanceTree != iInstanceMapTrees.end())
152 {
153 Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
154 Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
155 Vector3 resultPos;
156 bool result = instanceTree->second->getObjectHitPos(pos1, pos2, resultPos, modifyDist);
157 resultPos = convertPositionToInternalRep(resultPos.x, resultPos.y, resultPos.z);
158 rx = resultPos.x;
159 ry = resultPos.y;
160 rz = resultPos.z;
161 return result;
162 }
163 }
164
165 rx = x2;
166 ry = y2;
167 rz = z2;
168
169 return false;
170 }
171
175
176 float VMapManager2::getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist)
177 {
179 {
180 InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
181 if (instanceTree != iInstanceMapTrees.end())
182 {
183 Vector3 pos = convertPositionToInternalRep(x, y, z);
184 float height = instanceTree->second->getHeight(pos, maxSearchDist);
185 if (!(height < G3D::inf()))
186 return height = VMAP_INVALID_HEIGHT_VALUE; // No height
187
188 return height;
189 }
190 }
191
193 }
194
195 bool VMapManager2::getAreaInfo(unsigned int mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
196 {
198 {
199 InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId);
200 if (instanceTree != iInstanceMapTrees.end())
201 {
202 Vector3 pos = convertPositionToInternalRep(x, y, z);
203 bool result = instanceTree->second->getAreaInfo(pos, flags, adtId, rootId, groupId);
204 // z is not touched by convertPositionToInternalRep(), so just copy
205 z = pos.z;
206 return result;
207 }
208 }
209
210 return false;
211 }
212
213 bool VMapManager2::GetLiquidLevel(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const
214 {
216 {
217 InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId);
218 if (instanceTree != iInstanceMapTrees.end())
219 {
220 LocationInfo info;
221 Vector3 pos = convertPositionToInternalRep(x, y, z);
222 if (instanceTree->second->GetLocationInfo(pos, info))
223 {
224 floor = info.ground_Z;
225 ASSERT(floor < std::numeric_limits<float>::max());
226 type = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc
227 if (reqLiquidType && !(GetLiquidFlags(type) & reqLiquidType))
228 return false;
229 if (info.hitInstance->GetLiquidLevel(pos, info, level))
230 return true;
231 }
232 }
233 }
234
235 return false;
236 }
237
238 WorldModel* VMapManager2::acquireModelInstance(const std::string& basepath, const std::string& filename)
239 {
241 std::lock_guard<std::mutex> guard(LoadedModelFilesLock);
242
243 ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
244 if (model == iLoadedModelFiles.end())
245 {
246 WorldModel* worldmodel = new WorldModel();
247 if (!worldmodel->readFile(basepath + filename + ".vmo"))
248 {
249 VMAP_ERROR_LOG("misc", "VMapManager2: could not load '%s%s.vmo'", basepath.c_str(), filename.c_str());
250 delete worldmodel;
251 return NULL;
252 }
253 VMAP_DEBUG_LOG("maps", "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str());
254 model = iLoadedModelFiles.insert(std::pair<std::string, ManagedModel>(filename, ManagedModel())).first;
255 model->second.setModel(worldmodel);
256 }
257 model->second.incRefCount();
258 return model->second.getModel();
259 }
260
261 void VMapManager2::releaseModelInstance(const std::string &filename)
262 {
264 std::lock_guard<std::mutex> guard(LoadedModelFilesLock);
265
266 ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
267 if (model == iLoadedModelFiles.end())
268 {
269 VMAP_ERROR_LOG("misc", "VMapManager2: trying to unload non-loaded file '%s'", filename.c_str());
270 return;
271 }
272 if (model->second.decRefCount() == 0)
273 {
274 VMAP_DEBUG_LOG("maps", "VMapManager2: unloading file '%s'", filename.c_str());
275 delete model->second.getModel();
276 iLoadedModelFiles.erase(model);
277 }
278 }
279
280 bool VMapManager2::existsMap(const char* basePath, unsigned int mapId, int x, int y)
281 {
282 return StaticMapTree::CanLoadMap(std::string(basePath), mapId, x, y);
283 }
284
285} // namespace VMAP
uint32 GetLiquidFlags(uint32 liquidType)
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
@ VMAP_DISABLE_AREAFLAG
Definition DisableMgr.h:41
@ VMAP_DISABLE_HEIGHT
Definition DisableMgr.h:42
@ VMAP_DISABLE_LIQUIDSTATUS
Definition DisableMgr.h:44
@ VMAP_DISABLE_LOS
Definition DisableMgr.h:43
@ DISABLE_TYPE_VMAP
Definition DisableMgr.h:21
#define ASSERT
Definition Errors.h:29
#define VMAP_INVALID_HEIGHT_VALUE
#define VMAP_DEBUG_LOG(FILTER,...)
#define VMAP_ERROR_LOG(FILTER,...)
#define MAP_FILENAME_EXTENSION2
uint32 GetLiquidType() const
bool isHeightCalcEnabled() const
bool isMapLoadingEnabled() const
bool isLineOfSightCalcEnabled() const
bool GetLiquidLevel(const G3D::Vector3 &p, LocationInfo &info, float &liqHeight) const
static bool CanLoadMap(const std::string &basePath, uint32 mapID, uint32 tileX, uint32 tileY)
Definition MapTree.cpp:229
bool InitMap(const std::string &fname, VMapManager2 *vm)
Definition MapTree.cpp:266
int loadMap(const char *pBasePath, unsigned int mapId, int x, int y)
G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const
void releaseModelInstance(const std::string &filename)
std::mutex LoadedModelFilesLock
ModelFileMap iLoadedModelFiles
virtual bool existsMap(const char *basePath, unsigned int mapId, int x, int y)
bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
WorldModel * acquireModelInstance(const std::string &basepath, const std::string &filename)
void unloadMap(unsigned int mapId, int x, int y)
float getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist)
bool getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
bool isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2)
InstanceTreeMap iInstanceMapTrees
static std::string getMapFileName(unsigned int mapId)
bool _loadMap(uint32 mapId, const std::string &basePath, uint32 tileX, uint32 tileY)
bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float &level, float &floor, uint32 &type) const
bool readFile(const std::string &filename)
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
@ VMAP_LOAD_RESULT_ERROR
@ VMAP_LOAD_RESULT_OK
@ VMAP_LOAD_RESULT_IGNORED
const GroupModel * hitModel
Definition MapTree.h:23
const ModelInstance * hitInstance
Definition MapTree.h:22