diff --git a/Assets/Scriptables.meta b/Assets/Scriptables.meta new file mode 100644 index 0000000..94a9442 --- /dev/null +++ b/Assets/Scriptables.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1d13d7aac40657841955febd4faabbfa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scriptables/EnemyAttributes.asset b/Assets/Scriptables/EnemyAttributes.asset new file mode 100644 index 0000000..b389e2c --- /dev/null +++ b/Assets/Scriptables/EnemyAttributes.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c5304ff6dfe84844887d751cee48606a, type: 3} + m_Name: EnemyAttributes + m_EditorClassIdentifier: + STR: {fileID: 0} + CON: {fileID: 0} + SPD: {fileID: 0} + RNG: {fileID: 0} + MND: {fileID: 0} diff --git a/Assets/Scriptables/EnemyAttributes.asset.meta b/Assets/Scriptables/EnemyAttributes.asset.meta new file mode 100644 index 0000000..a7d5e8f --- /dev/null +++ b/Assets/Scriptables/EnemyAttributes.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d5bf638cf02c5b94cb9874d4414c1b8a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scriptables/StatEffect.asset b/Assets/Scriptables/StatEffect.asset new file mode 100644 index 0000000..8f4ca8c --- /dev/null +++ b/Assets/Scriptables/StatEffect.asset @@ -0,0 +1,14 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 494a21c06960ec442a7a6806f8aefedb, type: 3} + m_Name: StatEffect + m_EditorClassIdentifier: diff --git a/Assets/Scriptables/StatEffect.asset.meta b/Assets/Scriptables/StatEffect.asset.meta new file mode 100644 index 0000000..b6740dd --- /dev/null +++ b/Assets/Scriptables/StatEffect.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4c96040df8ebed746832db7857b25bed +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Attribute.cs b/Assets/Scripts/Attribute.cs index c8c9090..6c9a430 100644 --- a/Assets/Scripts/Attribute.cs +++ b/Assets/Scripts/Attribute.cs @@ -1,38 +1,24 @@ +using System; using System.Collections; using System.Collections.Generic; using UnityEngine; +[Serializable] public struct Attribute { - [SerializeField] - private long _base; + public long Base; - public Attribute(long stat) - { - _base = stat; - } - - /// - /// Permanently increase the stat value. - /// - /// Increase amount. - public void LevelUp(long by) - { - _base += by; - } + public Attribute(long stat) { Base = stat; } /// /// Calculates the stat value with accumulated buff and debuff modifiers. /// - /// 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 long Calc(long baseBonus, long permyriadBonus, long flatBonus) + public long Calc(EffectSO effect) { - var r = _base + 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..f50bce1 --- /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; + /// + /// Multiplicative scaling in units of hundredth of a percent. + /// E.g., 625 permyriad is 6.25%. + /// + public long Permyriad; + /// + /// Additive change applied after multiplicative scaling. + /// + public long Flat; + + /// + /// 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/Scripts/EnemyAttributesSO.cs b/Assets/Scripts/EnemyAttributesSO.cs new file mode 100644 index 0000000..9d1a39f --- /dev/null +++ b/Assets/Scripts/EnemyAttributesSO.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +[CreateAssetMenu(fileName = "EnemyAttributes", menuName = "Enemy Attributes")] +public class EnemyAttributesSO : ScriptableObject +{ + [SerializeField] private Attribute STR; + [SerializeField] private Attribute CON; + [SerializeField] private Attribute SPD; + [SerializeField] private Attribute RNG; + [SerializeField] private Attribute MND; + public long XP { get; private set; } + public long Threat { get; private set; } + + public static EnemyAttributesSO New() + { + return ScriptableObject.CreateInstance(); + } +} diff --git a/Assets/Scripts/EnemyAttributesSO.cs.meta b/Assets/Scripts/EnemyAttributesSO.cs.meta new file mode 100644 index 0000000..824414f --- /dev/null +++ b/Assets/Scripts/EnemyAttributesSO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c5304ff6dfe84844887d751cee48606a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/HeroAttributesSO.cs b/Assets/Scripts/HeroAttributesSO.cs new file mode 100644 index 0000000..2a949bb --- /dev/null +++ b/Assets/Scripts/HeroAttributesSO.cs @@ -0,0 +1,18 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class HeroAttributesSO : ScriptableObject +{ + [SerializeField] private Attribute STR; + [SerializeField] private Attribute MAG; + [SerializeField] private Attribute DEX; + [SerializeField] private Attribute CON; + [SerializeField] private Attribute CHA; + [SerializeField] private Attribute FTH; + + public static HeroAttributesSO New() + { + return ScriptableObject.CreateInstance(); + } +} diff --git a/Assets/Scripts/HeroAttributesSO.cs.meta b/Assets/Scripts/HeroAttributesSO.cs.meta new file mode 100644 index 0000000..a052f16 --- /dev/null +++ b/Assets/Scripts/HeroAttributesSO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 538672e6491e46748a1cc27fe3a52455 +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 8668e08..bfb95d4 100644 --- a/Assets/Tests/AttributeTest.cs +++ b/Assets/Tests/AttributeTest.cs @@ -7,19 +7,18 @@ using UnityEngine.TestTools; public class AttributeTest { [Test] - [TestCase(1000000, 0, 0, 0, 0, ExpectedResult = 1000000)] - [TestCase(1000000, 1, 0, 0, 0, ExpectedResult = 1000001)] - [TestCase(1000000, 0, 2, 0, 0, ExpectedResult = 1000002)] - [TestCase(1000000, 0, 0, 10000, 0, ExpectedResult = 2000000)] - [TestCase(1000000, 0, 0, 0, 3, ExpectedResult = 1000003)] - [TestCase(0, 1000000, 1000000, 5000, 1000, ExpectedResult = 3001000)] - [TestCase(1000000, 0, 0, -10000, 0, ExpectedResult = 0)] - [TestCase(1000000, 0, 0, -20000, 0, ExpectedResult = 0)] - [TestCase(1000000, 0, 0, -20000, 50, ExpectedResult = 0)] - public long Calc(long startStat, long levelUp, long baseBonus, long permyriadBonus, long flatBonus) + [TestCase(1000000, 0, 0, 0, ExpectedResult = 1000000)] + [TestCase(1000000, 1, 0, 0, ExpectedResult = 1000001)] + [TestCase(1000000, 0, 2, 0, ExpectedResult = 1000200)] + [TestCase(1000000, 0, 0, 10000, ExpectedResult = 1010000)] + [TestCase(0, 1000000, 5000, 1000000, ExpectedResult = 2500000)] + [TestCase(1000000, 0, -10000, 0, ExpectedResult = 0)] + [TestCase(1000000, 0, -20000, 0, ExpectedResult = 0)] + [TestCase(1000000, 0, -20000, 0, ExpectedResult = 0)] + public long Value(long startStat, long baseBonus, long permyriadBonus, long flatBonus) { var attr = new Attribute(startStat); - attr.LevelUp(levelUp); - return attr.Calc(baseBonus, permyriadBonus, flatBonus); + var effect = EffectSO.New(baseBonus, permyriadBonus, flatBonus); + return attr.Calc(effect); } }