summaryrefslogtreecommitdiff
path: root/src/server/game/Grids/GridTerrainLoader.cpp
blob: ecf9b09415cad85cd052e54025a41fbdea0a671f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "DisableMgr.h"
#include "GridTerrainLoader.h"
#include "MMapFactory.h"
#include "MMapMgr.h"
#include "ScriptMgr.h"
#include "VMapFactory.h"
#include "VMapMgr2.h"

void GridTerrainLoader::LoadTerrain()
{
    LoadMap();
    if (_map->GetInstanceId() == 0)
    {
        LoadVMap();
        LoadMMap();
    }
}

void GridTerrainLoader::LoadMap()
{
    // Instances will point to the parent maps terrain data
    if (_map->GetInstanceId() != 0)
    {
        // load grid map for base map
        Map* parentMap = const_cast<Map*>(_map->GetParent());

        // GetGridTerrainData will create the parent map grid
        _grid.SetTerrainData(parentMap->GetGridTerrainDataSharedPtr(GridCoord(_grid.GetX(), _grid.GetY())));
        return;
    }

    // map file name
    std::string const mapFileName = Acore::StringFormat("{}maps/{:03}{:02}{:02}.map", sWorld->GetDataPath(), _map->GetId(), _grid.GetX(), _grid.GetY());

    // loading data
    LOG_DEBUG("maps", "Loading map {}", mapFileName);
    std::unique_ptr<GridTerrainData> terrainData = std::make_unique<GridTerrainData>();
    TerrainMapDataReadResult loadResult = terrainData->Load(mapFileName);
    if (loadResult == TerrainMapDataReadResult::Success)
        _grid.SetTerrainData(std::move(terrainData));
    else
    {
        if (loadResult == TerrainMapDataReadResult::InvalidMagic)
            LOG_ERROR("maps", "Map file '{}' is from an incompatible clientversion. Please recreate using the mapextractor.", mapFileName);
        else
            LOG_DEBUG("maps", "Error (result: {}) loading map file: {}", uint32(loadResult), mapFileName);
    }

    sScriptMgr->OnLoadGridMap(_map, _grid.GetTerrainData(), _grid.GetX(), _grid.GetY());
}

void GridTerrainLoader::LoadVMap()
{
    int vmapLoadResult = VMAP::VMapFactory::createOrGetVMapMgr()->loadMap((sWorld->GetDataPath() + "vmaps").c_str(), _map->GetId(), _grid.GetX(), _grid.GetY());
    switch (vmapLoadResult)
    {
    case VMAP::VMAP_LOAD_RESULT_OK:
        LOG_DEBUG("maps", "VMAP loaded name:{}, id:{}, x:{}, y:{} (vmap rep.: x:{}, y:{})",
            _map->GetMapName(), _map->GetId(), _grid.GetX(), _grid.GetY(), _grid.GetX(), _grid.GetY());
        break;
    case VMAP::VMAP_LOAD_RESULT_ERROR:
        LOG_DEBUG("maps", "Could not load VMAP name:{}, id:{}, x:{}, y:{} (vmap rep.: x:{}, y:{})",
            _map->GetMapName(), _map->GetId(), _grid.GetX(), _grid.GetY(), _grid.GetX(), _grid.GetY());
        break;
    case VMAP::VMAP_LOAD_RESULT_IGNORED:
        LOG_DEBUG("maps", "Ignored VMAP name:{}, id:{}, x:{}, y:{} (vmap rep.: x:{}, y:{})",
            _map->GetMapName(), _map->GetId(), _grid.GetX(), _grid.GetY(), _grid.GetX(), _grid.GetY());
        break;
    }
}

