feature-attributes #7

Merged
zephyr merged 10 commits from feature-attributes into main 2023-07-30 10:58:19 -05:00
13 changed files with 190 additions and 34 deletions

8
Assets/Scriptables.meta generated Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1d13d7aac40657841955febd4faabbfa
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

19
Assets/Scriptables/EnemyAttributes.asset generated Normal file
View File

@ -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}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d5bf638cf02c5b94cb9874d4414c1b8a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

14
Assets/Scriptables/StatEffect.asset generated Normal file
View File

@ -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:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4c96040df8ebed746832db7857b25bed
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,38 +1,24 @@
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
zephyr marked this conversation as resolved Outdated

Missing SO suffix

Missing SO suffix

I think this should go back to a struct rather than an SO. But it also seems like that makes it so the editor can't see them. Might need to implement a custom editor?

I think this should go back to a struct rather than an SO. But it also seems like that makes it so the editor can't see them. Might need to implement a custom editor?
[Serializable]
public struct Attribute public struct Attribute
{ {
[SerializeField] public long Base;
private long _base;
public Attribute(long stat) public Attribute(long stat) { Base = stat; }
{
_base = stat;
}
/// <summary>
/// Permanently increase the stat value.
/// </summary>
/// <param name="by">Increase amount.</param>
public void LevelUp(long by)
{
_base += by;
}
/// <summary> /// <summary>
/// Calculates the stat value with accumulated buff and debuff modifiers. /// Calculates the stat value with accumulated buff and debuff modifiers.
/// </summary> /// </summary>
/// <param name="baseBonus">Additive bonus applied before multiplicative scaling.</param>
/// <param name="permyriadBonus">Multiplicative scaling in hundredths of a percent. E.g., 625 permyriad corresponds to 6.25%.</param>
/// <param name="flatBonus">Additive bonus applied after multiplicative scaling.</param>
/// <returns>(base + baseBonus) * (100% + permyriadBonus) + flatBonus, bounded below by 0.</returns> /// <returns>(base + baseBonus) * (100% + permyriadBonus) + flatBonus, bounded below by 0.</returns>
public long Calc(long baseBonus, long permyriadBonus, long flatBonus) public long Calc(EffectSO effect)
{ {
var r = _base + baseBonus; var r = Base + effect.Base;
var m = permyriadBonus + 10000; var m = effect.Permyriad + 10000;
r = r * (m / 10000) + (r / 10000) * (m % 10000) + flatBonus; r = r * (m / 10000) + (r / 10000) * (m % 10000) + effect.Flat;
if (r <= 0) if (r <= 0)
{ {
return 0; return 0;

View File

@ -0,0 +1,45 @@
using UnityEngine;
[CreateAssetMenu(fileName = "StatEffect", menuName = "Stat Effect")]
public class EffectSO : ScriptableObject
{
/// <summary>
/// Additive change applied before multiplicative scaling.
/// </summary>
public long Base;
zephyr marked this conversation as resolved Outdated

If we private set here is the editor able to set these values?

If we private set here is the editor able to set these values?

Tried some things. It looks like the editor can't set properties at all, only fields.

Tried some things. It looks like the editor can't set properties at all, only fields.
/// <summary>
/// Multiplicative scaling in units of hundredth of a percent.
/// E.g., 625 permyriad is 6.25%.
/// </summary>
public long Permyriad;
/// <summary>
/// Additive change applied after multiplicative scaling.
/// </summary>
public long Flat;
/// <summary>
/// Create a new attribute effect instance.
/// </summary>
/// <param name="baseBonus"></param>
/// <param name="permyriad"></param>
/// <param name="flat"></param>
/// <returns></returns>
public static EffectSO New(long baseBonus = 0, long permyriad = 0, long flat = 0)
{
var effect = ScriptableObject.CreateInstance<EffectSO>();
effect.Base = baseBonus;
effect.Permyriad = permyriad;
effect.Flat = flat;
return effect;
}
/// <summary>
/// Create a new EffectSO from a percentage.
/// </summary>
/// <param name="p">Percentage. E.g., 6.25f results in a Permyriad of 625.</param>
/// <returns>Effect with the given percentage.</returns>
public static EffectSO FromPercent(float p)
{
return New(permyriad: (long)(p * 100));
}
}

11
Assets/Scripts/EffectSO.cs.meta generated Normal file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 494a21c06960ec442a7a6806f8aefedb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<EnemyAttributesSO>();
}
}

11
Assets/Scripts/EnemyAttributesSO.cs.meta generated Normal file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c5304ff6dfe84844887d751cee48606a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<HeroAttributesSO>();
}
}

11
Assets/Scripts/HeroAttributesSO.cs.meta generated Normal file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 538672e6491e46748a1cc27fe3a52455
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -7,19 +7,18 @@ using UnityEngine.TestTools;
public class AttributeTest public class AttributeTest
{ {
[Test] [Test]
[TestCase(1000000, 0, 0, 0, 0, ExpectedResult = 1000000)] [TestCase(1000000, 0, 0, 0, ExpectedResult = 1000000)]
[TestCase(1000000, 1, 0, 0, 0, ExpectedResult = 1000001)] [TestCase(1000000, 1, 0, 0, ExpectedResult = 1000001)]
[TestCase(1000000, 0, 2, 0, 0, ExpectedResult = 1000002)] [TestCase(1000000, 0, 2, 0, ExpectedResult = 1000200)]
[TestCase(1000000, 0, 0, 10000, 0, ExpectedResult = 2000000)] [TestCase(1000000, 0, 0, 10000, ExpectedResult = 1010000)]
[TestCase(1000000, 0, 0, 0, 3, ExpectedResult = 1000003)] [TestCase(0, 1000000, 5000, 1000000, ExpectedResult = 2500000)]
[TestCase(0, 1000000, 1000000, 5000, 1000, ExpectedResult = 3001000)] [TestCase(1000000, 0, -10000, 0, ExpectedResult = 0)]
[TestCase(1000000, 0, 0, -10000, 0, ExpectedResult = 0)] [TestCase(1000000, 0, -20000, 0, ExpectedResult = 0)]
[TestCase(1000000, 0, 0, -20000, 0, ExpectedResult = 0)] [TestCase(1000000, 0, -20000, 0, ExpectedResult = 0)]
[TestCase(1000000, 0, 0, -20000, 50, ExpectedResult = 0)] public long Value(long startStat, long baseBonus, long permyriadBonus, long flatBonus)
public long Calc(long startStat, long levelUp, long baseBonus, long permyriadBonus, long flatBonus)
{ {
var attr = new Attribute(startStat); var attr = new Attribute(startStat);
attr.LevelUp(levelUp); var effect = EffectSO.New(baseBonus, permyriadBonus, flatBonus);
return attr.Calc(baseBonus, permyriadBonus, flatBonus); return attr.Calc(effect);
} }
} }