Files
aibis-dream/Assets/Scripts/Utility/YarnUtil.cs
T
2024-10-16 20:28:07 +08:00

153 lines
5.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using AibisDream.Kit;
using Yarn;
using Yarn.Markup;
using Yarn.Unity;
namespace AibisDream.Utility
{
public static class YarnUtil
{
private const string CommandAttr = "command";
private const string PauseAttr = "pause";
private const string CommandProp = "name";
private const string AutoNext = "auto_next";
public static bool HasCommandAttr(this MarkupParseResult text)
{
return MatchCommandType(text) != CommandLineType.NonCommand;
}
public static CommandLineType MatchCommandType(this MarkupParseResult text)
{
if (text.TryGetAttributeWithName(CommandAttr, out var attribute1))
{
return CommandLineType.OptionCommand;
}
if (text.TryGetAttributeWithName(PauseAttr, out var attribute2))
{
return CommandLineType.Pause;
}
return CommandLineType.NonCommand;
}
public static bool TryGetOptionCommandAttr(this MarkupParseResult text, out string commandName)
{
bool res = text.TryGetAttributeWithName(CommandAttr, out var attribute);
commandName = res ? attribute.Properties[CommandProp].StringValue : null;
return res;
}
public static bool TryGetPauseCommandAttr(this MarkupParseResult text, out string commandName)
{
bool res = text.TryGetAttributeWithName(PauseAttr, out var attribute);
commandName = res ? attribute.Properties[CommandProp].StringValue : null;
return res;
}
public static void AddCommandListener(this DialogueRunner runner, CommandHandler onCommand)
{
runner.Dialogue.CommandHandler += onCommand;
}
#region 处理行信息
/// <summary>
/// 当前行是否应该自动跳过
/// </summary>
/// <param name="line">当前行</param>
/// <returns>是否应该自动跳过</returns>
public static bool IsAutoSkipLine(this LocalizedLine line)
{
return line.Metadata != null && line.Metadata.Contains(AutoNext);
}
/// <summary>
/// 从line中获取角色vo定义
/// </summary>
/// <param name="line">行数据</param>
/// <returns>结果</returns>
public static CharacterVo GetCharacterVo(this LocalizedLine line)
{
if (line.Text.TryGetAttributeWithName("character", out var characterAttribute))
{
// 直接写就使用配置选项
if (characterAttribute.Properties.TryGetValue("name", out var nameValue))
{
return GetCharacterVoByKey(nameValue.StringValue);
}
// 带key就说明可能有自定义属性
if (characterAttribute.Properties.TryGetValue("key", out var keyValue))
{
// 先从配置文件找
var charVo = GetCharacterVoByKey(keyValue.StringValue);
// 再用自定义填充
return FullCharVoWithProps(charVo, characterAttribute.Properties);
}
// 找不到Name和Key
return new CharacterVo();
}
// 没有Character就直接返回空
return new CharacterVo();
}
private static CharacterVo GetCharacterVoByKey(string charKey)
{
if (ConfigUtil.Instance.TryGetCharacter(charKey, out var character))
{
return character.GetStructVo();
}
return new CharacterVo
{
key = charKey,
cn = charKey,
role = ActorRole.Aside
};
}
private static CharacterVo FullCharVoWithProps(CharacterVo vo, IReadOnlyDictionary<string, MarkupValue> props)
{
foreach (var pair in props)
{
switch (pair.Key)
{
case "cn":
vo.cn = pair.Value.StringValue;
break;
case "nameColor":
vo.nameColor = pair.Value.StringValue;
break;
case "headPicPath":
vo.headPicPath = pair.Value.StringValue;
break;
case "voicePath":
vo.voicePath = pair.Value.StringValue;
break;
case "role":
vo.role = Enum.TryParse<ActorRole>(pair.Value.StringValue, out var type) ? type : ActorRole.Aside;
break;
}
}
return vo;
}
#endregion
}
public enum CommandLineType
{
OptionCommand, Pause, NonCommand
}
}