diff --git a/Assets/Scripts/Attribute.cs b/Assets/Scripts/Attribute.cs
index 9d2ac95..222652f 100644
--- a/Assets/Scripts/Attribute.cs
+++ b/Assets/Scripts/Attribute.cs
@@ -5,25 +5,16 @@ using UnityEngine;
public class Attribute : ScriptableObject
{
public long Base { get; set; }
- public long BaseBonus { get; set; }
- public long PermyriadBonus { get; set; }
- public long FlatBonus { get; set; }
-
- public long Value => Calc(Base, BaseBonus, PermyriadBonus, FlatBonus);
///
/// Calculates the stat value with accumulated buff and debuff modifiers.
///
- /// Base value.
- /// Additive bonus applied before multiplicative scaling.
- /// Multiplicative scaling in hundredths of a percent. E.g., 625 permyriad corresponds to 6.25%.
- /// Additive bonus applied after multiplicative scaling.
/// (base + baseBonus) * (100% + permyriadBonus) + flatBonus, bounded below by 0.
- public static long Calc(long baseValue, long baseBonus, long permyriadBonus, long flatBonus)
+ public long Calc(EffectSO effect)
{
- var r = baseValue + baseBonus;
- var m = permyriadBonus + 10000;
- r = r * (m / 10000) + (r / 10000) * (m % 10000) + flatBonus;
+ var r = Base + effect.Base;
+ var m = effect.Permyriad + 10000;
+ r = r * (m / 10000) + (r / 10000) * (m % 10000) + effect.Flat;
if (r <= 0)
{
return 0;
diff --git a/Assets/Scripts/EffectSO.cs b/Assets/Scripts/EffectSO.cs
new file mode 100644
index 0000000..cd978c5
--- /dev/null
+++ b/Assets/Scripts/EffectSO.cs
@@ -0,0 +1,45 @@
+using UnityEngine;
+
+[CreateAssetMenu(fileName = "StatEffect", menuName = "Stat Effect")]
+public class EffectSO : ScriptableObject
+{
+ ///
+ /// Additive change applied before multiplicative scaling.
+ ///
+ public long Base { get; private set; }
+ ///
+ /// Multiplicative scaling in units of hundredth of a percent.
+ /// E.g., 625 permyriad is 6.25%.
+ ///
+ public long Permyriad { get; private set; }
+ ///
+ /// Additive change applied after multiplicative scaling.
+ ///
+ public long Flat { get; private set; }
+
+ ///
+ /// Create a new attribute effect instance.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static EffectSO New(long baseBonus = 0, long permyriad = 0, long flat = 0)
+ {
+ var effect = ScriptableObject.CreateInstance();
+ effect.Base = baseBonus;
+ effect.Permyriad = permyriad;
+ effect.Flat = flat;
+ return effect;
+ }
+
+ ///
+ /// Create a new EffectSO from a percentage.
+ ///
+ /// Percentage. E.g., 6.25f results in a Permyriad of 625.
+ /// Effect with the given percentage.
+ public static EffectSO FromPercent(float p)
+ {
+ return New(permyriad: (long)(p * 100));
+ }
+}
diff --git a/Assets/Scripts/EffectSO.cs.meta b/Assets/Scripts/EffectSO.cs.meta
new file mode 100644
index 0000000..a39567b
--- /dev/null
+++ b/Assets/Scripts/EffectSO.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 494a21c06960ec442a7a6806f8aefedb
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Tests/AttributeTest.cs b/Assets/Tests/AttributeTest.cs
index f4b216c..e240b88 100644
--- a/Assets/Tests/AttributeTest.cs
+++ b/Assets/Tests/AttributeTest.cs
@@ -19,9 +19,7 @@ public class AttributeTest
{
var attr = ScriptableObject.CreateInstance();
attr.Base = startStat;
- attr.BaseBonus = baseBonus;
- attr.PermyriadBonus = permyriadBonus;
- attr.FlatBonus = flatBonus;
- return attr.Value;
+ var effect = EffectSO.New(baseBonus, permyriadBonus, flatBonus);
+ return attr.Calc(effect);
}
}