NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/GameWrapper/Map/MapData.cs

370 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using cfg.FightCfg;
using Sirenix.OdinInspector;
using UnityEngine;
using Newtonsoft.Json;
using Obfuz;
[Serializable]
[ObfuzIgnore]
public class MapData
{
[Serializable]
public class Region
{
public List<int> positions = new();
[LabelText("手动指定中心格子索引")] public int centerCellIndex = -1;
public string note; // 策划使用备注
}
[Serializable]
public class BlockRegion
{
public int id;
public List<int> positions = new();
/// <summary>
/// 指示路径
/// </summary>
public string path;
/// <summary>
/// 指示位置
/// </summary>
public Vector3 centerPos = Vector3.zero;
public string note; // 策划使用备注
}
[Serializable]
public class BlockSphereInfo
{
[LabelText("地格")] public int cellIndex;
/// <summary>
/// 真实球体直径
/// </summary>
[HideInInspector] public float scale;
/// <summary>
/// 偏移后真实位置
/// </summary>
[HideInInspector] public Vector3 offestPos;
[LabelText("备注")]
// 策划使用
public string note;
}
[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;
[ReadOnly] [JsonProperty] [SerializeField]
private int _width = 2;
[JsonProperty] [ReadOnly] [SerializeField]
private int _height = 2;
public ELevelTerrainType environmentType;
/// <summary>
/// 所有地块属性
/// </summary>
[HideInInspector] public List<MapBlockData> BlocksData = new();
/// <summary>
/// 普通地区 (出生、撤退...
/// </summary>
[HideInInspector] public List<Region> regions = new();
/// <summary>
/// 阻挡攻击数据
/// </summary>
[HideInInspector] public List<BlockSphereInfo> BlockSphereInfos = new();
/// <summary>
/// 初始化相机数据
/// </summary>
[HideInInspector] public Vector2Int initialCameraPosition;
/// <summary>
/// 需要展示指示图标的格子数据
/// </summary>
[HideInInspector] public List<ShowBuffData> showBuffPoints = new List<ShowBuffData>();
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, bool isLegionMap = false)
{
if (blockIndex >= 0 && blockIndex < BlocksData.Count)
{
if (isLegionMap)
BlocksData[blockIndex].LegionTypeIndex = terrainTypeIndex;
else
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);
}
}