TH1/Unity/Assets/Scripts/TH1_Logic/Editor/MatchConfigEditorWindow.cs
2026-02-28 19:30:56 +08:00

390 lines
16 KiB
C#

/*
* @Author: 白哉
* @Description: 编辑器
* @Date: 2025年04月22日 星期二 15:04:14
* @Modify:
*/
using System.Collections.Generic;
using System.IO;
using Logic.Achievement;
using Logic.AI;
using Logic.CrashSight;
using Logic.HeroTask;
using Logic.Multilingual;
using NUnit.Framework;
using RuntimeData;
using TH1_Logic.Core;
using TH1_Logic.HeroTask;
using TH1_Logic.MatchConfig;
using UnityEditor;
using UnityEngine;
namespace Logic.Editor
{
public class MatchConfigEditorWindow : EditorWindow
{
// 滑条
private Vector2 _barPosition;
// 背景
private GUIStyle _redBoxStyle;
private GUIStyle _whiteBoxStyle;
private List<string> _levelStrList;
private uint _selectedId;
private List<string> _mapNameList;
private string _selectedMapName;
private uint _newConfigId = 1;
private Dictionary<PlayerSettlementInfo, bool> _settlementFoldouts = new Dictionary<PlayerSettlementInfo, bool>();
private Dictionary<PlayerTaskInfo, bool> _taskFoldouts = new Dictionary<PlayerTaskInfo, bool>();
[MenuItem("Tools/关卡编辑器")]
private static void ShowWindow()
{
var window = CreateWindow<MatchConfigEditorWindow>();
window.titleContent = new GUIContent("关卡编辑器");
window.Show();
}
private void OnEnable()
{
_levelStrList = new List<string>();
_mapNameList = new List<string>();
MatchConfigManager.Instance.Init();
RefreshMapNameList();
}
private void OnGUI()
{
if (_redBoxStyle == null)
{
_redBoxStyle = InspectorUtils.GetHelpBoxStyle();
InspectorUtils.AddBorder(_redBoxStyle, new Color(0.5f, 0.4f, 0.4f, 0.6f));
}
if (_whiteBoxStyle == null)
{
_whiteBoxStyle = InspectorUtils.GetHelpBoxStyle();
InspectorUtils.AddBorder(_whiteBoxStyle, new Color(1f, 1f, 1f, 0.2f));
}
GUI.skin.button.wordWrap = true;
_barPosition = EditorGUILayout.BeginScrollView(_barPosition);
EditorGUILayout.BeginHorizontal();
_newConfigId = (uint)EditorGUILayout.IntField((int)_newConfigId, GUILayout.Width(300));
if (InspectorUtils.InspectorButtonWithTextWidth("新增关卡"))
{
MatchConfigManager.Instance.AddMatchConfig(_newConfigId);
}
if (InspectorUtils.InspectorButtonWithTextWidth("刷新"))
{
RefreshMapNameList();
}
if (InspectorUtils.InspectorButtonWithTextWidth("保存"))
{
MatchConfigManager.Instance.SaveMatchLevelData();
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b> 选择关卡 : </b>");
var index = GetIndexInLevelList(_selectedId);
index = EditorGUILayout.Popup(index, _levelStrList.ToArray(), GUILayout.Width(300));
if (_levelStrList.Count != 0) _selectedId = uint.TryParse(_levelStrList[index], out var id) ? id : 0;
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
var mapConfig = MatchConfigManager.Instance.GetMatchConfig(_selectedId);
if(mapConfig != null) OnGUIMapConfig(mapConfig);
EditorGUILayout.EndScrollView();
}
private void OnGUIMapConfig(MapConfig mapConfig)
{
EditorGUILayout.BeginVertical();
// 基础配置
if (InspectorUtils.InspectorButtonWithTextWidth("删除关卡"))
{
if (EditorUtility.DisplayDialog("确认删除", $"确定要删除关卡 {mapConfig.Id} 吗?", "确定", "取消"))
{
MatchConfigManager.Instance.LevelData.LevelConfigs.Remove(mapConfig.Id);
_selectedId = 0;
}
}
InspectorUtils.InspectorTextWidthRich("<b>基础配置</b>");
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("关卡ID:");
mapConfig.Id = (uint)EditorGUILayout.IntField((int)mapConfig.Id, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("地图宽度:");
mapConfig.Width = (uint)EditorGUILayout.IntField((int)mapConfig.Width, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("地图高度:");
mapConfig.Height = (uint)EditorGUILayout.IntField((int)mapConfig.Height, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("玩家数量:");
mapConfig.PlayerCount = (uint)EditorGUILayout.IntField((int)mapConfig.PlayerCount, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("AI难度:");
mapConfig.AIDiff = (AIDifficult)EditorGUILayout.EnumPopup(mapConfig.AIDiff, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("是否开启回合限时");
mapConfig.IsLimitTime = EditorGUILayout.Toggle(mapConfig.IsLimitTime, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
if (mapConfig.IsLimitTime)
{
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("回合时长");
mapConfig.TimeLimitSeconds = EditorGUILayout.IntField(mapConfig.TimeLimitSeconds, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
}
// 单机配置
InspectorUtils.InspectorTextWidthRich("<b>单机配置</b>");
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("文明ID:");
mapConfig.selfCivId = (uint)EditorGUILayout.IntField((int)mapConfig.selfCivId, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("势力ID:");
mapConfig.selfForceId = (uint)EditorGUILayout.IntField((int)mapConfig.selfForceId, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
// 地图配置
InspectorUtils.InspectorTextWidthRich("<b>地图配置</b>");
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("自定义地图:");
mapConfig.IsCustomMap = EditorGUILayout.Toggle(mapConfig.IsCustomMap, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
if (mapConfig.IsCustomMap)
{
EditorGUILayout.BeginHorizontal();
if (_mapNameList.Count == 0) InspectorUtils.InspectorTextWidthRich("无地图可用");
else
{
InspectorUtils.InspectorTextWidthRich("地图名称:");
var mapIndex = GetIndexInMapNameList(mapConfig.MapName);
mapIndex = EditorGUILayout.Popup(mapIndex, _mapNameList.ToArray(), GUILayout.Width(200));
if (mapIndex >= 0 && mapIndex < _mapNameList.Count)
{
mapConfig.MapName = _mapNameList[mapIndex];
}
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.Space();
// Limit 配置
if (mapConfig.MatchLimits == null) mapConfig.MatchLimits = new List<MatchLimitType>();
InspectorUtils.InspectorTextWidthRich("<b>限制配置</b>");
EditorGUILayout.BeginHorizontal();
if (InspectorUtils.InspectorButtonWithTextWidth("添加限制"))
{
mapConfig.MatchLimits.Add(MatchLimitType.None);
mapConfig.RefreshLimits();
}
EditorGUILayout.EndHorizontal();
var deleteIndex = -1;
for (var i = 0; i < mapConfig.MatchLimits.Count; i++)
{
var limit = mapConfig.MatchLimits[i];
EditorGUILayout.BeginHorizontal();
mapConfig.MatchLimits[i] = (MatchLimitType)EditorGUILayout.EnumPopup(limit, GUILayout.Width(200));
InspectorUtils.InspectorTextWidthRich(MatchLimitData.GetMatchLimitTypeDesc(limit));
if (InspectorUtils.InspectorButtonWithTextWidth("x")) deleteIndex = i;
EditorGUILayout.EndHorizontal();
}
if (deleteIndex >= 0) mapConfig.MatchLimits.RemoveAt(deleteIndex);
EditorGUILayout.Space();
// 结算配置
InspectorUtils.InspectorTextWidthRich("<b>结算配置</b>");
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("对局结算类型:");
mapConfig.MatchSettlement = (MatchSettlementType)EditorGUILayout.EnumPopup(mapConfig.MatchSettlement, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
if (InspectorUtils.InspectorButtonWithTextWidth("添加玩家结算器"))
{
mapConfig.PlayerSettlements.Add(new PlayerSettlementInfo());
}
deleteIndex = -1;
for (int i = 0; i < mapConfig.PlayerSettlements.Count; i++)
{
if (OnGUIPlayerSettlement(mapConfig.PlayerSettlements[i], i)) deleteIndex = i;
}
if (deleteIndex >= 0) mapConfig.PlayerSettlements.RemoveAt(deleteIndex);
EditorGUILayout.EndVertical();
}
private bool OnGUIPlayerSettlement(PlayerSettlementInfo settlementInfo, int index)
{
EditorGUILayout.BeginVertical(_redBoxStyle, GUILayout.Width(500));
EditorGUILayout.BeginHorizontal(GUILayout.Width(150));
_settlementFoldouts.TryAdd(settlementInfo, false);
_settlementFoldouts[settlementInfo] = EditorGUILayout.Foldout(_settlementFoldouts[settlementInfo], $"玩家结算器 {index + 1}");
bool isDelete = InspectorUtils.InspectorButtonWithTextWidth("x");
if (!_settlementFoldouts[settlementInfo])
{
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
return isDelete;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("玩家结算类型:");
settlementInfo.SettlementType = (PlayerSettlementType)EditorGUILayout.EnumPopup(settlementInfo.SettlementType, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
if (settlementInfo.Tasks == null) settlementInfo.Tasks = new List<PlayerTaskInfo>();
EditorGUILayout.BeginHorizontal();
if (InspectorUtils.InspectorButtonWithTextWidth("添加任务"))
{
var newTask = new PlayerTaskInfo();
settlementInfo.Tasks.Add(newTask);
}
EditorGUILayout.EndHorizontal();
// 显示所有任务
var deleteIndex = -1;
for (int i = 0; i < settlementInfo.Tasks.Count; i++)
{
if(OnGUITask(settlementInfo.Tasks[i], i)) deleteIndex = i;
}
if (deleteIndex >= 0) settlementInfo.Tasks.RemoveAt(deleteIndex);
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
return isDelete;
}
private bool OnGUITask(PlayerTaskInfo taskInfo, int index)
{
EditorGUILayout.BeginVertical(_whiteBoxStyle, GUILayout.Width(500));
EditorGUILayout.BeginHorizontal(GUILayout.Width(150));
_taskFoldouts.TryAdd(taskInfo, false);
_taskFoldouts[taskInfo] = EditorGUILayout.Foldout(_taskFoldouts[taskInfo], $"任务 {index + 1}");
bool isDelete = InspectorUtils.InspectorButtonWithTextWidth("x");
if (!_taskFoldouts[taskInfo])
{
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
return isDelete;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("任务类型:");
taskInfo.TaskType = (PlayerTaskType)EditorGUILayout.EnumPopup(taskInfo.TaskType, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b> 描述: {PlayerTaskLogicFactory.GetPlayerTaskTypeDesc(taskInfo.TaskType)} </b> ");
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("参数1:");
taskInfo.Param1 = EditorGUILayout.IntField(taskInfo.Param1, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("参数2:");
taskInfo.Param2 = EditorGUILayout.IntField(taskInfo.Param2, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("参数3:");
taskInfo.Param3 = EditorGUILayout.IntField(taskInfo.Param3, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich("参数4:");
taskInfo.Param4 = (UnitType)EditorGUILayout.EnumPopup(taskInfo.Param4, GUILayout.Width(200));
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
return isDelete;
}
private int GetIndexInLevelList(uint id)
{
if (_levelStrList == null) return 0;
if (_levelStrList.Count != MatchConfigManager.Instance.LevelData.LevelConfigs.Count)
{
_levelStrList.Clear();
foreach (var kv in MatchConfigManager.Instance.LevelData.LevelConfigs)
{
_levelStrList.Add(kv.Value.Id.ToString());
}
}
for (int i = 0; i < _levelStrList.Count; i++)
{
if (_levelStrList[i] == id.ToString()) return i;
}
return 0;
}
private void RefreshMapNameList()
{
_mapNameList ??= new List<string>();
_mapNameList.Clear();
string folderPath = "Assets/Resources/MapRecord";
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
string[] files = Directory.GetFiles(folderPath, "*.bytes");
foreach (string file in files)
{
string fileName = Path.GetFileNameWithoutExtension(file);
if (!string.IsNullOrEmpty(fileName))
{
_mapNameList.Add(fileName);
}
}
LogSystem.LogInfo($"Init: 扫描完成,找到 {_mapNameList.Count} 个地图记录");
}
private int GetIndexInMapNameList(string mapName)
{
if (_mapNameList == null) return 0;
for (int i = 0; i < _mapNameList.Count; i++)
{
if (_mapNameList[i] == mapName) return i;
}
return 0;
}
}
}