169 lines
5.5 KiB
C#
169 lines
5.5 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
|
|
|
|
#region 部分命令
|
|
|
|
[YarnFunction("set_option_visited")]
|
|
public static int SetOptionVisited(int visitedState, int optionIdx)
|
|
{
|
|
return visitedState | ( 1 << (optionIdx - 1));
|
|
}
|
|
|
|
[YarnFunction("check_visited")]
|
|
public static bool CheckVisitedOptionNum(int visitedState, int totalOptionNum)
|
|
{
|
|
return visitedState == (1 << totalOptionNum) - 1;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public enum CommandLineType
|
|
{
|
|
OptionCommand, Pause, NonCommand
|
|
}
|
|
} |