Core/Maps: Fixed child/parent map crash

This commit is contained in:
Ovahlord
2018-03-30 00:08:53 +02:00
parent 98a7ccfab5
commit 2efc91a839
2 changed files with 32 additions and 21 deletions

View File

@@ -176,7 +176,7 @@ void Map::LoadMap(int gx, int gy, bool reload)
{
LoadMapImpl(this, gx, gy, reload);
for (Map* childBaseMap : *m_childTerrainMaps)
LoadMapImpl(childBaseMap, gx, gy, reload);
childBaseMap->LoadMap(gx, gy, reload);
}
void Map::LoadMapImpl(Map* map, int gx, int gy, bool reload)
@@ -187,10 +187,11 @@ void Map::LoadMapImpl(Map* map, int gx, int gy, bool reload)
return;
// load grid map for base map
if (!map->m_parentMap->GridMaps[gx][gy])
map->m_parentMap->EnsureGridCreated(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - gx, (MAX_NUMBER_OF_GRIDS - 1) - gy));
GridCoord ngridCoord = GridCoord((MAX_NUMBER_OF_GRIDS - 1) - gx, (MAX_NUMBER_OF_GRIDS - 1) - gy);
if (!map->m_parentMap->getNGrid(ngridCoord.x_coord, ngridCoord.y_coord))
map->m_parentMap->EnsureGridCreated(ngridCoord);
map->m_parentMap->ToMapInstanced()->AddGridMapReference(GridCoord(gx, gy));
static_cast<MapInstanced*>(map->m_parentMap)->AddGridMapReference(GridCoord(gx, gy));
map->GridMaps[gx][gy] = map->m_parentMap->GridMaps[gx][gy];
return;
}
@@ -219,7 +220,15 @@ void Map::LoadMapImpl(Map* map, int gx, int gy, bool reload)
sScriptMgr->OnLoadGridMap(map, map->GridMaps[gx][gy], gx, gy);
}
void Map::UnloadMap(Map* map, int gx, int gy)
void Map::UnloadMap(int gx, int gy)
{
for (Map* childBaseMap : *m_childTerrainMaps)
childBaseMap->UnloadMap(gx, gy);
UnloadMapImpl(this, gx, gy);
}
void Map::UnloadMapImpl(Map* map, int gx, int gy)
{
if (map->i_InstanceId == 0)
{
@@ -237,8 +246,8 @@ void Map::UnloadMap(Map* map, int gx, int gy)
void Map::LoadMapAndVMap(int gx, int gy)
{
LoadMap(gx, gy);
// Only load the data for the base map
m_parentTerrainMap->LoadMap(gx, gy);
// Only load the data for the base map
if (i_InstanceId == 0)
{
LoadVMap(gx, gy);
@@ -281,11 +290,13 @@ i_scriptLock(false), _defaultLight(GetDefaultMapLight(id))
if (_parent)
{
m_parentMap = _parent;
m_parentTerrainMap = m_parentMap->m_parentTerrainMap;
m_childTerrainMaps = m_parentMap->m_childTerrainMaps;
}
else
{
m_parentMap = this;
m_parentTerrainMap = this;
m_childTerrainMaps = new std::vector<Map*>();
}
@@ -1648,10 +1659,8 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll)
// 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
{
for (Map* childBaseMap : *m_childTerrainMaps)
UnloadMap(childBaseMap, gx, gy);
UnloadMap(this, gx, gy);
if (m_parentTerrainMap == this)
m_parentTerrainMap->UnloadMap(gx, gy);
if (i_InstanceId == 0)
{
@@ -2348,7 +2357,7 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float
// find raw .map surface under Z coordinates
float mapHeight = VMAP_INVALID_HEIGHT_VALUE;
uint32 terrainMapId = PhasingHandler::GetTerrainMapId(phaseShift, this, x, y);
if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(terrainMapId, x, y))
if (GridMap* gmap = m_parentTerrainMap->GetGrid(terrainMapId, x, y))
{
float gridHeight = gmap->getHeight(x, y);
// look from a bit higher pos to find the floor, ignore under surface case
@@ -2437,7 +2446,7 @@ bool Map::GetAreaInfo(PhaseShift const& phaseShift, float x, float y, float z, u
if (vmgr->getAreaInfo(terrainMapId, 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(terrainMapId, x, y))
if (GridMap* gmap = m_parentTerrainMap->GetGrid(terrainMapId, x, y))
{
float _mapheight = gmap->getHeight(x, y);
// z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice...
@@ -2473,7 +2482,7 @@ uint32 Map::GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, b
if (!areaId)
{
if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y))
if (GridMap* gmap = m_parentTerrainMap->GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y))
areaId = gmap->getArea(x, y);
// this used while not all *.map files generated (instances)
@@ -2516,7 +2525,7 @@ void Map::GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32&
uint8 Map::GetTerrainType(PhaseShift const& phaseShift, float x, float y) const
{
if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y))
if (GridMap* gmap = m_parentTerrainMap->GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y))
return gmap->getTerrainType(x, y);
else
return 0;
@@ -2587,7 +2596,7 @@ ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float
}
}
if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(terrainMapId, x, y))
if (GridMap* gmap = m_parentTerrainMap->GetGrid(terrainMapId, x, y))
{
LiquidData map_data;
ZLiquidStatus map_result = gmap->GetLiquidStatus(x, y, z, ReqLiquidType, &map_data);
@@ -2610,7 +2619,7 @@ ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float
float Map::GetWaterLevel(PhaseShift const& phaseShift, float x, float y) const
{
if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y))
if (GridMap* gmap = m_parentTerrainMap->GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y))
return gmap->getLiquidLevel(x, y);
else
return 0;

View File

@@ -327,7 +327,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
static void DeleteStateMachine();
Map const* GetParent() const { return m_parentMap; }
void AddChildTerrainMap(Map* map) { m_childTerrainMaps->push_back(map); }
void AddChildTerrainMap(Map* map) { m_childTerrainMaps->push_back(map); map->m_parentTerrainMap = this; }
void UnlinkAllChildTerrainMaps() { m_childTerrainMaps->clear(); }
// some calls like isInWater should not use vmaps due to processor power
@@ -575,7 +575,8 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
void LoadVMap(int gx, int gy);
void LoadMap(int gx, int gy, bool reload = false);
static void LoadMapImpl(Map* map, int gx, int gy, bool reload);
static void UnloadMap(Map* map, int gx, int gy);
void UnloadMap(int gx, int gy);
static void UnloadMapImpl(Map* map, int gx, int gy);
void LoadMMap(int gx, int gy);
GridMap* GetGrid(float x, float y);
GridMap* GetGrid(uint32 mapId, float x, float y);
@@ -668,8 +669,9 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
//used for fast base_map (e.g. MapInstanced class object) search for
//InstanceMaps and BattlegroundMaps...
Map* m_parentMap;
std::vector<Map*>* m_childTerrainMaps;
Map* m_parentMap; // points to MapInstanced* or self (always same map id)
Map* m_parentTerrainMap; // points to m_parentMap of MapEntry::ParentMapID
std::vector<Map*>* m_childTerrainMaps; // contains m_parentMap of maps that have MapEntry::ParentMapID == GetId()
NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
GridMap* GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];