using System; namespace Models; /// /// 属性值类型(通用数值封装) /// 设计说明: /// 1) 过去固定使用 0-100 的范围,导致“精力/算力”等大数值被强行截断。 /// 2) 现在改为“每个实例自带范围”,默认仍然是 0-100,兼顾直觉和可扩展性。 /// 3) 这个类仅承担“数值与范围”的职责,不负责业务含义,便于在 MVC 中被复用。 /// 注意事项: /// - 运算符会保留左操作数的范围(或右操作数的范围),避免范围丢失。 /// - 如果需要无上限/无下限,请显式传入更大的 Max/更小的 Min。 /// 未来扩展: /// - 可加入“软上限/软下限”和“可见范围”等 UI 表现字段。 /// - 可增加数值变化事件,以便 View 层更高效地刷新。 /// public sealed class PropertyValue { public const float DefaultMin = 0f; public const float DefaultMax = 100f; public float Min { get; } public float Max { get; } private float _value; public float Value { get => _value; set => _value = Clamp(value, Min, Max); } public PropertyValue(float value = 0, float min = DefaultMin, float max = DefaultMax) { if (max < min) { // 兜底修正,避免传参错误导致全局异常 (min, max) = (max, min); } Min = min; Max = max; Value = value; } public PropertyValue(int value, float min = DefaultMin, float max = DefaultMax) : this((float)value, min, max) { } public int DisplayInt() => (int)_value; public float Normalized { get { if (Max <= Min) return 0f; return (Value - Min) / (Max - Min); } } public PropertyValue Clone() => new(Value, Min, Max); public void Add(float delta) => Value += delta; public void Subtract(float delta) => Value -= delta; public override string ToString() => DisplayInt().ToString(); // --- 隐式转换(用于简化调用,但不改变范围语义) --- public static implicit operator PropertyValue(int value) { return new PropertyValue(value); } public static implicit operator PropertyValue(float value) { return new PropertyValue(value); } public static implicit operator int(PropertyValue p) { return (int)p._value; } public static implicit operator float(PropertyValue p) { return p._value; } // --- 运算符重载(保留范围) --- public static PropertyValue operator +(PropertyValue a, int b) => new(a._value + b, a.Min, a.Max); public static PropertyValue operator +(int a, PropertyValue b) => new(a + b._value, b.Min, b.Max); public static PropertyValue operator -(PropertyValue a, int b) => new(a._value - b, a.Min, a.Max); public static PropertyValue operator -(int a, PropertyValue b) => new(a - b._value, b.Min, b.Max); public static PropertyValue operator *(PropertyValue a, int b) => new(a._value * b, a.Min, a.Max); public static PropertyValue operator *(int a, PropertyValue b) => new(a * b._value, b.Min, b.Max); public static PropertyValue operator /(PropertyValue a, int b) { return b == 0 ? throw new DivideByZeroException() : new PropertyValue(a._value / b, a.Min, a.Max); } public static PropertyValue operator /(int a, PropertyValue b) { return b._value == 0 ? throw new DivideByZeroException() : new PropertyValue(a / b._value, b.Min, b.Max); } public static PropertyValue operator +(PropertyValue a, float b) => new(a._value + b, a.Min, a.Max); public static PropertyValue operator +(float a, PropertyValue b) => new(a + b._value, b.Min, b.Max); public static PropertyValue operator -(PropertyValue a, float b) => new(a._value - b, a.Min, a.Max); public static PropertyValue operator -(float a, PropertyValue b) => new(a - b._value, b.Min, b.Max); public static PropertyValue operator *(PropertyValue a, float b) => new(a._value * b, a.Min, a.Max); public static PropertyValue operator *(float a, PropertyValue b) => new(a * b._value, b.Min, b.Max); public static PropertyValue operator /(PropertyValue a, float b) => new(a._value / b, a.Min, a.Max); public static PropertyValue operator /(float a, PropertyValue b) => new(a / b._value, b.Min, b.Max); public static PropertyValue operator +(PropertyValue a, PropertyValue b) => new(a._value + b._value, a.Min, a.Max); public static PropertyValue operator -(PropertyValue a, PropertyValue b) => new(a._value - b._value, a.Min, a.Max); public static PropertyValue operator *(PropertyValue a, PropertyValue b) => new(a._value * b._value, a.Min, a.Max); public static PropertyValue operator /(PropertyValue a, PropertyValue b) { return b._value == 0 ? throw new DivideByZeroException() : new PropertyValue(a._value / b._value, a.Min, a.Max); } private static float Clamp(float value, float min, float max) { if (value < min) return min; if (value > max) return max; return value; } }