[10727] Map system re-engineered. Special thanks to Blueboy for tests.

Signed-off-by: Ambal <pogrebniak@gala.net>
This commit is contained in:
Ambal 2010-11-16 21:07:58 +02:00
parent f5e40a5fda
commit f67d89f109
43 changed files with 1254 additions and 1128 deletions

View file

@ -33,14 +33,12 @@ class GridInfo
public:
GridInfo()
: i_timer(0), i_unloadActiveLockCount(0), i_unloadExplicitLock(false),
i_unloadReferenceLock(false)
: i_timer(0), i_unloadActiveLockCount(0), i_unloadExplicitLock(false)
{
}
GridInfo(time_t expiry, bool unload = true )
: i_timer(expiry), i_unloadActiveLockCount(0), i_unloadExplicitLock(!unload),
i_unloadReferenceLock(false)
: i_timer(expiry), i_unloadActiveLockCount(0), i_unloadExplicitLock(!unload)
{
}
@ -48,11 +46,10 @@ class GridInfo
bool getUnloadLock() const
{
return i_unloadActiveLockCount || i_unloadExplicitLock || i_unloadReferenceLock;
return i_unloadActiveLockCount || i_unloadExplicitLock;
}
void setUnloadExplicitLock( bool on ) { i_unloadExplicitLock = on; }
void setUnloadReferenceLock( bool on ) { i_unloadReferenceLock = on; }
void incUnloadActiveLock() { ++i_unloadActiveLockCount; }
void decUnloadActiveLock() { if (i_unloadActiveLockCount) --i_unloadActiveLockCount; }
@ -65,7 +62,6 @@ class GridInfo
TimeTracker i_timer;
uint16 i_unloadActiveLockCount : 16; // lock from active object spawn points (prevent clone loading)
bool i_unloadExplicitLock : 1; // explicit manual lock or config setting
bool i_unloadReferenceLock : 1; // lock from instance map copy
};
typedef enum
@ -129,7 +125,6 @@ class MANGOS_DLL_DECL NGrid
const TimeTracker& getTimeTracker() const { return i_GridInfo.getTimeTracker(); }
bool getUnloadLock() const { return i_GridInfo.getUnloadLock(); }
void setUnloadExplicitLock(bool on) { i_GridInfo.setUnloadExplicitLock(on); }
void setUnloadReferenceLock(bool on) { i_GridInfo.setUnloadReferenceLock(on); }
void incUnloadActiveLock() { i_GridInfo.incUnloadActiveLock(); }
void decUnloadActiveLock() { i_GridInfo.decUnloadActiveLock(); }
void ResetTimeTracker(time_t interval) { i_GridInfo.ResetTimeTracker(interval); }

View file

