예제 #1
0
        public Detour.dtNavMeshQuery GetNavMeshQuery(uint mapId, uint instanceId, List <uint> swaps)
        {
            MMapData mmap = GetMMapData(mapId);

            if (mmap == null)
            {
                return(null);
            }

            if (!mmap.navMeshQueries.ContainsKey(instanceId))
            {
                // allocate mesh query
                Detour.dtNavMeshQuery query = new Detour.dtNavMeshQuery();
                if (Detour.dtStatusFailed(query.init(mmap.GetNavMesh(swaps), 1024)))
                {
                    Log.outError(LogFilter.Maps, "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId {0} instanceId {1}", mapId, instanceId);
                    return(null);
                }

                Log.outInfo(LogFilter.Maps, "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId {0} instanceId {1}", mapId, instanceId);
                mmap.navMeshQueries.Add(instanceId, query);
            }

            return(mmap.navMeshQueries[instanceId]);
        }
예제 #2
0
        public bool unloadMap(uint mapId)
        {
            if (!loadedMMaps.ContainsKey(mapId))
            {
                // file may not exist, therefore not loaded
                Log.outDebug(LogFilter.Maps, "MMAP:unloadMap: Asked to unload not loaded navmesh map {0:D4}", mapId);
                return(false);
            }

            // unload all tiles from given map
            MMapData mmap = loadedMMaps.LookupByKey(mapId);

            foreach (var i in mmap.loadedTileRefs)
            {
                uint x = (i.Key >> 16);
                uint y = (i.Key & 0x0000FFFF);
                Detour.dtRawTileData data;
                if (Detour.dtStatusFailed(mmap.navMesh.removeTile(i.Value, out data)))
                {
                    Log.outError(LogFilter.Maps, "MMAP:unloadMap: Could not unload {0:D4}{1:D2}{2:D2}.mmtile from navmesh", mapId, x, y);
                }
                else
                {
                    --loadedTiles;
                    Log.outInfo(LogFilter.Maps, "MMAP:unloadMap: Unloaded mmtile {0:D4} [{1:D2}, {2:D2}] from {3:D4}", mapId, x, y, mapId);
                }
            }

            loadedMMaps.Remove(mapId);
            Log.outInfo(LogFilter.Maps, "MMAP:unloadMap: Unloaded {0:D4}.mmap", mapId);

            return(true);
        }
예제 #3
0
        bool loadMapInstanceImpl(string basePath, uint mapId, uint instanceId)
        {
            if (!loadMapData(basePath, mapId))
            {
                return(false);
            }

            MMapData mmap = loadedMMaps[mapId];

            if (mmap.navMeshQueries.ContainsKey(instanceId))
            {
                return(true);
            }

            // allocate mesh query
            Detour.dtNavMeshQuery query = new Detour.dtNavMeshQuery();
            if (Detour.dtStatusFailed(query.init(mmap.navMesh, 1024)))
            {
                Log.outError(LogFilter.Maps, "MMAP.GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId {0:D4} instanceId {1}", mapId, instanceId);
                return(false);
            }

            Log.outDebug(LogFilter.Maps, "MMAP.GetNavMeshQuery: created dtNavMeshQuery for mapId {0:D4} instanceId {1}", mapId, instanceId);
            mmap.navMeshQueries.Add(instanceId, query);
            return(true);
        }
예제 #4
0
        public Detour.dtNavMesh GetNavMesh(uint mapId, List <uint> swaps)
        {
            MMapData mmap = GetMMapData(mapId);

            if (mmap == null)
            {
                return(null);
            }

            return(mmap.GetNavMesh(swaps));
        }
예제 #5
0
        public Detour.dtNavMeshQuery GetNavMeshQuery(uint mapId, uint instanceId)
        {
            MMapData mmap = GetMMapData(mapId);

            if (mmap == null)
            {
                return(null);
            }

            return(mmap.navMeshQueries[instanceId]);
        }
예제 #6
0
        public Detour.dtNavMesh GetNavMesh(uint mapId)
        {
            MMapData mmap = GetMMapData(mapId);

            if (mmap == null)
            {
                return(null);
            }

            return(mmap.navMesh);
        }
