com.wallstop-studios.unity-helpers 2.0.0-rc68 → 2.0.0-rc70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Editor/AnimationCopier.cs +875 -93
- package/Editor/AnimationCreator.cs +840 -137
- package/Editor/AnimationEventEditor.cs +4 -4
- package/Editor/AnimatorControllerCopier.cs +3 -3
- package/Editor/Extensions/UnityExtensions.cs +26 -0
- package/Editor/Extensions/UnityExtensions.cs.meta +3 -0
- package/Editor/Extensions.meta +3 -0
- package/Editor/FitTextureSizeWindow.cs +371 -0
- package/Editor/PrefabChecker.cs +716 -0
- package/Editor/SpriteAtlasGenerator.cs +598 -0
- package/Editor/SpriteAtlasGenerator.cs.meta +3 -0
- package/Editor/SpriteCropper.cs +407 -0
- package/Editor/SpriteCropper.cs.meta +3 -0
- package/Editor/SpriteSettingsApplier.cs +756 -92
- package/Editor/TextureResizerWizard.cs +3 -3
- package/Editor/TextureSettingsApplier.cs +9 -9
- package/Editor/WShowIfPropertyDrawer.cs +2 -2
- package/Runtime/Core/Attributes/EnumDisplayNameAttribute.cs +15 -0
- package/Runtime/Core/Attributes/EnumDisplayNameAttribute.cs.meta +3 -0
- package/Runtime/Core/Attributes/ValidateAssignmentAttribute.cs +1 -1
- package/Runtime/Core/Extension/EnumExtensions.cs +176 -1
- package/Runtime/Core/Extension/UnityExtensions.cs +1 -1
- package/Runtime/Core/Helper/Partials/LogHelpers.cs +1 -1
- package/Runtime/Core/Helper/Partials/MathHelpers.cs +1 -1
- package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +3 -4
- package/Runtime/Tags/Attribute.cs +205 -0
- package/Runtime/Tags/Attribute.cs.meta +3 -0
- package/Runtime/Tags/AttributeEffect.cs +276 -0
- package/Runtime/Tags/AttributeEffect.cs.meta +3 -0
- package/Runtime/Tags/AttributeModification.cs +51 -0
- package/Runtime/Tags/AttributeModification.cs.meta +3 -0
- package/Runtime/Tags/AttributeUtilities.cs +209 -0
- package/Runtime/Tags/AttributeUtilities.cs.meta +3 -0
- package/Runtime/Tags/AttributesComponent.cs +163 -0
- package/Runtime/Tags/AttributesComponent.cs.meta +3 -0
- package/Runtime/Tags/CosmeticEffectComponent.cs +50 -0
- package/Runtime/Tags/CosmeticEffectComponent.cs.meta +3 -0
- package/Runtime/Tags/CosmeticEffectData.cs +63 -0
- package/Runtime/Tags/CosmeticEffectData.cs.meta +3 -0
- package/Runtime/Tags/EffectHandle.cs +63 -0
- package/Runtime/Tags/EffectHandle.cs.meta +3 -0
- package/Runtime/Tags/EffectHandler.cs +380 -0
- package/Runtime/Tags/EffectHandler.cs.meta +3 -0
- package/Runtime/Tags/ModificationAction.cs +9 -0
- package/Runtime/Tags/ModificationAction.cs.meta +3 -0
- package/Runtime/Tags/ModifierDurationType.cs +13 -0
- package/Runtime/Tags/ModifierDurationType.cs.meta +3 -0
- package/Runtime/{Utils → Tags}/TagHandler.cs +42 -5
- package/Runtime/Tags.meta +3 -0
- package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs +1 -1
- package/Tests/Runtime/DataStructures/CyclicBufferTests.cs +1 -1
- package/Tests/Runtime/DataStructures/QuadTreeTests.cs +1 -1
- package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +1 -1
- package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs +1 -1
- package/Tests/Runtime/Extensions/DictionaryExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/EnumExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/IListExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/LoggingExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/StringExtensionTests.cs +1 -1
- package/Tests/Runtime/Helper/ObjectHelperTests.cs +1 -0
- package/Tests/Runtime/Helper/WallMathTests.cs +1 -1
- package/Tests/Runtime/Performance/KDTreePerformanceTests.cs +1 -1
- package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs +1 -1
- package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +1 -1
- package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs +1 -1
- package/Tests/Runtime/Random/RandomTestBase.cs +2 -2
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs +1 -1
- package/package.json +1 -1
- package/Editor/FitTextureSizeWizard.cs +0 -147
- package/Editor/PrefabCheckWizard.cs +0 -167
- /package/Editor/{FitTextureSizeWizard.cs.meta → FitTextureSizeWindow.cs.meta} +0 -0
- /package/Editor/{PrefabCheckWizard.cs.meta → PrefabChecker.cs.meta} +0 -0
- /package/Runtime/{Utils → Tags}/TagHandler.cs.meta +0 -0
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
using UnityEditor;
|
|
10
10
|
using UnityEngine;
|
|
11
11
|
using UnityEngine.Serialization;
|
|
12
|
-
using
|
|
13
|
-
using
|
|
12
|
+
using Core.Extension;
|
|
13
|
+
using Core.Helper;
|
|
14
14
|
using WallstopStudios.UnityHelpers.Utils;
|
|
15
15
|
using Object = UnityEngine.Object;
|
|
16
16
|
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
public float widthMultiplier = 0.54f;
|
|
40
40
|
public float heightMultiplier = 0.245f;
|
|
41
41
|
|
|
42
|
-
[MenuItem("Tools/Unity Helpers/Texture Resizer")]
|
|
42
|
+
[MenuItem("Tools/Wallstop Studios/Unity Helpers/Texture Resizer")]
|
|
43
43
|
public static void ResizeTextures()
|
|
44
44
|
{
|
|
45
45
|
_ = DisplayWizard<TextureResizerWizard>("Texture Resizer", "Resize");
|
|
@@ -7,23 +7,23 @@
|
|
|
7
7
|
using System.Linq;
|
|
8
8
|
using UnityEditor;
|
|
9
9
|
using UnityEngine;
|
|
10
|
-
using
|
|
11
|
-
using
|
|
10
|
+
using Core.Attributes;
|
|
11
|
+
using Core.Extension;
|
|
12
12
|
using WallstopStudios.UnityHelpers.Utils;
|
|
13
13
|
using Object = UnityEngine.Object;
|
|
14
14
|
|
|
15
15
|
public sealed class TextureSettingsApplier : ScriptableWizard
|
|
16
16
|
{
|
|
17
|
-
public bool applyReadOnly
|
|
18
|
-
public bool isReadOnly
|
|
19
|
-
public bool applyMipMaps
|
|
20
|
-
public bool generateMipMaps
|
|
21
|
-
public bool applyWrapMode
|
|
17
|
+
public bool applyReadOnly;
|
|
18
|
+
public bool isReadOnly;
|
|
19
|
+
public bool applyMipMaps;
|
|
20
|
+
public bool generateMipMaps;
|
|
21
|
+
public bool applyWrapMode;
|
|
22
22
|
|
|
23
23
|
[WShowIf(nameof(applyWrapMode))]
|
|
24
24
|
public TextureWrapMode wrapMode = TextureWrapMode.Clamp;
|
|
25
25
|
|
|
26
|
-
public bool applyFilterMode
|
|
26
|
+
public bool applyFilterMode;
|
|
27
27
|
|
|
28
28
|
[WShowIf(nameof(applyFilterMode))]
|
|
29
29
|
public FilterMode filterMode = FilterMode.Trilinear;
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
)]
|
|
43
43
|
public List<Object> directories = new();
|
|
44
44
|
|
|
45
|
-
[MenuItem("Tools/Unity Helpers/Texture Settings Applier")]
|
|
45
|
+
[MenuItem("Tools/Wallstop Studios/Unity Helpers/Texture Settings Applier")]
|
|
46
46
|
public static void CreateAnimation()
|
|
47
47
|
{
|
|
48
48
|
_ = DisplayWizard<TextureSettingsApplier>("Texture Settings Directory Applier", "Set");
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
using System.Reflection;
|
|
5
5
|
using UnityEditor;
|
|
6
6
|
using UnityEngine;
|
|
7
|
-
using
|
|
8
|
-
using
|
|
7
|
+
using Core.Attributes;
|
|
8
|
+
using Core.Extension;
|
|
9
9
|
|
|
10
10
|
[CustomPropertyDrawer(typeof(WShowIfAttribute))]
|
|
11
11
|
public sealed class WShowIfPropertyDrawer : PropertyDrawer
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Core.Attributes
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
|
|
5
|
+
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
|
|
6
|
+
public sealed class EnumDisplayNameAttribute : Attribute
|
|
7
|
+
{
|
|
8
|
+
public string DisplayName { get; }
|
|
9
|
+
|
|
10
|
+
public EnumDisplayNameAttribute(string displayName)
|
|
11
|
+
{
|
|
12
|
+
DisplayName = displayName;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,7 +1,158 @@
|
|
|
1
|
-
|
|
1
|
+
// ReSharper disable StaticMemberInGenericType
|
|
2
|
+
namespace WallstopStudios.UnityHelpers.Core.Extension
|
|
2
3
|
{
|
|
3
4
|
using System;
|
|
5
|
+
using System.Collections.Generic;
|
|
6
|
+
using System.Linq;
|
|
7
|
+
using System.Reflection;
|
|
4
8
|
using System.Runtime.CompilerServices;
|
|
9
|
+
using Attributes;
|
|
10
|
+
using Helper;
|
|
11
|
+
|
|
12
|
+
public static class EnumNameCache<T>
|
|
13
|
+
where T : struct, Enum
|
|
14
|
+
{
|
|
15
|
+
private const int MaxDenseRange = 1024;
|
|
16
|
+
|
|
17
|
+
private static readonly bool UseDensePacking;
|
|
18
|
+
private static readonly int Min;
|
|
19
|
+
private static readonly string[]? DenseNames;
|
|
20
|
+
private static readonly Dictionary<int, string>? SparseNames;
|
|
21
|
+
|
|
22
|
+
static EnumNameCache()
|
|
23
|
+
{
|
|
24
|
+
T[] values = Enum.GetValues(typeof(T)).Cast<T>().ToArray();
|
|
25
|
+
int[] intValues = values.Select(v => Unsafe.As<T, int>(ref v)).ToArray();
|
|
26
|
+
int min = intValues.Min();
|
|
27
|
+
int max = intValues.Max();
|
|
28
|
+
int range = max - min + 1;
|
|
29
|
+
|
|
30
|
+
if (range <= MaxDenseRange)
|
|
31
|
+
{
|
|
32
|
+
UseDensePacking = true;
|
|
33
|
+
Min = min;
|
|
34
|
+
DenseNames = new string[range];
|
|
35
|
+
|
|
36
|
+
for (int i = 0; i < values.Length; i++)
|
|
37
|
+
{
|
|
38
|
+
int key = intValues[i] - min;
|
|
39
|
+
T value = values[i];
|
|
40
|
+
DenseNames[key] = value.ToString("G");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else
|
|
44
|
+
{
|
|
45
|
+
UseDensePacking = false;
|
|
46
|
+
SparseNames = new Dictionary<int, string>();
|
|
47
|
+
for (int i = 0; i < values.Length; i++)
|
|
48
|
+
{
|
|
49
|
+
int key = Unsafe.As<T, int>(ref values[i]);
|
|
50
|
+
T value = values[i];
|
|
51
|
+
string name = value.ToString("G");
|
|
52
|
+
SparseNames.TryAdd(key, name);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
58
|
+
public static string ToCachedName(T value)
|
|
59
|
+
{
|
|
60
|
+
int key = Unsafe.As<T, int>(ref value);
|
|
61
|
+
if (UseDensePacking)
|
|
62
|
+
{
|
|
63
|
+
int idx = key - Min;
|
|
64
|
+
if ((uint)idx < (uint)DenseNames!.Length)
|
|
65
|
+
{
|
|
66
|
+
return DenseNames[idx];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
{
|
|
71
|
+
if (SparseNames!.TryGetValue(key, out string name))
|
|
72
|
+
{
|
|
73
|
+
return name;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return value.ToString();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public static class EnumDisplayNameCache<T>
|
|
82
|
+
where T : struct, Enum
|
|
83
|
+
{
|
|
84
|
+
private const int MaxDenseRange = 1024;
|
|
85
|
+
|
|
86
|
+
private static readonly bool UseDensePacking;
|
|
87
|
+
private static readonly int Min;
|
|
88
|
+
private static readonly string[]? DenseNames;
|
|
89
|
+
private static readonly Dictionary<int, string>? SparseNames;
|
|
90
|
+
|
|
91
|
+
static EnumDisplayNameCache()
|
|
92
|
+
{
|
|
93
|
+
Type type = typeof(T);
|
|
94
|
+
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
|
|
95
|
+
T[] values = fields.Select(f => (T)f.GetValue(null)).ToArray();
|
|
96
|
+
int[] intValues = values.Select(v => Unsafe.As<T, int>(ref v)).ToArray();
|
|
97
|
+
int min = intValues.Min();
|
|
98
|
+
int max = intValues.Max();
|
|
99
|
+
int range = max - min + 1;
|
|
100
|
+
|
|
101
|
+
if (range <= MaxDenseRange)
|
|
102
|
+
{
|
|
103
|
+
UseDensePacking = true;
|
|
104
|
+
Min = min;
|
|
105
|
+
DenseNames = new string[range];
|
|
106
|
+
|
|
107
|
+
for (int i = 0; i < fields.Length; i++)
|
|
108
|
+
{
|
|
109
|
+
int key = intValues[i] - min;
|
|
110
|
+
FieldInfo field = fields[i];
|
|
111
|
+
string name = field.IsAttributeDefined(out EnumDisplayNameAttribute displayName)
|
|
112
|
+
? displayName.DisplayName
|
|
113
|
+
: field.Name;
|
|
114
|
+
DenseNames[key] = name;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else
|
|
118
|
+
{
|
|
119
|
+
UseDensePacking = false;
|
|
120
|
+
SparseNames = new Dictionary<int, string>();
|
|
121
|
+
for (int i = 0; i < fields.Length; i++)
|
|
122
|
+
{
|
|
123
|
+
int key = Unsafe.As<T, int>(ref values[i]);
|
|
124
|
+
FieldInfo field = fields[i];
|
|
125
|
+
string name = field.IsAttributeDefined(out EnumDisplayNameAttribute displayName)
|
|
126
|
+
? displayName.DisplayName
|
|
127
|
+
: field.Name;
|
|
128
|
+
SparseNames.TryAdd(key, name);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
134
|
+
public static string ToDisplayName(T value)
|
|
135
|
+
{
|
|
136
|
+
int key = Unsafe.As<T, int>(ref value);
|
|
137
|
+
if (UseDensePacking)
|
|
138
|
+
{
|
|
139
|
+
int idx = key - Min;
|
|
140
|
+
if ((uint)idx < (uint)DenseNames!.Length)
|
|
141
|
+
{
|
|
142
|
+
return DenseNames[idx];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else
|
|
146
|
+
{
|
|
147
|
+
if (SparseNames!.TryGetValue(key, out string name))
|
|
148
|
+
{
|
|
149
|
+
return name;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return value.ToString();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
5
156
|
|
|
6
157
|
public static class EnumExtensions
|
|
7
158
|
{
|
|
@@ -14,6 +165,30 @@
|
|
|
14
165
|
return (valueUnderlying & flagUnderlying) == flagUnderlying;
|
|
15
166
|
}
|
|
16
167
|
|
|
168
|
+
public static string ToDisplayName<T>(this T value)
|
|
169
|
+
where T : unmanaged, Enum
|
|
170
|
+
{
|
|
171
|
+
return EnumDisplayNameCache<T>.ToDisplayName(value);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public static IEnumerable<string> ToDisplayNames<T>(this IEnumerable<T> enumerable)
|
|
175
|
+
where T : unmanaged, Enum
|
|
176
|
+
{
|
|
177
|
+
return enumerable.Select(value => value.ToDisplayName());
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public static string ToCachedName<T>(this T value)
|
|
181
|
+
where T : unmanaged, Enum
|
|
182
|
+
{
|
|
183
|
+
return EnumNameCache<T>.ToCachedName(value);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
public static IEnumerable<string> ToCachedNames<T>(this IEnumerable<T> enumerable)
|
|
187
|
+
where T : unmanaged, Enum
|
|
188
|
+
{
|
|
189
|
+
return enumerable.Select(value => value.ToCachedName());
|
|
190
|
+
}
|
|
191
|
+
|
|
17
192
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
18
193
|
private static unsafe ulong GetUInt64<T>(T value)
|
|
19
194
|
where T : unmanaged
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
{
|
|
3
3
|
using System;
|
|
4
4
|
using Extension;
|
|
5
|
+
using UnityEditor;
|
|
6
|
+
using UnityEditor.SceneManagement;
|
|
5
7
|
using UnityEngine;
|
|
6
8
|
using UnityEngine.SceneManagement;
|
|
7
9
|
using Object = UnityEngine.Object;
|
|
8
|
-
|
|
9
|
-
using UnityEditor;
|
|
10
|
-
using UnityEditor.SceneManagement;
|
|
11
|
-
#endif
|
|
10
|
+
|
|
12
11
|
public static partial class Helpers
|
|
13
12
|
{
|
|
14
13
|
public static T Find<T>(this Object component, string tag, bool log = true)
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Tags
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.ComponentModel;
|
|
6
|
+
using System.Globalization;
|
|
7
|
+
using System.Linq;
|
|
8
|
+
using System.Runtime.Serialization;
|
|
9
|
+
using System.Text.Json.Serialization;
|
|
10
|
+
using Core.Extension;
|
|
11
|
+
using ProtoBuf;
|
|
12
|
+
using UnityEngine;
|
|
13
|
+
|
|
14
|
+
[Serializable]
|
|
15
|
+
[ProtoContract]
|
|
16
|
+
public sealed class Attribute : IEquatable<Attribute>, IEquatable<float>
|
|
17
|
+
{
|
|
18
|
+
public float CurrentValue
|
|
19
|
+
{
|
|
20
|
+
get
|
|
21
|
+
{
|
|
22
|
+
#if UNITY_EDITOR
|
|
23
|
+
/*
|
|
24
|
+
For some reason, there's a bug with loot tables where
|
|
25
|
+
_currentValueCalculated will be true but the current
|
|
26
|
+
value is not calculated, so ignore the flag if we're
|
|
27
|
+
in editor mode, where this happens
|
|
28
|
+
*/
|
|
29
|
+
if (Application.isPlaying)
|
|
30
|
+
#endif
|
|
31
|
+
{
|
|
32
|
+
if (_currentValueCalculated)
|
|
33
|
+
{
|
|
34
|
+
return _currentValue;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
CalculateCurrentValue();
|
|
39
|
+
return _currentValue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public float BaseValue => _baseValue;
|
|
44
|
+
|
|
45
|
+
[SerializeField]
|
|
46
|
+
internal float _baseValue;
|
|
47
|
+
|
|
48
|
+
[SerializeField]
|
|
49
|
+
private float _currentValue;
|
|
50
|
+
|
|
51
|
+
private bool _currentValueCalculated;
|
|
52
|
+
|
|
53
|
+
internal void CalculateCurrentValue()
|
|
54
|
+
{
|
|
55
|
+
float calculatedValue = _baseValue;
|
|
56
|
+
foreach (
|
|
57
|
+
AttributeModification attributeModification in _modifications
|
|
58
|
+
.SelectMany(kvp => kvp.Value)
|
|
59
|
+
.OrderBy(mod => mod.action)
|
|
60
|
+
)
|
|
61
|
+
{
|
|
62
|
+
ApplyAttributeModification(attributeModification, ref calculatedValue);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
_currentValue = calculatedValue;
|
|
66
|
+
_currentValueCalculated = true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private readonly Dictionary<EffectHandle, List<AttributeModification>> _modifications =
|
|
70
|
+
new();
|
|
71
|
+
|
|
72
|
+
public static implicit operator float(Attribute attribute) => attribute.CurrentValue;
|
|
73
|
+
|
|
74
|
+
public static implicit operator Attribute(float value) => new(value);
|
|
75
|
+
|
|
76
|
+
public Attribute()
|
|
77
|
+
: this(0) { }
|
|
78
|
+
|
|
79
|
+
public Attribute(float value)
|
|
80
|
+
{
|
|
81
|
+
_baseValue = value;
|
|
82
|
+
_currentValueCalculated = false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
[JsonConstructor]
|
|
86
|
+
public Attribute(float baseValue, float currentValue)
|
|
87
|
+
{
|
|
88
|
+
_baseValue = baseValue;
|
|
89
|
+
_currentValue = currentValue;
|
|
90
|
+
_currentValueCalculated = true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public void ClearCache()
|
|
94
|
+
{
|
|
95
|
+
_currentValueCalculated = false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public void ApplyAttributeModification(
|
|
99
|
+
AttributeModification attributeModification,
|
|
100
|
+
EffectHandle? handle = null
|
|
101
|
+
)
|
|
102
|
+
{
|
|
103
|
+
// If we don't have a handle, then this is an instant effect, apply it to the base value.
|
|
104
|
+
if (!handle.HasValue)
|
|
105
|
+
{
|
|
106
|
+
ApplyAttributeModification(attributeModification, ref _baseValue);
|
|
107
|
+
}
|
|
108
|
+
else
|
|
109
|
+
{
|
|
110
|
+
_modifications.GetOrAdd(handle.Value).Add(attributeModification);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
CalculateCurrentValue();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public bool RemoveAttributeModification(EffectHandle handle)
|
|
117
|
+
{
|
|
118
|
+
bool removed = _modifications.Remove(handle);
|
|
119
|
+
if (removed)
|
|
120
|
+
{
|
|
121
|
+
CalculateCurrentValue();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return removed;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
[OnDeserialized]
|
|
128
|
+
private void AfterDeserialize(StreamingContext streamingContext)
|
|
129
|
+
{
|
|
130
|
+
ClearCache();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
[ProtoAfterDeserialization]
|
|
134
|
+
private void AfterProtoDeserialized()
|
|
135
|
+
{
|
|
136
|
+
ClearCache();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private static void ApplyAttributeModification(
|
|
140
|
+
AttributeModification attributeModification,
|
|
141
|
+
ref float value
|
|
142
|
+
)
|
|
143
|
+
{
|
|
144
|
+
switch (attributeModification.action)
|
|
145
|
+
{
|
|
146
|
+
case ModificationAction.Addition:
|
|
147
|
+
value += attributeModification.value;
|
|
148
|
+
break;
|
|
149
|
+
case ModificationAction.Multiplication:
|
|
150
|
+
value *= attributeModification.value;
|
|
151
|
+
break;
|
|
152
|
+
case ModificationAction.Override:
|
|
153
|
+
value = attributeModification.value;
|
|
154
|
+
break;
|
|
155
|
+
default:
|
|
156
|
+
throw new InvalidEnumArgumentException(
|
|
157
|
+
nameof(attributeModification.action),
|
|
158
|
+
(int)attributeModification.action,
|
|
159
|
+
typeof(ModificationAction)
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public bool Equals(Attribute other)
|
|
165
|
+
{
|
|
166
|
+
if (ReferenceEquals(this, other))
|
|
167
|
+
{
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return other != null && CurrentValue.Equals(other.CurrentValue);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public override bool Equals(object other)
|
|
175
|
+
{
|
|
176
|
+
switch (other)
|
|
177
|
+
{
|
|
178
|
+
case Attribute attribute:
|
|
179
|
+
return Equals(attribute);
|
|
180
|
+
case float attribute:
|
|
181
|
+
return Equals(attribute);
|
|
182
|
+
case double attribute:
|
|
183
|
+
return Equals((float)attribute);
|
|
184
|
+
default:
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
public bool Equals(float other)
|
|
190
|
+
{
|
|
191
|
+
return CurrentValue.Equals(other);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public override int GetHashCode()
|
|
195
|
+
{
|
|
196
|
+
// ReSharper disable once BaseObjectGetHashCodeCallInGetHashCode
|
|
197
|
+
return base.GetHashCode();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public override string ToString()
|
|
201
|
+
{
|
|
202
|
+
return ((float)this).ToString(CultureInfo.InvariantCulture);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|