257 lines
9.1 KiB
C#
257 lines
9.1 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using OfficeOpenXml;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
using Debug = UnityEngine.Debug;
|
||
|
||
namespace DesignTools.LimitedTimeEvent
|
||
{
|
||
/// <summary>
|
||
/// 小猫戏法限时事件常量配置工具
|
||
/// 读取 Docs/config/LimitedTimeEvent.xlsx 的 Const Sheet,仅编辑指定 Key 的 Value。
|
||
/// </summary>
|
||
public class CatTrickConstEditor : BaseDesignToolEditor
|
||
{
|
||
private const string LIMITED_TIME_EVENT_EXCEL_NAME = "LimitedTimeEvent.xlsx";
|
||
private const string CONST_SHEET_NAME = "Const";
|
||
private const int HEADER_ROW = 1;
|
||
private const int DATA_START_ROW = 3;
|
||
|
||
private const string KEY_CONSUME_ENERGY = "CatTrick_ConsumeEnergy";
|
||
private const string KEY_REWARD_DIAMOND = "CatTrick_RewardDiamond";
|
||
private const string LABEL_CONSUME_ENERGY = "小猫戏法每次获得钻石需要消耗的体力";
|
||
private const string LABEL_REWARD_DIAMOND = "每次领取的钻石数量";
|
||
|
||
private readonly List<CatTrickConstItem> constItems = new List<CatTrickConstItem>();
|
||
private int keyColumnIndex = -1;
|
||
private int valueColumnIndex = -1;
|
||
|
||
[MenuItem("策划工具/限时事件/小猫戏法")]
|
||
public static void ShowWindow()
|
||
{
|
||
CatTrickConstEditor window = GetWindow<CatTrickConstEditor>("小猫戏法");
|
||
window.minSize = window.GetMinWindowSize();
|
||
window.Show();
|
||
}
|
||
|
||
protected override string GetDocsPathPrefKey()
|
||
{
|
||
return "CatTrickConstEditor_DocsPath";
|
||
}
|
||
|
||
protected override string GetWindowTitle()
|
||
{
|
||
return "小猫戏法配置工具";
|
||
}
|
||
|
||
protected override Vector2 GetMinWindowSize()
|
||
{
|
||
return new Vector2(760, 420);
|
||
}
|
||
|
||
protected override void LoadConfigData()
|
||
{
|
||
LoadConstSheet();
|
||
}
|
||
|
||
protected override void DrawDataEditor()
|
||
{
|
||
EditorGUILayout.BeginVertical("box");
|
||
EditorGUILayout.HelpBox("仅会写回 LimitedTimeEvent.xlsx 的 Const Sheet,并且只修改 CatTrick_ConsumeEnergy 与 CatTrick_RewardDiamond 两个 Key 的 Value。", MessageType.Info);
|
||
EditorGUILayout.EndVertical();
|
||
|
||
EditorGUILayout.Space(6);
|
||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
||
|
||
foreach (CatTrickConstItem item in constItems)
|
||
{
|
||
DrawConstItem(item);
|
||
EditorGUILayout.Space(4);
|
||
}
|
||
|
||
EditorGUILayout.EndScrollView();
|
||
}
|
||
|
||
protected override void SaveDataToExcel()
|
||
{
|
||
SaveConstSheet();
|
||
}
|
||
|
||
private void LoadConstSheet()
|
||
{
|
||
constItems.Clear();
|
||
keyColumnIndex = -1;
|
||
valueColumnIndex = -1;
|
||
|
||
string excelPath = GetDocsConfigFilePath(LIMITED_TIME_EVENT_EXCEL_NAME);
|
||
if (!File.Exists(excelPath))
|
||
{
|
||
throw new FileNotFoundException($"未找到 {LIMITED_TIME_EVENT_EXCEL_NAME}", excelPath);
|
||
}
|
||
|
||
using (ExcelPackage package = new ExcelPackage(new FileInfo(excelPath)))
|
||
{
|
||
ExcelWorksheet worksheet = package.Workbook.Worksheets[CONST_SHEET_NAME];
|
||
if (worksheet == null)
|
||
{
|
||
throw new Exception($"{LIMITED_TIME_EVENT_EXCEL_NAME} 中未找到 Sheet: {CONST_SHEET_NAME}");
|
||
}
|
||
|
||
if (worksheet.Dimension == null)
|
||
{
|
||
throw new Exception($"{LIMITED_TIME_EVENT_EXCEL_NAME}/{CONST_SHEET_NAME} 没有可读取的数据");
|
||
}
|
||
|
||
keyColumnIndex = FindColumnIndex(worksheet, "Key");
|
||
valueColumnIndex = FindColumnIndex(worksheet, "Value");
|
||
|
||
if (keyColumnIndex < 0 || valueColumnIndex < 0)
|
||
{
|
||
throw new Exception($"{LIMITED_TIME_EVENT_EXCEL_NAME}/{CONST_SHEET_NAME} 表结构不正确,缺少 Key 或 Value 列");
|
||
}
|
||
|
||
int rowCount = worksheet.Dimension.End.Row;
|
||
for (int row = DATA_START_ROW; row <= rowCount; row++)
|
||
{
|
||
string key = worksheet.Cells[row, keyColumnIndex].Text.Trim();
|
||
if (string.IsNullOrEmpty(key))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (key != KEY_CONSUME_ENERGY && key != KEY_REWARD_DIAMOND)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
string valueText = worksheet.Cells[row, valueColumnIndex].Text.Trim();
|
||
if (!int.TryParse(valueText, out int value))
|
||
{
|
||
throw new Exception($"{CONST_SHEET_NAME} Sheet 第 {row} 行 Key={key} 的 Value 不是有效整数:{valueText}");
|
||
}
|
||
|
||
constItems.Add(new CatTrickConstItem
|
||
{
|
||
Key = key,
|
||
Value = value,
|
||
RowIndex = row
|
||
});
|
||
}
|
||
}
|
||
|
||
string[] missingKeys = new[] { KEY_CONSUME_ENERGY, KEY_REWARD_DIAMOND }
|
||
.Where(targetKey => constItems.All(item => item.Key != targetKey))
|
||
.ToArray();
|
||
|
||
if (missingKeys.Length > 0)
|
||
{
|
||
throw new Exception($"{CONST_SHEET_NAME} Sheet 缺少以下 Key:{string.Join("、", missingKeys)}");
|
||
}
|
||
|
||
constItems.Sort((left, right) => string.CompareOrdinal(left.Key, right.Key));
|
||
Debug.Log($"小猫戏法配置读取完成,共加载 {constItems.Count} 条数据");
|
||
}
|
||
|
||
private void DrawConstItem(CatTrickConstItem item)
|
||
{
|
||
EditorGUILayout.BeginVertical("box");
|
||
|
||
EditorGUILayout.LabelField(GetDisplayName(item.Key), EditorStyles.boldLabel);
|
||
EditorGUILayout.BeginHorizontal();
|
||
EditorGUILayout.LabelField("Value", GUILayout.Width(60));
|
||
item.Value = EditorGUILayout.IntField(item.Value, GUILayout.Width(180));
|
||
GUILayout.FlexibleSpace();
|
||
EditorGUILayout.EndHorizontal();
|
||
|
||
EditorGUILayout.BeginHorizontal();
|
||
GUILayout.Space(4);
|
||
EditorGUILayout.LabelField($"Excel 行号:{item.RowIndex}", EditorStyles.miniLabel);
|
||
EditorGUILayout.EndHorizontal();
|
||
|
||
EditorGUILayout.EndVertical();
|
||
}
|
||
|
||
private void SaveConstSheet()
|
||
{
|
||
if (constItems.Count == 0)
|
||
{
|
||
EditorUtility.DisplayDialog("提示", "当前没有可保存的数据,请先加载配置。", "确定");
|
||
return;
|
||
}
|
||
|
||
string excelPath = GetDocsConfigFilePath(LIMITED_TIME_EVENT_EXCEL_NAME);
|
||
if (!File.Exists(excelPath))
|
||
{
|
||
EditorUtility.DisplayDialog("错误", $"未找到文件:{excelPath}", "确定");
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
using (ExcelPackage package = new ExcelPackage(new FileInfo(excelPath)))
|
||
{
|
||
ExcelWorksheet worksheet = package.Workbook.Worksheets[CONST_SHEET_NAME];
|
||
if (worksheet == null)
|
||
{
|
||
EditorUtility.DisplayDialog("错误", $"未找到 Sheet: {CONST_SHEET_NAME}", "确定");
|
||
return;
|
||
}
|
||
|
||
foreach (CatTrickConstItem item in constItems)
|
||
{
|
||
worksheet.Cells[item.RowIndex, valueColumnIndex].Value = item.Value;
|
||
}
|
||
|
||
package.Save();
|
||
}
|
||
|
||
EditorUtility.DisplayDialog("成功", "小猫戏法配置已保存到 Excel!", "确定");
|
||
Debug.Log("小猫戏法配置保存成功");
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
EditorUtility.DisplayDialog("错误", $"保存失败: {e.Message}", "确定");
|
||
Debug.LogError($"保存小猫戏法配置失败: {e}");
|
||
}
|
||
}
|
||
|
||
private int FindColumnIndex(ExcelWorksheet worksheet, string columnName)
|
||
{
|
||
int columnCount = worksheet.Dimension?.End.Column ?? 0;
|
||
for (int col = 1; col <= columnCount; col++)
|
||
{
|
||
if (string.Equals(worksheet.Cells[HEADER_ROW, col].Text.Trim(), columnName, StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
return col;
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
private string GetDisplayName(string key)
|
||
{
|
||
switch (key)
|
||
{
|
||
case KEY_CONSUME_ENERGY:
|
||
return LABEL_CONSUME_ENERGY;
|
||
case KEY_REWARD_DIAMOND:
|
||
return LABEL_REWARD_DIAMOND;
|
||
default:
|
||
return key;
|
||
}
|
||
}
|
||
|
||
[Serializable]
|
||
private class CatTrickConstItem
|
||
{
|
||
public string Key;
|
||
public int Value;
|
||
public int RowIndex;
|
||
}
|
||
}
|
||
}
|