예제 #7
0
        public bool unloadMap(uint mapId, uint x, uint y)
        {
            // check if we have this map loaded
            MMapData mmap = GetMMapData(mapId);

            if (mmap == null)
            {
                // file may not exist, therefore not loaded
                Log.outDebug(LogFilter.Maps, "MMAP:unloadMap: Asked to unload not loaded navmesh map. {0:D4}{1:D2}{2:D2}.mmtile", mapId, x, y);
                return(false);
            }

            // check if we have this tile loaded
            uint packedGridPos = packTileID((int)x, (int)y);

            if (!mmap.loadedTileRefs.ContainsKey(packedGridPos))
            {
                // file may not exist, therefore not loaded
                Log.outDebug(LogFilter.Maps, "MMAP:unloadMap: Asked to unload not loaded navmesh tile. {0:D4}{1:D2}{2:D2}.mmtile", mapId, x, y);
                return(false);
            }

            ulong tileRef = mmap.loadedTileRefs.LookupByKey(packedGridPos);

            // unload, and mark as non loaded
            Detour.dtRawTileData data;
            if (Detour.dtStatusFailed(mmap.navMesh.removeTile(tileRef, out data)))
            {
                // this is technically a memory leak
                // if the grid is later reloaded, dtNavMesh.addTile will return error but no extra memory is used
                // we cannot recover from this error - assert out
                Log.outError(LogFilter.Maps, "MMAP:unloadMap: Could not unload {0:D4}{1:D2}{2:D2}.mmtile from navmesh", mapId, x, y);
                Contract.Assert(false);
            }
            else
            {
                mmap.loadedTileRefs.Remove(packedGridPos);
                --loadedTiles;
                Log.outInfo(LogFilter.Maps, "MMAP:unloadMap: Unloaded mmtile {0:D4}[{1:D2}, {2:D2}] from {3:D4}", mapId, x, y, mapId);

                var phasedMaps = phaseMapData.LookupByKey(mapId);
                if (!phasedMaps.Empty())
                {
                    mmap.DeleteBaseTile(packedGridPos);
                    UnloadPhaseTile(phasedMaps, (int)x, (int)y);
                }
                return(true);
            }

            return(false);
        }
예제 #8
0
        bool loadMapData(uint mapId)
        {
            // we already have this map loaded?
            if (loadedMMaps.ContainsKey(mapId) && loadedMMaps[mapId] != null)
            {
                return(true);
            }

            // load and init dtNavMesh - read parameters from file
            string filename = string.Format(MAP_FILE_NAME_FORMAT, Global.WorldMgr.GetDataPath(), mapId);

            if (!File.Exists(filename))
            {
                Log.outError(LogFilter.Maps, "Could not open mmap file {0}", filename);
                return(false);
            }

            using (BinaryReader reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read), Encoding.UTF8))
            {
                Detour.dtNavMeshParams Params = new Detour.dtNavMeshParams();
                Params.orig[0] = reader.ReadSingle();
                Params.orig[1] = reader.ReadSingle();
                Params.orig[2] = reader.ReadSingle();

                Params.tileWidth  = reader.ReadSingle();
                Params.tileHeight = reader.ReadSingle();
                Params.maxTiles   = reader.ReadInt32();
                Params.maxPolys   = reader.ReadInt32();

                Detour.dtNavMesh mesh = new Detour.dtNavMesh();
                if (Detour.dtStatusFailed(mesh.init(Params)))
                {
                    Log.outError(LogFilter.Maps, "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap {0:D4} from file {1}", mapId, filename);
                    return(false);
                }

                Log.outInfo(LogFilter.Maps, "MMAP:loadMapData: Loaded {0:D4}.mmap", mapId);

                // store inside our map list
                loadedMMaps[mapId] = new MMapData(mesh, mapId);
                return(true);
            }
        }
예제 #9
0
        public bool unloadMapInstance(uint mapId, uint instanceId)
        {
            // check if we have this map loaded
            MMapData mmap = GetMMapData(mapId);

            if (mmap == null)
            {
                // file may not exist, therefore not loaded
                Log.outDebug(LogFilter.Maps, "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map {0}", mapId);
                return(false);
            }

            if (!mmap.navMeshQueries.ContainsKey(instanceId))
            {
                Log.outDebug(LogFilter.Maps, "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId {0} instanceId {1}", mapId, instanceId);
                return(false);
            }

            mmap.navMeshQueries.Remove(instanceId);
            Log.outInfo(LogFilter.Maps, "MMAP:unloadMapInstance: Unloaded mapId {0} instanceId {1}", mapId, instanceId);

            return(true);
        }
