114 lines
4.2 KiB
C#
114 lines
4.2 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using DynamicExpresso;
|
||
using Sirenix.OdinInspector;
|
||
using UnityEngine;
|
||
using UnityEngine.Serialization;
|
||
|
||
namespace Cielonos.MainGame.Inventory
|
||
{
|
||
[CreateAssetMenu(fileName = "UpgradeData", menuName = "Cielonos/Items/UpgradeData")]
|
||
public class UpgradeData : SerializedScriptableObject
|
||
{
|
||
public int maxLevel = 5;
|
||
public List<UpgradeInfo> upgrades = new List<UpgradeInfo>();
|
||
}
|
||
|
||
[Serializable, InlineProperty]
|
||
public partial class UpgradeInfo
|
||
{
|
||
public UpgradeTarget upgradeTarget;
|
||
public UpgradeMode upgradeMode;
|
||
[ShowIf("upgradeTarget", UpgradeTarget.CharacterAttribute)]
|
||
[InfoBox("UpgradeTarget为CharacterAttribute时,Category不能设为Item", InfoMessageType.Error,
|
||
"@upgradeTarget == UpgradeTarget.CharacterAttribute && category == Category.Item")]
|
||
public Category category;
|
||
|
||
[FormerlySerializedAs("attributeKey")]
|
||
[ShowIf("upgradeTarget", UpgradeTarget.CharacterAttribute)]
|
||
[ValueDropdown("@EditorBaseCollection.GetCharacterAttributesDropdown($property)", IsUniqueList = true)]
|
||
public string characterAttributeKey; // 要升级的属性键
|
||
|
||
[ShowIf("upgradeTarget", UpgradeTarget.ItemAttribute)]
|
||
public string itemAttributeKey; // 要升级的道具属性键
|
||
|
||
/// <summary>
|
||
/// 根据 upgradeTarget 返回实际使用的属性键。
|
||
/// </summary>
|
||
public string EffectiveKey => upgradeTarget == UpgradeTarget.ItemAttribute ? itemAttributeKey : characterAttributeKey;
|
||
|
||
[ShowIf("upgradeMode", UpgradeMode.ManualList)]
|
||
public List<float> valueList;
|
||
[ShowIf("upgradeMode", UpgradeMode.ManualList)]
|
||
public float defaultUpgradeValue; // 溢出后的固定增量
|
||
|
||
[ShowIf("upgradeMode", UpgradeMode.Expression)]
|
||
public List<LevelRangeExpression> 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 float GetDifference(int high, int low)
|
||
{
|
||
return GetValue(high) - GetValue(low);
|
||
}
|
||
}
|
||
|
||
public partial class UpgradeInfo
|
||
{
|
||
public enum UpgradeTarget { CharacterAttribute, ItemAttribute }
|
||
public enum UpgradeMode { ManualList, Expression }
|
||
public enum Category { Item, Numeric, PercentageOfAccumulation, PercentageOfMultiplication }
|
||
|
||
[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);
|
||
}
|
||
}
|
||
} |