@ -121,12 +121,12 @@ namespace MaNGOS
{
public:
Lock(T& /*host*/)
Lock(const T& /*host*/)
{
ClassLevelLockable<T, MUTEX>::si_mtx.acquire();
}
Lock(ClassLevelLockable<T, MUTEX> &)
Lock(const ClassLevelLockable<T, MUTEX> &)
{
ClassLevelLockable<T, MUTEX>::si_mtx.acquire();
}

View file

@ -35,7 +35,6 @@
#include "BattleGroundRB.h"
#include "MapManager.h"
#include "Map.h"
#include "MapInstanced.h"
#include "ObjectMgr.h"
#include "ProgressBar.h"
#include "Chat.h"

View file

@ -32,7 +32,7 @@ ConfusedMovementGenerator<T>::Initialize(T &unit)
y = unit.GetPositionY();
z = unit.GetPositionZ();
Map const* map = unit.GetBaseMap();
TerrainInfo const* map = unit.GetTerrain();
i_nextMove = 1;

View file

@ -1237,7 +1237,7 @@ bool Creature::LoadFromDB(uint32 guidlow, Map *map)
m_deathState = DEAD;
if(CanFly())
{
float tz = GetMap()->GetHeight(data->posX, data->posY, data->posZ, false);
float tz = GetTerrain()->GetHeight(data->posX, data->posY, data->posZ, false);
if(data->posZ - tz > 0.1)
Relocate(data->posX, data->posY, tz);
}
@ -1427,7 +1427,7 @@ bool Creature::FallGround()
return false;
// use larger distance for vmap height search than in most other cases
float tz = GetMap()->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true, MAX_FALL_DISTANCE);
float tz = GetTerrain()->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true, MAX_FALL_DISTANCE);
if (tz < INVALID_HEIGHT)
{

View file

@ -133,9 +133,9 @@ DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff,
float x,y,z;
if (traveller.GetTraveller().hasUnitState(UNIT_STAT_TAXI_FLIGHT))
GetLocationNow(traveller.GetTraveller().GetBaseMap() ,x, y, z, true); // Should reposition Object with right Coord, so I can bypass some Grid Relocation
GetLocationNow(traveller.GetTraveller().GetMap() ,x, y, z, true); // Should reposition Object with right Coord, so I can bypass some Grid Relocation
else
GetLocationNow(traveller.GetTraveller().GetBaseMap(), x, y, z, false);
GetLocationNow(traveller.GetTraveller().GetMap(), x, y, z, false);
if (traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y || traveller.GetTraveller().GetPositionZ() != z)
{
@ -185,7 +185,7 @@ DestinationHolder<TRAVELLER>::GetLocationNow(const Map * map, float &x, float &y
else
{
//That part is good for mob Walking on the floor. But the floor is not always what we thought.
z = map->GetHeight(x,y,i_fromZ,false); // Disable cave check
z = map->GetTerrain()->GetHeight(x,y,i_fromZ,false); // Disable cave check
const float groundDist = sqrt(distanceX*distanceX + distanceY*distanceY);
const float zDist = fabs(i_fromZ - z) + 0.000001f;
const float slope = groundDist / zDist;

View file

@ -61,7 +61,7 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
z = owner.GetPositionZ();
float temp_x, temp_y, angle;
const Map * _map = owner.GetBaseMap();
const TerrainInfo * _map = owner.GetTerrain();
//primitive path-finding
for(uint8 i = 0; i < 18; ++i)
{

View file

@ -568,7 +568,10 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
sObjectMgr.AddCreatureToGrid(*itr, data);
// Spawn if necessary (loaded grids only)
Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid));
Map* map = const_cast<Map*>(sMapMgr.FindMap(data->mapid));
if(!map)
return;
// We use spawn coords to spawn
if(!map->Instanceable() && map->IsLoaded(data->posX,data->posY))
{
@ -614,7 +617,10 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
// Spawn if necessary (loaded grids only)
// this base map checked as non-instanced and then only existing
Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid));
Map* map = const_cast<Map*>(sMapMgr.FindMap(data->mapid));
if(!map)
return;
// We use current coords to unspawn, not spawn coords since creature can have changed grid
if(!map->Instanceable() && map->IsLoaded(data->posX, data->posY))
{

View file

@ -26,6 +26,8 @@
#include "GridMap.h"
#include "VMapFactory.h"
#include "World.h"
#include "Policies/SingletonImp.h"
#include "Util.h"
char const* MAP_MAGIC = "MAPS";
char const* MAP_VERSION_MAGIC = "v1.1";
@ -614,3 +616,597 @@ bool GridMap::ExistVMap(uint32 mapid,int gx,int gy)
return true;
}
//////////////////////////////////////////////////////////////////////////
TerrainInfo::TerrainInfo(uint32 mapid) : m_mapId(mapid)
{
for (int k = 0; k < MAX_NUMBER_OF_GRIDS; ++k)
{
for (int i = 0; i < MAX_NUMBER_OF_GRIDS; ++i)
{
m_GridMaps[i][k] = NULL;
m_GridRef[i][k] = 0;
}
}
//clean up GridMap objects every minute
const uint32 iCleanUpInterval = 60;
//schedule start randlomly
const uint32 iRandomStart = urand(20, 40);
i_timer.SetInterval(iCleanUpInterval * 1000);
i_timer.SetCurrent(iRandomStart * 1000);
}
TerrainInfo::~TerrainInfo()
{
for (int k = 0; k < MAX_NUMBER_OF_GRIDS; ++k)
for (int i = 0; i < MAX_NUMBER_OF_GRIDS; ++i)
delete m_GridMaps[i][k];
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(m_mapId);
}
GridMap * TerrainInfo::Load(const uint32 x, const uint32 y)
{
MANGOS_ASSERT(x < MAX_NUMBER_OF_GRIDS);
MANGOS_ASSERT(y < MAX_NUMBER_OF_GRIDS);
//reference grid as a first step
RefGrid(x, y);
//quick check if GridMap already loaded
GridMap * pMap = m_GridMaps[x][y];
if(!pMap)
pMap = LoadMapAndVMap(x, y);
return pMap;
}
//schedule lazy GridMap object cleanup
void TerrainInfo::Unload(const uint32 x, const uint32 y)
{
MANGOS_ASSERT(x < MAX_NUMBER_OF_GRIDS);
MANGOS_ASSERT(y < MAX_NUMBER_OF_GRIDS);
if(m_GridMaps[x][y])
{
//decrease grid reference count...
if(UnrefGrid(x, y) == 0)
{
//TODO: add your additional logic here
}
}
}
//call this method only
void TerrainInfo::CleanUpGrids(const uint32 diff)
{
i_timer.Update(diff);
if( !i_timer.Passed() )
return;
for (int y = 0; y < MAX_NUMBER_OF_GRIDS; ++y)
{
for (int x = 0; x < MAX_NUMBER_OF_GRIDS; ++x)
{
const int16& iRef = m_GridRef[x][y];
GridMap * pMap = m_GridMaps[x][y];
//delete those GridMap objects which have refcount = 0
if(pMap && iRef == 0 )
{
m_GridMaps[x][y] = NULL;
//delete grid data if reference count == 0
pMap->unloadData();
delete pMap;
//unload VMAPS...
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(m_mapId, x, y);
}
}
}
i_timer.Reset();
}
int TerrainInfo::RefGrid(const uint32& x, const uint32& y)
{
MANGOS_ASSERT(x < MAX_NUMBER_OF_GRIDS);
MANGOS_ASSERT(y < MAX_NUMBER_OF_GRIDS);
LOCK_GUARD _lock(m_refMutex);
return (m_GridRef[x][y] += 1);
}
int TerrainInfo::UnrefGrid(const uint32& x, const uint32& y)
{
MANGOS_ASSERT(x < MAX_NUMBER_OF_GRIDS);
MANGOS_ASSERT(y < MAX_NUMBER_OF_GRIDS);
int16& iRef = m_GridRef[x][y];
LOCK_GUARD _lock(m_refMutex);
if(iRef > 0)
return (iRef -= 1);
return 0;
}
float TerrainInfo::GetHeight(float x, float y, float z, bool pUseVmaps, float maxSearchDist) const
{
// find raw .map surface under Z coordinates
float mapHeight;
float z2 = z + 2.f;
if (GridMap *gmap = const_cast<TerrainInfo*>(this)->GetGrid(x, y))
{
float _mapheight = gmap->getHeight(x,y);
// look from a bit higher pos to find the floor, ignore under surface case
if (z2 > _mapheight)
mapHeight = _mapheight;
else
mapHeight = VMAP_INVALID_HEIGHT_VALUE;
}
else
mapHeight = VMAP_INVALID_HEIGHT_VALUE;
float vmapHeight;
if (pUseVmaps)
{
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
if (vmgr->isHeightCalcEnabled())
{
// if mapHeight has been found search vmap height at least until mapHeight point
// this prevent case when original Z "too high above ground and vmap height search fail"
// this will not affect most normal cases (no map in instance, or stay at ground at continent)
if (mapHeight > INVALID_HEIGHT && z2 - mapHeight > maxSearchDist)
maxSearchDist = z2 - mapHeight + 1.0f; // 1.0 make sure that we not fail for case when map height near but above for vamp height
// look from a bit higher pos to find the floor
vmapHeight = vmgr->getHeight(GetMapId(), x, y, z2, maxSearchDist);
}
else
vmapHeight = VMAP_INVALID_HEIGHT_VALUE;
}
else
vmapHeight = VMAP_INVALID_HEIGHT_VALUE;
// mapHeight set for any above raw ground Z or <= INVALID_HEIGHT
// vmapheight set for any under Z value or <= INVALID_HEIGHT
if (vmapHeight > INVALID_HEIGHT)
{
if (mapHeight > INVALID_HEIGHT)
{
// we have mapheight and vmapheight and must select more appropriate
// we are already under the surface or vmap height above map heigt
// or if the distance of the vmap height is less the land height distance
if (z < mapHeight || vmapHeight > mapHeight || fabs(mapHeight-z) > fabs(vmapHeight-z))
return vmapHeight;
else
return mapHeight; // better use .map surface height
}
else
return vmapHeight; // we have only vmapHeight (if have)
}
return mapHeight;
}
inline bool IsOutdoorWMO(uint32 mogpFlags, int32 adtId, int32 rootId, int32 groupId,
WMOAreaTableEntry const* wmoEntry, AreaTableEntry const* atEntry)
{
bool outdoor = true;
if(wmoEntry && atEntry)
{
if(atEntry->flags & AREA_FLAG_OUTSIDE)
return true;
if(atEntry->flags & AREA_FLAG_INSIDE)
return false;
}
outdoor = mogpFlags&0x8;
if(wmoEntry)
{
if(wmoEntry->Flags & 4)
return true;
if((wmoEntry->Flags & 2)!=0)
outdoor = false;
}
return outdoor;
}
bool TerrainInfo::IsOutdoors(float x, float y, float z) const
{
uint32 mogpFlags;
int32 adtId, rootId, groupId;
// no wmo found? -> outside by default
if(!GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId))
return true;
AreaTableEntry const* atEntry = 0;
WMOAreaTableEntry const* wmoEntry= GetWMOAreaTableEntryByTripple(rootId, adtId, groupId);
if(wmoEntry)
{
DEBUG_LOG("Got WMOAreaTableEntry! flag %u, areaid %u", wmoEntry->Flags, wmoEntry->areaId);
atEntry = GetAreaEntryByAreaID(wmoEntry->areaId);
}
return IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry);
}
bool TerrainInfo::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
{
float vmap_z = z;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
if (vmgr->getAreaInfo(GetMapId(), x, y, vmap_z, flags, adtId, rootId, groupId))
{
// check if there's terrain between player height and object height
if(GridMap *gmap = const_cast<TerrainInfo*>(this)->GetGrid(x, y))
{
float _mapheight = gmap->getHeight(x,y);
// z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice...
if(z + 2.0f > _mapheight && _mapheight > vmap_z)
return false;
}
return true;
}
return false;
}
uint16 TerrainInfo::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const
{
uint32 mogpFlags;
int32 adtId, rootId, groupId;
WMOAreaTableEntry const* wmoEntry = 0;
AreaTableEntry const* atEntry = 0;
bool haveAreaInfo = false;
if(GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId))
{
haveAreaInfo = true;
wmoEntry = GetWMOAreaTableEntryByTripple(rootId, adtId, groupId);
if(wmoEntry)
atEntry = GetAreaEntryByAreaID(wmoEntry->areaId);
}
uint16 areaflag;
if (atEntry)
areaflag = atEntry->exploreFlag;
else
{
if(GridMap *gmap = const_cast<TerrainInfo*>(this)->GetGrid(x, y))
areaflag = gmap->getArea(x, y);
// this used while not all *.map files generated (instances)
else
areaflag = GetAreaFlagByMapId(GetMapId());
}
if (isOutdoors)
{
if (haveAreaInfo)
*isOutdoors = IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry);
else
*isOutdoors = true;
}
return areaflag;
}
uint8 TerrainInfo::GetTerrainType(float x, float y ) const
{
if(GridMap *gmap = const_cast<TerrainInfo*>(this)->GetGrid(x, y))
return gmap->getTerrainType(x, y);
else
return 0;
}
uint32 TerrainInfo::GetAreaId(float x, float y, float z) const
{
return TerrainManager::GetAreaIdByAreaFlag(GetAreaFlag(x,y,z),m_mapId);
}
uint32 TerrainInfo::GetZoneId(float x, float y, float z) const
{
return TerrainManager::GetZoneIdByAreaFlag(GetAreaFlag(x,y,z),m_mapId);
}
void TerrainInfo::GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const
{
TerrainManager::GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(x,y,z),m_mapId);
}
GridMapLiquidStatus TerrainInfo::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData *data) const
{
GridMapLiquidStatus result = LIQUID_MAP_NO_WATER;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
float liquid_level, ground_level = INVALID_HEIGHT;
uint32 liquid_type;
if (vmgr->GetLiquidLevel(GetMapId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type))
{
DEBUG_LOG("getLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type);
// Check water level and ground level
if (liquid_level > ground_level && z > ground_level - 2)
{
// All ok in water -> store data
if (data)
{
data->type = liquid_type;
data->level = liquid_level;
data->depth_level = ground_level;
}
// For speed check as int values
int delta = int((liquid_level - z) * 10);
// Get position delta
if (delta > 20) // Under water
return LIQUID_MAP_UNDER_WATER;
if (delta > 0 ) // In water
return LIQUID_MAP_IN_WATER;
if (delta > -1) // Walk on water
return LIQUID_MAP_WATER_WALK;
result = LIQUID_MAP_ABOVE_WATER;
}
}
if(GridMap* gmap = const_cast<TerrainInfo*>(this)->GetGrid(x, y))
{
GridMapLiquidData map_data;
GridMapLiquidStatus map_result = gmap->getLiquidStatus(x, y, z, ReqLiquidType, &map_data);
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level))
{
if (data)
*data = map_data;
return map_result;
}
}
return result;
}
bool TerrainInfo::IsInWater(float x, float y, float pZ, GridMapLiquidData *data) const
{
// Check surface in x, y point for liquid
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
{
GridMapLiquidData liquid_status;
GridMapLiquidData *liquid_ptr = data ? data : &liquid_status;
if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr))
{
//if (liquid_prt->level - liquid_prt->depth_level > 2) //???
return true;
}
}
return false;
}
bool TerrainInfo::IsUnderWater(float x, float y, float z) const
{
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
{
if (getLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER|MAP_LIQUID_TYPE_OCEAN)&LIQUID_MAP_UNDER_WATER)
return true;
}
return false;
}
/**
* Function find higher form water or ground height for current floor
*
* @param x, y, z Coordinates original point at floor level
*
* @param pGround optional arg for retrun calculated by function work ground height, it let avoid in caller code recalculate height for point if it need
*
* @param swim z coordinate can be calculated for select above/at or under z coordinate (for fly or swim/walking by bottom)
* in last cases for in water returned under water height for avoid client set swimming unit as saty at water.
*
* @return calculated z coordinate
*/
float TerrainInfo::GetWaterOrGroundLevel(float x, float y, float z, float* pGround /*= NULL*/, bool swim /*= false*/) const
{
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
{
// we need ground level (including grid height version) for proper return water level in point
float ground_z = GetHeight(x, y, z, true, DEFAULT_WATER_SEARCH);
if (pGround)
*pGround = ground_z;
GridMapLiquidData liquid_status;
GridMapLiquidStatus res = getLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status);
return res ? ( swim ? liquid_status.level - 2.0f : liquid_status.level) : ground_z;
}
return VMAP_INVALID_HEIGHT_VALUE;
}
GridMap * TerrainInfo::GetGrid( const float x, const float y )
{
// half opt method
int gx=(int)(32-x/SIZE_OF_GRIDS); //grid x
int gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
//quick check if GridMap already loaded
GridMap * pMap = m_GridMaps[gx][gy];
if(!pMap)
pMap = LoadMapAndVMap(gx, gy);
return pMap;
}
GridMap * TerrainInfo::LoadMapAndVMap( const uint32 x, const uint32 y )
{
//double checked lock pattern
if(!m_GridMaps[x][y])
{
LOCK_GUARD lock(m_mutex);
if(!m_GridMaps[x][y])
{
GridMap * map = new GridMap();
// map file name
char *tmp=NULL;
int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1;
tmp = new char[len];
snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),m_mapId, x, y);
sLog.outDetail("Loading map %s",tmp);
if(!map->loadData(tmp))
{
sLog.outError("Error load map file: \n %s\n", tmp);
//ASSERT(false);
}
delete [] tmp;
m_GridMaps[x][y] = map;
//load VMAPs for current map/grid...
const MapEntry * i_mapEntry = sMapStore.LookupEntry(m_mapId);
const char* mapName = i_mapEntry ? i_mapEntry->name[sWorld.GetDefaultDbcLocale()] : "UNNAMEDMAP\x0";
int vmapLoadResult = VMAP::VMapFactory::createOrGetVMapManager()->loadMap((sWorld.GetDataPath()+ "vmaps").c_str(), m_mapId, x, y);
switch(vmapLoadResult)
{
case VMAP::VMAP_LOAD_RESULT_OK:
sLog.outDetail("VMAP loaded name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", mapName, m_mapId, x,y,x,y);
break;
case VMAP::VMAP_LOAD_RESULT_ERROR:
sLog.outDetail("Could not load VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", mapName, m_mapId, x,y,x,y);
break;
case VMAP::VMAP_LOAD_RESULT_IGNORED:
DEBUG_LOG("Ignored VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", mapName, m_mapId, x,y,x,y);
break;
}
}
}
return m_GridMaps[x][y];
}
float TerrainInfo::GetWaterLevel(float x, float y, float z, float* pGround /*= NULL*/) const
{
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
{
// we need ground level (including grid height version) for proper return water level in point
float ground_z = GetHeight(x, y, z, true, DEFAULT_WATER_SEARCH);
if (pGround)
*pGround = ground_z;
GridMapLiquidData liquid_status;
GridMapLiquidStatus res = getLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status);
if (!res)
return VMAP_INVALID_HEIGHT_VALUE;
return liquid_status.level;
}
return VMAP_INVALID_HEIGHT_VALUE;
}
//////////////////////////////////////////////////////////////////////////
#define CLASS_LOCK MaNGOS::ClassLevelLockable<TerrainManager, ACE_Thread_Mutex>
INSTANTIATE_SINGLETON_2(TerrainManager, CLASS_LOCK);
INSTANTIATE_CLASS_MUTEX(TerrainManager, ACE_Thread_Mutex);
TerrainManager::TerrainManager()
{
}
TerrainManager::~TerrainManager()
{
for (TerrainDataMap::iterator it = i_TerrainMap.begin(); it != i_TerrainMap.end(); ++it)
delete it->second;
}
TerrainInfo * TerrainManager::LoadTerrain(const uint32 mapId)
{
Guard _guard(*this);
TerrainInfo * ptr = NULL;
TerrainDataMap::const_iterator iter = i_TerrainMap.find(mapId);
if(iter == i_TerrainMap.end())
{
ptr = new TerrainInfo(mapId);
i_TerrainMap[mapId] = ptr;
}
else
ptr = (*iter).second;
return ptr;
}
void TerrainManager::UnloadTerrain(const uint32 mapId)
{
if(sWorld.getConfig(CONFIG_BOOL_GRID_UNLOAD) == 0)
return;
Guard _guard(*this);
TerrainDataMap::iterator iter = i_TerrainMap.find(mapId);
if(iter != i_TerrainMap.end())
{
TerrainInfo * ptr = (*iter).second;
//lets check if this object can be actually freed
if(ptr->IsReferenced() == false)
{
i_TerrainMap.erase(iter);
delete ptr;
}
}
}
void TerrainManager::Update(const uint32 diff)
{
//global garbage collection for GridMap objects and VMaps
for (TerrainDataMap::iterator iter = i_TerrainMap.begin(); iter != i_TerrainMap.end(); ++iter)
iter->second->CleanUpGrids(diff);
}
void TerrainManager::UnloadAll()
{
for (TerrainDataMap::iterator it = i_TerrainMap.begin(); it != i_TerrainMap.end(); ++it)
delete it->second;
i_TerrainMap.clear();
}
uint32 TerrainManager::GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id)
{
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
if (entry)
return entry->ID;
else
return 0;
}
uint32 TerrainManager::GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id)
{
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
if( entry )
return ( entry->zone != 0 ) ? entry->zone : entry->ID;
else
return 0;
}
void TerrainManager::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id)
{
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
areaid = entry ? entry->ID : 0;
zoneid = entry ? (( entry->zone != 0 ) ? entry->zone : entry->ID) : 0;
}

