完成导表工具, 支持根据excel表生成表结构代码和加载数据代码

This commit is contained in:
小李xl 2023-06-05 01:41:21 +08:00
parent 275f5269f8
commit b841cbcf8d
53 changed files with 1512 additions and 786 deletions

4
.gitignore vendored
View File

@ -14,4 +14,6 @@
/DScript/DScript_Runtime/Backups
/DScript/DScript.sln.DotSettings.user
**/.idea
**/~$*
**/~$*
/DungeonShooting_ExcelTool/obj
/DungeonShooting_ExcelTool/bin

View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NPOI" Version="2.6.0" />
</ItemGroup>
<ItemGroup>
<None Include="excelFile/**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DungeonShooting_ExcelTool", "DungeonShooting_ExcelTool.csproj", "{F6A26370-A918-40F0-8D78-414213011172}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F6A26370-A918-40F0-8D78-414213011172}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F6A26370-A918-40F0-8D78-414213011172}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F6A26370-A918-40F0-8D78-414213011172}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F6A26370-A918-40F0-8D78-414213011172}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/PencilsConfiguration/ActualSeverity/@EntryValue">WARNING</s:String></wpf:ResourceDictionary>

View File

@ -0,0 +1,534 @@
using System.Text.Json;
using System.Text.RegularExpressions;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
public static class ExcelGenerator
{
private const string CodeOutPath = "src/config/";
private const string JsonOutPath = "resource/config/";
#if DEBUG
private const string ExcelFilePath = "excelFile";
#else
private const string ExcelFilePath = "excel/excelFile";
#endif
private class MappingData
{
public string TypeStr;
public string TypeName;
public MappingData(string typeStr, string typeName)
{
TypeStr = typeStr;
TypeName = typeName;
}
}
private class ExcelData
{
public string TableName;
public string OutCode;
public List<string> ColumnNames = new List<string>();
public Dictionary<string, MappingData> ColumnMappingData = new Dictionary<string, MappingData>();
public Dictionary<string, Type> ColumnType = new Dictionary<string, Type>();
public List<Dictionary<string, object>> DataList = new List<Dictionary<string, object>>();
}
public static bool ExportExcel()
{
Console.WriteLine("当前路径: " + Environment.CurrentDirectory);
try
{
var excelDataList = new List<ExcelData>();
var directoryInfo = new DirectoryInfo(ExcelFilePath);
if (directoryInfo.Exists)
{
var fileInfos = directoryInfo.GetFiles();
foreach (var fileInfo in fileInfos)
{
if (fileInfo.Extension == ".xlsx")
{
if (fileInfo.Name == "ExcelConfig.xlsx")
{
throw new Exception("excel表文件名称不允许叫'ExcelConfig.xlsx'!");
}
Console.WriteLine("excel表: " + fileInfo.FullName);
excelDataList.Add(ReadExcel(fileInfo.FullName));
}
}
}
Console.WriteLine($"一共检测到excel表共{excelDataList.Count}张.");
if (Directory.Exists(CodeOutPath))
{
Directory.Delete(CodeOutPath, true);
}
if (Directory.Exists(JsonOutPath))
{
Directory.Delete(JsonOutPath, true);
}
Directory.CreateDirectory(CodeOutPath);
Directory.CreateDirectory(JsonOutPath);
//保存配置和代码
foreach (var excelData in excelDataList)
{
File.WriteAllText(CodeOutPath + "ExcelConfig_" + excelData.TableName + ".cs", excelData.OutCode);
var config = new JsonSerializerOptions();
config.WriteIndented = true;
File.WriteAllText(JsonOutPath + excelData.TableName + ".json", JsonSerializer.Serialize(excelData.DataList, config));
}
//生成加载代码
var code = GeneratorInitCode(excelDataList);
File.WriteAllText(CodeOutPath + "ExcelConfig.cs", code);
}
catch (Exception e)
{
PrintError(e.ToString());
return false;
}
return true;
}
private static string GeneratorInitCode(List<ExcelData> excelList)
{
var code = $"using System;\n";
code += $"using System.Collections.Generic;\n";
code += $"using System.Text.Json;\n";
code += $"using Godot;\n";
code += $"\n";
code += $"namespace Config;\n";
code += $"\n";
code += $"public static partial class ExcelConfig\n";
code += $"{{\n";
var fieldCode = "";
var callFuncCode = "";
var funcCode = "";
foreach (var excelData in excelList)
{
var idName = excelData.ColumnNames[0];
var idTypeStr = excelData.ColumnMappingData[idName].TypeStr;
fieldCode += $" /// <summary>\n";
fieldCode += $" /// {excelData.TableName}.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同\n";
fieldCode += $" /// </summary>\n";
fieldCode += $" public static List<{excelData.TableName}> {excelData.TableName}_List {{ get; private set; }}\n";
fieldCode += $" /// <summary>\n";
fieldCode += $" /// {excelData.TableName}.xlsx表数据集合, 里 Map 形式存储, key 为 {idName}\n";
fieldCode += $" /// </summary>\n";
fieldCode += $" public static Dictionary<{idTypeStr}, {excelData.TableName}> {excelData.TableName}_Map {{ get; private set; }}\n";
fieldCode += $"\n";
callFuncCode += $" _Init{excelData.TableName}Config();\n";
funcCode += $" private static void _Init{excelData.TableName}Config()\n";
funcCode += $" {{\n";
funcCode += $" try\n";
funcCode += $" {{\n";
funcCode += $" var text = _ReadConfigAsText(\"res://resource/config/{excelData.TableName}.json\");\n";
funcCode += $" {excelData.TableName}_List = JsonSerializer.Deserialize<List<{excelData.TableName}>>(text);\n";
funcCode += $" {excelData.TableName}_Map = new Dictionary<{idTypeStr}, {excelData.TableName}>();\n";
funcCode += $" foreach (var item in {excelData.TableName}_List)\n";
funcCode += $" {{\n";
funcCode += $" {excelData.TableName}_Map.Add(item.{idName}, item);\n";
funcCode += $" }}\n";
funcCode += $" }}\n";
funcCode += $" catch (Exception e)\n";
funcCode += $" {{\n";
funcCode += $" GD.PrintErr(e.ToString());\n";
funcCode += $" throw new Exception(\"'{excelData.TableName}'!\");\n";
funcCode += $" }}\n";
funcCode += $" }}\n";
}
code += fieldCode;
code += $"\n";
code += $" private static bool _init = false;\n";
code += $" /// <summary>\n";
code += $" /// 初始化所有配置表数据\n";
code += $" /// </summary>\n";
code += $" public static void Init()\n";
code += $" {{\n";
code += $" if (_init) return;\n";
code += $" _init = true;\n";
code += $"\n";
code += callFuncCode;
code += $" }}\n";
code += funcCode;
code += $" private static string _ReadConfigAsText(string path)\n";
code += $" {{\n";
code += $" var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);\n";
code += $" var asText = file.GetAsText();\n";
code += $" file.Dispose();\n";
code += $" return asText;\n";
code += $" }}\n";
code += $"}}";
return code;
}
private static ExcelData ReadExcel(string excelPath)
{
var excelData = new ExcelData();
//文件名称
var fileName = Path.GetFileNameWithoutExtension(excelPath).FirstToUpper();
excelData.TableName = fileName;
//输出代码
var outStr = $"using System.Text.Json.Serialization;\n";
outStr += $"using System.Collections.Generic;\n\n";
outStr += $"namespace Config;\n\n";
outStr += $"public static partial class ExcelConfig\n{{\n";
outStr += $" public class {fileName}\n";
outStr += $" {{\n";
var sourceFile = excelPath;
//行数
var rowCount = -1;
//列数
var columnCount = -1;
//加载表数据
var workbook = new XSSFWorkbook(sourceFile);
using (workbook)
{
var sheet1 = workbook.GetSheet("Sheet1");
rowCount = sheet1.LastRowNum;
//先解析表中的列名, 注释, 类型
var names = sheet1.GetRow(0);
var descriptions = sheet1.GetRow(1);
var types = sheet1.GetRow(2);
columnCount = names.LastCellNum;
foreach (var cell in names)
{
//字段名称
var field = GetCellStringValue(cell);
if (string.IsNullOrEmpty(field))
{
if (cell.ColumnIndex == 0)
{
throw new Exception($"表'{fileName}'的列数为0!");
}
//到达最后一列了
columnCount = cell.ColumnIndex;
break;
}
field = field.FirstToUpper();
excelData.ColumnNames.Add(field);
var descriptionCell = descriptions.GetCell(cell.ColumnIndex);
//描述
string description;
if (descriptionCell != null)
{
description = GetCellStringValue(descriptionCell).Replace("\n", " <br/>\n /// ");
}
else
{
description = "";
}
//类型
var typeString = GetCellStringValue(types.GetCell(cell.ColumnIndex));
if (string.IsNullOrEmpty(typeString))
{
throw new Exception($"表'{fileName}'中'{field}'这一列类型为空!");
}
//尝试解析类型
MappingData mappingData;
try
{
mappingData = ConvertToType(typeString.Replace(" ", ""));
}
catch (Exception e)
{
PrintError(e.ToString());
throw new Exception($"表'{fileName}'中'{field}'这一列类型描述语法错误: {typeString}");
}
if (!excelData.ColumnMappingData.TryAdd(field, mappingData))
{
throw new Exception($"表'{fileName}'中存在相同名称的列: '{field}'!");
}
outStr += $" /// <summary>\n";
outStr += $" /// {description}\n";
outStr += $" /// </summary>\n";
outStr += $" [JsonInclude]\n";
outStr += $" public {mappingData.TypeStr} {field} {{ get; private set; }}\n\n";
}
outStr += " }\n";
outStr += "}";
//解析字段类型
foreach (var kv in excelData.ColumnMappingData)
{
var typeName = kv.Value.TypeName;
var type = Type.GetType(typeName);
if (type == null)
{
throw new Exception($"表'{fileName}'中'{kv.Key}'这一列类型未知! " + kv.Value.TypeStr);
}
excelData.ColumnType.Add(kv.Key, type);
}
//解析数据
for (int i = 3; i <= rowCount; i++)
{
Dictionary<string, object> data = null;
var row = sheet1.GetRow(i);
for (int j = 0; j < columnCount; j++)
{
var cell = row.GetCell(j);
var strValue = GetCellStringValue(cell);
//如果这一行的第一列数据为空, 则跳过这一行
if (j == 0 && string.IsNullOrEmpty(strValue))
{
break;
}
else if (data == null)
{
data = new Dictionary<string, object>();
excelData.DataList.Add(data);
}
var fieldName = excelData.ColumnNames[j];
var mappingData = excelData.ColumnMappingData[fieldName];
try
{
switch (mappingData.TypeStr)
{
case "bool":
case "boolean":
data.Add(fieldName, GetCellBooleanValue(cell));
break;
case "byte":
data.Add(fieldName, Convert.ToByte(GetCellNumberValue(cell)));
break;
case "sbyte":
data.Add(fieldName, Convert.ToSByte(GetCellNumberValue(cell)));
break;
case "short":
data.Add(fieldName, Convert.ToInt16(GetCellNumberValue(cell)));
break;
case "ushort":
data.Add(fieldName, Convert.ToUInt16(GetCellNumberValue(cell)));
break;
case "int":
data.Add(fieldName, Convert.ToInt32(GetCellNumberValue(cell)));
break;
case "uint":
data.Add(fieldName, Convert.ToUInt32(GetCellNumberValue(cell)));
break;
case "long":
data.Add(fieldName, Convert.ToInt64(GetCellNumberValue(cell)));
break;
case "ulong":
data.Add(fieldName, Convert.ToUInt64(GetCellNumberValue(cell)));
break;
case "float":
data.Add(fieldName, Convert.ToSingle(GetCellNumberValue(cell)));
break;
case "double":
data.Add(fieldName, GetCellNumberValue(cell));
break;
case "string":
data.Add(fieldName, GetCellStringValue(cell));
break;
default:
{
var cellStringValue = GetCellStringValue(cell);
if (cellStringValue.Length == 0)
{
data.Add(fieldName, null);
}
else
{
data.Add(fieldName, JsonSerializer.Deserialize(cellStringValue, excelData.ColumnType[fieldName]));
}
}
break;
}
}
catch (Exception e)
{
PrintError(e.ToString());
throw new Exception($"解析表'{fileName}'第'{i + 1}'行第'{j + 1}'列数据时发生异常");
}
}
}
}
excelData.OutCode = outStr;
return excelData;
}
private static string GetCellStringValue(ICell cell)
{
if (cell == null)
{
return "";
}
switch (cell.CellType)
{
case CellType.Numeric:
return cell.NumericCellValue.ToString();
case CellType.String:
return cell.StringCellValue;
case CellType.Formula:
return cell.CellFormula;
case CellType.Boolean:
return cell.BooleanCellValue ? "true" : "false";
}
return "";
}
private static double GetCellNumberValue(ICell cell)
{
if (cell == null)
{
return 0;
}
return cell.NumericCellValue;
}
private static bool GetCellBooleanValue(ICell cell)
{
if (cell == null)
{
return false;
}
return cell.BooleanCellValue;
}
private static MappingData ConvertToType(string str)
{
if (Regex.IsMatch(str, "^\\w+$"))
{
var typeStr = TypeStrMapping(str);
var typeName = TypeNameMapping(str);
return new MappingData(typeStr, typeName);
}
else if (str.StartsWith('{'))
{
var tempStr = str.Substring(1, str.Length - 2);
var index = tempStr.IndexOf(':');
if (index == -1)
{
throw new Exception("类型描述语法错误!");
}
var keyStr = tempStr.Substring(0, index);
if (!IsBaseType(keyStr))
{
throw new Exception($"字典key类型必须是基础类型!");
}
var type1 = ConvertToType(keyStr);
var type2 = ConvertToType(tempStr.Substring(index + 1));
var typeStr = $"Dictionary<{type1.TypeStr}, {type2.TypeStr}>";
var typeName = $"System.Collections.Generic.Dictionary`2[[{type1.TypeName}],[{type2.TypeName}]]";
return new MappingData(typeStr, typeName);
}
else if (str.StartsWith('['))
{
var tempStr = str.Substring(1, str.Length - 2);
var typeData = ConvertToType(tempStr);
var typeStr = typeData.TypeStr + "[]";
var typeName = typeData.TypeName + "[]";
return new MappingData(typeStr, typeName);
}
throw new Exception("类型描述语法错误!");
}
private static string TypeStrMapping(string typeName)
{
switch (typeName)
{
case "boolean": return "bool";
case "vector2": return "SerializeVector2";
case "vector3": return "SerializeVector3";
case "color": return "SerializeColor";
}
return typeName;
}
private static string TypeNameMapping(string typeName)
{
switch (typeName)
{
case "bool":
case "boolean": return typeof(bool).FullName;
case "byte": return typeof(byte).FullName;
case "sbyte": return typeof(sbyte).FullName;
case "short": return typeof(short).FullName;
case "ushort": return typeof(ushort).FullName;
case "int": return typeof(int).FullName;
case "uint": return typeof(uint).FullName;
case "long": return typeof(long).FullName;
case "ulong": return typeof(ulong).FullName;
case "string": return typeof(string).FullName;
case "float": return typeof(float).FullName;
case "double": return typeof(double).FullName;
case "vector2": return "SerializeVector2";
case "vector3": return "SerializeVector3";
case "color": return "SerializeColor";
}
return typeName;
}
private static bool IsBaseType(string typeName)
{
switch (typeName)
{
case "bool":
case "boolean":
case "byte":
case "sbyte":
case "short":
case "ushort":
case "int":
case "uint":
case "long":
case "ulong":
case "string":
case "float":
case "double":
return true;
}
return false;
}
private static void PrintError(string message)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(message);
Console.ResetColor();
}
/// <summary>
/// 字符串首字母小写
/// </summary>
public static string FirstToLower(this string str)
{
return str.Substring(0, 1).ToLower() + str.Substring(1);
}
/// <summary>
/// 字符串首字母大写
/// </summary>
public static string FirstToUpper(this string str)
{
return str.Substring(0, 1).ToUpper() + str.Substring(1);
}
}

