From 37436793ce20230679d455313b146b949acd61da Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Sun, 30 Jul 2023 00:04:07 -0500 Subject: [PATCH 01/10] rework Attribute to track its own bonuses --- Assets/Scripts/Attribute.cs | 27 +++++++++------------------ Assets/Tests/AttributeTest.cs | 28 +++++++++++++++------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/Assets/Scripts/Attribute.cs b/Assets/Scripts/Attribute.cs index c8c9090..9d2ac95 100644 --- a/Assets/Scripts/Attribute.cs +++ b/Assets/Scripts/Attribute.cs @@ -2,35 +2,26 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; -public struct Attribute +public class Attribute : ScriptableObject { - [SerializeField] - private long _base; + public long Base { get; set; } + public long BaseBonus { get; set; } + public long PermyriadBonus { get; set; } + public long FlatBonus { get; set; } - public Attribute(long stat) - { - _base = stat; - } - - /// - /// Permanently increase the stat value. - /// - /// Increase amount. - public void LevelUp(long by) - { - _base += by; - } + 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 long Calc(long baseBonus, long permyriadBonus, long flatBonus) + public static long Calc(long baseValue, long baseBonus, long permyriadBonus, long flatBonus) { - var r = _base + baseBonus; + var r = baseValue + baseBonus; var m = permyriadBonus + 10000; r = r * (m / 10000) + (r / 10000) * (m % 10000) + flatBonus; if (r <= 0) diff --git a/Assets/Tests/AttributeTest.cs b/Assets/Tests/AttributeTest.cs index 8668e08..f4b216c 100644 --- a/Assets/Tests/AttributeTest.cs +++ b/Assets/Tests/AttributeTest.cs @@ -7,19 +7,21 @@ 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 attr = ScriptableObject.CreateInstance(); + attr.Base = startStat; + attr.BaseBonus = baseBonus; + attr.PermyriadBonus = permyriadBonus; + attr.FlatBonus = flatBonus; + return attr.Value; } } -- 2.40.1 From 2bffefc0cb7fac8c24a84e0722074980b159ae91 Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Sun, 30 Jul 2023 00:48:16 -0500 Subject: [PATCH 02/10] add skeleton of hero attributes --- Assets/Scripts/HeroAttributes.cs | 15 +++++++++++++++ Assets/Scripts/HeroAttributes.cs.meta | 11 +++++++++++ 2 files changed, 26 insertions(+) create mode 100644 Assets/Scripts/HeroAttributes.cs create mode 100644 Assets/Scripts/HeroAttributes.cs.meta diff --git a/Assets/Scripts/HeroAttributes.cs b/Assets/Scripts/HeroAttributes.cs new file mode 100644 index 0000000..28f7ce7 --- /dev/null +++ b/Assets/Scripts/HeroAttributes.cs @@ -0,0 +1,15 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class HeroAttributes : ScriptableObject +{ + // TODO(zeph): does these being private make it hard to create a new hero? + // what about applying effects? + [SerializeField] private Attribute STR; + [SerializeField] private Attribute MAG; + [SerializeField] private Attribute DEX; + [SerializeField] private Attribute CON; + [SerializeField] private Attribute CHA; + [SerializeField] private Attribute FTH; +} diff --git a/Assets/Scripts/HeroAttributes.cs.meta b/Assets/Scripts/HeroAttributes.cs.meta new file mode 100644 index 0000000..a052f16 --- /dev/null +++ b/Assets/Scripts/HeroAttributes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 538672e6491e46748a1cc27fe3a52455 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: -- 2.40.1 From 8170727c598b89c8980da6b11857737a640745ba Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Sun, 30 Jul 2023 01:19:08 -0500 Subject: [PATCH 03/10] add stat effects, and rework attributes again --- Assets/Scripts/Attribute.cs | 17 +++---------- Assets/Scripts/EffectSO.cs | 45 +++++++++++++++++++++++++++++++++ Assets/Scripts/EffectSO.cs.meta | 11 ++++++++ Assets/Tests/AttributeTest.cs | 6 ++--- 4 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 Assets/Scripts/EffectSO.cs create mode 100644 Assets/Scripts/EffectSO.cs.meta 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); } } -- 2.40.1 From 3b0fc4481e828a4dd8ab431c96c1368c62c40d3f Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Sun, 30 Jul 2023 01:35:57 -0500 Subject: [PATCH 04/10] rename HeroAttributes -> HeroAttributesSO --- .../Scripts/{HeroAttributes.cs => HeroAttributesSO.cs} | 9 ++++++--- .../{HeroAttributes.cs.meta => HeroAttributesSO.cs.meta} | 0 2 files changed, 6 insertions(+), 3 deletions(-) rename Assets/Scripts/{HeroAttributes.cs => HeroAttributesSO.cs} (67%) rename Assets/Scripts/{HeroAttributes.cs.meta => HeroAttributesSO.cs.meta} (100%) diff --git a/Assets/Scripts/HeroAttributes.cs b/Assets/Scripts/HeroAttributesSO.cs similarity index 67% rename from Assets/Scripts/HeroAttributes.cs rename to Assets/Scripts/HeroAttributesSO.cs index 28f7ce7..2a949bb 100644 --- a/Assets/Scripts/HeroAttributes.cs +++ b/Assets/Scripts/HeroAttributesSO.cs @@ -2,14 +2,17 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; -public class HeroAttributes : ScriptableObject +public class HeroAttributesSO : ScriptableObject { - // TODO(zeph): does these being private make it hard to create a new hero? - // what about applying effects? [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/HeroAttributes.cs.meta b/Assets/Scripts/HeroAttributesSO.cs.meta similarity index 100% rename from Assets/Scripts/HeroAttributes.cs.meta rename to Assets/Scripts/HeroAttributesSO.cs.meta -- 2.40.1 From 124cb74bd59ce085a3ce15b29e4e5b0ec0166732 Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Sun, 30 Jul 2023 08:33:19 -0500 Subject: [PATCH 05/10] add enemy attributes --- Assets/Scripts/EnemyAttributesSO.cs | 15 +++++++++++++++ Assets/Scripts/EnemyAttributesSO.cs.meta | 11 +++++++++++ 2 files changed, 26 insertions(+) create mode 100644 Assets/Scripts/EnemyAttributesSO.cs create mode 100644 Assets/Scripts/EnemyAttributesSO.cs.meta diff --git a/Assets/Scripts/EnemyAttributesSO.cs b/Assets/Scripts/EnemyAttributesSO.cs new file mode 100644 index 0000000..2b62462 --- /dev/null +++ b/Assets/Scripts/EnemyAttributesSO.cs @@ -0,0 +1,15 @@ +using UnityEngine; + +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 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: -- 2.40.1 From ee2d696cecdb3dc42bb992e11f16ad66039de1e6 Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Sun, 30 Jul 2023 08:35:42 -0500 Subject: [PATCH 06/10] add create asset to enemy attributes --- Assets/Scripts/EnemyAttributesSO.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Assets/Scripts/EnemyAttributesSO.cs b/Assets/Scripts/EnemyAttributesSO.cs index 2b62462..ce9744d 100644 --- a/Assets/Scripts/EnemyAttributesSO.cs +++ b/Assets/Scripts/EnemyAttributesSO.cs @@ -1,5 +1,6 @@ using UnityEngine; +[CreateAssetMenu(fileName = "EnemyAttributes", menuName = "Enemy Attributes")] public class EnemyAttributesSO : ScriptableObject { [SerializeField] private Attribute STR; -- 2.40.1 From d8d3a69c36bf640fd77deb8a9e4d3127cd17e3ba Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Sun, 30 Jul 2023 08:41:01 -0500 Subject: [PATCH 07/10] add non-attribute XP and threat to enemy stats --- Assets/Scripts/EnemyAttributesSO.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Assets/Scripts/EnemyAttributesSO.cs b/Assets/Scripts/EnemyAttributesSO.cs index ce9744d..9d1a39f 100644 --- a/Assets/Scripts/EnemyAttributesSO.cs +++ b/Assets/Scripts/EnemyAttributesSO.cs @@ -8,6 +8,8 @@ public class EnemyAttributesSO : ScriptableObject [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() { -- 2.40.1 From 3b1b4a90b7f18c66a20724dd41d46fdf99d19166 Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Sun, 30 Jul 2023 10:16:12 -0500 Subject: [PATCH 08/10] make Attribute a struct again --- Assets/Scripts/Attribute.cs | 8 ++++++-- Assets/Tests/AttributeTest.cs | 3 +-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Assets/Scripts/Attribute.cs b/Assets/Scripts/Attribute.cs index 222652f..6c9a430 100644 --- a/Assets/Scripts/Attribute.cs +++ b/Assets/Scripts/Attribute.cs @@ -1,10 +1,14 @@ +using System; using System.Collections; using System.Collections.Generic; using UnityEngine; -public class Attribute : ScriptableObject +[Serializable] +public struct Attribute { - public long Base { get; set; } + public long Base; + + public Attribute(long stat) { Base = stat; } /// /// Calculates the stat value with accumulated buff and debuff modifiers. diff --git a/Assets/Tests/AttributeTest.cs b/Assets/Tests/AttributeTest.cs index e240b88..bfb95d4 100644 --- a/Assets/Tests/AttributeTest.cs +++ b/Assets/Tests/AttributeTest.cs @@ -17,8 +17,7 @@ public class AttributeTest [TestCase(1000000, 0, -20000, 0, ExpectedResult = 0)] public long Value(long startStat, long baseBonus, long permyriadBonus, long flatBonus) { - var attr = ScriptableObject.CreateInstance(); - attr.Base = startStat; + var attr = new Attribute(startStat); var effect = EffectSO.New(baseBonus, permyriadBonus, flatBonus); return attr.Calc(effect); } -- 2.40.1 From 61b7bbefc0b740b3bbb5ac742ee05c4dffe6121d Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Sun, 30 Jul 2023 10:16:49 -0500 Subject: [PATCH 09/10] use fields instead of properties --- Assets/Scripts/EffectSO.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Assets/Scripts/EffectSO.cs b/Assets/Scripts/EffectSO.cs index cd978c5..f50bce1 100644 --- a/Assets/Scripts/EffectSO.cs +++ b/Assets/Scripts/EffectSO.cs @@ -6,16 +6,16 @@ public class EffectSO : ScriptableObject /// /// Additive change applied before multiplicative scaling. /// - public long Base { get; private set; } + public long Base; /// /// Multiplicative scaling in units of hundredth of a percent. /// E.g., 625 permyriad is 6.25%. /// - public long Permyriad { get; private set; } + public long Permyriad; /// /// Additive change applied after multiplicative scaling. /// - public long Flat { get; private set; } + public long Flat; /// /// Create a new attribute effect instance. -- 2.40.1 From d9bbef4b055d5c5cfbff4dac459a4df3b17ec78a Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Sun, 30 Jul 2023 10:17:39 -0500 Subject: [PATCH 10/10] add example Effect and EnemyAttributes assets --- Assets/Scriptables.meta | 8 ++++++++ Assets/Scriptables/EnemyAttributes.asset | 19 +++++++++++++++++++ Assets/Scriptables/EnemyAttributes.asset.meta | 8 ++++++++ Assets/Scriptables/StatEffect.asset | 14 ++++++++++++++ Assets/Scriptables/StatEffect.asset.meta | 8 ++++++++ 5 files changed, 57 insertions(+) create mode 100644 Assets/Scriptables.meta create mode 100644 Assets/Scriptables/EnemyAttributes.asset create mode 100644 Assets/Scriptables/EnemyAttributes.asset.meta create mode 100644 Assets/Scriptables/StatEffect.asset create mode 100644 Assets/Scriptables/StatEffect.asset.meta 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: -- 2.40.1