using System; using System.Collections.Generic; using System.Linq; using AibisDream.Kit; using Yarn.Markup; using Yarn.Unity; namespace AibisDream.Utility { public static class YarnUtil { private const string AutoNext = "auto_next"; #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)) { var charVo = GetCharacterVoByKey(nameValue.StringValue); if (characterAttribute.Properties.Count > 1) { charVo = FullCharVoWithProps(charVo, characterAttribute.Properties); } return charVo; } // 找不到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 "bubbleIdx": vo.bubbleIdx = pair.Value.IntegerValue; 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 #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 } }