View File

@ -0,0 +1,16 @@

public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("准备导出excel表...");
if (ExcelGenerator.ExportExcel())
{
Console.WriteLine("excel表导出成功!");
}
else
{
Console.WriteLine("excel表导出失败!");
}
}
}

View File

@ -0,0 +1,31 @@
using System.Text.Json.Serialization;
/// <summary>
/// 可序列化的 Color 对象
/// </summary>
public class SerializeColor
{
public SerializeColor(float r, float g, float b, float a)
{
R = r;
G = g;
B = b;
A = a;
}
public SerializeColor()
{
}
[JsonInclude]
public float R { get; private set; }
[JsonInclude]
public float G { get; private set; }
[JsonInclude]
public float B { get; private set; }
[JsonInclude]
public float A { get; private set; }
}

View File

@ -0,0 +1,30 @@

using System.Text.Json.Serialization;
/// <summary>
/// 可序列化的 Vector2 对象
/// </summary>
public class SerializeVector2
{
public SerializeVector2(float x, float y)
{
X = x;
Y = y;
}
public SerializeVector2(SerializeVector2 v)
{
X = v.X;
Y = v.Y;
}
public SerializeVector2()
{
}
[JsonInclude]
public float X { get; private set; }
[JsonInclude]
public float Y { get; private set; }
}

View File

