using System; using System.Collections.Generic; using System.Globalization; using DynamicExpresso; using UnityEngine; namespace Continentis.MainGame.Card { public static partial class CardDescriptionInterpreter { public static Interpreter DescriptionInterpreter; static CardDescriptionInterpreter() { DescriptionInterpreter = new Interpreter(); DescriptionInterpreter.SetFunction("GetDynamicValue", new Func(GetDynamicValue)); DescriptionInterpreter.SetFunction("GetDynamicValue", new Func(GetDynamicValue)); DescriptionInterpreter.SetFunction("AttributeCheck", new Func(AttributeCheck)); foreach (KeyValuePair keyword in CombatMainManager.Instance.keywordCollection.keywords) { DescriptionInterpreter.SetVariable(keyword.Key, keyword.Key); } foreach (KeyValuePair keyword in CombatMainManager.Instance.keywordCollection.interpretedKeywords) { DescriptionInterpreter.SetVariable(keyword.Key, keyword.Value.name); } } public static string InterpretDescription(CardLogicBase card) { card.contentSubmodule.keywords.Clear(); foreach (KeyValuePair attribute in card.attributeSubmodule.attributeGroup.current) { DescriptionInterpreter.SetVariable(attribute.Key, attribute.Value); } DescriptionInterpreter.SetFunction("RemoveWhenSelecting", new Func((toRemove) => RemoveWhenSelecting(card, toRemove))); string result = ParseKeywords(card.cardData.cardDescription, card.contentSubmodule.keywords); card.contentSubmodule.cardDescription = result; Debug.Log($"Interpreted Description: {result}"); return result; } } public partial class CardDescriptionInterpreter { public static List GetKeywords(string template) { List keywords = new List(); DescriptionInterpreter.UnsetExpression("Keyword"); DescriptionInterpreter.SetFunction("Keyword", new Action((keywordName) => { if (!string.IsNullOrEmpty(keywordName) && !keywords.Contains(keywordName)) { keywords.Add(keywordName); } })); try { //提取所有$Keyword(...)的关键词 //其它的表达式直接跳过 while (template.Contains("$")) { int startIndex = template.LastIndexOf('$'); int endIndex = FindMatchingClosingParenthesis(template, startIndex); if (endIndex == -1) { Debug.LogError($"解析错误: 在 '{template}' 中找不到与 '{template.Substring(startIndex)}' 匹配的闭合括号。"); break; // 中断以防止死循环 } string expressionToEvaluate = template.Substring(startIndex, endIndex - startIndex + 1); string cleanExpression = expressionToEvaluate.Substring(1); // 仅处理 Keyword 函数,跳过其他表达式 if (cleanExpression.StartsWith("Keyword")) { DescriptionInterpreter.Eval(cleanExpression); } // 移除已处理的表达式,继续查找下一个 template = template.Substring(0, startIndex) + template.Substring(endIndex + 1); } } catch (Exception ex) { throw new Exception($"解析模板时发生严重错误: {ex.Message}\nStackTrace: {ex.StackTrace}"); } return keywords; } public static string ParseKeywords(string template, List keywords) { DescriptionInterpreter.UnsetExpression("Keyword"); DescriptionInterpreter.SetFunction("Keyword", new Func((keywordName) => { if (!string.IsNullOrEmpty(keywordName) && !keywords.Contains(keywordName)) { keywords.Add(keywordName); } return Keyword(keywordName); })); try { while (template.Contains("$")) { int startIndex = template.LastIndexOf('$'); int endIndex = FindMatchingClosingParenthesis(template, startIndex); if (endIndex == -1) { Debug.LogError($"解析错误: 在 '{template}' 中找不到与 '{template.Substring(startIndex)}' 匹配的闭合括号。"); return template; // 中断以防止死循环 } string expressionToEvaluate = template.Substring(startIndex, endIndex - startIndex + 1); string cleanExpression = expressionToEvaluate.Substring(1); object result = DescriptionInterpreter.Eval(cleanExpression); string resultAsLiteral = result.ToString(); template = template.Substring(0, startIndex) + resultAsLiteral + template.Substring(endIndex + 1); } } catch (Exception ex) { throw new Exception($"解析模板时发生严重错误: {ex.Message}\nStackTrace: {ex.StackTrace}"); } return template; } private static int FindMatchingClosingParenthesis(string text, int startIndex) { int openParenIndex = text.IndexOf('(', startIndex); if (openParenIndex == -1) return -1; int parenthesisCounter = 1; bool isInString = false; for (int i = openParenIndex + 1; i < text.Length; i++) { char c = text[i]; char prevC = i > 0 ? text[i - 1] : '\0'; // 检查是否进入或退出字符串(忽略转义的引号 \") if (c == '"' && prevC != '\\') { isInString = !isInString; } // 如果在字符串中,则跳过对括号的计数 if (isInString) { continue; } if (c == '(') { parenthesisCounter++; } else if (c == ')') { parenthesisCounter--; } if (parenthesisCounter == 0) { return i; } } return -1; // 没有找到匹配的闭合括号 } } public partial class CardDescriptionInterpreter { private static string GetDynamicValue(float current, float baseValue, bool normalMode) { string color; if (current > baseValue) color = normalMode ? "green" : "red"; else if (current < baseValue) color = normalMode ? "red" : "green"; else color = "white"; //Debug.Log($"GetDynamicValue: current={current}, baseValue={baseValue}, normalMode={normalMode}, color={color}"); return $"{current}"; } private static string GetDynamicValue(float current) { return current.ToString(CultureInfo.CurrentCulture); } private static string Keyword(string keyword) { string color = "orange"; return $"{keyword}"; } private static string RemoveWhenSelecting(CardLogicBase card, string toRemove) { return card.handCardView != null && card.handCardView.isSelecting ? "" : toRemove; } private static string AttributeCheck(string attributeName, float requirement, float probability) { if (probability < 0) { return "{" + attributeName + " check: " + requirement + "}"; } int percent = Mathf.RoundToInt(probability * 100); string result = percent + "%"; if (percent == 0) { result = "" + result + ""; } else if (percent > 0 && percent < 100) { result = "" + result + ""; } else if (percent == 100) { result = "" + result + ""; } return result; } } }