2023-08-22 19:08:45 +08:00
|
|
|
using System;
|
2023-11-17 15:57:18 +08:00
|
|
|
using System.Collections;
|
2023-08-22 19:08:45 +08:00
|
|
|
using System.Collections.Generic;
|
2023-11-17 15:57:18 +08:00
|
|
|
using System.Diagnostics;
|
|
|
|
|
using Gameplay;
|
2023-08-22 19:08:45 +08:00
|
|
|
using Sirenix.OdinInspector;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using Newtonsoft.Json;
|
2023-11-17 15:57:18 +08:00
|
|
|
using TGS;
|
|
|
|
|
using UnityEngine.Serialization;
|
|
|
|
|
using Debug = UnityEngine.Debug;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
public class MapData
|
|
|
|
|
{
|
|
|
|
|
public enum EnvironmentType
|
|
|
|
|
{
|
|
|
|
|
[LabelText("平原")]
|
|
|
|
|
Plain = 0,
|
2023-11-17 15:57:18 +08:00
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
[LabelText("山地")]
|
|
|
|
|
Mountain,
|
2023-11-17 15:57:18 +08:00
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
[LabelText("草原")]
|
|
|
|
|
Grassland,
|
2023-11-17 15:57:18 +08:00
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
[LabelText("林地")]
|
|
|
|
|
Forest,
|
2023-11-17 15:57:18 +08:00
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
[LabelText("雪地")]
|
|
|
|
|
Snow,
|
2023-11-17 15:57:18 +08:00
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
[LabelText("泥地")]
|
|
|
|
|
MuddyLand,
|
2023-11-17 15:57:18 +08:00
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
[LabelText("戈壁")]
|
|
|
|
|
Gobi,
|
2023-11-17 15:57:18 +08:00
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
[LabelText("沙漠")]
|
|
|
|
|
Desert,
|
2023-11-17 15:57:18 +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-11-17 15:57:18 +08:00
|
|
|
[HideInInspector]
|
|
|
|
|
public List<int> positions = new();
|
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
[Button("编辑")]
|
|
|
|
|
[ShowIf("@!MapData.EditingRegion && MapData.currEditRegion != this")]
|
|
|
|
|
private void Edit()
|
|
|
|
|
{
|
|
|
|
|
EditingRegion = true;
|
|
|
|
|
currEditRegion = this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Button("退出编辑")]
|
|
|
|
|
[ShowIf("@MapData.EditingRegion && MapData.currEditRegion == this")]
|
|
|
|
|
private void ExitEdit()
|
|
|
|
|
{
|
|
|
|
|
EditingRegion = false;
|
|
|
|
|
currEditRegion = null;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2023-08-22 19:08:45 +08:00
|
|
|
}
|
|
|
|
|
|
2023-11-17 15:57:18 +08:00
|
|
|
private static readonly Color regionColor = MapUtils.GetRGBAColor("FF960072");
|
|
|
|
|
private static Map currMap => MapSceneEditor._map;
|
|
|
|
|
private static bool EditingBlockData;
|
|
|
|
|
private static bool EditingRegion;
|
|
|
|
|
private static Region currEditRegion;
|
|
|
|
|
private static List<TerrainTypeProperty> _terrainTypeConfig;
|
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
[ReadOnly]
|
2023-11-17 15:57:18 +08:00
|
|
|
[LabelText("地图宽度")]
|
2023-08-22 19:08:45 +08:00
|
|
|
public int width;
|
2023-11-17 15:57:18 +08:00
|
|
|
|
2023-11-15 16:24:53 +08:00
|
|
|
[ReadOnly]
|
2023-11-17 15:57:18 +08:00
|
|
|
[LabelText("地图高度")]
|
2023-08-22 19:08:45 +08:00
|
|
|
public int height;
|
2023-11-17 15:57:18 +08:00
|
|
|
|
|
|
|
|
[LabelText("环境类型")]
|
2023-08-22 19:08:45 +08:00
|
|
|
public EnvironmentType environmentType;
|
2023-11-17 15:57:18 +08:00
|
|
|
|
|
|
|
|
[BoxGroup("地块信息")]
|
|
|
|
|
[HorizontalGroup("地块信息/地块")]
|
|
|
|
|
[Button("刷地块")]
|
|
|
|
|
[ShowIf("@!EditingBlockData")]
|
|
|
|
|
private void EditBlock()
|
|
|
|
|
{
|
|
|
|
|
EditingBlockData = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[BoxGroup("地块信息")]
|
|
|
|
|
[HorizontalGroup("地块信息/地块")]
|
|
|
|
|
[Button("完成刷地块")]
|
|
|
|
|
[ShowIf("EditingBlockData")]
|
|
|
|
|
private void ExitEditBlock()
|
|
|
|
|
{
|
|
|
|
|
EditingBlockData = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// [HorizontalGroup("地块信息/Territory")]
|
|
|
|
|
[ValueDropdown("GetTerrainTypeProperties")]
|
|
|
|
|
[BoxGroup("地块信息")]
|
|
|
|
|
[HorizontalGroup("地块信息/地块")]
|
|
|
|
|
[LabelText("选择地块")]
|
|
|
|
|
[ShowIf("EditingBlockData")]
|
|
|
|
|
public int TerrainTypeIndex = 0;
|
|
|
|
|
|
2023-11-15 16:24:53 +08:00
|
|
|
public List<MapBlockData> BlocksData = new();
|
2023-11-17 15:57:18 +08:00
|
|
|
|
|
|
|
|
[PropertyOrder(100)]
|
|
|
|
|
[LabelText("地区信息")]
|
|
|
|
|
public List<Region> regions = new();
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
|
|
|
[HideInInspector]
|
|
|
|
|
public Vector2Int initialCameraPosition;
|
|
|
|
|
|
2023-11-15 13:30:13 +08:00
|
|
|
public MapData()
|
|
|
|
|
{
|
|
|
|
|
}
|
2023-11-17 15:57:18 +08:00
|
|
|
|
|
|
|
|
public MapData(int id, string name, int width, int height, EnvironmentType envType = EnvironmentType.Plain)
|
2023-08-22 19:08:45 +08:00
|
|
|
{
|
|
|
|
|
this.width = width;
|
|
|
|
|
this.height = height;
|
2023-10-19 15:00:19 +08:00
|
|
|
environmentType = envType;
|
2023-08-22 19:08:45 +08:00
|
|
|
ResetBlocks();
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-17 15:57:18 +08:00
|
|
|
public static void ResetEditor()
|
|
|
|
|
{
|
|
|
|
|
EditingBlockData = false;
|
|
|
|
|
EditingRegion = false;
|
|
|
|
|
currEditRegion = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Conditional("UNITY_EDITOR")]
|
|
|
|
|
public void SetActiveSceneEdit(bool isActive)
|
|
|
|
|
{
|
|
|
|
|
if(currMap == null)
|
|
|
|
|
return;
|
|
|
|
|
if (isActive)
|
|
|
|
|
currMap.TerrainGridSystem.OnMouseClickOnGrid += OnCellClick;
|
|
|
|
|
else
|
|
|
|
|
currMap.TerrainGridSystem.OnMouseClickOnGrid -= OnCellClick;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnCellClick(TerrainGridSystem tgs, int cellIndex, int buttonIndex)
|
|
|
|
|
{
|
|
|
|
|
if (!EditingBlockData && !EditingRegion)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var map = currMap;
|
|
|
|
|
|
|
|
|
|
int leftButton = 0;
|
|
|
|
|
int rightButton = 1;
|
|
|
|
|
|
|
|
|
|
if (buttonIndex == leftButton && TerrainTypeIndex >= 0 && EditingBlockData)
|
|
|
|
|
{
|
|
|
|
|
SetCellTerritory(tgs, cellIndex, TerrainTypeIndex);
|
|
|
|
|
}
|
|
|
|
|
else if (buttonIndex == rightButton && EditingBlockData)
|
|
|
|
|
{
|
|
|
|
|
ClearCellTerritory(tgs, cellIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (buttonIndex == leftButton && EditingRegion)
|
|
|
|
|
{
|
|
|
|
|
if (!currEditRegion.positions.Contains(cellIndex))
|
|
|
|
|
{
|
|
|
|
|
currEditRegion.positions.Add(cellIndex);
|
|
|
|
|
map.TerrainGridSystem.CellToggleRegionSurface(cellIndex, true, regionColor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (buttonIndex == rightButton && EditingRegion)
|
|
|
|
|
{
|
|
|
|
|
ClearCellRegion(cellIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetCellTerritory(TerrainGridSystem tgs, int cellIndex, int TerrainTypeIndex)
|
|
|
|
|
{
|
|
|
|
|
var map = currMap;
|
|
|
|
|
// Key: TerrainTypeIndex Value: tgs.territories.index
|
|
|
|
|
if (!map.TerrainTypeIndexDic.ContainsKey(TerrainTypeIndex))
|
|
|
|
|
{
|
|
|
|
|
Territory territory = tgs.TerritoryCreate(cellIndex);
|
|
|
|
|
map.TerrainTypeIndexDic.Add(TerrainTypeIndex, map.TerrainTypeIndexDic.Count);
|
|
|
|
|
territory.fillColor = _terrainTypeConfig[TerrainTypeIndex].Color;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_terrainTypeConfig[TerrainTypeIndex].emptyBlock)
|
|
|
|
|
{
|
|
|
|
|
map.TerrainGridSystem.CellSetBorderVisible(cellIndex, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
map?.SetTerrainType(cellIndex, TerrainTypeIndex);
|
|
|
|
|
tgs.CellSetTerritory(cellIndex, map.TerrainTypeIndexDic[TerrainTypeIndex]);
|
|
|
|
|
Debug.Log(
|
|
|
|
|
$"Set Territory, cellIndex ({cellIndex}), terrain type ({TerrainTypeIndex}), name ({_terrainTypeConfig[TerrainTypeIndex].Color})");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ClearCellTerritory(TerrainGridSystem tgs, int cellIndex)
|
|
|
|
|
{
|
|
|
|
|
var map = currMap;
|
|
|
|
|
map.TerrainGridSystem.CellSetBorderVisible(cellIndex, true);
|
|
|
|
|
|
|
|
|
|
var tIndex = tgs.CellGetTerritoryIndex(cellIndex);
|
|
|
|
|
if (tIndex != -1)
|
|
|
|
|
{
|
|
|
|
|
tgs.CellSetTerritory(cellIndex, -1);
|
|
|
|
|
map?.SetTerrainType(cellIndex, -1);
|
|
|
|
|
Debug.Log($"Cell Clear Territory, cellIndex({cellIndex})");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ClearCellRegion(int cellIndex)
|
|
|
|
|
{
|
|
|
|
|
var map = currMap;
|
|
|
|
|
if (currEditRegion.positions.Contains(cellIndex))
|
|
|
|
|
{
|
|
|
|
|
currEditRegion.positions.Remove(cellIndex);
|
|
|
|
|
map.TerrainGridSystem.CellHideRegionSurface(cellIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
public void ResetBlocks()
|
|
|
|
|
{
|
|
|
|
|
var count = width * height;
|
2023-11-15 16:24:53 +08:00
|
|
|
BlocksData.Clear();
|
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());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetBlockData(Vector2Int position, MapBlockData blockData)
|
|
|
|
|
{
|
|
|
|
|
if (CheckPosition(position))
|
|
|
|
|
{
|
|
|
|
|
BlocksData[position.x * width + position.y] = blockData;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public MapBlockData GetBlockData(Vector2Int position)
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
return CheckPosition(position) ? BlocksData[Position2BlockIndex(position)] : null;
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Position2BlockIndex(Vector2Int position)
|
|
|
|
|
{
|
|
|
|
|
return position.x * width + position.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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-17 15:57:18 +08:00
|
|
|
// public void AddRegion(Region region)
|
|
|
|
|
// {
|
|
|
|
|
// if (!CheckRegion(region))
|
|
|
|
|
// {
|
|
|
|
|
// DebugUtil.LogError("{0} AddPreparingArea failed, area:{1} is invalid!", GetType().Name, region);
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
// _regions.Add(region);
|
|
|
|
|
// }
|
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 15:57:18 +08:00
|
|
|
if (regionId < 0 || regionId >= regions.Count)
|
2023-08-22 19:08:45 +08:00
|
|
|
return null;
|
2023-11-17 15:57:18 +08:00
|
|
|
return regions[regionId];
|
|
|
|
|
// if (_regions.TryGetValue(regionId, out var region))
|
|
|
|
|
// {
|
|
|
|
|
// return region;
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// DebugUtil.LogError("{0} GetPreparingArea failed, id:{1} not exists!", GetType().Name, regionId);
|
|
|
|
|
// return null;
|
|
|
|
|
// }
|
2023-08-22 19:08:45 +08:00
|
|
|
}
|
|
|
|
|
|
2023-11-17 15:57:18 +08:00
|
|
|
// public Dictionary<int, Region> GetAllRegions()
|
|
|
|
|
// {
|
|
|
|
|
// return _regions;
|
|
|
|
|
// }
|
2023-08-22 19:08:45 +08:00
|
|
|
|
2023-11-17 15:57:18 +08:00
|
|
|
// public void RemoveRegion(int regionId)
|
|
|
|
|
// {
|
|
|
|
|
// if (_regions.ContainsKey(regionId))
|
|
|
|
|
// {
|
|
|
|
|
// _regions.Remove(regionId);
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// DebugUtil.LogError("{0} RemovePreparingArea failed, id:{1} not exists!", GetType().Name, regionId);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
|
|
|
public void RemoveAllRegion()
|
|
|
|
|
{
|
2023-11-17 15:57:18 +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-17 15:57:18 +08:00
|
|
|
return regionIndex >= 0 && regionIndex < regions.Count;
|
2023-08-22 19:08:45 +08:00
|
|
|
}
|
2023-11-17 15:57:18 +08:00
|
|
|
|
|
|
|
|
private static IEnumerable GetTerrainTypeProperties()
|
2023-08-22 19:08:45 +08:00
|
|
|
{
|
2023-11-17 15:57:18 +08:00
|
|
|
_terrainTypeConfig = TerrainTypeConfig.TerrainTypeProperties;
|
|
|
|
|
var list = new ValueDropdownList<int>();
|
|
|
|
|
if (_terrainTypeConfig != null)
|
2023-08-22 19:08:45 +08:00
|
|
|
{
|
2023-11-17 15:57:18 +08:00
|
|
|
for (int i = 0; i < _terrainTypeConfig.Count; i++)
|
2023-08-22 19:08:45 +08:00
|
|
|
{
|
2023-11-17 15:57:18 +08:00
|
|
|
list.Add(_terrainTypeConfig[i].name, i);
|
2023-08-22 19:08:45 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-11-17 15:57:18 +08:00
|
|
|
|
|
|
|
|
return list;
|
2023-08-22 19:08:45 +08:00
|
|
|
}
|
|
|
|
|
}
|