322 lines
8.2 KiB
C#
322 lines
8.2 KiB
C#
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<int> positions = new();
|
||
}
|
||
|
||
[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<MapBlockData> BlocksData = new();
|
||
|
||
[HideInInspector]
|
||
public List<Region> regions = new();
|
||
|
||
[HideInInspector]
|
||
public Vector2Int initialCameraPosition;
|
||
|
||
[HideInInspector] public List<ShowBuffData> showBuffPoints = new List<ShowBuffData>();
|
||
|
||
[JsonIgnore]
|
||
private Dictionary<int, MapBlockData> _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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 地图尺寸改变时,之前保存的区域数据可能会错位,需要处理之前的数据
|
||
/// </summary>
|
||
/// <param name="index">之前保存的下标</param>
|
||
/// <param name="colDelta">列增量</param>
|
||
/// <param name="rowDelta">行增量</param>
|
||
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<MapBlockData> 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<Region> 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);
|
||
}
|
||
} |