using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using Gameplay; using Sirenix.OdinInspector; using UnityEngine; using Newtonsoft.Json; using TGS; using UnityEngine.Serialization; using Debug = UnityEngine.Debug; [Serializable] public class MapData { public enum EnvironmentType { [LabelText("平原")] Plain = 0, [LabelText("山地")] Mountain, [LabelText("草原")] Grassland, [LabelText("林地")] Forest, [LabelText("雪地")] Snow, [LabelText("泥地")] MuddyLand, [LabelText("戈壁")] Gobi, [LabelText("沙漠")] Desert, [LabelText("高原")] Plateau } [Serializable] public class Region { [HideInInspector] public List 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 } 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 _terrainTypeConfig; [ReadOnly] [LabelText("地图宽度")] public int width; [ReadOnly] [LabelText("地图高度")] public int height; [LabelText("环境类型")] public EnvironmentType environmentType; [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; public List BlocksData = new(); [PropertyOrder(100)] [LabelText("地区信息")] public List regions = new(); [HideInInspector] public Vector2Int initialCameraPosition; public MapData() { } public MapData(int id, string name, int width, int height, EnvironmentType envType = EnvironmentType.Plain) { this.width = width; this.height = height; environmentType = envType; ResetBlocks(); } 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); } } public void ResetBlocks() { var count = width * height; BlocksData.Clear(); for (var i = 0; i < count; i++) { 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) { return CheckPosition(position) ? BlocksData[Position2BlockIndex(position)] : null; } public bool CheckPosition(Vector2Int position) { return position.x >= 0 && position.y >= 0; } 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; } } // public void AddRegion(Region region) // { // if (!CheckRegion(region)) // { // DebugUtil.LogError("{0} AddPreparingArea failed, area:{1} is invalid!", GetType().Name, region); // return; // } // _regions.Add(region); // } public Region GetRegion(int regionId) { if (regionId < 0 || regionId >= regions.Count) return null; 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; // } } // public Dictionary GetAllRegions() // { // return _regions; // } // 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); // } // } 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; } private static IEnumerable GetTerrainTypeProperties() { _terrainTypeConfig = TerrainTypeConfig.TerrainTypeProperties; var list = new ValueDropdownList(); if (_terrainTypeConfig != null) { for (int i = 0; i < _terrainTypeConfig.Count; i++) { list.Add(_terrainTypeConfig[i].name, i); } } return list; } }