View file

@ -20,6 +20,7 @@
#define MANGOS_GRIDMAP_H
#include "Platform/Define.h"
#include "Policies/Singleton.h"
#include "DBCStructure.h"
#include "GridDefines.h"
#include "Object.h"
@ -37,6 +38,7 @@ class InstanceSave;
struct ScriptInfo;
struct ScriptAction;
class BattleGround;
class Map;
struct GridMapFileHeader
{
@ -180,4 +182,143 @@ class GridMap
GridMapLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData *data = 0);
};
template<typename Countable>
class MANGOS_DLL_SPEC Referencable
{
public:
Referencable() { m_count = 0; }
void AddRef() { ++m_count; }
bool Release() { return (--m_count < 1); }
bool IsReferenced() const { return (m_count > 0); }
private:
Referencable(const Referencable&);
Referencable& operator=(const Referencable&);
Countable m_count;
};
typedef ACE_Atomic_Op<ACE_Thread_Mutex, long> AtomicLong;
#define MAX_HEIGHT 100000.0f // can be use for find ground height at surface
#define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE
#define MAX_FALL_DISTANCE 250000.0f // "unlimited fall" to find VMap ground if it is available, just larger than MAX_HEIGHT - INVALID_HEIGHT
#define DEFAULT_HEIGHT_SEARCH 10.0f // default search distance to find height at nearby locations
#define DEFAULT_WATER_SEARCH 50.0f // default search distance to case detection water level
//class for sharing and managin GridMap objects
class MANGOS_DLL_SPEC TerrainInfo : public Referencable<AtomicLong>
{
public:
TerrainInfo(uint32 mapid);
~TerrainInfo();
uint32 GetMapId() const { return m_mapId; }
//TODO: move all terrain/vmaps data info query functions
//from 'Map' class into this class
float GetHeight(float x, float y, float z, bool pCheckVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const;
float GetWaterLevel(float x, float y, float z, float* pGround = NULL) const;
float GetWaterOrGroundLevel(float x, float y, float z, float* pGround = NULL, bool swim = false) const;
bool IsInWater(float x, float y, float z, GridMapLiquidData *data = 0) const;
bool IsUnderWater(float x, float y, float z) const;
GridMapLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData *data = 0) const;
uint16 GetAreaFlag(float x, float y, float z, bool *isOutdoors=0) const;
uint8 GetTerrainType(float x, float y ) const;
uint32 GetAreaId(float x, float y, float z) const;
uint32 GetZoneId(float x, float y, float z) const;
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const;
bool GetAreaInfo(float x, float y, float z, uint32 &mogpflags, int32 &adtId, int32 &rootId, int32 &groupId) const;
bool IsOutdoors(float x, float y, float z) const;
//this method should be used only by TerrainManager
//to cleanup unreferenced GridMap objects - they are too heavy
//to destroy them dynamically, especially on highly populated servers
//THIS METHOD IS NOT THREAD-SAFE!!!! AND IT SHOULDN'T BE THREAD-SAFE!!!!
void CleanUpGrids(const uint32 diff);
protected:
friend class Map;
//load/unload terrain data
GridMap * Load(const uint32 x, const uint32 y);
void Unload(const uint32 x, const uint32 y);
private:
TerrainInfo(const TerrainInfo&);
TerrainInfo& operator=(const TerrainInfo&);
GridMap * GetGrid( const float x, const float y );
GridMap * LoadMapAndVMap(const uint32 x, const uint32 y );
int RefGrid(const uint32& x, const uint32& y);
int UnrefGrid(const uint32& x, const uint32& y);
const uint32 m_mapId;
GridMap *m_GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
int16 m_GridRef[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
//global garbage collection timer
ShortIntervalTimer i_timer;
typedef ACE_Thread_Mutex LOCK_TYPE;
typedef ACE_Guard<LOCK_TYPE> LOCK_GUARD;
LOCK_TYPE m_mutex;
LOCK_TYPE m_refMutex;
};
//class for managing TerrainData object and all sort of geometry querying operations
class MANGOS_DLL_DECL TerrainManager : public MaNGOS::Singleton<TerrainManager, MaNGOS::ClassLevelLockable<TerrainManager, ACE_Thread_Mutex> >
{
typedef UNORDERED_MAP<uint32, TerrainInfo *> TerrainDataMap;
friend class MaNGOS::OperatorNew<TerrainManager>;
public:
TerrainInfo * LoadTerrain(const uint32 mapId);
void UnloadTerrain(const uint32 mapId);
void Update(const uint32 diff);
void UnloadAll();
uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const
{
TerrainInfo *pData = const_cast<TerrainManager*>(this)->LoadTerrain(mapid);
return pData->GetAreaFlag(x, y, z);
}
uint32 GetAreaId(uint32 mapid, float x, float y, float z) const
{
return TerrainManager::GetAreaIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid);
}
uint32 GetZoneId(uint32 mapid, float x, float y, float z) const
{
return TerrainManager::GetZoneIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid);
}
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z)
{
TerrainManager::GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(mapid, x, y, z),mapid);
}
static uint32 GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id);
static uint32 GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id);
static void GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id);
private:
TerrainManager();
~TerrainManager();
TerrainManager(const TerrainManager &);
TerrainManager& operator=(const TerrainManager &);
typedef MaNGOS::ClassLevelLockable<TerrainManager, ACE_Thread_Mutex>::Lock Guard;
TerrainDataMap i_TerrainMap;
};
#define sTerrainMgr TerrainManager::Instance()
#endif

View file

@ -30,7 +30,6 @@
#include "BattleGround.h"
#include "MapManager.h"
#include "InstanceSaveMgr.h"
#include "MapInstanced.h"
#include "Util.h"
#include "LootMgr.h"

View file

@ -26,7 +26,6 @@
#include "CellImpl.h"
#include "Map.h"
#include "MapManager.h"
#include "MapInstanced.h"
#include "Timer.h"
#include "GridNotifiersImpl.h"
#include "Transports.h"
@ -581,8 +580,8 @@ void InstanceSaveManager::_ResetSave(InstanceSaveHashMap::iterator &itr)
void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId)
{
DEBUG_LOG("InstanceSaveMgr::_ResetInstance %u, %u", mapid, instanceId);
Map *map = (MapInstanced*)sMapMgr.CreateBaseMap(mapid);
if (!map->Instanceable())
Map * iMap = sMapMgr.FindMap(mapid, instanceId);
if (!iMap || !iMap->Instanceable())
return;
InstanceSaveHashMap::iterator itr = m_instanceSaveById.find(instanceId);
@ -591,8 +590,7 @@ void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId)
DeleteInstanceFromDB(instanceId); // even if save not loaded
Map* iMap = ((MapInstanced*)map)->FindMap(instanceId);
if (iMap && iMap->IsDungeon())
if (iMap->IsDungeon())
((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY);
else
sObjectMgr.DeleteRespawnTimeForInstance(instanceId);// even if map is not loaded
@ -639,14 +637,14 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b
}
// note: this isn't fast but it's meant to be executed very rarely
Map const *map = sMapMgr.CreateBaseMap(mapid); // _not_ include difficulty
MapInstanced::InstancedMaps &instMaps = ((MapInstanced*)map)->GetInstancedMaps();
MapInstanced::InstancedMaps::iterator mitr;
for(mitr = instMaps.begin(); mitr != instMaps.end(); ++mitr)
const MapManager::MapMapType& maps = sMapMgr.Maps();
MapManager::MapMapType::const_iterator iter_last = maps.lower_bound(MapID(mapid + 1));
for(MapManager::MapMapType::const_iterator mitr = maps.lower_bound(MapID(mapid)); mitr != iter_last; ++mitr)
{
Map *map2 = mitr->second;
if (!map2->IsDungeon())
continue;
if(map2->GetId() != mapid)
break;
if (warn)
((InstanceMap*)map2)->SendResetWarnings(timeLeft);

View file

@ -293,7 +293,7 @@ bool ChatHandler::HandleGPSCommand(char* args)
zone_y = 0;
}
Map const *map = obj->GetMap();
TerrainInfo const *map = obj->GetTerrain();
float ground_z = map->GetHeight(obj->GetPositionX(), obj->GetPositionY(), MAX_HEIGHT);
float floor_z = map->GetHeight(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ());
@ -1830,7 +1830,7 @@ bool ChatHandler::HandleTeleNameCommand(char* args)
PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), GetMangosString(LANG_OFFLINE), tele->name.c_str());
Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation,
sMapMgr.GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),target_guid);
sTerrainMgr.GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),target_guid);
}
return true;
@ -2034,7 +2034,7 @@ bool ChatHandler::HandleGoHelper( Player* player, uint32 mapid, float x, float y
return false;
}
Map const *map = sMapMgr.CreateBaseMap(mapid);
TerrainInfo const *map = sTerrainMgr.LoadTerrain(mapid);
z = map->GetWaterOrGroundLevel(x, y, MAX_HEIGHT);
}

View file

@ -178,8 +178,6 @@ libmangosgame_a_SOURCES = \
Mail.h \
Map.cpp \
Map.h \
MapInstanced.cpp \
MapInstanced.h \
MapManager.cpp \
MapManager.h \
MapReference.h \

View file

