Support for optional custom parameters for registering item information from yaml

为从yaml注册物品信息提供了可选自定义参数的支持
This commit is contained in:
霧雨烨 2024-06-15 17:07:50 +08:00
parent 9a83fd1dd2
commit 197930f446
4 changed files with 73 additions and 9 deletions

View File

@ -33,3 +33,4 @@ log_start_item_register_from_file,开始从文件注册物品信息,Start regist
log_found_files,找到{0}个文件,Found {0} files,{0}ファイルが見つかりました log_found_files,找到{0}个文件,Found {0} files,{0}ファイルが見つかりました
log_found_item_types,从文件中找到{0}个物品类型,Found {0} item types in files,ファイルから{0}個のアイテム・タイプが見つかった log_found_item_types,从文件中找到{0}个物品类型,Found {0} item types in files,ファイルから{0}個のアイテム・タイプが見つかった
log_error_when_open_item_regs_dir,尝试打开物品信息目录时发生错误,Error when opening itemRegs dir,アイテム情報カタログを開こうとしてエラーが発生しました。 log_error_when_open_item_regs_dir,尝试打开物品信息目录时发生错误,Error when opening itemRegs dir,アイテム情報カタログを開こうとしてエラーが発生しました。
log_wrong_custom_arg,不匹配的参数:类型为{0}而值为{1},Mismatched parameter: type {0} and value {1},パラメータの不一致:型{0}と値{1}。
1 id zh en ja
33 log_error_when_open_item_regs_dir 尝试打开物品信息目录时发生错误 Error when opening itemRegs dir アイテム情報カタログを開こうとしてエラーが発生しました。
34 log_wrong_custom_arg 不匹配的参数:类型为{0}而值为{1} Mismatched parameter: type {0} and value {1} パラメータの不一致:型{0}と値{1}。
35
36

View File

@ -16,9 +16,9 @@ namespace ColdMint.scripts.item;
public interface ICommonItem : IItem public interface ICommonItem : IItem
{ {
/// <summary> /// <summary>
/// <para>Method to copy an instance same with self. Will be used to pick out item instance from a <see cref="CommonItemStack"/></para> /// <para>Method to clone an instance same with self. Will be used to pick out item instance from a <see cref="CommonItemStack"/></para>
/// <para>复制与自身相同的实例的方法。将用于从 <see cref="CommonItemStack"/> 中拿取新的物品实例。</para> /// <para>复制与自身相同的实例的方法。将用于从 <see cref="CommonItemStack"/> 中拿取新的物品实例。</para>
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
ICommonItem CopyInstance(); ICommonItem CloneInstance();
} }

View File

@ -56,25 +56,88 @@ public static class ItemTypeRegister
private static IList<ItemTypeInfo> ParseFile(IDeserializer deserializer, string filePath) private static IList<ItemTypeInfo> ParseFile(IDeserializer deserializer, string filePath)
{ {
string itemRegsDirPath;
string file;
var yamlFile = FileAccess.Open(filePath, FileAccess.ModeFlags.Read); var yamlFile = FileAccess.Open(filePath, FileAccess.ModeFlags.Read);
//Read & deserialize
var yamlString = yamlFile.GetAsText(); var yamlString = yamlFile.GetAsText();
var typeInfos = deserializer.Deserialize<IList<ItemTypeInfo>>(yamlString); var typeInfos = deserializer.Deserialize<IList<ItemTypeInfo>>(yamlString);
yamlFile.Close(); yamlFile.Close();
return typeInfos; return typeInfos;
} }
private static void RegisterTypeInfo(ItemTypeInfo typeInfo) private static void RegisterTypeInfo(ItemTypeInfo typeInfo)
{ {
//Load scene and icon
var scene = ResourceLoader.Load<PackedScene>(typeInfo.ScenePath); var scene = ResourceLoader.Load<PackedScene>(typeInfo.ScenePath);
var icon = ResourceLoader.Load<Texture2D>(typeInfo.IconPath); var icon = ResourceLoader.Load<Texture2D>(typeInfo.IconPath);
//Create init delegate
Func<IItem?> newItemFunc;
if (typeInfo.CustomArgs is null or [])
{
newItemFunc = () => NodeUtils.InstantiatePackedScene<IItem>(scene);
}
else
{
Action<Node?>? setArgs = null;
foreach (var arg in typeInfo.CustomArgs)
{
setArgs +=
node => node?.SetDeferred(arg.Name, arg.ParseValue());
}
newItemFunc = () =>
{
var newItem = NodeUtils.InstantiatePackedScene<IItem>(scene);
setArgs?.Invoke(newItem as Node);
return newItem;
};
}
//construct item type, register
var itemType = new ItemType(typeInfo.Id, var itemType = new ItemType(typeInfo.Id,
() => NodeUtils.InstantiatePackedScene<Packsack>(scene), newItemFunc,
icon, typeInfo.MaxStackValue); icon, typeInfo.MaxStackValue);
ItemTypeManager.Register(itemType); ItemTypeManager.Register(itemType);
} }
//Use for yaml deserialization //Use for yaml deserialization
private record struct ItemTypeInfo(string Id, string ScenePath, string IconPath, int MaxStackValue) { } private record struct ItemTypeInfo(
string Id, string ScenePath, string IconPath, int MaxStackValue,
IList<CustomArg>? CustomArgs) { }
private readonly record struct CustomArg(string Name, CustomArgType Type, string Value)
{
public Variant ParseValue() =>
Type switch
{
CustomArgType.String => Value,
CustomArgType.Int => int.Parse(Value),
CustomArgType.Float => double.Parse(Value),
CustomArgType.Vector2 => ParseVector2FromString(Value),
CustomArgType.Texture => ResourceLoader.Load<Texture2D>("res://sprites/" + Value),
_ => throw new ArgumentOutOfRangeException($"Unknown Arg Type {Type}")
};
private Vector2 ParseVector2FromString(string s)
{
var ss = s.Split(',');
if (ss.Length != 2)
{
LogCat.LogErrorWithFormat("wrong_custom_arg", "Vector2", s);
return Vector2.Zero;
}
return new Vector2(float.Parse(ss[0]), float.Parse(ss[1]));
}
}
private enum CustomArgType
{
String,
Int,
Float,
Vector2,
Texture,
}
} }

View File

@ -67,7 +67,7 @@ public class CommonItemStack(ICommonItem innerItem) : IItemStack
{ {
if(Empty) return null; if(Empty) return null;
Quantity--; Quantity--;
var result = innerItem.CopyInstance(); var result = innerItem.CloneInstance();
if(Empty) innerItem.Destroy(); if(Empty) innerItem.Destroy();
return result; return result;
} }
@ -75,7 +75,7 @@ public class CommonItemStack(ICommonItem innerItem) : IItemStack
public IItemStack? PickItems(int value) public IItemStack? PickItems(int value)
{ {
if (Empty) return null; if (Empty) return null;
var result = new CommonItemStack(innerItem.CopyInstance()); var result = new CommonItemStack(innerItem.CloneInstance());
var n = Math.Min(Quantity, value); var n = Math.Min(Quantity, value);
if (n < 0) if (n < 0)
{ {