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 处理行信息 /// /// 当前行是否应该自动跳过 /// /// 当前行 /// 是否应该自动跳过 public static bool IsAutoSkipLine(this LocalizedLine line) { return line.Metadata != null && line.Metadata.Contains(AutoNext); } /// /// 从line中获取角色vo定义 /// /// 行数据 /// 结果 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 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(pair.Value.StringValue, out var type) ? type : ActorRole.Aside; break; } } return vo; } #endregion } public enum CommandLineType { OptionCommand, Pause, NonCommand } }