using System; using System.Collections.Generic; using DynamicExpresso; using Sirenix.OdinInspector; using UnityEngine; namespace Cielonos.MainGame.Characters.Inventory { [CreateAssetMenu(fileName = "UpgradeData", menuName = "Cielonos/Items/UpgradeData")] public class UpgradeData : SerializedScriptableObject { public List upgrades = new List(); } [Serializable, InlineProperty] public partial class UpgradeInfo { public UpgradeMode upgradeMode; [ValueDropdown("@EditorBaseCollection.GetCharacterAttributesDropdown($property)", IsUniqueList = true)] public string attributeKey; // 要升级的属性键 [ShowIf("upgradeMode", UpgradeMode.ManualList)] public List valueList; [ShowIf("upgradeMode", UpgradeMode.ManualList)] public float defaultUpgradeValue; // 溢出后的固定增量 [ShowIf("upgradeMode", UpgradeMode.Expression)] public List ranges; // 分段函数区间 [ShowIf("upgradeMode", UpgradeMode.Expression)] public string defaultExpression = "0"; // 默认公式 public float GetValue(int level) { if (upgradeMode == UpgradeMode.ManualList) { if (valueList.Count == 0) { return defaultUpgradeValue * level; } if (level < valueList.Count) { return valueList[level]; } return valueList[valueList.Count - 1] + (level - valueList.Count + 1) * defaultUpgradeValue; } else { // 查找匹配的区间 foreach (var range in ranges) { if (level >= range.minLevel && level <= range.maxLevel) { return UpgradeExpressionEvaluator.Eval(range.expression, level); } } return UpgradeExpressionEvaluator.Eval(defaultExpression, level); } } } public partial class UpgradeInfo { public enum UpgradeMode { ManualList, Expression } [Serializable, InlineProperty] public class LevelRangeExpression { [HorizontalGroup("Interval"), LabelText("Min"), LabelWidth(40)] public int minLevel; [HorizontalGroup("Interval", MarginLeft = 40), LabelText("Max"), LabelWidth(40)] public int maxLevel; [LabelText("Expression"), LabelWidth(80)] public string expression; } } public static class UpgradeExpressionEvaluator { private static readonly Interpreter Interpreter = new Interpreter(); public static float Eval(string expression, int level) { object result = Interpreter.Eval(expression, new Parameter("level", level)); return Convert.ToSingle(result); } } }