@ -0,0 +1,32 @@
using System.Text.Json.Serialization;
/// <summary>
/// 可序列化的 Vector3 对象
/// </summary>
public class SerializeVector3
{
public SerializeVector3(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
public SerializeVector3(SerializeVector3 v)
{
X = v.X;
Y = v.Y;
}
public SerializeVector3()
{
}
[JsonInclude]
public float X { get; private set; }
[JsonInclude]
public float Y { get; private set; }
[JsonInclude]
public float Z { get; private set; }
}

View File

@ -6,10 +6,6 @@
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
</PropertyGroup>
<ItemGroup>
<Folder Include="src\config\" />
<Folder Include="src\game\ui\editorTools" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NPOI" Version="2.6.0" />
</ItemGroup>
</Project>

Binary file not shown.

View File

@ -0,0 +1,352 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v6.0/win-x64",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v6.0": {},
".NETCoreApp,Version=v6.0/win-x64": {
"DungeonShooting_ExcelTool/1.0.0": {
"dependencies": {
"NPOI": "2.6.0"
},
"runtime": {
"DungeonShooting_ExcelTool.dll": {}
}
},
"Enums.NET/4.0.0": {
"runtime": {
"lib/netcoreapp3.0/Enums.NET.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.0.0.0"
}
}
},
"MathNet.Numerics.Signed/4.15.0": {
"runtime": {
"lib/netstandard2.0/MathNet.Numerics.dll": {
"assemblyVersion": "4.15.0.0",
"fileVersion": "4.15.0.0"
}
}
},
"Microsoft.IO.RecyclableMemoryStream/2.2.0": {
"runtime": {
"lib/net5.0/Microsoft.IO.RecyclableMemoryStream.dll": {
"assemblyVersion": "2.2.0.0",
"fileVersion": "2.2.0.0"
}
}
},
"Microsoft.Win32.SystemEvents/6.0.0": {
"runtime": {
"runtimes/win/lib/net6.0/Microsoft.Win32.SystemEvents.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"NPOI/2.6.0": {
"dependencies": {
"Enums.NET": "4.0.0",
"MathNet.Numerics.Signed": "4.15.0",
"Microsoft.IO.RecyclableMemoryStream": "2.2.0",
"Portable.BouncyCastle": "1.9.0",
"SharpZipLib": "1.3.3",
"SixLabors.Fonts": "1.0.0-beta18",
"SixLabors.ImageSharp": "2.1.3",
"System.Configuration.ConfigurationManager": "6.0.0",
"System.Security.Cryptography.Xml": "6.0.1",
"System.Text.Encoding.CodePages": "6.0.0"
},
"runtime": {
"lib/net6.0/NPOI.OOXML.dll": {
"assemblyVersion": "2.6.0.0",
"fileVersion": "2.6.0.0"
},
"lib/net6.0/NPOI.OpenXml4Net.dll": {
"assemblyVersion": "2.6.0.0",
"fileVersion": "2.6.0.0"
},
"lib/net6.0/NPOI.OpenXmlFormats.dll": {
"assemblyVersion": "2.6.0.0",
"fileVersion": "2.6.0.0"
},
"lib/net6.0/NPOI.dll": {
"assemblyVersion": "2.6.0.0",
"fileVersion": "2.6.0.0"
}
}
},
"Portable.BouncyCastle/1.9.0": {
"runtime": {
"lib/netstandard2.0/BouncyCastle.Crypto.dll": {
"assemblyVersion": "1.9.0.0",
"fileVersion": "1.9.0.1"
}
}
},
"SharpZipLib/1.3.3": {
"runtime": {
"lib/netstandard2.1/ICSharpCode.SharpZipLib.dll": {
"assemblyVersion": "1.3.3.11",
"fileVersion": "1.3.3.11"
}
}
},
"SixLabors.Fonts/1.0.0-beta18": {
"runtime": {
"lib/netcoreapp3.1/SixLabors.Fonts.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"SixLabors.ImageSharp/2.1.3": {
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
"System.Text.Encoding.CodePages": "6.0.0"
},
"runtime": {
"lib/netcoreapp3.1/SixLabors.ImageSharp.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.1.3.0"
}
}
},
"System.Configuration.ConfigurationManager/6.0.0": {
"dependencies": {
"System.Security.Cryptography.ProtectedData": "6.0.0",
"System.Security.Permissions": "6.0.0"
},
"runtime": {
"lib/net6.0/System.Configuration.ConfigurationManager.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"System.Drawing.Common/6.0.0": {
"dependencies": {
"Microsoft.Win32.SystemEvents": "6.0.0"
},
"runtime": {
"runtimes/win/lib/net6.0/System.Drawing.Common.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"System.Formats.Asn1/6.0.0": {},
"System.Runtime.CompilerServices.Unsafe/6.0.0": {},
"System.Security.AccessControl/6.0.0": {},
"System.Security.Cryptography.Pkcs/6.0.1": {
"dependencies": {
"System.Formats.Asn1": "6.0.0"
},
"runtime": {
"runtimes/win/lib/net6.0/System.Security.Cryptography.Pkcs.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.522.21309"
}
}
},
"System.Security.Cryptography.ProtectedData/6.0.0": {
"runtime": {
"runtimes/win/lib/net6.0/System.Security.Cryptography.ProtectedData.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"System.Security.Cryptography.Xml/6.0.1": {
"dependencies": {
"System.Security.AccessControl": "6.0.0",
"System.Security.Cryptography.Pkcs": "6.0.1"
},
"runtime": {
"lib/net6.0/System.Security.Cryptography.Xml.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.822.36306"
}
}
},
"System.Security.Permissions/6.0.0": {
"dependencies": {
"System.Security.AccessControl": "6.0.0",
"System.Windows.Extensions": "6.0.0"
},
"runtime": {
"lib/net6.0/System.Security.Permissions.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"System.Text.Encoding.CodePages/6.0.0": {
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Windows.Extensions/6.0.0": {
"dependencies": {
"System.Drawing.Common": "6.0.0"
},
"runtime": {
"runtimes/win/lib/net6.0/System.Windows.Extensions.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
}
}
},
"libraries": {
"DungeonShooting_ExcelTool/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Enums.NET/4.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-d47SgeuGxKpalKhYoHqFkDPmO9SoE3amSwVNDoUdy4d675/tX7bLyZFHdjfo3Tobth9Y80VnjfasQ/PD4LqUuA==",
"path": "enums.net/4.0.0",
"hashPath": "enums.net.4.0.0.nupkg.sha512"
},
"MathNet.Numerics.Signed/4.15.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-LFjukMRatkg9dgRM7U/gM4uKgaWAX7E0lt3fsVDTPdtBIVuh7uPlksDie290br1/tv1a4Ar/Bz9ywCPSL8PhHg==",
"path": "mathnet.numerics.signed/4.15.0",
"hashPath": "mathnet.numerics.signed.4.15.0.nupkg.sha512"
},
"Microsoft.IO.RecyclableMemoryStream/2.2.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-uyjY/cqomw1irT4L7lDeg4sJ36MsjHg3wKqpGrBAdzvZaxo85yMF+sAA9RIzTV92fDxuUzjqksMqA0+SNMkMgA==",
"path": "microsoft.io.recyclablememorystream/2.2.0",
"hashPath": "microsoft.io.recyclablememorystream.2.2.0.nupkg.sha512"
},
"Microsoft.Win32.SystemEvents/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-hqTM5628jSsQiv+HGpiq3WKBl2c8v1KZfby2J6Pr7pEPlK9waPdgEO6b8A/+/xn/yZ9ulv8HuqK71ONy2tg67A==",
"path": "microsoft.win32.systemevents/6.0.0",
"hashPath": "microsoft.win32.systemevents.6.0.0.nupkg.sha512"
},
"NPOI/2.6.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Pwjo65CUH3MiRnBEbVo8ff31ZrDGdGyyFJyAEncmbTQ0/gYgDkBUnGKm20aLpdwCpPNLzvapZm8v5tx4S6qAWg==",
"path": "npoi/2.6.0",
"hashPath": "npoi.2.6.0.nupkg.sha512"
},
"Portable.BouncyCastle/1.9.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-eZZBCABzVOek+id9Xy04HhmgykF0wZg9wpByzrWN7q8qEI0Qen9b7tfd7w8VA3dOeesumMG7C5ZPy0jk7PSRHw==",
"path": "portable.bouncycastle/1.9.0",
"hashPath": "portable.bouncycastle.1.9.0.nupkg.sha512"
},
"SharpZipLib/1.3.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-N8+hwhsKZm25tDJfWpBSW7EGhH/R7EMuiX+KJ4C4u+fCWVc1lJ5zg1u3S1RPPVYgTqhx/C3hxrqUpi6RwK5+Tg==",
"path": "sharpziplib/1.3.3",
"hashPath": "sharpziplib.1.3.3.nupkg.sha512"
},
"SixLabors.Fonts/1.0.0-beta18": {
"type": "package",
"serviceable": true,
"sha512": "sha512-evykNmy/kEE9EAEKgZm3MNUYXuMHFfmcLUNPw7Ho5q7OI96GFkkIxBm+QaKOTPBKw+L0AjKOs+ArVg8P40Ac9g==",
"path": "sixlabors.fonts/1.0.0-beta18",
"hashPath": "sixlabors.fonts.1.0.0-beta18.nupkg.sha512"
},
"SixLabors.ImageSharp/2.1.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-8yonNRWX3vUE9k29ta0Hbfa0AEc0hbDjSH/nZ3vOTJEXmY6hLnGsjDKoz96Z+AgOsrdkAu6PdL/Ebaf70aitzw==",
"path": "sixlabors.imagesharp/2.1.3",
"hashPath": "sixlabors.imagesharp.2.1.3.nupkg.sha512"
},
"System.Configuration.ConfigurationManager/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-7T+m0kDSlIPTHIkPMIu6m6tV6qsMqJpvQWW2jIc2qi7sn40qxFo0q+7mEQAhMPXZHMKnWrnv47ntGlM/ejvw3g==",
"path": "system.configuration.configurationmanager/6.0.0",
"hashPath": "system.configuration.configurationmanager.6.0.0.nupkg.sha512"
},
"System.Drawing.Common/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-NfuoKUiP2nUWwKZN6twGqXioIe1zVD0RIj2t976A+czLHr2nY454RwwXs6JU9Htc6mwqL6Dn/nEL3dpVf2jOhg==",
"path": "system.drawing.common/6.0.0",
"hashPath": "system.drawing.common.6.0.0.nupkg.sha512"
},
"System.Formats.Asn1/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-T6fD00dQ3NTbPDy31m4eQUwKW84s03z0N2C8HpOklyeaDgaJPa/TexP4/SkORMSOwc7WhKifnA6Ya33AkzmafA==",
"path": "system.formats.asn1/6.0.0",
"hashPath": "system.formats.asn1.6.0.0.nupkg.sha512"
},
"System.Runtime.CompilerServices.Unsafe/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==",
"path": "system.runtime.compilerservices.unsafe/6.0.0",
"hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512"
},
"System.Security.AccessControl/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==",
"path": "system.security.accesscontrol/6.0.0",
"hashPath": "system.security.accesscontrol.6.0.0.nupkg.sha512"
},
"System.Security.Cryptography.Pkcs/6.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ynmbW2GjIGg9K1wXmVIRs4IlyDolf0JXNpzFQ8JCVgwM+myUC2JeUggl2PwQig2PNVMegKmN1aAx7WPQ8tI3vA==",
"path": "system.security.cryptography.pkcs/6.0.1",
"hashPath": "system.security.cryptography.pkcs.6.0.1.nupkg.sha512"
},
"System.Security.Cryptography.ProtectedData/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ==",
"path": "system.security.cryptography.protecteddata/6.0.0",
"hashPath": "system.security.cryptography.protecteddata.6.0.0.nupkg.sha512"
},
"System.Security.Cryptography.Xml/6.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-5e5bI28T0x73AwTsbuFP4qSRzthmU2C0Gqgg3AZ3KTxmSyA+Uhk31puA3srdaeWaacVnHhLdJywCzqOiEpbO/w==",
"path": "system.security.cryptography.xml/6.0.1",
"hashPath": "system.security.cryptography.xml.6.0.1.nupkg.sha512"
},
"System.Security.Permissions/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==",
"path": "system.security.permissions/6.0.0",
"hashPath": "system.security.permissions.6.0.0.nupkg.sha512"
},
"System.Text.Encoding.CodePages/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==",
"path": "system.text.encoding.codepages/6.0.0",
"hashPath": "system.text.encoding.codepages.6.0.0.nupkg.sha512"
},
"System.Windows.Extensions/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-IXoJOXIqc39AIe+CIR7koBtRGMiCt/LPM3lI+PELtDIy9XdyeSrwXFdWV9dzJ2Awl0paLWUaknLxFQ5HpHZUog==",
"path": "system.windows.extensions/6.0.0",
"hashPath": "system.windows.extensions.6.0.0.nupkg.sha512"
}
}
}

