using System; using System.IO; using UnityEngine; namespace MindPowerSdk { public partial class MPMap { private MPMapFileHeader _mapHeader; public int Width => _mapHeader.Width; public int Height => _mapHeader.Height; public int SectionWidth => _mapHeader.SectionWidth; public int SectionHeight => _mapHeader.SectionHeight; // 部分数据的数量(地图分块) public int SectionCntX; public int SecitonCntY; public int SectionCnt; // 地图块索引偏移 private int[] _offsetIdx; public MPActiveMapSection[,] ActiveSectionArray; // private List ActiveSections = new(); private BinaryReader _fp; private MPTile _defaultTile; public MPMap() { _defaultTile = new MPTile(); _defaultTile.TexLayer = new MPTileTex[4]; //_pDefaultTile->TexLayer[0].btTexNo = UNDERWATER_TEXNO; //_pDefaultTile->TexLayer[0].btAlphaNo = 15; //_pDefaultTile->TexLayer[1].btTexNo = 255; // 标示为DefaultTile //_pDefaultTile->fHeight = UNDERWATER_HEIGHT; //_pDefaultTile->dwColor = 0xffffffff; _defaultTile.TexLayer[0].TexNo = 22; _defaultTile.TexLayer[0].AlphaNo = 15; _defaultTile.TexLayer[1].TexNo = 255; _defaultTile.Height = -2.0f; } public void Load(BinaryReader reader) { _fp = reader; this._mapHeader = MPMapFileHeader.Load(reader); Debug.Log($"version: {this._mapHeader.MapFlag}"); SectionCntX = this.Width / SectionWidth; SecitonCntY = this.Height / SectionHeight; SectionCnt = SectionCntX * SecitonCntY; // 读取块的偏移位置 _offsetIdx = new int[SectionCnt]; for (int i = 0; i < _offsetIdx.Length; i++) _offsetIdx[i] = reader.ReadInt32(); ActiveSectionArray = new MPActiveMapSection[SectionCntX, SecitonCntY]; FullLoading(); } private void FullLoading() { for (int i = 0; i < SectionCnt; i++) { int x = i % SectionCntX; int y = i / SectionCntX; if (_offsetIdx[i] != 0) { LoadSectionData(x, y); } } } private void LoadSectionData(int sectionX, int sectionY) { MPActiveMapSection section = new MPActiveMapSection { X = sectionX, Y = sectionY }; LoadSectionData(ref section); ActiveSectionArray[sectionX, sectionY] = section; } /// /// 读取地图区块数据 /// /// private void LoadSectionData(ref MPActiveMapSection section) { int sectionX = section.X; int sectionY = section.Y; section.DataOffset = ReadSectionDataOffset(sectionX, sectionY); if (section.DataOffset == 0) { Debug.LogWarning($"空块数据: {sectionX},{sectionY}"); return; } // 开始读取tile数据 _fp.BaseStream.Seek(section.DataOffset, SeekOrigin.Begin); section.TileData = new MPTile[SectionWidth * SectionHeight]; for (int y = 0; y < SectionHeight; y++) { for (int x = 0; x < SectionWidth; x++) { int idx = GetMPTileIndex(x, y); MPTile tile = new MPTile(); SNewFileTile fileTile = SNewFileTile.Load(_fp); // rgb565 to int short rgb = fileTile.Color; byte r = (byte)((rgb & 0xf800) >> 8); byte g = (byte)((rgb & 0x7e0) >> 3); byte b = (byte)((rgb & 0x1f) << 3); tile.UniColor = new Color(r / 255f, g / 255f, b / 255f); tile.TileInfo_5To8(fileTile.btTileInfo, fileTile.dwTileInfo); tile.Height = (fileTile.Height) * 10f / 100.0f; tile.IsLand = fileTile.IsLand; tile.Region = fileTile.Region; unsafe { Span dst = new Span(tile.Block, 4); Span src = new Span(fileTile.Block, 4); src.CopyTo(dst); } section.TileData[idx] = tile; } } } /// /// 设置读取区块数据的偏移 /// /// /// /// private int ReadSectionDataOffset(int sectionX, int sectionY) { int loc = sectionY * SectionCntX + sectionX; return _offsetIdx[loc]; } public int GetMPTileIndex(int x, int y) { return SectionWidth * y + x; } /// /// 通过地图坐标直接获取Tile点 /// /// /// /// public MPTile GetTile(int x, int y) { // y = Height - y - 1; int sX = x / SectionWidth; int sY = y / SectionHeight; if (ActiveSectionArray.GetLength(0) <= sX || ActiveSectionArray.GetLength(1) <= sY) return _defaultTile; MPActiveMapSection section = ActiveSectionArray[sX, sY]; if (section.TileData is not { Length: > 0 }) return _defaultTile; int tX = x % SectionWidth; int tY = y % SectionHeight; int idx = GetMPTileIndex(tX, tY); if (idx >= section.TileData.Length || idx < 0) return _defaultTile; return section.TileData[idx]; } } }