using System; using System.Collections.Generic; using cfg.FightCfg; using Sirenix.OdinInspector; using UnityEngine; using Newtonsoft.Json; using UnityEngine.Serialization; [Serializable] public class MapData { [Serializable] public class Region { public List positions = new(); } [Serializable] public class BlockRegion { public List positions = new(); // 模型ID public int modelID; } [Serializable] public class CameraInfo { public float leftMarginInFight = 1.5f; public float rightMarginInFight = 1.5f; public float topMarginInFight = 0.9f; public float bottomMarginInFight = 0.9f; public float leftMarginInPre = 1.5f; public float rightMarginInPre = 1.5f; public float topMarginInInPre = 0.9f; public float bottomMarginInPre = 0.9f; public float initialFOV = 30f; public float initialOrthographicSize = 12f; } public CameraInfo cameraMarginInfo = new CameraInfo(); [Serializable] public class ShowBuffData { public int cellIndex; public string path; } [JsonIgnore] public int Width { get => _width; set { if (_width != value) OnMapSizeChanged(value - _width, 0); } } [JsonIgnore] public int Height { get => _height; set { if (_height != value) OnMapSizeChanged(0, value - _height); } } public Vector3 position; [FormerlySerializedAs("width")] [ReadOnly] [JsonProperty] [SerializeField] private int _width = 2; [FormerlySerializedAs("height")] [JsonProperty] [ReadOnly] [SerializeField] private int _height = 2; public ELevelTerrainType environmentType; [HideInInspector] public List BlocksData = new(); [HideInInspector] public List regions = new(); [HideInInspector] public List blockRegions = new(); [HideInInspector] public Vector2Int initialCameraPosition; [HideInInspector] public List showBuffPoints = new List(); [JsonIgnore] private Dictionary _blockDataDic = new(); public MapData() { } private void OnMapSizeChanged(int cDelta, int rDelta) { var targetWidth = _width + cDelta; var targetHeight = _height + rDelta; if (targetWidth <= 0 && targetHeight <= 0) return; RefreshBlocks(cDelta, rDelta); RefreshRegions(cDelta, rDelta); _width = targetWidth; _height = targetHeight; } /// /// 地图尺寸改变时,之前保存的区域数据可能会错位,需要处理之前的数据 /// /// 之前保存的下标 /// 列增量 /// 行增量 private int CalculateIndexOnMapSizeChanged(int index, int colDelta, int rowDelta) { var pos = BlockIndex2Position(index); pos = new Vector2Int(pos.x + rowDelta / 2, pos.y + colDelta / 2); if (pos.x < 0 || pos.y < 0) return -1; return pos.x * (_width + colDelta) + pos.y; } //当地图宽高改变时需要重新计算index,并拷贝MapBlockData到对应位置 private void RefreshBlocks(int colDelta, int rowDelta) { List blockDataListNew = new(); var count = (_width + colDelta) * (_height + rowDelta); for (var i = 0; i < count; i++) { blockDataListNew.Add(new MapBlockData()); } var index = 0; foreach (var blockData in BlocksData) { if (blockData.TerrainTypeIndex != -1) { var indexNew = CalculateIndexOnMapSizeChanged(index, colDelta, rowDelta); if (indexNew >= 0 && indexNew < blockDataListNew.Count) { blockDataListNew[indexNew] = blockData; } } index++; } BlocksData = blockDataListNew; } private void RefreshRegions(int colDelta, int rowDelta) { foreach (var region in regions) { for (int i = region.positions.Count - 1; i >= 0; i--) { var indexNew = CalculateIndexOnMapSizeChanged(region.positions[i], colDelta, rowDelta); if (indexNew >= 0) { region.positions[i] = indexNew; } else { region.positions.RemoveAt(i); } } } } public void ClearGridData() { BlocksData.Clear(); var count = _width * _height; for (var i = 0; i < count; i++) { BlocksData.Add(new MapBlockData()); } regions.Clear(); } public void SetBlockData(Vector2Int position, MapBlockData blockData) { if (CheckPosition(position)) { BlocksData[position.x * _width + position.y] = blockData; } } public MapBlockData GetBlockData(int cellIndex) { if (cellIndex < 0 || cellIndex >= BlocksData.Count) { DebugUtil.LogError("GetBlockData failed, position:{0} is invalid!", cellIndex); return null; } return BlocksData[cellIndex]; } public bool CheckPosition(Vector2Int position) { return position.x >= 0 && position.y >= 0; } //为了和TGS中坐标定义一致,格子的坐标采用X朝上,Y朝右 public int Position2BlockIndex(Vector2Int position) { return position.x * _width + position.y; } //为了和TGS中坐标定义一致,格子的坐标采用X朝上,Y朝右 public Vector2Int BlockIndex2Position(int blockIndex) { return new Vector2Int(blockIndex / _width, blockIndex % _width); } public void SetBlockTerrainType(int blockIndex, int terrainTypeIndex) { if (blockIndex >= 0 && blockIndex < BlocksData.Count) { BlocksData[blockIndex].TerrainTypeIndex = terrainTypeIndex; } } // public void AddRegion(Region area, int newRegionId = -1) // { // // if (!CheckRegion(area)) // { // DebugUtil.LogError("{0} AddPreparingArea failed, area:{1} is invalid!", GetType().Name, area); // } // var regionId = GenerateRegionId(); // if (_regions.ContainsKey(newRegionId) && newRegionId >= 0) // { // _regions[newRegionId] = area; // } // else // { // _regions.Add(regionId, area); // } // // } public Region GetRegion(int regionId) { if (IsRegionExist(regionId)) return regions[regionId]; DebugUtil.LogError("{0} GetPreparingArea failed, id:{1} not exists!", GetType().Name, regionId); return null; } // public List GetAllRegions() // { // return _regions; // } public void RemoveRegion(int regionId) { if (IsRegionExist(regionId)) regions.RemoveAt(regionId); else { DebugUtil.LogError("{0} RemovePreparingArea failed, id:{1} not exists!",GetType().Name, regionId); } } public void RemoveAllRegion() { regions.Clear(); } // private int GenerateRegionId() // { // var max = _regions.Count; // for (var i = 0; i < max; i++) // { // if (!_regions.ContainsKey(i)) // { // return i; // } // } // return max; // } // private bool CheckRegion(Region area) // { // for (var i = 0; i < area.positions.Count; i++) // { // if (!CheckPosition(area.positions[i])) // { // return false; // } // } // return true; // } public bool IsRegionExist(int regionIndex) { return regionIndex >= 0 && regionIndex < regions.Count; } public bool IsCellInsideRegion(int cellIndex, int regionIndex) { if (!IsRegionExist(regionIndex)) { return false; } return regions[regionIndex].positions.Contains(cellIndex); } }