2023-08-22 19:08:45 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2023-12-18 19:42:46 +08:00
|
|
|
|
using System.Runtime.Serialization;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
using Sirenix.OdinInspector;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using Newtonsoft.Json;
|
2023-12-18 19:42:46 +08:00
|
|
|
|
using TGS;
|
2023-11-19 14:01:26 +08:00
|
|
|
|
using UnityEngine.Serialization;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class MapData
|
|
|
|
|
|
{
|
|
|
|
|
|
public enum EnvironmentType
|
|
|
|
|
|
{
|
|
|
|
|
|
[LabelText("平原")]
|
|
|
|
|
|
Plain = 0,
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
[LabelText("山地")]
|
|
|
|
|
|
Mountain,
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
[LabelText("草原")]
|
|
|
|
|
|
Grassland,
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
[LabelText("林地")]
|
|
|
|
|
|
Forest,
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
[LabelText("雪地")]
|
|
|
|
|
|
Snow,
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
[LabelText("泥地")]
|
|
|
|
|
|
MuddyLand,
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
[LabelText("戈壁")]
|
|
|
|
|
|
Gobi,
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
[LabelText("沙漠")]
|
|
|
|
|
|
Desert,
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
[LabelText("高原")]
|
2023-10-19 15:00:19 +08:00
|
|
|
|
Plateau
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class Region
|
|
|
|
|
|
{
|
2023-12-18 19:42:46 +08:00
|
|
|
|
public List<int> positions = new();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[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);
|
|
|
|
|
|
}
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-12-20 12:47:57 +08:00
|
|
|
|
public Vector3 position;
|
|
|
|
|
|
|
2023-12-18 19:42:46 +08:00
|
|
|
|
[FormerlySerializedAs("width")]
|
2023-08-22 19:08:45 +08:00
|
|
|
|
[ReadOnly]
|
2023-12-18 19:42:46 +08:00
|
|
|
|
[JsonProperty]
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private int _width = 2;
|
|
|
|
|
|
|
|
|
|
|
|
[FormerlySerializedAs("height")]
|
|
|
|
|
|
[JsonProperty]
|
2023-11-15 16:24:53 +08:00
|
|
|
|
[ReadOnly]
|
2023-12-18 19:42:46 +08:00
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private int _height = 2;
|
|
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
public EnvironmentType environmentType;
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-11-19 22:57:17 +08:00
|
|
|
|
[HideInInspector]
|
2023-11-15 16:24:53 +08:00
|
|
|
|
public List<MapBlockData> BlocksData = new();
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-11-19 14:01:26 +08:00
|
|
|
|
[HideInInspector]
|
|
|
|
|
|
public List<Region> regions = new();
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
|
|
|
|
|
[HideInInspector]
|
|
|
|
|
|
public Vector2Int initialCameraPosition;
|
|
|
|
|
|
|
2023-12-18 19:42:46 +08:00
|
|
|
|
[JsonIgnore]
|
|
|
|
|
|
private Dictionary<int, MapBlockData> _blockDataDic = new();
|
|
|
|
|
|
|
2023-11-17 18:16:53 +08:00
|
|
|
|
|
2023-11-15 13:30:13 +08:00
|
|
|
|
public MapData()
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
2023-12-18 19:42:46 +08:00
|
|
|
|
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;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-18 19:42:46 +08:00
|
|
|
|
//当地图宽高改变时需要重新计算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()
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
2023-11-15 16:24:53 +08:00
|
|
|
|
BlocksData.Clear();
|
2023-12-18 19:42:46 +08:00
|
|
|
|
var count = _width * _height;
|
2023-10-19 15:00:19 +08:00
|
|
|
|
for (var i = 0; i < count; i++)
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
BlocksData.Add(new MapBlockData());
|
|
|
|
|
|
}
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
|
|
|
|
|
regions.Clear();
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetBlockData(Vector2Int position, MapBlockData blockData)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (CheckPosition(position))
|
|
|
|
|
|
{
|
2023-12-18 19:42:46 +08:00
|
|
|
|
BlocksData[position.x * _width + position.y] = blockData;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-14 18:25:52 +08:00
|
|
|
|
public MapBlockData GetBlockData(int cellIndex)
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
2023-12-14 18:25:52 +08:00
|
|
|
|
if (cellIndex < 0 || cellIndex >= BlocksData.Count)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError("GetBlockData failed, position:{0} is invalid!", cellIndex);
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2023-12-18 19:42:46 +08:00
|
|
|
|
|
2023-12-14 18:25:52 +08:00
|
|
|
|
return BlocksData[cellIndex];
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool CheckPosition(Vector2Int position)
|
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
|
return position.x >= 0 && position.y >= 0;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-21 19:52:50 +08:00
|
|
|
|
//为了和TGS中坐标定义一致,格子的坐标采用X朝上,Y朝右
|
2023-08-22 19:08:45 +08:00
|
|
|
|
public int Position2BlockIndex(Vector2Int position)
|
|
|
|
|
|
{
|
2023-12-18 19:42:46 +08:00
|
|
|
|
return position.x * _width + position.y;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-21 19:52:50 +08:00
|
|
|
|
//为了和TGS中坐标定义一致,格子的坐标采用X朝上,Y朝右
|
2023-08-22 19:08:45 +08:00
|
|
|
|
public Vector2Int BlockIndex2Position(int blockIndex)
|
|
|
|
|
|
{
|
2023-12-18 19:42:46 +08:00
|
|
|
|
return new Vector2Int(blockIndex / _width, blockIndex % _width);
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetBlockTerrainType(int blockIndex, int terrainTypeIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (blockIndex >= 0 && blockIndex < BlocksData.Count)
|
|
|
|
|
|
{
|
|
|
|
|
|
BlocksData[blockIndex].TerrainTypeIndex = terrainTypeIndex;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-17 18:16:53 +08:00
|
|
|
|
// public void AddRegion(Region area, int newRegionId = -1)
|
2023-11-17 15:57:18 +08:00
|
|
|
|
// {
|
2023-11-17 18:16:53 +08:00
|
|
|
|
//
|
|
|
|
|
|
// if (!CheckRegion(area))
|
2023-11-17 15:57:18 +08:00
|
|
|
|
// {
|
2023-11-17 18:16:53 +08:00
|
|
|
|
// DebugUtil.LogError("{0} AddPreparingArea failed, area:{1} is invalid!", GetType().Name, area);
|
2023-11-17 15:57:18 +08:00
|
|
|
|
// }
|
2023-11-17 18:16:53 +08:00
|
|
|
|
// var regionId = GenerateRegionId();
|
|
|
|
|
|
// if (_regions.ContainsKey(newRegionId) && newRegionId >= 0)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// _regions[newRegionId] = area;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// else
|
|
|
|
|
|
// {
|
|
|
|
|
|
// _regions.Add(regionId, area);
|
|
|
|
|
|
// }
|
|
|
|
|
|
//
|
2023-11-17 15:57:18 +08:00
|
|
|
|
// }
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
public Region GetRegion(int regionId)
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
2023-11-17 18:16:53 +08:00
|
|
|
|
if (IsRegionExist(regionId))
|
2023-11-19 14:01:26 +08:00
|
|
|
|
return regions[regionId];
|
2023-12-21 12:16:13 +08:00
|
|
|
|
|
|
|
|
|
|
DebugUtil.LogError("{0} GetPreparingArea failed, id:{1} not exists!", GetType().Name, regionId);
|
2023-11-17 18:16:53 +08:00
|
|
|
|
return null;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-19 14:01:26 +08:00
|
|
|
|
// public List<Region> GetAllRegions()
|
|
|
|
|
|
// {
|
|
|
|
|
|
// return _regions;
|
|
|
|
|
|
// }
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
2023-11-17 18:16:53 +08:00
|
|
|
|
public void RemoveRegion(int regionId)
|
|
|
|
|
|
{
|
2023-12-21 12:16:13 +08:00
|
|
|
|
if (IsRegionExist(regionId))
|
2023-11-19 14:01:26 +08:00
|
|
|
|
regions.RemoveAt(regionId);
|
2023-12-21 12:16:13 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError("{0} RemovePreparingArea failed, id:{1} not exists!",GetType().Name, regionId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-11-17 18:16:53 +08:00
|
|
|
|
}
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
|
|
|
|
|
public void RemoveAllRegion()
|
|
|
|
|
|
{
|
2023-11-19 14:01:26 +08:00
|
|
|
|
regions.Clear();
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-17 15:57:18 +08:00
|
|
|
|
// 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)
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
2023-11-19 14:01:26 +08:00
|
|
|
|
return regionIndex >= 0 && regionIndex < regions.Count;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
2023-12-29 15:07:04 +08:00
|
|
|
|
|
|
|
|
|
|
public bool IsCellInsideRegion(int cellIndex, int regionIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!IsRegionExist(regionIndex))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return regions[regionIndex].positions.Contains(cellIndex);
|
|
|
|
|
|
}
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|