예제 #10
0
        public bool loadMap(uint mapId, int x, int y)
        {
            // make sure the mmap is loaded and ready to load tiles
            if (!loadMapData(mapId))
            {
                return(false);
            }

            // get this mmap data
            MMapData mmap = loadedMMaps[mapId];

            Contract.Assert(mmap.navMesh != null);

            // check if we already have this tile loaded
            uint packedGridPos = packTileID(x, y);

            if (mmap.loadedTileRefs.ContainsKey(packedGridPos))
            {
                return(false);
            }

            // load this tile . mmaps/MMMXXYY.mmtile
            string filename = string.Format(TILE_FILE_NAME_FORMAT, Global.WorldMgr.GetDataPath(), mapId, x, y);

            if (!File.Exists(filename))
            {
                Log.outDebug(LogFilter.Maps, "MMAP:loadMap: Could not open mmtile file '{0}'", filename);
                return(false);
            }

            using (BinaryReader reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read)))
            {
                MmapTileHeader fileHeader = reader.ReadStruct <MmapTileHeader>();
                Array.Reverse(fileHeader.mmapMagic);
                if (new string(fileHeader.mmapMagic) != MapConst.mmapMagic)
                {
                    Log.outError(LogFilter.Maps, "MMAP:loadMap: Bad header in mmap {0:D4}{1:D2}{2:D2}.mmtile", mapId, x, y);
                    return(false);
                }
                if (fileHeader.mmapVersion != MapConst.mmapVersion)
                {
                    Log.outError(LogFilter.Maps, "MMAP:loadMap: {0:D4}{1:D2}{2:D2}.mmtile was built with generator v{3}, expected v{4}",
                                 mapId, x, y, fileHeader.mmapVersion, MapConst.mmapVersion);
                    return(false);
                }

                var bytes = reader.ReadBytes((int)fileHeader.size);

                Detour.dtRawTileData data = new Detour.dtRawTileData();
                data.FromBytes(bytes, 0);

                ulong tileRef = 0;
                // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
                if (Detour.dtStatusSucceed(mmap.navMesh.addTile(data, 0, 0, ref tileRef)))
                {
                    mmap.loadedTileRefs.Add(packedGridPos, tileRef);
                    ++loadedTiles;
                    Log.outInfo(LogFilter.Maps, "MMAP:loadMap: Loaded mmtile {0:D4}[{1:D2}, {2:D2}]", mapId, x, y);

                    var phasedMaps = phaseMapData.LookupByKey(mapId);
                    if (!phasedMaps.Empty())
                    {
                        mmap.AddBaseTile(packedGridPos, data, fileHeader, fileHeader.size);
                        LoadPhaseTiles(phasedMaps, x, y);
                    }

                    return(true);
                }

                Log.outError(LogFilter.Maps, "MMAP:loadMap: Could not load {0:D4}{1:D2}{2:D2}.mmtile into navmesh", mapId, x, y);
                return(false);
            }
        }
예제 #11
0
        bool LoadMapImpl(string basePath, uint mapId, uint x, uint y)
        {
            // make sure the mmap is loaded and ready to load tiles
            if (!LoadMapData(basePath, mapId))
            {
                return(false);
            }

            // get this mmap data
            MMapData mmap = loadedMMaps[mapId];

            Cypher.Assert(mmap.navMesh != null);

            // check if we already have this tile loaded
            uint packedGridPos = PackTileID(x, y);

            if (mmap.loadedTileRefs.ContainsKey(packedGridPos))
            {
                return(false);
            }

            // load this tile . mmaps/MMMXXYY.mmtile
            string fileName = string.Format(TILE_FILE_NAME_FORMAT, basePath, mapId, x, y);

            if (!File.Exists(fileName))
            {
                if (parentMapData.ContainsKey(mapId))
                {
                    fileName = string.Format(TILE_FILE_NAME_FORMAT, basePath, parentMapData[mapId], x, y);
                }
            }

            if (!File.Exists(fileName))
            {
                Log.outDebug(LogFilter.Maps, "MMAP:loadMap: Could not open mmtile file '{0}'", fileName);
                return(false);
            }

            using (BinaryReader reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read)))
            {
                MmapTileHeader fileHeader = reader.Read <MmapTileHeader>();
                if (fileHeader.mmapMagic != MapConst.mmapMagic)
                {
                    Log.outError(LogFilter.Maps, "MMAP:loadMap: Bad header in mmap {0:D4}{1:D2}{2:D2}.mmtile", mapId, x, y);
                    return(false);
                }
                if (fileHeader.mmapVersion != MapConst.mmapVersion)
                {
                    Log.outError(LogFilter.Maps, "MMAP:loadMap: {0:D4}{1:D2}{2:D2}.mmtile was built with generator v{3}, expected v{4}",
                                 mapId, x, y, fileHeader.mmapVersion, MapConst.mmapVersion);
                    return(false);
                }

                var bytes = reader.ReadBytes((int)fileHeader.size);
                Detour.dtRawTileData data = new Detour.dtRawTileData();
                data.FromBytes(bytes, 0);

                ulong tileRef = 0;
                // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
                if (Detour.dtStatusSucceed(mmap.navMesh.addTile(data, 1, 0, ref tileRef)))
                {
                    mmap.loadedTileRefs.Add(packedGridPos, tileRef);
                    ++loadedTiles;
                    Log.outInfo(LogFilter.Maps, "MMAP:loadMap: Loaded mmtile {0:D4}[{1:D2}, {2:D2}]", mapId, x, y);
                    return(true);
                }

                Log.outError(LogFilter.Maps, "MMAP:loadMap: Could not load {0:D4}{1:D2}{2:D2}.mmtile into navmesh", mapId, x, y);
                return(false);
            }
        }