Skip to content

Commit

Permalink
Map/Vmap: Fix liquid level query not going through on maps without te…
Browse files Browse the repository at this point in the history
…rrain but with vmap
  • Loading branch information
killerwife committed May 30, 2022
1 parent b3e22cc commit 4ff7417
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 22 deletions.
60 changes: 38 additions & 22 deletions src/game/Maps/GridMap.cpp
Expand Up @@ -718,6 +718,7 @@ TerrainInfo::TerrainInfo(uint32 mapid) : m_mapId(mapid)
{
m_GridMaps[i][k] = nullptr;
m_GridRef[i][k] = 0;
m_GridMapsLoadAttempted[i][k] = false;
}
}

Expand All @@ -728,6 +729,8 @@ TerrainInfo::TerrainInfo(uint32 mapid) : m_mapId(mapid)

i_timer.SetInterval(iCleanUpInterval * 1000);
i_timer.SetCurrent(iRandomStart * 1000);

m_vmgr = VMAP::VMapFactory::createOrGetVMapManager();
}

TerrainInfo::~TerrainInfo()
Expand All @@ -736,7 +739,7 @@ TerrainInfo::~TerrainInfo()
for (auto& m_GridMap : m_GridMaps)
delete m_GridMap[k];

VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(m_mapId);
m_vmgr->unloadMap(m_mapId);
MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(m_mapId);
}