@ -34,7 +34,6 @@
#include "Group.h"
#include "MapRefManager.h"
#include "DBCEnums.h"
#include "MapInstanced.h"
#include "InstanceSaveMgr.h"
#include "VMapFactory.h"
#include "BattleGroundMgr.h"
@ -57,88 +56,35 @@ Map::~Map()
if (m_instanceSave)
m_instanceSave->SetUsedByMapState(false); // field pointer can be deleted after this
}
void Map::LoadVMap(int gx,int gy)
{
// x and y are swapped !!
VMAP::VMAPLoadResult vmapLoadResult = VMAP::VMapFactory::createOrGetVMapManager()->loadMap((sWorld.GetDataPath()+ "vmaps").c_str(), GetId(), gx,gy);
switch(vmapLoadResult)
{
case VMAP::VMAP_LOAD_RESULT_OK:
DETAIL_LOG("VMAP loaded name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx,gy,gx,gy);
break;
case VMAP::VMAP_LOAD_RESULT_ERROR:
DETAIL_LOG("Could not load VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx,gy,gx,gy);
break;
case VMAP::VMAP_LOAD_RESULT_IGNORED:
DEBUG_LOG("Ignored VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx,gy,gx,gy);
break;
}
}
void Map::LoadMap(int gx,int gy, bool reload)
{
if( i_InstanceId != 0 )
{
if(GridMaps[gx][gy])
return;
// load grid map for base map
if (!m_parentMap->GridMaps[gx][gy])
m_parentMap->EnsureGridCreated(GridPair(63-gx,63-gy));
((MapInstanced*)(m_parentMap))->AddGridMapReference(GridPair(gx,gy));
GridMaps[gx][gy] = m_parentMap->GridMaps[gx][gy];
return;
}
if(GridMaps[gx][gy] && !reload)
return;
//map already load, delete it before reloading (Is it necessary? Do we really need the ability the reload maps during runtime?)
if(GridMaps[gx][gy])
{
DETAIL_LOG("Unloading already loaded map %u before reloading.",i_id);
delete (GridMaps[gx][gy]);
GridMaps[gx][gy]=NULL;
}
// map file name
char *tmp=NULL;
int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1;
tmp = new char[len];
snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),i_id,gx,gy);
DETAIL_LOG("Loading map %s",tmp);
// loading data
GridMaps[gx][gy] = new GridMap();
if (!GridMaps[gx][gy]->loadData(tmp))
{
sLog.outError("Error load map file: \n %s\n", tmp);
}
delete [] tmp;
//release reference count
if(m_TerrainData->Release())
sTerrainMgr.UnloadTerrain(m_TerrainData->GetMapId());
}
void Map::LoadMapAndVMap(int gx,int gy)
{
LoadMap(gx,gy);
if(i_InstanceId == 0)
LoadVMap(gx, gy); // Only load the data for the base map
if(m_bLoadedGrids[gx][gx])
return;
GridMap * pInfo = m_TerrainData->Load(gx, gy);
if(pInfo)
m_bLoadedGrids[gx][gy] = true;
}
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent)
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode),
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_instanceSave(NULL),
m_activeNonPlayersIter(m_activeNonPlayers.end()),
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this)
{
for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
i_gridExpiry(expiry), m_TerrainData(sTerrainMgr.LoadTerrain(id))
{
for(unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j)
{
for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
{
//z code
GridMaps[idx][j] =NULL;
m_bLoadedGrids[idx][j] = false;
setNGrid(NULL, idx, j);
}
}
@ -146,6 +92,9 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
//lets initialize visibility distance for map
Map::InitVisibilityDistance();
//add reference for TerrainData object
m_TerrainData->AddRef();
}
void Map::InitVisibilityDistance()
@ -292,7 +241,7 @@ Map::EnsureGridCreated(const GridPair &p)
int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord;
int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord;
if(!GridMaps[gx][gy])
if(!m_bLoadedGrids[gx][gy])
LoadMapAndVMap(gx,gy);
}
}
@ -916,23 +865,14 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
int gx = (MAX_NUMBER_OF_GRIDS - 1) - x;
int gy = (MAX_NUMBER_OF_GRIDS - 1) - y;
// delete grid map, but don't delete if it is from parent map (and thus only reference)
//+++if (GridMaps[gx][gy]) don't check for GridMaps[gx][gy], we might have to unload vmaps
// unload GridMap - it is reference-countable so will be deleted safely when lockCount < 1
// also simply set Map's pointer to corresponding GridMap object to NULL
if(m_bLoadedGrids[gx][gy])
{
if (i_InstanceId == 0)
{
if(GridMaps[gx][gy])
{
GridMaps[gx][gy]->unloadData();
delete GridMaps[gx][gy];
m_bLoadedGrids[gx][gy] = false;
m_TerrainData->Unload(gx, gy);
}
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gx, gy);
}
else
((MapInstanced*)m_parentMap)->RemoveGridMapReference(GridPair(gx, gy));
GridMaps[gx][gy] = NULL;
}
DEBUG_LOG("Unloading grid[%u,%u] for map %u finished", x,y, i_id);
return true;
}
@ -973,346 +913,6 @@ uint32 Map::GetMaxResetDelay() const
return InstanceResetScheduler::GetMaxResetTimeFor(GetMapDifficulty());
}
inline GridMap *Map::GetGrid(float x, float y)
{
// half opt method
int gx=(int)(32-x/SIZE_OF_GRIDS); //grid x
int gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
// ensure GridMap is loaded
EnsureGridCreated(GridPair(63-gx,63-gy));
return GridMaps[gx][gy];
}
float Map::GetHeight(float x, float y, float z, bool pUseVmaps, float maxSearchDist) const
{
// find raw .map surface under Z coordinates
float mapHeight;
float z2 = z + 2.f;
if (GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
{
float _mapheight = gmap->getHeight(x,y);
// look from a bit higher pos to find the floor, ignore under surface case
if (z2 > _mapheight)
mapHeight = _mapheight;
else
mapHeight = VMAP_INVALID_HEIGHT_VALUE;
}
else
mapHeight = VMAP_INVALID_HEIGHT_VALUE;
float vmapHeight;
if (pUseVmaps)
{
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
if (vmgr->isHeightCalcEnabled())
{
// if mapHeight has been found search vmap height at least until mapHeight point
// this prevent case when original Z "too high above ground and vmap height search fail"
// this will not affect most normal cases (no map in instance, or stay at ground at continent)
if (mapHeight > INVALID_HEIGHT && z2 - mapHeight > maxSearchDist)
maxSearchDist = z2 - mapHeight + 1.0f; // 1.0 make sure that we not fail for case when map height near but above for vamp height
// look from a bit higher pos to find the floor
vmapHeight = vmgr->getHeight(GetId(), x, y, z2, maxSearchDist);
}
else
vmapHeight = VMAP_INVALID_HEIGHT_VALUE;
}
else
vmapHeight = VMAP_INVALID_HEIGHT_VALUE;
// mapHeight set for any above raw ground Z or <= INVALID_HEIGHT
// vmapheight set for any under Z value or <= INVALID_HEIGHT
if (vmapHeight > INVALID_HEIGHT)
{
if (mapHeight > INVALID_HEIGHT)
{
// we have mapheight and vmapheight and must select more appropriate
// we are already under the surface or vmap height above map heigt
// or if the distance of the vmap height is less the land height distance
if (z < mapHeight || vmapHeight > mapHeight || fabs(mapHeight-z) > fabs(vmapHeight-z))
return vmapHeight;
else
return mapHeight; // better use .map surface height
}
else
return vmapHeight; // we have only vmapHeight (if have)
}
return mapHeight;
}
inline bool IsOutdoorWMO(uint32 mogpFlags, int32 adtId, int32 rootId, int32 groupId,
WMOAreaTableEntry const* wmoEntry, AreaTableEntry const* atEntry)
{
bool outdoor = true;
if(wmoEntry && atEntry)
{
if(atEntry->flags & AREA_FLAG_OUTSIDE)
return true;
if(atEntry->flags & AREA_FLAG_INSIDE)
return false;
}
outdoor = mogpFlags&0x8;
if(wmoEntry)
{
if(wmoEntry->Flags & 4)
return true;
if((wmoEntry->Flags & 2)!=0)
outdoor = false;
}
return outdoor;
}
bool Map::IsOutdoors(float x, float y, float z) const
{
uint32 mogpFlags;
int32 adtId, rootId, groupId;
// no wmo found? -> outside by default
if(!GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId))
return true;
AreaTableEntry const* atEntry = 0;
WMOAreaTableEntry const* wmoEntry= GetWMOAreaTableEntryByTripple(rootId, adtId, groupId);
if(wmoEntry)
{
DEBUG_LOG("Got WMOAreaTableEntry! flag %u, areaid %u", wmoEntry->Flags, wmoEntry->areaId);
atEntry = GetAreaEntryByAreaID(wmoEntry->areaId);
}
return IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry);
}
bool Map::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
{
float vmap_z = z;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
if (vmgr->getAreaInfo(GetId(), x, y, vmap_z, flags, adtId, rootId, groupId))
{
// check if there's terrain between player height and object height
if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
{
float _mapheight = gmap->getHeight(x,y);
// z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice...
if(z + 2.0f > _mapheight && _mapheight > vmap_z)
return false;
}
return true;
}
return false;
}
uint16 Map::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const
{
uint32 mogpFlags;
int32 adtId, rootId, groupId;
WMOAreaTableEntry const* wmoEntry = 0;
AreaTableEntry const* atEntry = 0;
bool haveAreaInfo = false;
if(GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId))
{
haveAreaInfo = true;
wmoEntry = GetWMOAreaTableEntryByTripple(rootId, adtId, groupId);
if (wmoEntry)
atEntry = GetAreaEntryByAreaID(wmoEntry->areaId);
}
uint16 areaflag;
if (atEntry)
areaflag = atEntry->exploreFlag;
else
{
if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
areaflag = gmap->getArea(x, y);
// this used while not all *.map files generated (instances)
else
areaflag = GetAreaFlagByMapId(i_id);
}
if (isOutdoors)
{
if (haveAreaInfo)
*isOutdoors = IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry);
else
*isOutdoors = true;
}
return areaflag;
}
uint8 Map::GetTerrainType(float x, float y ) const
{
if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
return gmap->getTerrainType(x, y);
else
return 0;
}
GridMapLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData *data) const
{
GridMapLiquidStatus result = LIQUID_MAP_NO_WATER;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
float liquid_level, ground_level = INVALID_HEIGHT;
uint32 liquid_type;
if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type))
{
DEBUG_LOG("getLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type);
// Check water level and ground level
if (liquid_level > ground_level && z > ground_level - 2)
{
// All ok in water -> store data
if (data)
{
data->type = liquid_type;
data->level = liquid_level;
data->depth_level = ground_level;
}
// For speed check as int values
int delta = int((liquid_level - z) * 10);
// Get position delta
if (delta > 20) // Under water
return LIQUID_MAP_UNDER_WATER;
if (delta > 0 ) // In water
return LIQUID_MAP_IN_WATER;
if (delta > -1) // Walk on water
return LIQUID_MAP_WATER_WALK;
result = LIQUID_MAP_ABOVE_WATER;
}
}
if(GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
{
GridMapLiquidData map_data;
GridMapLiquidStatus map_result = gmap->getLiquidStatus(x, y, z, ReqLiquidType, &map_data);
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level))
{
if (data)
*data = map_data;
return map_result;
}
}
return result;
}
uint32 Map::GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id)
{
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
if (entry)
return entry->ID;
else
return 0;
}
uint32 Map::GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id)
{
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
if( entry )
return ( entry->zone != 0 ) ? entry->zone : entry->ID;
else
return 0;
}
void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id)
{
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
areaid = entry ? entry->ID : 0;
zoneid = entry ? (( entry->zone != 0 ) ? entry->zone : entry->ID) : 0;
}
bool Map::IsInWater(float x, float y, float pZ, GridMapLiquidData *data) const
{
// Check surface in x, y point for liquid
if (const_cast<Map*>(this)->GetGrid(x, y))
{
GridMapLiquidData liquid_status;
GridMapLiquidData *liquid_ptr = data ? data : &liquid_status;
if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr))
{
//if (liquid_prt->level - liquid_prt->depth_level > 2) //???
return true;
}
}
return false;
}
bool Map::IsUnderWater(float x, float y, float z) const
{
if (const_cast<Map*>(this)->GetGrid(x, y))
{
if (getLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER|MAP_LIQUID_TYPE_OCEAN)&LIQUID_MAP_UNDER_WATER)
return true;
}
return false;
}
/**
* Function find higher form water or ground height for current floor
*
* @param x, y, z Coordinates original point at floor level
*
* @param pGround optional arg for retrun calculated by function work ground height, it let avoid in caller code recalculate height for point if it need
*
* @param swim z coordinate can be calculated for select above/at or under z coordinate (for fly or swim/walking by bottom)
* in last cases for in water returned under water height for avoid client set swimming unit as saty at water.
*
* @return calculated z coordinate
*/
float Map::GetWaterOrGroundLevel(float x, float y, float z, float* pGround /*= NULL*/, bool swim /*= false*/) const
{
if (const_cast<Map*>(this)->GetGrid(x, y))
{
// we need ground level (including grid height version) for proper return water level in point
float ground_z = GetHeight(x, y, z, true, DEFAULT_WATER_SEARCH);
if (pGround)
*pGround = ground_z;
GridMapLiquidData liquid_status;
GridMapLiquidStatus res = getLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status);
return res ? ( swim ? liquid_status.level - 2.0f : liquid_status.level) : ground_z;
}
return VMAP_INVALID_HEIGHT_VALUE;
}
float Map::GetWaterLevel(float x, float y, float z, float* pGround /*= NULL*/) const
{
if (const_cast<Map*>(this)->GetGrid(x, y))
{
// we need ground level (including grid height version) for proper return water level in point
float ground_z = GetHeight(x, y, z, true, DEFAULT_WATER_SEARCH);
if (pGround)
*pGround = ground_z;
GridMapLiquidData liquid_status;
GridMapLiquidStatus res = getLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status);
if (!res)
return VMAP_INVALID_HEIGHT_VALUE;
return liquid_status.level;
}
return VMAP_INVALID_HEIGHT_VALUE;
}
bool Map::CheckGridIntegrity(Creature* c, bool moved) const
{
Cell const& cur_cell = c->GetCurrentCell();
@ -1628,8 +1228,8 @@ template void Map::Remove(DynamicObject *, bool);
/* ******* Dungeon Instance Maps ******* */
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent)
: Map(id, expiry, InstanceId, SpawnMode, _parent),
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
: Map(id, expiry, InstanceId, SpawnMode),
m_resetAfterUnload(false), m_unloadWhenEmpty(false),
i_data(NULL), i_script_id(0)
{
@ -1998,8 +1598,8 @@ void InstanceMap::SetResetSchedule(bool on)
/* ******* Battleground Instance Maps ******* */
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent, uint8 spawnMode)
: Map(id, expiry, InstanceId, spawnMode, _parent)
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 spawnMode)
: Map(id, expiry, InstanceId, spawnMode)
{
//lets initialize visibility distance for BG/Arenas
BattleGroundMap::InitVisibilityDistance();

View file

@ -78,11 +78,6 @@ enum LevelRequirementVsMode
#pragma pack(pop)
#endif
#define MAX_HEIGHT 100000.0f // can be use for find ground height at surface
#define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE
#define MAX_FALL_DISTANCE 250000.0f // "unlimited fall" to find VMap ground if it is available, just larger than MAX_HEIGHT - INVALID_HEIGHT
#define DEFAULT_HEIGHT_SEARCH 10.0f // default search distance to find height at nearby locations
#define DEFAULT_WATER_SEARCH 50.0f // default search distance to case detection water level
#define MIN_UNLOAD_DELAY 1 // immediate unload
class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::ObjectLevelLockable<Map, ACE_Thread_Mutex>
@ -91,7 +86,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
friend class ObjectGridLoader;
friend class ObjectWorldLoader;
public:
Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL);
Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode);
virtual ~Map();
// currently unused for normal maps
@ -150,39 +145,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
time_t GetGridExpiry(void) const { return i_gridExpiry; }
uint32 GetId(void) const { return i_id; }
Map const * GetParent() const { return m_parentMap; }
// some calls like isInWater should not use vmaps due to processor power
// can return INVALID_HEIGHT if under z+2 z coord not found height
float GetHeight(float x, float y, float z, bool pCheckVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const;
float GetWaterLevel(float x, float y, float z, float* pGround = NULL) const;
float GetWaterOrGroundLevel(float x, float y, float z, float* pGround = NULL, bool swim = false) const;
bool IsInWater(float x, float y, float z, GridMapLiquidData *data = 0) const;
bool IsUnderWater(float x, float y, float z) const;
GridMapLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData *data = 0) const;
uint16 GetAreaFlag(float x, float y, float z, bool *isOutdoors=0) const;
uint8 GetTerrainType(float x, float y ) const;
static uint32 GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id);
static uint32 GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id);
static void GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id);
uint32 GetAreaId(float x, float y, float z) const
{
return GetAreaIdByAreaFlag(GetAreaFlag(x,y,z),i_id);
}
uint32 GetZoneId(float x, float y, float z) const
{
return GetZoneIdByAreaFlag(GetAreaFlag(x,y,z),i_id);
}
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const
{
GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(x,y,z),i_id);
}
virtual void RemoveAllObjectsInRemoveList();
@ -268,13 +232,12 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
// DynObjects currently
uint32 GenerateLocalLowGuid(HighGuid guidhigh);
bool GetAreaInfo(float x, float y, float z, uint32 &mogpflags, int32 &adtId, int32 &rootId, int32 &groupId) const;
bool IsOutdoors(float x, float y, float z) const;
//get corresponding TerrainData object for this particular map
const TerrainInfo * GetTerrain() const { return m_TerrainData; }
private:
void LoadMapAndVMap(int gx, int gy);
void LoadVMap(int gx, int gy);
void LoadMap(int gx,int gy, bool reload = false);
GridMap *GetGrid(float x, float y);
void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; }
@ -313,8 +276,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
void SendObjectUpdates();
std::set<Object *> i_objectsToClientUpdate;
protected:
void SetUnloadReferenceLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); }
typedef MaNGOS::ObjectLevelLockable<Map, ACE_Thread_Mutex>::Lock Guard;
MapEntry const* i_mapEntry;
@ -335,12 +296,12 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
private:
time_t i_gridExpiry;
//used for fast base_map (e.g. MapInstanced class object) search for
//InstanceMaps and BattleGroundMaps...
Map* m_parentMap;
NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
GridMap *GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
//Shared geodata object with map coord info...
TerrainInfo * const m_TerrainData;
bool m_bLoadedGrids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
std::bitset<TOTAL_NUMBER_OF_CELLS_PER_MAP*TOTAL_NUMBER_OF_CELLS_PER_MAP> marked_cells;
std::set<WorldObject *> i_objectsToRemove;
@ -368,7 +329,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
class MANGOS_DLL_SPEC InstanceMap : public Map
{
public:
InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent);
InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode);
~InstanceMap();
bool Add(Player *);
void Remove(Player *, bool);
@ -394,7 +355,7 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
class MANGOS_DLL_SPEC BattleGroundMap : public Map
{
public:
BattleGroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, uint8 spawnMode);
BattleGroundMap(uint32 id, time_t, uint32 InstanceId, uint8 spawnMode);
~BattleGroundMap();
void Update(const uint32&);

