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

375 lines
9.8 KiB
C#
Raw Normal View History

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
}
}