void GridTerrainLoader::LoadMMap()
{
    if (!DisableMgr::IsPathfindingEnabled(_map))
        return;

    int mmapLoadResult = MMAP::MMapFactory::createOrGetMMapMgr()->loadMap(_map->GetId(), _grid.GetX(), _grid.GetY());
    switch (mmapLoadResult)
    {
    case MMAP::MMAP_LOAD_RESULT_OK:
        LOG_DEBUG("maps", "MMAP loaded name:{}, id:{}, x:{}, y:{} (vmap rep.: x:{}, y:{})",
            _map->GetMapName(), _map->GetId(), _grid.GetX(), _grid.GetY(), _grid.GetX(), _grid.GetY());
        break;
    case MMAP::MMAP_LOAD_RESULT_ERROR:
        LOG_DEBUG("maps", "Could not load MMAP name:{}, id:{}, x:{}, y:{} (vmap rep.: x:{}, y:{})",
            _map->GetMapName(), _map->GetId(), _grid.GetX(), _grid.GetY(), _grid.GetX(), _grid.GetY());
        break;
    case MMAP::MMAP_LOAD_RESULT_IGNORED:
        LOG_DEBUG("maps", "Ignored MMAP name:{}, id:{}, x:{}, y:{} (vmap rep.: x:{}, y:{})",
            _map->GetMapName(), _map->GetId(), _grid.GetX(), _grid.GetY(), _grid.GetX(), _grid.GetY());
        break;
    }
}

bool GridTerrainLoader::ExistMap(uint32 mapid, int gx, int gy)
{
    std::string const mapFileName = Acore::StringFormat("{}maps/{:03}{:02}{:02}.map", sWorld->GetDataPath(), mapid, gx, gy);
    std::ifstream fileStream(mapFileName, std::ios::binary);
    if (fileStream.fail())
    {
        LOG_DEBUG("maps", "Map file '{}': error opening file", mapFileName);
        return false;
    }

    map_fileheader header;
    if (!fileStream.read(reinterpret_cast<char*>(&header), sizeof(header)))
    {
        LOG_DEBUG("maps", "Map file '{}': unable to read header", mapFileName);
        return false;
    }

    if (header.mapMagic != MapMagic.asUInt || header.versionMagic != MapVersionMagic)
    {
        LOG_ERROR("maps", "Map file '{}' is from an incompatible map version ({:.4u} v{}), {:.4s} v{} is expected. Please pull your source, recompile tools and recreate maps using the updated mapextractor, then replace your old map files with new files.",
            mapFileName, 4, header.mapMagic, header.versionMagic, 4, MapMagic.asChar, MapVersionMagic);
        return false;
    }

    return true;
}

bool GridTerrainLoader::ExistVMap(uint32 mapid, int gx, int gy)
{
    if (VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr())
    {
        if (vmgr->isMapLoadingEnabled())
        {
            VMAP::LoadResult result = vmgr->existsMap((sWorld->GetDataPath() + "vmaps").c_str(), mapid, gx, gy);
            std::string name = vmgr->getDirFileName(mapid, gx, gy);
            switch (result)
            {
            case VMAP::LoadResult::Success:
                break;
            case VMAP::LoadResult::FileNotFound:
                LOG_DEBUG("maps", "VMap file '{}' does not exist", (sWorld->GetDataPath() + "vmaps/" + name));
                LOG_DEBUG("maps", "Please place VMAP files (*.vmtree and *.vmtile) in the vmap directory ({}), or correct the DataDir setting in your worldserver.conf file.", (sWorld->GetDataPath() + "vmaps/"));
                return false;
            case VMAP::LoadResult::VersionMismatch:
                LOG_ERROR("maps", "VMap file '{}' couldn't be loaded", (sWorld->GetDataPath() + "vmaps/" + name));
                LOG_ERROR("maps", "This is because the version of the VMap file and the version of this module are different, please re-extract the maps with the tools compiled with this module.");
                return false;
            }
        }
    }

    return true;
}

void GridTerrainUnloader::UnloadTerrain()
{
    // Only parent maps manage terrain data
    if (_map->GetInstanceId() != 0)
        return;

    VMAP::VMapFactory::createOrGetVMapMgr()->unloadMap(_map->GetId(), _grid.GetX(), _grid.GetY());
    MMAP::MMapFactory::createOrGetMMapMgr()->unloadMap(_map->GetId(), _grid.GetX(), _grid.GetY());
}