View file

@ -1,207 +0,0 @@
/*
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "MapInstanced.h"
#include "ObjectMgr.h"
#include "MapManager.h"
#include "BattleGround.h"
#include "VMapFactory.h"
#include "InstanceSaveMgr.h"
#include "World.h"
MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, DUNGEON_DIFFICULTY_NORMAL)
{
// initialize instanced maps list
m_InstancedMaps.clear();
// fill with zero
memset(&GridMapReference, 0, MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_GRIDS*sizeof(uint16));
}
void MapInstanced::InitVisibilityDistance()
{
if(m_InstancedMaps.empty())
return;
//initialize visibility distances for all instance copies
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
{
(*i).second->InitVisibilityDistance();
}
}
void MapInstanced::Update(const uint32& t)
{
// take care of loaded GridMaps (when unused, unload it!)
Map::Update(t);
// update the instanced maps
InstancedMaps::iterator i = m_InstancedMaps.begin();
while (i != m_InstancedMaps.end())
{
if(i->second->CanUnload(t))
{
DestroyInstance(i); // iterator incremented
}
else
{
// update only here, because it may schedule some bad things before delete
i->second->Update(t);
++i;
}
}
}
void MapInstanced::RemoveAllObjectsInRemoveList()
{
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
{
i->second->RemoveAllObjectsInRemoveList();
}
Map::RemoveAllObjectsInRemoveList();
}
void MapInstanced::UnloadAll(bool pForce)
{
// Unload instanced maps
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
i->second->UnloadAll(pForce);
// Delete the maps only after everything is unloaded to prevent crashes
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
delete i->second;
m_InstancedMaps.clear();
// Unload own grids (just dummy(placeholder) grids, neccesary to unload GridMaps!)
Map::UnloadAll(pForce);
}
/// returns a new or existing Instance
/// in case of battlegrounds it will only return an existing map, those maps are created by bg-system
Map* MapInstanced::CreateInstance(Player * player)
{
Map* map;
uint32 NewInstanceId; // instanceId of the resulting map
if(IsBattleGroundOrArena())
{
// find existing bg map for player
NewInstanceId = player->GetBattleGroundId();
MANGOS_ASSERT(NewInstanceId);
map = _FindMap(NewInstanceId);
MANGOS_ASSERT(map);
}
else if (InstanceSave* pSave = player->GetBoundInstanceSaveForSelfOrGroup(GetId()))
{
// solo/perm/group
NewInstanceId = pSave->GetInstanceId();
map = _FindMap(NewInstanceId);
// it is possible that the save exists but the map doesn't
if (!map)
map = CreateInstanceMap(NewInstanceId, pSave->GetDifficulty(), pSave);
}
else
{
// if no instanceId via group members or instance saves is found
// the instance will be created for the first time
NewInstanceId = sObjectMgr.GenerateLowGuid(HIGHGUID_INSTANCE);
Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(IsRaid()) : player->GetDifficulty(IsRaid());
map = CreateInstanceMap(NewInstanceId, diff);
}
return map;
}
InstanceMap* MapInstanced::CreateInstanceMap(uint32 InstanceId, Difficulty difficulty, InstanceSave *save)
{
// load/create a map
Guard guard(*this);
// make sure we have a valid map id
if (!sMapStore.LookupEntry(GetId()))
{
sLog.outError("CreateInstanceMap: no entry for map %d", GetId());
MANGOS_ASSERT(false);
}
if (!ObjectMgr::GetInstanceTemplate(GetId()))
{
sLog.outError("CreateInstanceMap: no instance template for map %d", GetId());
MANGOS_ASSERT(false);
}
// some instances only have one difficulty
if (!GetMapDifficultyData(GetId(),difficulty))
difficulty = DUNGEON_DIFFICULTY_NORMAL;
DEBUG_LOG("MapInstanced::CreateInstanceMap: %s map instance %d for %d created with difficulty %d", save?"":"new ", InstanceId, GetId(), difficulty);
InstanceMap *map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty, this);
MANGOS_ASSERT(map->IsDungeon());
bool load_data = save != NULL;
map->CreateInstanceData(load_data);
m_InstancedMaps[InstanceId] = map;
return map;
}
BattleGroundMap* MapInstanced::CreateBattleGroundMap(uint32 InstanceId, BattleGround* bg)
{
// load/create a map
Guard guard(*this);
DEBUG_LOG("MapInstanced::CreateBattleGroundMap: instance:%d for map:%d and bgType:%d created.", InstanceId, GetId(), bg->GetTypeID());
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),bg->GetMinLevel());
uint8 spawnMode = bracketEntry ? bracketEntry->difficulty : REGULAR_DIFFICULTY;
BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId, this, spawnMode);
MANGOS_ASSERT(map->IsBattleGroundOrArena());
map->SetBG(bg);
bg->SetBgMap(map);
m_InstancedMaps[InstanceId] = map;
return map;
}
void MapInstanced::DestroyInstance(uint32 InstanceId)
{
InstancedMaps::iterator itr = m_InstancedMaps.find(InstanceId);
if(itr != m_InstancedMaps.end())
DestroyInstance(itr);
}
// increments the iterator after erase
void MapInstanced::DestroyInstance(InstancedMaps::iterator &itr)
{
itr->second->UnloadAll(true);
// should only unload VMaps if this is the last instance and grid unloading is enabled
if(m_InstancedMaps.size() <= 1 && sWorld.getConfig(CONFIG_BOOL_GRID_UNLOAD))
{
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(itr->second->GetId());
// in that case, unload grids of the base map, too
// so in the next map creation, (EnsureGridCreated actually) VMaps will be reloaded
Map::UnloadAll(true);
}
// erase map
delete itr->second;
m_InstancedMaps.erase(itr++);
}

View file

@ -1,77 +0,0 @@
/*
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MANGOS_MAP_INSTANCED_H
#define MANGOS_MAP_INSTANCED_H
#include "Common.h"
#include "Map.h"
#include "InstanceSaveMgr.h"
#include "DBCEnums.h"
class MANGOS_DLL_DECL MapInstanced : public Map
{
friend class MapManager;
public:
typedef UNORDERED_MAP< uint32, Map* > InstancedMaps;
MapInstanced(uint32 id, time_t expiry);
~MapInstanced() {}
// functions overwrite Map versions
void Update(const uint32&);
void RemoveAllObjectsInRemoveList();
void UnloadAll(bool pForce);
Map* CreateInstance(Player* player);
Map* FindMap(uint32 InstanceId) const { return _FindMap(InstanceId); }
void DestroyInstance(uint32 InstanceId);
void DestroyInstance(InstancedMaps::iterator &itr);
void AddGridMapReference(const GridPair &p)
{
++GridMapReference[p.x_coord][p.y_coord];
SetUnloadReferenceLock(GridPair(63-p.x_coord, 63-p.y_coord), true);
}
void RemoveGridMapReference(GridPair const& p)
{
--GridMapReference[p.x_coord][p.y_coord];
if (!GridMapReference[p.x_coord][p.y_coord])
SetUnloadReferenceLock(GridPair(63-p.x_coord, 63-p.y_coord), false);
}
InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; }
virtual void InitVisibilityDistance();
BattleGroundMap* CreateBattleGroundMap(uint32 InstanceId, BattleGround* bg);
private:
InstanceMap* CreateInstanceMap(uint32 InstanceId, Difficulty difficulty, InstanceSave *save = NULL);
InstancedMaps m_InstancedMaps;
Map* _FindMap(uint32 InstanceId) const
{
InstancedMaps::const_iterator i = m_InstancedMaps.find(InstanceId);
return(i == m_InstancedMaps.end() ? NULL : i->second);
}
uint16 GridMapReference[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
};
#endif

View file

@ -23,16 +23,15 @@
#include "Log.h"
#include "Transports.h"
#include "GridDefines.h"
#include "MapInstanced.h"
#include "DestinationHolderImp.h"
#include "World.h"
#include "CellImpl.h"
#include "Corpse.h"
#include "ObjectMgr.h"
#define CLASS_LOCK MaNGOS::ClassLevelLockable<MapManager, ACE_Thread_Mutex>
#define CLASS_LOCK MaNGOS::ClassLevelLockable<MapManager, ACE_Recursive_Thread_Mutex>
INSTANTIATE_SINGLETON_2(MapManager, CLASS_LOCK);
INSTANTIATE_CLASS_MUTEX(MapManager, ACE_Thread_Mutex);
INSTANTIATE_CLASS_MUTEX(MapManager, ACE_Recursive_Thread_Mutex);
MapManager::MapManager()
: i_gridCleanUpDelay(sWorld.getConfig(CONFIG_UINT32_INTERVAL_GRIDCLEAN))
@ -88,60 +87,64 @@ void MapManager::InitializeVisibilityDistanceInfo()
(*iter).second->InitVisibilityDistance();
}
Map*
MapManager::_createBaseMap(uint32 id)
{
Map *m = _findMap(id);
if( m == NULL )
{
Guard guard(*this);
const MapEntry* entry = sMapStore.LookupEntry(id);
if (entry && entry->Instanceable())
{
m = new MapInstanced(id, i_gridCleanUpDelay);
}
else
{
m = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY);
}
i_maps[id] = m;
}
MANGOS_ASSERT(m != NULL);
return m;
}
Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
{
MANGOS_ASSERT(obj);
//if(!obj->IsInWorld()) sLog.outError("GetMap: called for map %d with object (typeid %d, guid %d, mapid %d, instanceid %d) who is not in world!", id, obj->GetTypeId(), obj->GetGUIDLow(), obj->GetMapId(), obj->GetInstanceId());
Map *m = _createBaseMap(id);
Guard _guard(*this);
if (m && (obj->GetTypeId() == TYPEID_PLAYER) && m->Instanceable())
m = ((MapInstanced*)m)->CreateInstance((Player*)obj);
Map * m = NULL;
const MapEntry* entry = sMapStore.LookupEntry(id);
if(!entry)
return NULL;
if(entry->Instanceable())
{
MANGOS_ASSERT(obj->GetTypeId() == TYPEID_PLAYER);
//create InstanceMap object
if(obj->GetTypeId() == TYPEID_PLAYER)
m = CreateInstance(id, (Player*)obj);
}
else
{
//create regular Continent map
m = FindMap(id);
if( m == NULL )
{
m = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY);
//add map into container
i_maps[MapID(id)] = m;
}
}
return m;
}
Map* MapManager::CreateBgMap(uint32 mapid, BattleGround* bg)
{
Map *m = _createBaseMap(mapid);
((MapInstanced*)m)->CreateBattleGroundMap(sObjectMgr.GenerateLowGuid(HIGHGUID_INSTANCE), bg);
return m;
TerrainInfo * pData = sTerrainMgr.LoadTerrain(mapid);
Guard _guard(*this);
return CreateBattleGroundMap(mapid, sObjectMgr.GenerateLowGuid(HIGHGUID_INSTANCE), bg);
}
Map* MapManager::FindMap(uint32 mapid, uint32 instanceId) const
{
Map *map = _findMap(mapid);
if(!map)
Guard guard(*this);
MapMapType::const_iterator iter = i_maps.find(MapID(mapid, instanceId));
if(iter == i_maps.end())
return NULL;
if(!map->Instanceable())
return instanceId == 0 ? map : NULL;
//this is a small workaround for transports
if(instanceId == 0 && iter->second->Instanceable())
{
assert(false);
return NULL;
}
return ((MapInstanced*)map)->FindMap(instanceId);
return iter->second;
}
/*
@ -233,9 +236,20 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
void MapManager::DeleteInstance(uint32 mapid, uint32 instanceId)
{
Map *m = _createBaseMap(mapid);
if (m && m->Instanceable())
((MapInstanced*)m)->DestroyInstance(instanceId);
Guard _guard(*this);
MapMapType::iterator iter = i_maps.find(MapID(mapid, instanceId));
if(iter != i_maps.end())
{
Map * pMap = iter->second;
if (pMap->Instanceable())
{
i_maps.erase(iter);
pMap->UnloadAll(true);
delete pMap;
}
}
}
void
@ -251,6 +265,23 @@ MapManager::Update(uint32 diff)
for (TransportSet::iterator iter = m_Transports.begin(); iter != m_Transports.end(); ++iter)
(*iter)->Update((uint32)i_timer.GetCurrent());
//remove all maps which can be unloaded
MapMapType::iterator iter = i_maps.begin();
while(iter != i_maps.end())
{
Map * pMap = iter->second;
//check if map can be unloaded
if(pMap->CanUnload((uint32)i_timer.GetCurrent()))
{
pMap->UnloadAll(true);
delete pMap;
i_maps.erase(iter++);
}
else
++iter;
}
i_timer.SetCurrent(0);
}
@ -287,6 +318,8 @@ void MapManager::UnloadAll()
delete i_maps.begin()->second;
i_maps.erase(i_maps.begin());
}
TerrainManager::Instance().UnloadAll();
}
uint32 MapManager::GetNumInstances()
@ -295,10 +328,8 @@ uint32 MapManager::GetNumInstances()
for(MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr)
{
Map *map = itr->second;
if(!map->Instanceable()) continue;
MapInstanced::InstancedMaps &maps = ((MapInstanced *)map)->GetInstancedMaps();
for(MapInstanced::InstancedMaps::iterator mitr = maps.begin(); mitr != maps.end(); ++mitr)
if(mitr->second->IsDungeon()) ret++;
if(!map->IsDungeon()) continue;
ret += 1;
}
return ret;
}
@ -309,11 +340,103 @@ uint32 MapManager::GetNumPlayersInInstances()
for(MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr)
{
Map *map = itr->second;
if(!map->Instanceable()) continue;
MapInstanced::InstancedMaps &maps = ((MapInstanced *)map)->GetInstancedMaps();
for(MapInstanced::InstancedMaps::iterator mitr = maps.begin(); mitr != maps.end(); ++mitr)
if(mitr->second->IsDungeon())
ret += ((InstanceMap*)mitr->second)->GetPlayers().getSize();
if(!map->IsDungeon()) continue;
ret += map->GetPlayers().getSize();
}
return ret;
}
///// returns a new or existing Instance
///// in case of battlegrounds it will only return an existing map, those maps are created by bg-system
Map* MapManager::CreateInstance(uint32 id, Player * player)
{
Map* map = NULL;
Map * pNewMap = NULL;
uint32 NewInstanceId = 0; // instanceId of the resulting map
const MapEntry* entry = sMapStore.LookupEntry(id);
if(entry->IsBattleGroundOrArena())
{
// find existing bg map for player
NewInstanceId = player->GetBattleGroundId();
MANGOS_ASSERT(NewInstanceId);
map = FindMap(id, NewInstanceId);
MANGOS_ASSERT(map);
}
else if (InstanceSave* pSave = player->GetBoundInstanceSaveForSelfOrGroup(id))
{
// solo/perm/group
NewInstanceId = pSave->GetInstanceId();
map = FindMap(id, NewInstanceId);
// it is possible that the save exists but the map doesn't
if (!map)
pNewMap = CreateInstanceMap(id, NewInstanceId, pSave->GetDifficulty(), pSave);
}
else
{
// if no instanceId via group members or instance saves is found
// the instance will be created for the first time
NewInstanceId = sObjectMgr.GenerateLowGuid(HIGHGUID_INSTANCE);
Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(entry->IsRaid()) : player->GetDifficulty(entry->IsRaid());
pNewMap = CreateInstanceMap(id, NewInstanceId, diff);
}
//add a new map object into the registry
if(pNewMap)
{
i_maps[MapID(id, NewInstanceId)] = pNewMap;
map = pNewMap;
}
return map;
}
InstanceMap* MapManager::CreateInstanceMap(uint32 id, uint32 InstanceId, Difficulty difficulty, InstanceSave *save)
{
// make sure we have a valid map id
if (!sMapStore.LookupEntry(id))
{
sLog.outError("CreateInstanceMap: no entry for map %d", id);
MANGOS_ASSERT(false);
}
if (!ObjectMgr::GetInstanceTemplate(id))
{
sLog.outError("CreateInstanceMap: no instance template for map %d", id);
MANGOS_ASSERT(false);
}
// some instances only have one difficulty
if (!GetMapDifficultyData(id, difficulty))
difficulty = DUNGEON_DIFFICULTY_NORMAL;
DEBUG_LOG("MapInstanced::CreateInstanceMap: %s map instance %d for %d created with difficulty %d", save?"":"new ", InstanceId, id, difficulty);
InstanceMap *map = new InstanceMap(id, i_gridCleanUpDelay, InstanceId, difficulty);
MANGOS_ASSERT(map->IsDungeon());
bool load_data = save != NULL;
map->CreateInstanceData(load_data);
return map;
}
BattleGroundMap* MapManager::CreateBattleGroundMap(uint32 id, uint32 InstanceId, BattleGround* bg)
{
DEBUG_LOG("MapInstanced::CreateBattleGroundMap: instance:%d for map:%d and bgType:%d created.", InstanceId, id, bg->GetTypeID());
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),bg->GetMinLevel());
uint8 spawnMode = bracketEntry ? bracketEntry->difficulty : REGULAR_DIFFICULTY;
BattleGroundMap *map = new BattleGroundMap(id, i_gridCleanUpDelay, InstanceId, spawnMode);
MANGOS_ASSERT(map->IsBattleGroundOrArena());
map->SetBG(bg);
bg->SetBgMap(map);
//add map into map container
i_maps[MapID(id, InstanceId)] = map;
return map;
}

View file

@ -22,25 +22,45 @@
#include "Common.h"
#include "Platform/Define.h"
#include "Policies/Singleton.h"
#include "ace/Thread_Mutex.h"
#include "ace/Recursive_Thread_Mutex.h"
#include "Map.h"
#include "GridStates.h"
class Transport;
class BattleGround;
class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::ClassLevelLockable<MapManager, ACE_Thread_Mutex> >
struct MANGOS_DLL_DECL MapID
{
explicit MapID(uint32 id) : nMapId(id), nInstanceId(0) {}
MapID(uint32 id, uint32 instid) : nMapId(id), nInstanceId(instid) {}
bool operator<(const MapID& val) const
{
if(nMapId == val.nMapId)
return nInstanceId < val.nInstanceId;
return nMapId < val.nMapId;
}
bool operator==(const MapID& val) const { return nMapId == val.nMapId && nInstanceId == val.nInstanceId; }
uint32 nMapId;
uint32 nInstanceId;
};
class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::ClassLevelLockable<MapManager, ACE_Recursive_Thread_Mutex> >
{
friend class MaNGOS::OperatorNew<MapManager>;
typedef UNORDERED_MAP<uint32, Map*> MapMapType;
typedef std::pair<UNORDERED_MAP<uint32, Map*>::iterator, bool> MapMapPair;
typedef ACE_Recursive_Thread_Mutex LOCK_TYPE;
typedef ACE_Guard<LOCK_TYPE> LOCK_TYPE_GUARD;
typedef MaNGOS::ClassLevelLockable<MapManager, ACE_Recursive_Thread_Mutex>::Lock Guard;
public:
typedef std::map<MapID, Map* > MapMapType;
Map* CreateMap(uint32, const WorldObject* obj);
Map* CreateBgMap(uint32 mapid, BattleGround* bg);
Map const* CreateBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_createBaseMap(id); }
Map* FindMap(uint32 mapid, uint32 instanceId = 0) const;
void UpdateGridState(grid_state_t state, Map& map, NGridType& ngrid, GridInfo& ginfo, const uint32 &x, const uint32 &y, const uint32 &t_diff);
@ -48,24 +68,6 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
// only const version for outer users
void DeleteInstance(uint32 mapid, uint32 instanceId);
uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const
{
Map const* m = CreateBaseMap(mapid);
return m->GetAreaFlag(x, y, z);
}
uint32 GetAreaId(uint32 mapid, float x, float y, float z) const
{
return Map::GetAreaIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid);
}
uint32 GetZoneId(uint32 mapid, float x, float y, float z) const
{
return Map::GetZoneIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid);
}
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z)
{
Map::GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(mapid, x, y, z),mapid);
}
void Initialize(void);
void Update(uint32);
@ -144,6 +146,10 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
uint32 GetNumInstances();
uint32 GetNumPlayersInInstances();
//get list of all maps
const MapMapType& Maps() const { return i_maps; }
private:
// debugging code, should be deleted some day
@ -161,14 +167,10 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
void InitStateMachine();
void DeleteStateMachine();
Map* _createBaseMap(uint32 id);
Map* _findMap(uint32 id) const
{
MapMapType::const_iterator iter = i_maps.find(id);
return (iter == i_maps.end() ? NULL : iter->second);
}
Map* CreateInstance(uint32 id, Player * player);
InstanceMap* CreateInstanceMap(uint32 id, uint32 InstanceId, Difficulty difficulty, InstanceSave *save = NULL);
BattleGroundMap* CreateBattleGroundMap(uint32 id, uint32 InstanceId, BattleGround* bg);
typedef MaNGOS::ClassLevelLockable<MapManager, ACE_Thread_Mutex>::Lock Guard;
uint32 i_gridCleanUpDelay;
MapMapType i_maps;
IntervalTimer i_timer;

View file

@ -544,7 +544,7 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover
if (movementInfo.HasMovementFlag(MOVEFLAG_SWIMMING) != plMover->IsInWater())
{
// now client not include swimming flag in case jumping under water
plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z) );
plMover->SetInWater( !plMover->IsInWater() || plMover->GetTerrain()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z) );
}
plMover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);

View file

@ -1160,17 +1160,17 @@ void WorldObject::Relocate(float x, float y, float z)
uint32 WorldObject::GetZoneId() const
{
return GetBaseMap()->GetZoneId(m_positionX, m_positionY, m_positionZ);
return GetTerrain()->GetZoneId(m_positionX, m_positionY, m_positionZ);
}
uint32 WorldObject::GetAreaId() const
{
return GetBaseMap()->GetAreaId(m_positionX, m_positionY, m_positionZ);
return GetTerrain()->GetAreaId(m_positionX, m_positionY, m_positionZ);
}
void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const
{
GetBaseMap()->GetZoneAndAreaId(zoneid, areaid, m_positionX, m_positionY, m_positionZ);
GetTerrain()->GetZoneAndAreaId(zoneid, areaid, m_positionX, m_positionY, m_positionZ);
}
InstanceData* WorldObject::GetInstanceData() const
@ -1458,7 +1458,7 @@ void WorldObject::GetRandomPoint( float x, float y, float z, float distance, flo
void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
{
float new_z = GetBaseMap()->GetHeight(x,y,z,true);
float new_z = GetTerrain()->GetHeight(x,y,z,true);
if(new_z > INVALID_HEIGHT)
z = new_z+ 0.05f; // just to be sure that we are not a few pixel under the surface
}
@ -1476,8 +1476,8 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
bool CanSwim = ((Creature const*)this)->CanSwim();
float ground_z = z;
float max_z = CanSwim
? GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK))
: ((ground_z = GetBaseMap()->GetHeight(x, y, z, true)));
? GetTerrain()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK))
: ((ground_z = GetTerrain()->GetHeight(x, y, z, true)));
if (max_z > INVALID_HEIGHT)
{
if (z > max_z)
@ -1488,7 +1488,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
}
else
{
float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
float ground_z = GetTerrain()->GetHeight(x, y, z, true);
if (z < ground_z)
z = ground_z;
}
@ -1500,7 +1500,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
if (!((Player const*)this)->CanFly())
{
float ground_z = z;
float max_z = GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK));
float max_z = GetTerrain()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK));
if (max_z > INVALID_HEIGHT)
{
if (z > max_z)
@ -1511,7 +1511,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
}
else
{
float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
float ground_z = GetTerrain()->GetHeight(x, y, z, true);
if (z < ground_z)
z = ground_z;
}
@ -1519,7 +1519,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
}
default:
{
float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
float ground_z = GetTerrain()->GetHeight(x, y, z, true);
if(ground_z > INVALID_HEIGHT)
z = ground_z;
break;
@ -1713,10 +1713,10 @@ void WorldObject::SetMap(Map * map)
m_InstanceId = map->GetInstanceId();
}
Map const* WorldObject::GetBaseMap() const
TerrainInfo const* WorldObject::GetTerrain() const
{
MANGOS_ASSERT(m_currMap);
return m_currMap->GetParent();
return m_currMap->GetTerrain();
}
void WorldObject::AddObjectToRemoveList()

View file

@ -69,6 +69,7 @@ class Unit;
class Map;
class UpdateMask;
class InstanceData;
class TerrainInfo;
typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;
@ -480,8 +481,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
//used to check all object's GetMap() calls when object is not in world!
void ResetMap() { m_currMap = NULL; }
//this function should be removed in nearest time...
Map const* GetBaseMap() const;
//obtain terrain data for map where this object belong...
TerrainInfo const* GetTerrain() const;
void AddToClientUpdateList();
void RemoveFromClientUpdateList();

View file

@ -34,7 +34,6 @@
#include "GridNotifiersImpl.h"
#include "Opcodes.h"
#include "ObjectGuid.h"
#include "MapInstanced.h"
#include "World.h"
#include <cmath>

View file

@ -5942,7 +5942,7 @@ void ObjectMgr::LoadGraveyardZones()
WorldSafeLocsEntry const *ObjectMgr::GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team)
{
// search for zone associated closest graveyard
uint32 zoneId = sMapMgr.GetZoneId(MapId,x,y,z);
uint32 zoneId = sTerrainMgr.GetZoneId(MapId,x,y,z);
// Simulate std. algorithm:
// found some graveyard associated to (ghost_zone,ghost_map)

View file

@ -34,7 +34,6 @@
#include "Channel.h"
#include "ChannelMgr.h"
#include "MapManager.h"
#include "MapInstanced.h"
#include "InstanceSaveMgr.h"
#include "InstanceData.h"
#include "GridNotifiers.h"
@ -1444,7 +1443,7 @@ void Player::Update( uint32 p_time )
}
// not auto-free ghost from body in instances
if(m_deathTimer > 0 && !GetBaseMap()->Instanceable())
if(m_deathTimer > 0 && !GetMap()->Instanceable())
{
if(p_time >= m_deathTimer)
{
@ -2324,7 +2323,7 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameo
bool Player::IsUnderWater() const
{
return GetBaseMap()->IsUnderWater(GetPositionX(), GetPositionY(), GetPositionZ()+2);
return GetTerrain()->IsUnderWater(GetPositionX(), GetPositionY(), GetPositionZ()+2);
}
void Player::SetInWater(bool apply)
@ -6139,7 +6138,7 @@ void Player::CheckAreaExploreAndOutdoor()
return;
bool isOutdoor;
uint16 areaFlag = GetBaseMap()->GetAreaFlag(GetPositionX(),GetPositionY(),GetPositionZ(), &isOutdoor);
uint16 areaFlag = GetTerrain()->GetAreaFlag(GetPositionX(),GetPositionY(),GetPositionZ(), &isOutdoor);
if (isOutdoor)
{
@ -6665,7 +6664,7 @@ uint32 Player::GetZoneIdFromDB(ObjectGuid guid)
float posz = fields[3].GetFloat();
delete result;
zone = sMapMgr.GetZoneId(map,posx,posy,posz);
zone = sTerrainMgr.GetZoneId(map,posx,posy,posz);
if (zone > 0)
CharacterDatabase.PExecute("UPDATE characters SET zone='%u' WHERE guid='%u'", zone, lowguid);
@ -20845,7 +20844,7 @@ void Player::SetOriginalGroup(Group *group, int8 subgroup)
void Player::UpdateUnderwaterState( Map* m, float x, float y, float z )
{
GridMapLiquidData liquid_status;
GridMapLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
GridMapLiquidStatus res = m->GetTerrain()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
if (!res)
{
m_MirrorTimerFlags &= ~(UNDERWATER_INWATER|UNDERWATER_INLAVA|UNDERWATER_INSLIME|UNDERWATER_INDARKWATER);

View file

@ -368,7 +368,10 @@ void PoolGroup<Creature>::Spawn1Object(PoolObject* obj, bool instantly)
sObjectMgr.AddCreatureToGrid(obj->guid, data);
// Spawn if necessary (loaded grids only)
Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid));
Map* map = const_cast<Map*>(sMapMgr.FindMap(data->mapid));
if(!map)
return;
// We use spawn coords to spawn (avoid work for instances until implemented support)
if (!map->Instanceable() && map->IsLoaded(data->posX, data->posY))
{
@ -408,7 +411,10 @@ void PoolGroup<GameObject>::Spawn1Object(PoolObject* obj, bool instantly)
sObjectMgr.AddGameobjectToGrid(obj->guid, data);
// Spawn if necessary (loaded grids only)
// this base map checked as non-instanced and then only existing
Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid));
Map* map = const_cast<Map*>(sMapMgr.FindMap(data->mapid));
if(!map)
return;
// We use current coords to unspawn, not spawn coords since creature can have changed grid
// (avoid work for instances until implemented support)
if (!map->Instanceable() && map->IsLoaded(data->posX, data->posY))

View file

@ -296,7 +296,7 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/)
if (corpseMapEntry->IsDungeon() && corpseMapEntry->ghost_entrance_map >= 0)
{
// if corpse map have entrance
if (Map const* entranceMap = sMapMgr.CreateBaseMap(corpseMapEntry->ghost_entrance_map))
if(TerrainInfo const* entranceMap = sTerrainMgr.LoadTerrain(corpseMapEntry->ghost_entrance_map))
{
mapid = corpseMapEntry->ghost_entrance_map;
x = corpseMapEntry->ghost_entrance_x;

View file

@ -32,7 +32,7 @@ RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
creature.GetRespawnCoord(respX, respY, respZ, &respO, &wander_distance);
currZ = creature.GetPositionZ();
Map const* map = creature.GetBaseMap();
TerrainInfo const* map = creature.GetTerrain();
// For 2D/3D system selection
//bool is_land_ok = creature.CanWalk(); // not used?

View file

@ -4243,11 +4243,11 @@ SpellCastResult Spell::CheckCast(bool strict)
VMAP::VMapFactory::createOrGetVMapManager()->isLineOfSightCalcEnabled())
{
if (m_spellInfo->Attributes & SPELL_ATTR_OUTDOORS_ONLY &&
!m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
!m_caster->GetTerrain()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
return SPELL_FAILED_ONLY_OUTDOORS;
if(m_spellInfo->Attributes & SPELL_ATTR_INDOORS_ONLY &&
m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
m_caster->GetTerrain()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
return SPELL_FAILED_ONLY_INDOORS;
}
// only check at first call, Stealth auras are already removed at second call
@ -5130,7 +5130,7 @@ SpellCastResult Spell::CheckCast(bool strict)
float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation());
float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation());
// teleport a bit above terrain level to avoid falling below it
float fz = m_caster->GetBaseMap()->GetHeight(fx, fy, m_caster->GetPositionZ(), true);
float fz = m_caster->GetTerrain()->GetHeight(fx, fy, m_caster->GetPositionZ(), true);
if(fz <= INVALID_HEIGHT) // note: this also will prevent use effect in instances without vmaps height enabled
return SPELL_FAILED_TRY_AGAIN;

View file

@ -7819,7 +7819,7 @@ void Spell::EffectTransmitted(SpellEffectIndex eff_idx)
if(goinfo->type==GAMEOBJECT_TYPE_FISHINGNODE)
{
GridMapLiquidData liqData;
if ( !cMap->IsInWater(fx, fy, fz + 1.f/* -0.5f */, &liqData)) // Hack to prevent fishing bobber from failing to land on fishing hole
if ( !m_caster->GetTerrain()->IsInWater(fx, fy, fz + 1.f/* -0.5f */, &liqData)) // Hack to prevent fishing bobber from failing to land on fishing hole
{ // but this is not proper, we really need to ignore not materialized objects
SendCastResult(SPELL_FAILED_NOT_HERE);
SendChannelUpdate(0);
@ -8156,7 +8156,7 @@ void Spell::EffectBind(SpellEffectIndex eff_idx)
loc.coord_y = st->target_Y;
loc.coord_z = st->target_Y;
loc.orientation = st->target_Orientation;
area_id = sMapMgr.GetAreaId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z);
area_id = sTerrainMgr.GetAreaId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z);
}
else
{

View file

@ -1016,7 +1016,7 @@ void SpellMgr::LoadSpellTargetPositions()
// additional requirements
if (spellInfo->Effect[i]==SPELL_EFFECT_BIND && spellInfo->EffectMiscValue[i])
{
uint32 zone_id = sMapMgr.GetAreaId(st.target_mapId, st.target_X, st.target_Y, st.target_Z);
uint32 zone_id = sTerrainMgr.GetAreaId(st.target_mapId, st.target_X, st.target_Y, st.target_Z);
if (int32(zone_id) != spellInfo->EffectMiscValue[i])
{
sLog.outErrorDb("Spell (Id: %u) listed in `spell_target_position` expected point to zone %u bit point to zone %u.",Spell_ID, spellInfo->EffectMiscValue[i], zone_id);

View file

@ -91,6 +91,14 @@ void MapManager::LoadTransports()
uint32 mapid;
x = t->m_WayPoints[0].x; y = t->m_WayPoints[0].y; z = t->m_WayPoints[0].z; mapid = t->m_WayPoints[0].mapid; o = 1;
//current code does not support transports in dungeon!
const MapEntry* pMapInfo = sMapStore.LookupEntry(mapid);
if(!pMapInfo || pMapInfo->Instanceable())
{
delete t;
continue;
}
// creates the Gameobject
if (!t->Create(entry, mapid, x, y, z, o, GO_ANIMPROGRESS_DEFAULT, 0))
{

View file

@ -3712,12 +3712,12 @@ bool Unit::isInAccessablePlaceFor(Creature const* c) const
bool Unit::IsInWater() const
{
return GetBaseMap()->IsInWater(GetPositionX(),GetPositionY(), GetPositionZ());
return GetTerrain()->IsInWater(GetPositionX(),GetPositionY(), GetPositionZ());
}
bool Unit::IsUnderWater() const
{
return GetBaseMap()->IsUnderWater(GetPositionX(),GetPositionY(),GetPositionZ());
return GetTerrain()->IsUnderWater(GetPositionX(),GetPositionY(),GetPositionZ());
}
void Unit::DeMorph()

View file

@ -152,7 +152,7 @@ void WaypointManager::Load()
if (result1)
{
node.z = MapManager::Instance ().CreateBaseMap(result1->Fetch()[1].GetUInt32())->GetHeight(node.x, node.y, node.z);
node.z = sTerrainMgr.LoadTerrain(result1->Fetch()[1].GetUInt32())->GetHeight(node.x, node.y, node.z);
delete result1;
}

View file

@ -335,7 +335,7 @@ void FlightPathMovementGenerator::Finalize(Player & player)
player.clearUnitState(UNIT_STAT_TAXI_FLIGHT);
float x, y, z;
i_destinationHolder.GetLocationNow(player.GetBaseMap(), x, y, z);
i_destinationHolder.GetLocationNow(player.GetMap(), x, y, z);
player.SetPosition(x, y, z, player.GetOrientation());
player.Unmount();

View file

@ -1507,6 +1507,9 @@ void World::Update(uint32 diff)
// And last, but not least handle the issued cli commands
ProcessCliCommands();
//cleanup unused GridMap objects as well as VMaps
sTerrainMgr.Update(diff);
}
/// Send a packet to all players (except self if mentioned)

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10726"
#define REVISION_NR "10727"
#endif // __REVISION_NR_H__

View file

@ -426,7 +426,6 @@
<ClCompile Include="..\..\src\game\LootMgr.cpp" />
<ClCompile Include="..\..\src\game\Mail.cpp" />
<ClCompile Include="..\..\src\game\Map.cpp" />
<ClCompile Include="..\..\src\game\MapInstanced.cpp" />
<ClCompile Include="..\..\src\game\MapManager.cpp" />
<ClCompile Include="..\..\src\game\MiscHandler.cpp" />
<ClCompile Include="..\..\src\game\MotionMaster.cpp" />
@ -573,7 +572,6 @@
<ClInclude Include="..\..\src\game\LootMgr.h" />
<ClInclude Include="..\..\src\game\Mail.h" />
<ClInclude Include="..\..\src\game\Map.h" />
<ClInclude Include="..\..\src\game\MapInstanced.h" />
<ClInclude Include="..\..\src\game\MapManager.h" />
<ClInclude Include="..\..\src\game\MapReference.h" />
<ClInclude Include="..\..\src\game\MapRefManager.h" />

View file

@ -159,9 +159,6 @@
<ClCompile Include="..\..\src\game\Map.cpp">
<Filter>World/Handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\game\MapInstanced.cpp">
<Filter>World/Handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\game\MapManager.cpp">
<Filter>World/Handlers</Filter>
</ClCompile>
@ -552,9 +549,6 @@
<ClInclude Include="..\..\src\game\Map.h">
<Filter>World/Handlers</Filter>
</ClInclude>
<ClInclude Include="..\..\src\game\MapInstanced.h">
<Filter>World/Handlers</Filter>
</ClInclude>
<ClInclude Include="..\..\src\game\MapManager.h">
<Filter>World/Handlers</Filter>
</ClInclude>

View file

@ -100,6 +100,90 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
IntermediateDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP /bigobj /Zm200"
Optimization="0"
AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers"
PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;"
StringPooling="false"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
EnableFunctionLevelLinking="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="pchdef.h"
PrecompiledHeaderFile=".\game__$(PlatformName)_$(ConfigurationName)\game.pch"
AssemblerListingLocation=".\game__$(PlatformName)_$(ConfigurationName)\"
ObjectFile=".\game__$(PlatformName)_$(ConfigurationName)\"
ProgramDataBaseFileName=".\game__$(PlatformName)_$(ConfigurationName)\"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CompileAs="0"
ForcedIncludeFiles="pchdef.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib"
OutputFile=".\game__$(PlatformName)_$(ConfigurationName)\game.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
@ -182,170 +266,6 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug_NoPCH|Win32"
OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
IntermediateDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
Optimization="0"
AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers"
PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;"
StringPooling="false"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\game__$(PlatformName)_$(ConfigurationName)\game.pch"
AssemblerListingLocation=".\game__$(PlatformName)_$(ConfigurationName)\"
ObjectFile=".\game__$(PlatformName)_$(ConfigurationName)\"
ProgramDataBaseFileName=".\game__$(PlatformName)_$(ConfigurationName)\"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib"
OutputFile=".\game__$(PlatformName)_$(ConfigurationName)\game.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
IntermediateDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP /bigobj /Zm200"
Optimization="0"
AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers"
PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;"
StringPooling="false"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
EnableFunctionLevelLinking="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="pchdef.h"
PrecompiledHeaderFile=".\game__$(PlatformName)_$(ConfigurationName)\game.pch"
AssemblerListingLocation=".\game__$(PlatformName)_$(ConfigurationName)\"
ObjectFile=".\game__$(PlatformName)_$(ConfigurationName)\"
ProgramDataBaseFileName=".\game__$(PlatformName)_$(ConfigurationName)\"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CompileAs="0"
ForcedIncludeFiles="pchdef.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib"
OutputFile=".\game__$(PlatformName)_$(ConfigurationName)\game.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
@ -429,6 +349,86 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug_NoPCH|Win32"
OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
IntermediateDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
Optimization="0"
AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers"
PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;"
StringPooling="false"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\game__$(PlatformName)_$(ConfigurationName)\game.pch"
AssemblerListingLocation=".\game__$(PlatformName)_$(ConfigurationName)\"
ObjectFile=".\game__$(PlatformName)_$(ConfigurationName)\"
ProgramDataBaseFileName=".\game__$(PlatformName)_$(ConfigurationName)\"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib"
OutputFile=".\game__$(PlatformName)_$(ConfigurationName)\game.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug_NoPCH|x64"
OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)"
@ -565,14 +565,6 @@
RelativePath="..\..\src\game\BattleGroundAB.h"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundRB.cpp"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundRB.h"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundAV.cpp"
>
@ -633,6 +625,14 @@
RelativePath="..\..\src\game\BattleGroundNA.h"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundRB.cpp"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundRB.h"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundRL.cpp"
>
@ -841,14 +841,6 @@
RelativePath="..\..\src\game\Map.h"
>
</File>
<File
RelativePath="..\..\src\game\MapInstanced.cpp"
>
</File>
<File
RelativePath="..\..\src\game\MapInstanced.h"
>
</File>
<File
RelativePath="..\..\src\game\MapManager.cpp"
>
@ -965,10 +957,6 @@
RelativePath="..\..\src\game\SpellAuras.h"
>
</File>
<File
RelativePath="..\..\src\game\UnitAuraProcHandler.cpp"
>
</File>
<File
RelativePath="..\..\src\game\SpellEffects.cpp"
>
@ -993,6 +981,10 @@
RelativePath="..\..\src\game\Transports.h"
>
</File>
<File
RelativePath="..\..\src\game\UnitAuraProcHandler.cpp"
>
</File>
<File
RelativePath="..\..\src\game\UpdateData.cpp"
>
@ -1639,7 +1631,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
@ -1648,7 +1640,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Version="8,00"
Name="mangosd"
ProjectGUID="{A3A04E47-43A2-4C08-90B3-029CEF558594}"
RootNamespace="mangosd"

View file

@ -834,14 +834,6 @@
RelativePath="..\..\src\game\Map.h"
>
</File>
<File
RelativePath="..\..\src\game\MapInstanced.cpp"
>
</File>
<File
RelativePath="..\..\src\game\MapInstanced.h"
>
</File>
<File
RelativePath="..\..\src\game\MapManager.cpp"
>
@ -958,10 +950,6 @@
RelativePath="..\..\src\game\SpellAuras.h"
>
</File>
<File
RelativePath="..\..\src\game\UnitAuraProcHandler.cpp"
>
</File>
<File
RelativePath="..\..\src\game\SpellEffects.cpp"
>
@ -986,6 +974,10 @@
RelativePath="..\..\src\game\Transports.h"
>
</File>
<File
RelativePath="..\..\src\game\UnitAuraProcHandler.cpp"
>
</File>
<File
RelativePath="..\..\src\game\UpdateData.cpp"
>