View File

@ -0,0 +1,12 @@
{
"runtimeOptions": {
"tfm": "net6.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "6.0.0"
},
"configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://kw3o772vpne"]
[ext_resource type="Script" path="res://src/game/ui/editorTools/EditorToolsPanel.cs" id="1_otnjl"]
[ext_resource type="Script" path="res://src/game/ui/editorTools/EditorToolsPanel.cs" id="1_qrlbl"]
[node name="EditorTools" type="Control"]
layout_mode = 3
@ -11,7 +11,7 @@ grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource("1_otnjl")
script = ExtResource("1_qrlbl")
[node name="ScrollContainer" type="ScrollContainer" parent="."]
layout_mode = 0

View File

@ -11,7 +11,7 @@ config_version=5
[application]
config/name="DungeonShooting"
run/main_scene="res://scene/test/TestReadExcel.tscn"
run/main_scene="res://scene/Main.tscn"
config/features=PackedStringArray("4.1", "C#")
config/icon="res://icon.png"

View File

@ -1,6 +1,6 @@
[gd_resource type="Theme" load_steps=78 format=3 uid="uid://ds668te2rph30"]
[ext_resource type="FontFile" uid="uid://cad0in7dtweo5" path="res://resource/font/VonwaonBitmap-16px.ttf" id="1_elq6j"]
[ext_resource type="FontFile" uid="uid://cad0in7dtweo5" path="res://resource/font/VonwaonBitmap-16px.ttf" id="1_gtn70"]
[sub_resource type="StyleBoxFlat" id="1"]
content_margin_left = 6.0
@ -352,7 +352,7 @@ bg_color = Color(0.260588, 0.156863, 0.724706, 0.8)
[sub_resource type="ImageTexture" id="58"]
[sub_resource type="Image" id="Image_tkjgp"]
[sub_resource type="Image" id="Image_se3lp"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 1, 255, 255, 255, 39, 255, 255, 255, 67, 255, 255, 255, 67, 255, 255, 255, 39, 255, 255, 255, 1, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 39, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 39, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 66, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 66, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 66, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 66, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 39, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 39, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 1, 255, 255, 255, 39, 255, 255, 255, 67, 255, 255, 255, 67, 255, 255, 255, 39, 255, 255, 255, 1, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "RGBA8",
@ -362,7 +362,7 @@ data = {
}
[sub_resource type="ImageTexture" id="60"]
image = SubResource("Image_tkjgp")
image = SubResource("Image_se3lp")
[sub_resource type="StyleBoxTexture" id="61"]
content_margin_left = 2.0
@ -372,7 +372,7 @@ content_margin_bottom = 2.0
texture = SubResource("60")
region_rect = Rect2(0, 0, 12, 12)
[sub_resource type="Image" id="Image_vh8j7"]
[sub_resource type="Image" id="Image_ekkc7"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 191, 191, 0, 247, 247, 247, 0, 248, 248, 248, 0, 248, 248, 248, 0, 247, 247, 247, 0, 191, 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 191, 191, 0, 191, 191, 191, 4, 247, 247, 247, 98, 248, 248, 248, 167, 248, 248, 248, 167, 247, 247, 247, 98, 191, 191, 191, 4, 191, 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 247, 247, 0, 247, 247, 247, 97, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 247, 247, 247, 97, 247, 247, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 248, 248, 0, 248, 248, 248, 164, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 164, 248, 248, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 248, 248, 0, 248, 248, 248, 164, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 164, 248, 248, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 247, 247, 0, 247, 247, 247, 97, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 247, 247, 247, 97, 247, 247, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 191, 191, 0, 191, 191, 191, 4, 247, 247, 247, 98, 248, 248, 248, 167, 248, 248, 248, 167, 247, 247, 247, 98, 191, 191, 191, 4, 191, 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 191, 191, 0, 247, 247, 247, 0, 248, 248, 248, 0, 248, 248, 248, 0, 247, 247, 247, 0, 191, 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "RGBA8",
@ -382,7 +382,7 @@ data = {
}
[sub_resource type="ImageTexture" id="63"]
image = SubResource("Image_vh8j7")
image = SubResource("Image_ekkc7")
[sub_resource type="StyleBoxTexture" id="64"]
content_margin_left = 2.0
@ -392,7 +392,7 @@ content_margin_bottom = 2.0
texture = SubResource("63")
region_rect = Rect2(0, 0, 12, 12)
[sub_resource type="Image" id="Image_285tr"]
[sub_resource type="Image" id="Image_tjuv8"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 0, 173, 173, 173, 0, 173, 173, 173, 0, 173, 173, 173, 0, 173, 173, 173, 0, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 0, 127, 127, 127, 4, 173, 173, 173, 97, 173, 173, 173, 166, 173, 173, 173, 166, 173, 173, 173, 97, 127, 127, 127, 4, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 0, 172, 172, 172, 96, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 172, 172, 172, 96, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 173, 173, 0, 173, 173, 173, 163, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 163, 173, 173, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 173, 173, 0, 173, 173, 173, 163, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 163, 173, 173, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 0, 172, 172, 172, 96, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 172, 172, 172, 96, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 0, 127, 127, 127, 4, 173, 173, 173, 97, 173, 173, 173, 166, 173, 173, 173, 166, 173, 173, 173, 97, 127, 127, 127, 4, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 0, 173, 173, 173, 0, 173, 173, 173, 0, 173, 173, 173, 0, 173, 173, 173, 0, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "RGBA8",
@ -402,7 +402,7 @@ data = {
}
[sub_resource type="ImageTexture" id="66"]
image = SubResource("Image_285tr")
image = SubResource("Image_tjuv8")
[sub_resource type="StyleBoxTexture" id="67"]
content_margin_left = 2.0
@ -412,7 +412,7 @@ content_margin_bottom = 2.0
texture = SubResource("66")
region_rect = Rect2(0, 0, 12, 12)
[sub_resource type="Image" id="Image_g5g1k"]
[sub_resource type="Image" id="Image_01xpj"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 4, 255, 255, 255, 16, 255, 255, 255, 16, 255, 255, 255, 4, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 16, 255, 255, 255, 21, 255, 255, 255, 21, 255, 255, 255, 16, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 16, 255, 255, 255, 21, 255, 255, 255, 21, 255, 255, 255, 16, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 4, 255, 255, 255, 16, 255, 255, 255, 16, 255, 255, 255, 4, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "RGBA8",
@ -422,7 +422,7 @@ data = {
}
[sub_resource type="ImageTexture" id="69"]
image = SubResource("Image_g5g1k")
image = SubResource("Image_01xpj")
[sub_resource type="StyleBoxTexture" id="70"]
content_margin_left = 0.0
@ -446,7 +446,7 @@ content_margin_top = 4.0
content_margin_right = 4.0
content_margin_bottom = 4.0
[sub_resource type="Image" id="Image_30y2k"]
[sub_resource type="Image" id="Image_wq66t"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 76, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 76, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 76, 255, 255, 255, 228, 255, 255, 255, 188, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 188, 255, 255, 255, 228, 255, 255, 255, 76, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 18, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 187, 255, 255, 255, 17, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 187, 255, 255, 255, 229, 255, 255, 255, 188, 255, 255, 255, 18, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 185, 255, 255, 255, 17, 255, 255, 255, 17, 255, 255, 255, 186, 255, 255, 255, 229, 255, 255, 255, 188, 255, 255, 255, 19, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 190, 255, 255, 255, 229, 255, 255, 255, 185, 255, 255, 255, 185, 255, 255, 255, 229, 255, 255, 255, 189, 255, 255, 255, 19, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 191, 255, 255, 255, 229, 255, 255, 255, 229, 255, 255, 255, 190, 255, 255, 255, 19, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 229, 255, 255, 255, 188, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 188, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 187, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 187, 255, 255, 255, 229, 255, 255, 255, 188, 255, 255, 255, 18, 255, 255, 255, 19, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 186, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 185, 255, 255, 255, 229, 255, 255, 255, 189, 255, 255, 255, 19, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 189, 255, 255, 255, 229, 255, 255, 255, 185, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 76, 255, 255, 255, 229, 255, 255, 255, 190, 255, 255, 255, 19, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 190, 255, 255, 255, 229, 255, 255, 255, 76, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 77, 255, 255, 255, 19, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 77, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "RGBA8",
@ -456,7 +456,7 @@ data = {
}
[sub_resource type="ImageTexture" id="56"]
image = SubResource("Image_30y2k")
image = SubResource("Image_wq66t")
[sub_resource type="StyleBoxFlat" id="57"]
content_margin_left = 6.0
@ -506,7 +506,7 @@ texture = SubResource("69")
region_rect = Rect2(0, 0, 12, 12)
[resource]
default_font = ExtResource("1_elq6j")
default_font = ExtResource("1_gtn70")
default_font_size = 32
Button/colors/font_color = Color(0.780392, 0.780392, 0.780392, 1)
Button/colors/font_color_disabled = Color(1, 1, 1, 0.3)
@ -516,7 +516,7 @@ Button/colors/font_color_pressed = Color(0.117647, 0.431373, 0.905882, 1)
Button/colors/icon_color_hover = Color(1.15, 1.15, 1.15, 1)
Button/colors/icon_color_pressed = Color(0.135294, 0.496079, 1.04176, 1)
Button/constants/hseparation = 2
Button/fonts/font = ExtResource("1_elq6j")
Button/fonts/font = ExtResource("1_gtn70")
Button/styles/disabled = SubResource("1")
Button/styles/focus = SubResource("2")
Button/styles/hover = SubResource("3")
@ -618,7 +618,7 @@ Label/constants/line_spacing = 3
Label/constants/shadow_as_outline = 0
Label/constants/shadow_offset_x = 1
Label/constants/shadow_offset_y = 1
Label/fonts/font = ExtResource("1_elq6j")
Label/fonts/font = ExtResource("1_gtn70")
Label/styles/normal = SubResource("54")
LineEdit/colors/clear_button_color = Color(0.780392, 0.780392, 0.780392, 1)
LineEdit/colors/clear_button_color_pressed = Color(0.117647, 0.431373, 0.905882, 1)
@ -629,7 +629,7 @@ LineEdit/colors/font_color_uneditable = Color(1, 1, 1, 0.65)
LineEdit/colors/read_only = Color(1, 1, 1, 0.3)
LineEdit/colors/selection_color = Color(0.117647, 0.431373, 0.905882, 0.4)
LineEdit/constants/minimum_spaces = 12
LineEdit/fonts/font = ExtResource("1_elq6j")
LineEdit/fonts/font = ExtResource("1_gtn70")
LineEdit/icons/clear = SubResource("56")
LineEdit/styles/focus = SubResource("2")
LineEdit/styles/normal = SubResource("4")

View File

@ -1,7 +1,7 @@
[gd_scene load_steps=5 format=3 uid="uid://lbe753cb8heb"]
[ext_resource type="Script" path="res://src/game/GameApplication.cs" id="1_lgroc"]
[ext_resource type="Script" path="res://src/game/camera/GameCamera.cs" id="2_kdkre"]
[ext_resource type="Script" path="res://src/game/GameApplication.cs" id="1_vsjst"]
[ext_resource type="Script" path="res://src/game/camera/GameCamera.cs" id="2_v4b0g"]
[sub_resource type="Shader" id="1"]
code = "shader_type canvas_item;
@ -21,7 +21,7 @@ shader = SubResource("1")
shader_parameter/offset = Vector2(0, 0)
[node name="Main" type="Node2D" node_paths=PackedStringArray("SubViewport", "SubViewportContainer", "SceneRoot", "GlobalNodeRoot")]
script = ExtResource("1_lgroc")
script = ExtResource("1_vsjst")
SubViewport = NodePath("ViewCanvas/SubViewportContainer/SubViewport")
SubViewportContainer = NodePath("ViewCanvas/SubViewportContainer")
SceneRoot = NodePath("ViewCanvas/SubViewportContainer/SubViewport/SceneRoot")
@ -49,6 +49,6 @@ position = Vector2(253, 219)
process_callback = 0
limit_smoothed = true
editor_draw_drag_margin = true
script = ExtResource("2_kdkre")
script = ExtResource("2_v4b0g")
[node name="GlobalNodeRoot" type="Node2D" parent="."]

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://deq562id5sngp"]
[ext_resource type="Script" path="res://src/test/TestReadExcel.cs" id="1_1jhga"]
[ext_resource type="Script" path="res://src/test/TestReadExcel.cs" id="1_5kr2c"]
[node name="TestReadExcel" type="Node2D"]
script = ExtResource("1_1jhga")
script = ExtResource("1_5kr2c")

View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using Godot;
namespace Config;
public static partial class ExcelConfig
{
/// <summary>
/// Role.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
/// </summary>
public static List<Role> Role_List { get; private set; }
/// <summary>
/// Role.xlsx表数据集合, 里 Map 形式存储, key 为 Id
/// </summary>
public static Dictionary<string, Role> Role_Map { get; private set; }
/// <summary>
/// Weapon.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
/// </summary>
public static List<Weapon> Weapon_List { get; private set; }
/// <summary>
/// Weapon.xlsx表数据集合, 里 Map 形式存储, key 为 Id
/// </summary>
public static Dictionary<string, Weapon> Weapon_Map { get; private set; }
private static bool _init = false;
/// <summary>
/// 初始化所有配置表数据
/// </summary>
public static void Init()
{
if (_init) return;
_init = true;
_InitRoleConfig();
_InitWeaponConfig();
}
private static void _InitRoleConfig()
{
try
{
var text = _ReadConfigAsText("res://resource/config/Role.json");
Role_List = JsonSerializer.Deserialize<List<Role>>(text);
Role_Map = new Dictionary<string, Role>();
foreach (var item in Role_List)
{
Role_Map.Add(item.Id, item);
}
}
catch (Exception e)
{
GD.PrintErr(e.ToString());
throw new Exception("初始化表'Role'失败!");
}
}
private static void _InitWeaponConfig()
{
try
{
var text = _ReadConfigAsText("res://resource/config/Weapon.json");
Weapon_List = JsonSerializer.Deserialize<List<Weapon>>(text);
Weapon_Map = new Dictionary<string, Weapon>();
foreach (var item in Weapon_List)
{
Weapon_Map.Add(item.Id, item);
}
}
catch (Exception e)
{
GD.PrintErr(e.ToString());
throw new Exception("初始化表'Weapon'失败!");
}
}
private static string _ReadConfigAsText(string path)
{
var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
var asText = file.GetAsText();
file.Dispose();
return asText;
}
}

View File

@ -0,0 +1,48 @@
using System.Text.Json.Serialization;
using System.Collections.Generic;
namespace Config;
public static partial class ExcelConfig
{
public class Role
{
/// <summary>
/// 物体唯一id <br/>
/// 不需要添加类型前缀
/// </summary>
[JsonInclude]
public string Id { get; private set; }
/// <summary>
/// 222
/// </summary>
[JsonInclude]
public string[] A { get; private set; }
/// <summary>
///
/// </summary>
[JsonInclude]
public Dictionary<string, int> B { get; private set; }
/// <summary>
///
/// </summary>
[JsonInclude]
public Dictionary<string, string[]>[] C { get; private set; }
/// <summary>
/// 123
/// </summary>
[JsonInclude]
public SerializeVector2 D { get; private set; }
/// <summary>
///
/// </summary>
[JsonInclude]
public SerializeVector2[] E { get; private set; }
}
}

View File

@ -0,0 +1,261 @@
using System.Text.Json.Serialization;
using System.Collections.Generic;
namespace Config;
public static partial class ExcelConfig
{
public class Weapon
{
/// <summary>
/// 物体唯一id <br/>
/// 不需要添加类型前缀
/// </summary>
[JsonInclude]
public string Id { get; private set; }
/// <summary>
/// 武器 Prefab, 必须继承场景 "res://prefab/weapon/Weapon.tscn"
/// </summary>
[JsonInclude]
public string Prefab { get; private set; }
/// <summary>
/// 重量
/// </summary>
[JsonInclude]
public float Weight { get; private set; }
/// <summary>
/// 武器显示的名称
/// </summary>
[JsonInclude]
public string Name { get; private set; }
/// <summary>
/// 武器的图标
/// </summary>
[JsonInclude]
public string Icon { get; private set; }
/// <summary>
/// 武器类型: <br/>
/// 1.副武器 <br/>
/// 2.主武器 <br/>
/// 3.重型武器
/// </summary>
[JsonInclude]
public byte WeightType { get; private set; }
/// <summary>
/// 是否连续发射, 如果为false, 则每次发射都需要扣动扳机
/// </summary>
[JsonInclude]
public bool ContinuousShoot { get; private set; }
/// <summary>
/// 弹夹容量
/// </summary>
[JsonInclude]
public int AmmoCapacity { get; private set; }
/// <summary>
/// 弹药容量上限
/// </summary>
[JsonInclude]
public int MaxAmmoCapacity { get; private set; }
/// <summary>
/// 起始备用弹药数量
/// </summary>
[JsonInclude]
public int StandbyAmmoCapacity { get; private set; }
/// <summary>
/// 装弹时间, 单位: 秒
/// </summary>
[JsonInclude]
public float ReloadTime { get; private set; }
/// <summary>
/// 每粒子弹是否是单独装填, 如果是, 那么每上一发子弹的时间就是 ReloadTime, 可以做霰弹武器装填效果
/// </summary>
[JsonInclude]
public bool AloneReload { get; private set; }
/// <summary>
/// 单独装填时每次装填子弹数量, 必须要将 'AloneReload' 属性设置为 true
/// </summary>
[JsonInclude]
public int AloneReloadCount { get; private set; }
/// <summary>
/// 单独装填的子弹时可以立即射击, 必须要将 'AloneReload' 属性设置为 true
/// </summary>
[JsonInclude]
public bool AloneReloadCanShoot { get; private set; }
/// <summary>
/// 是否为松发开火, 也就是松开扳机才开火, 若要启用该属性, 必须将 'ContinuousShoot' 设置为 false
/// </summary>
[JsonInclude]
public bool LooseShoot { get; private set; }
/// <summary>
/// 最少需要蓄力多久才能开火, 必须将 'LooseShoot' 设置为 true
/// </summary>
[JsonInclude]
public float MinChargeTime { get; private set; }
/// <summary>
/// 连续发射最小次数, 仅当 ContinuousShoot 为 false 时生效
/// </summary>
[JsonInclude]
public int MinContinuousCount { get; private set; }
/// <summary>
/// 连续发射最大次数, 仅当 ContinuousShoot 为 false 时生效
/// </summary>
[JsonInclude]
public int MaxContinuousCount { get; private set; }
/// <summary>
/// 按下一次扳机后需要多长时间才能再次感应按下
/// </summary>
[JsonInclude]
public float TriggerInterval { get; private set; }
/// <summary>
/// 初始射速, 初始每分钟能开火次数
/// </summary>
[JsonInclude]
public float StartFiringSpeed { get; private set; }
/// <summary>
/// 最终射速, 最终每分钟能开火次数, 仅当 ContinuousShoot 为 true 时生效
/// </summary>
[JsonInclude]
public float FinalFiringSpeed { get; private set; }
/// <summary>
/// 按下扳机并开火后射速增加速率
/// </summary>
[JsonInclude]
public float FiringSpeedAddSpeed { get; private set; }
/// <summary>
/// 松开扳机后射速消散速率
/// </summary>
[JsonInclude]
public float FiringSpeedBackSpeed { get; private set; }
/// <summary>
/// 单次开火发射子弹最小数量
/// </summary>
[JsonInclude]
public int MinFireBulletCount { get; private set; }
/// <summary>
/// 单次开火发射子弹最大数量
/// </summary>
[JsonInclude]
public int MaxFireBulletCount { get; private set; }
/// <summary>
/// 开火前延时
/// </summary>
[JsonInclude]
public float DelayedTime { get; private set; }
/// <summary>
/// 初始散射半径
/// </summary>
[JsonInclude]
public float StartScatteringRange { get; private set; }
/// <summary>
/// 最终散射半径
/// </summary>
[JsonInclude]
public float FinalScatteringRange { get; private set; }
/// <summary>
/// 每次发射后散射增加值
/// </summary>
[JsonInclude]
public float ScatteringRangeAddValue { get; private set; }
/// <summary>
/// 松开扳机后散射销退速率
/// </summary>
[JsonInclude]
public float ScatteringRangeBackSpeed { get; private set; }
/// <summary>
/// 松开扳机多久后开始销退散射值 (单位: 秒)
/// </summary>
[JsonInclude]
public float ScatteringRangeBackTime { get; private set; }
/// <summary>
/// 子弹飞行最大距离
/// </summary>
[JsonInclude]
public float MaxDistance { get; private set; }
/// <summary>
/// 子弹飞行最小距离
/// </summary>
[JsonInclude]
public float MinDistance { get; private set; }
/// <summary>
/// 最大后坐力 (仅用于开火后武器身抖动)
/// </summary>
[JsonInclude]
public float MaxBacklash { get; private set; }
/// <summary>
/// 最小后坐力 (仅用于开火后武器身抖动)
/// </summary>
[JsonInclude]
public float MinBacklash { get; private set; }
/// <summary>
/// 后坐力偏移回归回归速度
/// </summary>
[JsonInclude]
public float BacklashRegressionSpeed { get; private set; }
/// <summary>
/// 开火后武器口上抬角度
/// </summary>
[JsonInclude]
public float UpliftAngle { get; private set; }
/// <summary>
/// 武器默认上抬角度
/// </summary>
[JsonInclude]
public float DefaultAngle { get; private set; }
/// <summary>
/// 开火后武器口角度恢复速度倍数
/// </summary>
[JsonInclude]
public float UpliftAngleRestore { get; private set; }
/// <summary>
/// 默认射出的子弹id
/// </summary>
[JsonInclude]
public string BulletId { get; private set; }
/// <summary>
/// 投抛状态下物体碰撞器大小
/// </summary>
[JsonInclude]
public SerializeVector2 ThrowCollisionSize { get; private set; }
}
}

View File

@ -1,45 +0,0 @@
using System.Text.Json.Serialization;
using System.Collections.Generic;
namespace Config;
public class Role
{
/// <summary>
/// 物体唯一id <br/>
/// 不需要添加类型前缀
/// </summary>
[JsonInclude]
public string Id { get; private set; }
/// <summary>
/// 222
/// </summary>
[JsonInclude]
public string[] A { get; private set; }
/// <summary>
///
/// </summary>
[JsonInclude]
public Dictionary<string, int> B { get; private set; }
/// <summary>
///
/// </summary>
[JsonInclude]
public Dictionary<string, string[]>[] C { get; private set; }
/// <summary>
/// 123
/// </summary>
[JsonInclude]
public SerializeVector2 D { get; private set; }
/// <summary>
///
/// </summary>
[JsonInclude]
public SerializeVector2[] E { get; private set; }
}

View File

@ -1,258 +0,0 @@
using System.Text.Json.Serialization;
using System.Collections.Generic;
namespace Config;
public class Weapon
{
/// <summary>
/// 物体唯一id <br/>
/// 不需要添加类型前缀
/// </summary>
[JsonInclude]
public string Id { get; private set; }
/// <summary>
/// 武器 Prefab, 必须继承场景 "res://prefab/weapon/Weapon.tscn"
/// </summary>
[JsonInclude]
public string Prefab { get; private set; }
/// <summary>
/// 重量
/// </summary>
[JsonInclude]
public float Weight { get; private set; }
/// <summary>
/// 武器显示的名称
/// </summary>
[JsonInclude]
public string Name { get; private set; }
/// <summary>
/// 武器的图标
/// </summary>
[JsonInclude]
public string Icon { get; private set; }
/// <summary>
/// 武器类型: <br/>
/// 1.副武器 <br/>
/// 2.主武器 <br/>
/// 3.重型武器
/// </summary>
[JsonInclude]
public byte WeightType { get; private set; }
/// <summary>
/// 是否连续发射, 如果为false, 则每次发射都需要扣动扳机
/// </summary>
[JsonInclude]
public bool ContinuousShoot { get; private set; }
/// <summary>
/// 弹夹容量
/// </summary>
[JsonInclude]
public int AmmoCapacity { get; private set; }
/// <summary>
/// 弹药容量上限
/// </summary>
[JsonInclude]
public int MaxAmmoCapacity { get; private set; }
/// <summary>
/// 起始备用弹药数量
/// </summary>
[JsonInclude]
public int StandbyAmmoCapacity { get; private set; }
/// <summary>
/// 装弹时间, 单位: 秒
/// </summary>
[JsonInclude]
public float ReloadTime { get; private set; }
/// <summary>
/// 每粒子弹是否是单独装填, 如果是, 那么每上一发子弹的时间就是 ReloadTime, 可以做霰弹武器装填效果
/// </summary>
[JsonInclude]
public bool AloneReload { get; private set; }
/// <summary>
/// 单独装填时每次装填子弹数量, 必须要将 'AloneReload' 属性设置为 true
/// </summary>
[JsonInclude]
public int AloneReloadCount { get; private set; }
/// <summary>
/// 单独装填的子弹时可以立即射击, 必须要将 'AloneReload' 属性设置为 true
/// </summary>
[JsonInclude]
public bool AloneReloadCanShoot { get; private set; }
/// <summary>
/// 是否为松发开火, 也就是松开扳机才开火, 若要启用该属性, 必须将 'ContinuousShoot' 设置为 false
/// </summary>
[JsonInclude]
public bool LooseShoot { get; private set; }
/// <summary>
/// 最少需要蓄力多久才能开火, 必须将 'LooseShoot' 设置为 true
/// </summary>
[JsonInclude]
public float MinChargeTime { get; private set; }
/// <summary>
/// 连续发射最小次数, 仅当 ContinuousShoot 为 false 时生效
/// </summary>
[JsonInclude]
public int MinContinuousCount { get; private set; }
/// <summary>
/// 连续发射最大次数, 仅当 ContinuousShoot 为 false 时生效
/// </summary>
[JsonInclude]
public int MaxContinuousCount { get; private set; }
/// <summary>
/// 按下一次扳机后需要多长时间才能再次感应按下
/// </summary>
[JsonInclude]
public float TriggerInterval { get; private set; }
/// <summary>
/// 初始射速, 初始每分钟能开火次数
/// </summary>
[JsonInclude]
public float StartFiringSpeed { get; private set; }
/// <summary>
/// 最终射速, 最终每分钟能开火次数, 仅当 ContinuousShoot 为 true 时生效
/// </summary>
[JsonInclude]
public float FinalFiringSpeed { get; private set; }
/// <summary>
/// 按下扳机并开火后射速增加速率
/// </summary>
[JsonInclude]
public float FiringSpeedAddSpeed { get; private set; }
/// <summary>
/// 松开扳机后射速消散速率
/// </summary>
[JsonInclude]
public float FiringSpeedBackSpeed { get; private set; }
/// <summary>
/// 单次开火发射子弹最小数量
/// </summary>
[JsonInclude]
public int MinFireBulletCount { get; private set; }
/// <summary>
/// 单次开火发射子弹最大数量
/// </summary>
[JsonInclude]
public int MaxFireBulletCount { get; private set; }
/// <summary>
/// 开火前延时
/// </summary>
[JsonInclude]
public float DelayedTime { get; private set; }
/// <summary>
/// 初始散射半径
/// </summary>
[JsonInclude]
public float StartScatteringRange { get; private set; }
/// <summary>
/// 最终散射半径
/// </summary>
[JsonInclude]
public float FinalScatteringRange { get; private set; }
/// <summary>
/// 每次发射后散射增加值
/// </summary>
[JsonInclude]
public float ScatteringRangeAddValue { get; private set; }
/// <summary>
/// 松开扳机后散射销退速率
/// </summary>
[JsonInclude]
public float ScatteringRangeBackSpeed { get; private set; }
/// <summary>
/// 松开扳机多久后开始销退散射值 (单位: 秒)
/// </summary>
[JsonInclude]
public float ScatteringRangeBackTime { get; private set; }
/// <summary>
/// 子弹飞行最大距离
/// </summary>
[JsonInclude]
public float MaxDistance { get; private set; }
/// <summary>
/// 子弹飞行最小距离
/// </summary>
[JsonInclude]
public float MinDistance { get; private set; }
/// <summary>
/// 最大后坐力 (仅用于开火后武器身抖动)
/// </summary>
[JsonInclude]
public float MaxBacklash { get; private set; }
/// <summary>
/// 最小后坐力 (仅用于开火后武器身抖动)
/// </summary>
[JsonInclude]
public float MinBacklash { get; private set; }
/// <summary>
/// 后坐力偏移回归回归速度
/// </summary>
[JsonInclude]
public float BacklashRegressionSpeed { get; private set; }
/// <summary>
/// 开火后武器口上抬角度
/// </summary>
[JsonInclude]
public float UpliftAngle { get; private set; }
/// <summary>
/// 武器默认上抬角度
/// </summary>
[JsonInclude]
public float DefaultAngle { get; private set; }
/// <summary>
/// 开火后武器口角度恢复速度倍数
/// </summary>
[JsonInclude]
public float UpliftAngleRestore { get; private set; }
/// <summary>
/// 默认射出的子弹id
/// </summary>
[JsonInclude]
public string BulletId { get; private set; }
/// <summary>
/// 投抛状态下物体碰撞器大小
/// </summary>
[JsonInclude]
public SerializeVector2 ThrowCollisionSize { get; private set; }
}

View File

@ -1,415 +1,17 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Text.RegularExpressions;
using Godot;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Godot;
using Godot.Collections;
namespace Generator;
public static class ExcelGenerator
{
private class MappingData
public static void ExportExcel()
{
public string TypeStr;
public string TypeName;
public MappingData(string typeStr, string typeName)
var arr = new Array();
OS.Execute("excel/DungeonShooting_ExcelTool.exe", new string[0], arr);
foreach (var message in arr)
{
TypeStr = typeStr;
TypeName = typeName;
GD.Print(message);
}
}
private class ExcelData
{
public string TableName;
public string OutCode;
public List<string> ColumnNames = new List<string>();
public Dictionary<string, MappingData> ColumnMappingData = new Dictionary<string, MappingData>();
public Dictionary<string, Type> ColumnType = new Dictionary<string, Type>();
public List<Dictionary<string, object>> DataList = new List<Dictionary<string, object>>();
}
public static bool ExportExcel()
{
GD.Print("准备导出excel表...");
try
{
var excelDataList = new List<ExcelData>();
var directoryInfo = new DirectoryInfo(GameConfig.ExcelFilePath);
if (directoryInfo.Exists)
{
var fileInfos = directoryInfo.GetFiles();
foreach (var fileInfo in fileInfos)
{
if (fileInfo.Extension == ".xlsx")
{
GD.Print("excel表: " + fileInfo.FullName);
excelDataList.Add(ReadExcel(fileInfo.FullName));
}
}
}
if (Directory.Exists("src/config"))
{
Directory.Delete("src/config", true);
}
if (Directory.Exists("resource/config"))
{
Directory.Delete("resource/config", true);
}
Directory.CreateDirectory("resource/config");
Directory.CreateDirectory("src/config");
//保存配置和代码
foreach (var excelData in excelDataList)
{
File.WriteAllText("src/config/" + excelData.TableName + ".cs", excelData.OutCode);
var config = new JsonSerializerOptions();
config.WriteIndented = true;
File.WriteAllText("resource/config/" + excelData.TableName + ".json", JsonSerializer.Serialize(excelData.DataList, config));
}
}
catch (Exception e)
{
GD.PrintErr(e.ToString());
return false;
}
return true;
}
private static ExcelData ReadExcel(string excelPath)
{
var excelData = new ExcelData();
//文件名称
var fileName = Path.GetFileNameWithoutExtension(excelPath).FirstToUpper();
excelData.TableName = fileName;
//输出代码
var outStr = $"using System.Text.Json.Serialization;\n";
outStr += $"using System.Collections.Generic;\n\n";
outStr += $"namespace Config;\n\n";
outStr += $"public class {fileName}\n{{\n";
var sourceFile = excelPath;
//行数
var rowCount = -1;
//列数
var columnCount = -1;
//加载表数据
var workbook = new XSSFWorkbook(sourceFile);
using (workbook)
{
var sheet1 = workbook.GetSheet("Sheet1");
rowCount = sheet1.LastRowNum;
//先解析表中的列名, 注释, 类型
var names = sheet1.GetRow(0);
var descriptions = sheet1.GetRow(1);
var types = sheet1.GetRow(2);
columnCount = names.LastCellNum;
foreach (var cell in names)
{
//字段名称
var field = GetCellStringValue(cell);
if (string.IsNullOrEmpty(field))
{
//到达最后一列了
columnCount = cell.ColumnIndex;
break;
}
field = field.FirstToUpper();
excelData.ColumnNames.Add(field);
outStr += $" /// <summary>\n";
var descriptionCell = descriptions.GetCell(cell.ColumnIndex);
//描述
string description;
if (descriptionCell != null)
{
description = GetCellStringValue(descriptionCell).Replace("\n", " <br/>\n /// ");
}
else
{
description = "";
}
//类型
var typeString = GetCellStringValue(types.GetCell(cell.ColumnIndex));
if (string.IsNullOrEmpty(typeString))
{
throw new Exception($"表'{fileName}'中'{field}'这一列类型为空!");
}
//尝试解析类型
MappingData mappingData;
try
{
mappingData = ConvertToType(typeString.Replace(" ", ""));
}
catch (Exception e)
{
GD.PrintErr(e.ToString());
throw new Exception($"表'{fileName}'中'{field}'这一列类型描述语法错误: {typeString}");
}
if (!excelData.ColumnMappingData.TryAdd(field, mappingData))
{
throw new Exception($"表'{fileName}'中存在相同名称的列: '{field}'!");
}
outStr += $" /// {description}\n";
outStr += $" /// </summary>\n";
outStr += $" [JsonInclude]\n";
outStr += $" public {mappingData.TypeStr} {field} {{ get; private set; }}\n\n";
}
outStr += "}";
//解析字段类型
foreach (var kv in excelData.ColumnMappingData)
{
var typeName = kv.Value.TypeName;
var type = Type.GetType(typeName);
if (type == null)
{
throw new Exception($"表'{fileName}'中'{kv.Key}'这一列类型未知! " + kv.Value.TypeStr);
}
excelData.ColumnType.Add(kv.Key, type);
}
//解析数据
for (int i = 3; i <= rowCount; i++)
{
Dictionary<string, object> data = null;
var row = sheet1.GetRow(i);
for (int j = 0; j < columnCount; j++)
{
var cell = row.GetCell(j);
var strValue = GetCellStringValue(cell);
//如果这一行的第一列数据为空, 则跳过这一行
if (j == 0 && string.IsNullOrEmpty(strValue))
{
break;
}
else if (data == null)
{
data = new Dictionary<string, object>();
excelData.DataList.Add(data);
}
var fieldName = excelData.ColumnNames[j];
var mappingData = excelData.ColumnMappingData[fieldName];
try
{
switch (mappingData.TypeStr)
{
case "bool":
case "boolean":
data.Add(fieldName, GetCellBooleanValue(cell));
break;
case "byte":
data.Add(fieldName, Convert.ToByte(GetCellNumberValue(cell)));
break;
case "sbyte":
data.Add(fieldName, Convert.ToSByte(GetCellNumberValue(cell)));
break;
case "short":
data.Add(fieldName, Convert.ToInt16(GetCellNumberValue(cell)));
break;
case "ushort":
data.Add(fieldName, Convert.ToUInt16(GetCellNumberValue(cell)));
break;
case "int":
data.Add(fieldName, Convert.ToInt32(GetCellNumberValue(cell)));
break;
case "uint":
data.Add(fieldName, Convert.ToUInt32(GetCellNumberValue(cell)));
break;
case "long":
data.Add(fieldName, Convert.ToInt64(GetCellNumberValue(cell)));
break;
case "ulong":
data.Add(fieldName, Convert.ToUInt64(GetCellNumberValue(cell)));
break;
case "float":
data.Add(fieldName, Convert.ToSingle(GetCellNumberValue(cell)));
break;
case "double":
data.Add(fieldName, GetCellNumberValue(cell));
break;
case "string":
data.Add(fieldName, GetCellStringValue(cell));
break;
default:
{
var cellStringValue = GetCellStringValue(cell);
if (cellStringValue.Length == 0)
{
data.Add(fieldName, null);
}
else
{
data.Add(fieldName, JsonSerializer.Deserialize(cellStringValue, excelData.ColumnType[fieldName]));
}
}
break;
}
}
catch (Exception e)
{
GD.PrintErr(e.ToString());
throw new Exception($"解析表'{fileName}'第'{i + 1}'行第'{j + 1}'列数据时发生异常");
}
}
}
}
excelData.OutCode = outStr;
return excelData;
}
private static string GetCellStringValue(ICell cell)
{
if (cell == null)
{
return "";
}
switch (cell.CellType)
{
case CellType.Numeric:
return cell.NumericCellValue.ToString();
case CellType.String:
return cell.StringCellValue;
case CellType.Formula:
return cell.CellFormula;
case CellType.Boolean:
return cell.BooleanCellValue ? "true" : "false";
}
return "";
}
private static double GetCellNumberValue(ICell cell)
{
if (cell == null)
{
return 0;
}
return cell.NumericCellValue;
}
private static bool GetCellBooleanValue(ICell cell)
{
if (cell == null)
{
return false;
}
return cell.BooleanCellValue;
}
private static MappingData ConvertToType(string str)
{
if (Regex.IsMatch(str, "^\\w+$"))
{
var typeStr = TypeStrMapping(str);
var typeName = TypeNameMapping(str);
return new MappingData(typeStr, typeName);
}
else if (str.StartsWith('{'))
{
var tempStr = str.Substring(1, str.Length - 2);
var index = tempStr.IndexOf(':');
if (index == -1)
{
throw new Exception("类型描述语法错误!");
}
var keyStr = tempStr.Substring(0, index);
if (!IsBaseType(keyStr))
{
throw new Exception($"字典key类型必须是基础类型!");
}
var type1 = ConvertToType(keyStr);
var type2 = ConvertToType(tempStr.Substring(index + 1));
var typeStr = $"Dictionary<{type1.TypeStr}, {type2.TypeStr}>";
var typeName = $"System.Collections.Generic.Dictionary`2[[{type1.TypeName}],[{type2.TypeName}]]";
return new MappingData(typeStr, typeName);
}
else if (str.StartsWith('['))
{
var tempStr = str.Substring(1, str.Length - 2);
var typeData = ConvertToType(tempStr);
var typeStr = typeData.TypeStr + "[]";
var typeName = typeData.TypeName + "[]";
return new MappingData(typeStr, typeName);
}
throw new Exception("类型描述语法错误!");
}
private static string TypeStrMapping(string typeName)
{
switch (typeName)
{
case "boolean": return "bool";
case "vector2": return "SerializeVector2";
case "vector3": return "SerializeVector3";
case "color": return "SerializeColor";
}
return typeName;
}
private static string TypeNameMapping(string typeName)
{
switch (typeName)
{
case "bool":
case "boolean": return typeof(bool).FullName;
case "byte": return typeof(byte).FullName;
case "sbyte": return typeof(sbyte).FullName;
case "short": return typeof(short).FullName;
case "ushort": return typeof(ushort).FullName;
case "int": return typeof(int).FullName;
case "uint": return typeof(uint).FullName;
case "long": return typeof(long).FullName;
case "ulong": return typeof(ulong).FullName;
case "string": return typeof(string).FullName;
case "float": return typeof(float).FullName;
case "double": return typeof(double).FullName;
case "vector2": return typeof(SerializeVector2).FullName;
case "vector3": return typeof(SerializeVector3).FullName;
case "color": return typeof(SerializeColor).FullName;
}
return typeName;
}
private static bool IsBaseType(string typeName)
{
switch (typeName)
{
case "bool":
case "boolean":
case "byte":
case "sbyte":
case "short":
case "ushort":
case "int":
case "uint":
case "long":
case "ulong":
case "string":
case "float":
case "double":
return true;
}
return false;
}
}

View File

@ -3,6 +3,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.Json;
using Config;
using Godot;
public partial class GameApplication : Node2D
@ -88,8 +89,10 @@ public partial class GameApplication : Node2D
{
Instance = this;
//初始化配置表
ExcelConfig.Init();
//初始化房间配置数据
InitRoomConfig();
//初始化 ActivityObject
ActivityObject.InitActivity();
@ -100,6 +103,7 @@ public partial class GameApplication : Node2D
public override void _EnterTree()
{
return;
//随机化种子
//GD.Randomize();
//固定帧率

View File

@ -72,9 +72,4 @@ public static class GameConfig
/// 配置层级的自定义数据名称
/// </summary>
public const string CustomTileLayerName = "TileLayer";
/// <summary>
/// excel配置文件存放路径
/// </summary>
public const string ExcelFilePath = "excel/";
}

View File

@ -390,15 +390,7 @@ public partial class EditorToolsPanel : EditorTools
/// </summary>
private void ExportExcel()
{
if (ExcelGenerator.ExportExcel())
{
ShowTips("提示", "导出Excel表执行完成!");
}
else
{
ShowTips("错误", "导出Excel表执行失败! 前往控制台查看错误日志!");
}
;
ExcelGenerator.ExportExcel();
ShowTips("提示", "已启动导表程序, 注意查看控制台信息!");
}
}

View File

@ -1,44 +1,44 @@
using Godot;
using System;
using System.IO;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
// using NPOI.SS.UserModel;
// using NPOI.XSSF.UserModel;
public partial class TestReadExcel : Node2D
{
public override void _Ready()
{
string sourceFile = @"excel/Weapon.xlsx";
IWorkbook workbook = new XSSFWorkbook(sourceFile);
ISheet sheet1 = workbook.GetSheet("Sheet1");
int columnCount = -1;
foreach (IRow row in sheet1)
{
foreach (var cell in row)
{
if (columnCount >= 0 && cell.ColumnIndex >= columnCount)
{
break;
}
var value = cell.StringCellValue;
if (string.IsNullOrEmpty(value))
{
if (columnCount < 0)
{
columnCount = cell.ColumnIndex;
break;
}
else if (cell.ColumnIndex == 0)
{
break;
}
}
GD.Print("row: " + row.RowNum + " , Column: " + cell.ColumnIndex + ", value: " + cell.StringCellValue);
}
}
workbook.Close();
// string sourceFile = @"excel/Weapon.xlsx";
//
// IWorkbook workbook = new XSSFWorkbook(sourceFile);
// ISheet sheet1 = workbook.GetSheet("Sheet1");
//
// int columnCount = -1;
// foreach (IRow row in sheet1)
// {
// foreach (var cell in row)
// {
// if (columnCount >= 0 && cell.ColumnIndex >= columnCount)
// {
// break;
// }
// var value = cell.StringCellValue;
// if (string.IsNullOrEmpty(value))
// {
// if (columnCount < 0)
// {
// columnCount = cell.ColumnIndex;
// break;
// }
// else if (cell.ColumnIndex == 0)
// {
// break;
// }
// }
// GD.Print("row: " + row.RowNum + " , Column: " + cell.ColumnIndex + ", value: " + cell.StringCellValue);
// }
// }
// workbook.Close();
// sheet1.CreateRow(0).CreateCell(0).SetCellValue(1);
// sheet1.CreateRow(1).CreateCell(0).SetCellValue(2);
// sheet1.CreateRow(2).CreateCell(0).SetCellValue(3);