Expand All @@ -751,7 +754,10 @@ GridMap* TerrainInfo::Load(const uint32 x, const uint32 y, bool mapOnly /*= fals
// quick check if GridMap already loaded
GridMap* pMap = m_GridMaps[x][y];
if (!pMap)
{
pMap = LoadMapAndVMap(x, y, mapOnly);
m_GridMapsLoadAttempted[x][y] = true;
}

return pMap;
}
Expand Down Expand Up @@ -795,7 +801,7 @@ void TerrainInfo::CleanUpGrids(const uint32 diff)
delete pMap;

// unload VMAPS...
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(m_mapId, x, y);
m_vmgr->unloadMap(m_mapId, x, y);

// unload mmap... - not possible like this - mmaps are per-map
// MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(m_mapId, x, y);
Expand All @@ -806,6 +812,14 @@ void TerrainInfo::CleanUpGrids(const uint32 diff)
i_timer.Reset();
}

bool TerrainInfo::CanCheckLiquidLevel(float x, float y) const
{
if (m_vmgr->isHeightCalcEnabled())
return true;

return const_cast<TerrainInfo*>(this)->GetGrid(x, y);
}

int TerrainInfo::RefGrid(const uint32& x, const uint32& y)
{
MANGOS_ASSERT(x < MAX_NUMBER_OF_GRIDS);
Expand Down Expand Up @@ -840,8 +854,7 @@ float TerrainInfo::GetHeightStatic(float x, float y, float z, bool useVmaps/*=tr

if (useVmaps)
{
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
if (vmgr->isHeightCalcEnabled())
if (m_vmgr->isHeightCalcEnabled())
{
float z2 = z + 2.0f;

Expand All @@ -852,19 +865,19 @@ float TerrainInfo::GetHeightStatic(float x, float y, float z, bool useVmaps/*=tr
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);
vmapHeight = m_vmgr->getHeight(GetMapId(), x, y, z2, maxSearchDist);

// if not found in expected range, look for infinity range (case of far above floor, but below terrain-height)
if (vmapHeight <= INVALID_HEIGHT)
vmapHeight = vmgr->getHeight(GetMapId(), x, y, z2, 10000.0f);
vmapHeight = m_vmgr->getHeight(GetMapId(), x, y, z2, 10000.0f);

// look upwards
if (vmapHeight <= INVALID_HEIGHT && mapHeight > z2 && std::abs(z2 - mapHeight) > 30.f)
vmapHeight = vmgr->getHeight(GetMapId(), x, y, z2, -maxSearchDist);
vmapHeight = m_vmgr->getHeight(GetMapId(), x, y, z2, -maxSearchDist);

// still not found, look near terrain height
if (vmapHeight <= INVALID_HEIGHT && mapHeight > INVALID_HEIGHT && z2 < mapHeight)
vmapHeight = vmgr->getHeight(GetMapId(), x, y, mapHeight + 2.0f, DEFAULT_HEIGHT_SEARCH);
vmapHeight = m_vmgr->getHeight(GetMapId(), x, y, mapHeight + 2.0f, DEFAULT_HEIGHT_SEARCH);
}
}

Expand Down Expand Up @@ -943,8 +956,7 @@ bool TerrainInfo::IsOutdoors(float x, float y, float z) const
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))
if (m_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))
Expand Down Expand Up @@ -1031,12 +1043,11 @@ void TerrainInfo::GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, floa
GridMapLiquidStatus TerrainInfo::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData* data, float collisionHeight) const
{
GridMapLiquidStatus result = LIQUID_MAP_NO_WATER;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
uint32 liquid_type = 0;
float liquid_level = INVALID_HEIGHT_VALUE;
float ground_level = GetHeightStatic(x, y, z, true, DEFAULT_WATER_SEARCH);

if (vmgr->GetLiquidLevel(GetMapId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type))
if (m_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
Expand Down Expand Up @@ -1116,7 +1127,7 @@ GridMapLiquidStatus TerrainInfo::getLiquidStatus(float x, float y, float z, uint
bool TerrainInfo::IsInWater(float x, float y, float z, GridMapLiquidData* data, float min_depth /*=2.0f*/) const
{
// Check surface in x, y point for liquid
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
if (CanCheckLiquidLevel(x, y))
{
GridMapLiquidData liquid_status;
GridMapLiquidData* liquid_ptr = data ? data : &liquid_status;
Expand Down Expand Up @@ -1144,7 +1155,7 @@ bool TerrainInfo::IsInWater(float x, float y, float z, GridMapLiquidData* data,
bool TerrainInfo::IsSwimmable(float x, float y, float z, float radius /*= 1.5f*/, GridMapLiquidData* data /*=nullptr*/) const
{
// Check surface in x, y point for liquid
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
if (CanCheckLiquidLevel(x, y))
{
GridMapLiquidData liquid_status;
GridMapLiquidData* liquid_ptr = data ? data : &liquid_status;
Expand All @@ -1159,7 +1170,7 @@ bool TerrainInfo::IsSwimmable(float x, float y, float z, float radius /*= 1.5f*/

bool TerrainInfo::IsAboveWater(float x, float y, float z, float* pWaterZ/*= nullptr*/) const
{
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
if (CanCheckLiquidLevel(x, y))
{
GridMapLiquidData mapData;

Expand All @@ -1176,7 +1187,7 @@ bool TerrainInfo::IsAboveWater(float x, float y, float z, float* pWaterZ/*= null

bool TerrainInfo::IsUnderWater(float x, float y, float z, float* pWaterZ/*= nullptr*/) const
{
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
if (CanCheckLiquidLevel(x, y))
{
GridMapLiquidData mapData;

Expand Down Expand Up @@ -1207,7 +1218,7 @@ bool TerrainInfo::IsUnderWater(float x, float y, float z, float* pWaterZ/*= null
*/
float TerrainInfo::GetWaterOrGroundLevel(float x, float y, float z, float& groundZ, bool swim /*= false*/, float minWaterDeep /*= DEFAULT_COLLISION_HEIGHT*/) const
{
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
if (CanCheckLiquidLevel(x, y))
{
GridMapLiquidData liquid_status;

Expand Down Expand Up @@ -1241,15 +1252,20 @@ GridMap* TerrainInfo::GetGrid(const float x, const float y, bool loadOnlyMap /*=

// quick check if GridMap already loaded
GridMap* pMap = m_GridMaps[gx][gy];
if (!pMap || (!pMap->IsFullyLoaded() && !loadOnlyMap))
if (!pMap && m_GridMapsLoadAttempted[gx][gy] == true)
return pMap;
else if (!pMap || (!pMap->IsFullyLoaded() && !loadOnlyMap))
{
pMap = LoadMapAndVMap(gx, gy, loadOnlyMap);
m_GridMapsLoadAttempted[gx][gy] = true;
}

return pMap;
}

GridMap* TerrainInfo::LoadMapAndVMap(const uint32 x, const uint32 y, bool mapOnly /*= false*/)
{
if ((m_GridMaps[x][y] && mapOnly) || VMAP::VMapFactory::createOrGetVMapManager()->IsTileLoaded(m_mapId, x, y))
if ((m_GridMaps[x][y] && mapOnly) || m_vmgr->IsTileLoaded(m_mapId, x, y))
{
// nothing to load here
return m_GridMaps[x][y];
Expand Down Expand Up @@ -1283,13 +1299,13 @@ GridMap* TerrainInfo::LoadMapAndVMap(const uint32 x, const uint32 y, bool mapOnl
if (mapOnly)
return m_GridMaps[x][y];

if (!VMAP::VMapFactory::createOrGetVMapManager()->IsTileLoaded(m_mapId, x, y))
if (!m_vmgr->IsTileLoaded(m_mapId, x, y))
{
// 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);
int vmapLoadResult = m_vmgr->loadMap((sWorld.GetDataPath() + "vmaps").c_str(), m_mapId, x, y);
switch (vmapLoadResult)
{
case VMAP::VMAP_LOAD_RESULT_OK:
Expand All @@ -1312,7 +1328,7 @@ GridMap* TerrainInfo::LoadMapAndVMap(const uint32 x, const uint32 y, bool mapOnl

float TerrainInfo::GetWaterLevel(float x, float y, float z, float* pGround /*= nullptr*/) const
{
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
if (CanCheckLiquidLevel(x, y))
{
// we need ground level (including grid height version) for proper return water level in point
float ground_z = GetHeightStatic(x, y, z, true, DEFAULT_WATER_SEARCH);
Expand Down
10 changes: 10 additions & 0 deletions src/game/Maps/GridMap.h
Expand Up @@ -37,6 +37,11 @@ class Group;
class BattleGround;
class Map;

namespace VMAP
{
class IVMapManager;
};

class GridMap
{
private:
Expand Down Expand Up @@ -167,6 +172,8 @@ class TerrainInfo : public Referencable<std::atomic_long>
// THIS METHOD IS NOT THREAD-SAFE!!!! AND IT SHOULDN'T BE THREAD-SAFE!!!!
void CleanUpGrids(const uint32 diff);

bool CanCheckLiquidLevel(float x, float y) const;

protected:
friend class Map;
friend class ObjectMgr;
Expand All @@ -187,11 +194,14 @@ class TerrainInfo : public Referencable<std::atomic_long>
const uint32 m_mapId;

GridMap* m_GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
bool m_GridMapsLoadAttempted[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;

VMAP::IVMapManager* m_vmgr;

typedef std::mutex LOCK_TYPE;
typedef std::lock_guard<LOCK_TYPE> LOCK_GUARD;
LOCK_TYPE m_mutex;
Expand Down

0 comments on commit 4ff7417

Please sign in to comment.