com.wallstop-studios.unity-helpers 2.0.0-rc68 → 2.0.0-rc69
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/Runtime/Core/Attributes/ValidateAssignmentAttribute.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 +208 -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 +379 -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/SpatialTreeTests.cs +1 -1
- package/Tests/Runtime/Helper/ObjectHelperTests.cs +1 -0
- package/package.json +1 -1
- /package/Runtime/{Utils → Tags}/TagHandler.cs.meta +0 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Tags
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.Linq;
|
|
6
|
+
using System.Reflection;
|
|
7
|
+
using Core.Extension;
|
|
8
|
+
using Core.Helper;
|
|
9
|
+
using Object = UnityEngine.Object;
|
|
10
|
+
|
|
11
|
+
public static class AttributeUtilities
|
|
12
|
+
{
|
|
13
|
+
private static string[] AllAttributeNames;
|
|
14
|
+
private static readonly Dictionary<Type, Dictionary<string, FieldInfo>> AttributeFields =
|
|
15
|
+
new();
|
|
16
|
+
|
|
17
|
+
// TODO: Use TypeCache + serialize
|
|
18
|
+
public static string[] GetAllAttributeNames()
|
|
19
|
+
{
|
|
20
|
+
return AllAttributeNames ??= AppDomain
|
|
21
|
+
.CurrentDomain.GetAssemblies()
|
|
22
|
+
.SelectMany(assembly => assembly.GetTypes())
|
|
23
|
+
.Where(type => !type.IsAbstract)
|
|
24
|
+
.Where(type => type.IsSubclassOf(typeof(AttributesComponent)))
|
|
25
|
+
.SelectMany(type =>
|
|
26
|
+
type.GetFields(
|
|
27
|
+
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
.Where(fieldInfo => fieldInfo.FieldType == typeof(Attribute))
|
|
31
|
+
.Select(fieldInfo => fieldInfo.Name)
|
|
32
|
+
.Distinct()
|
|
33
|
+
.Ordered()
|
|
34
|
+
.ToArray();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public static bool HasTag(this Object target, string effectTag)
|
|
38
|
+
{
|
|
39
|
+
if (target == null)
|
|
40
|
+
{
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return target.TryGetComponent(out TagHandler tagHandler)
|
|
45
|
+
&& tagHandler.HasTag(effectTag);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public static bool HasAnyTag(this Object target, IEnumerable<string> effectTags)
|
|
49
|
+
{
|
|
50
|
+
if (target == null)
|
|
51
|
+
{
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return target.TryGetComponent(out TagHandler tagHandler)
|
|
56
|
+
&& tagHandler.HasAnyTag(effectTags);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public static bool HasAnyTag(this Object target, IReadOnlyList<string> effectTags)
|
|
60
|
+
{
|
|
61
|
+
if (target == null)
|
|
62
|
+
{
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return target.TryGetComponent(out TagHandler tagHandler)
|
|
67
|
+
&& tagHandler.HasAnyTag(effectTags);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public static EffectHandle? ApplyEffect(this Object target, AttributeEffect attributeEffect)
|
|
71
|
+
{
|
|
72
|
+
if (target == null)
|
|
73
|
+
{
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return target.TryGetComponent(out EffectHandler effectHandler)
|
|
78
|
+
? effectHandler.ApplyEffect(attributeEffect)
|
|
79
|
+
: null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public static void ApplyEffectsNoAlloc(
|
|
83
|
+
this Object target,
|
|
84
|
+
List<AttributeEffect> attributeEffects
|
|
85
|
+
)
|
|
86
|
+
{
|
|
87
|
+
if (attributeEffects is not { Count: > 0 })
|
|
88
|
+
{
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (target == null || !target.TryGetComponent(out EffectHandler effectHandler))
|
|
93
|
+
{
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
foreach (AttributeEffect attributeEffect in attributeEffects)
|
|
98
|
+
{
|
|
99
|
+
_ = effectHandler.ApplyEffect(attributeEffect);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public static void ApplyEffectsNoAlloc(
|
|
104
|
+
this Object target,
|
|
105
|
+
IEnumerable<AttributeEffect> attributeEffects
|
|
106
|
+
)
|
|
107
|
+
{
|
|
108
|
+
if (target == null || !target.TryGetComponent(out EffectHandler effectHandler))
|
|
109
|
+
{
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
foreach (AttributeEffect attributeEffect in attributeEffects)
|
|
114
|
+
{
|
|
115
|
+
_ = effectHandler.ApplyEffect(attributeEffect);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public static void ApplyEffectsNoAlloc(
|
|
120
|
+
this Object target,
|
|
121
|
+
List<AttributeEffect> attributeEffects,
|
|
122
|
+
List<EffectHandle> effectHandles
|
|
123
|
+
)
|
|
124
|
+
{
|
|
125
|
+
if (target == null || !target.TryGetComponent(out EffectHandler effectHandler))
|
|
126
|
+
{
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
foreach (AttributeEffect attributeEffect in attributeEffects)
|
|
131
|
+
{
|
|
132
|
+
EffectHandle? handle = effectHandler.ApplyEffect(attributeEffect);
|
|
133
|
+
if (handle.HasValue)
|
|
134
|
+
{
|
|
135
|
+
effectHandles.Add(handle.Value);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public static List<EffectHandle> ApplyEffects(
|
|
141
|
+
this Object target,
|
|
142
|
+
List<AttributeEffect> attributeEffects
|
|
143
|
+
)
|
|
144
|
+
{
|
|
145
|
+
List<EffectHandle> handles = new(attributeEffects.Count);
|
|
146
|
+
ApplyEffectsNoAlloc(target, attributeEffects, handles);
|
|
147
|
+
return handles;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
public static void RemoveEffect(this Object target, EffectHandle effectHandle)
|
|
151
|
+
{
|
|
152
|
+
if (target == null)
|
|
153
|
+
{
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (target.TryGetComponent(out EffectHandler effectHandler))
|
|
158
|
+
{
|
|
159
|
+
effectHandler.RemoveEffect(effectHandle);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
public static void RemoveEffects(this Object target, List<EffectHandle> effectHandles)
|
|
164
|
+
{
|
|
165
|
+
if (target == null || effectHandles.Count <= 0)
|
|
166
|
+
{
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (target.TryGetComponent(out EffectHandler effectHandler))
|
|
171
|
+
{
|
|
172
|
+
foreach (EffectHandle effectHandle in effectHandles)
|
|
173
|
+
{
|
|
174
|
+
effectHandler.RemoveEffect(effectHandle);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public static void RemoveAllEffects(this Object target)
|
|
180
|
+
{
|
|
181
|
+
if (target == null)
|
|
182
|
+
{
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (target.TryGetComponent(out EffectHandler effectHandler))
|
|
187
|
+
{
|
|
188
|
+
effectHandler.RemoveAllEffects();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
public static Dictionary<string, FieldInfo> GetAttributeFields(Type type)
|
|
193
|
+
{
|
|
194
|
+
return AttributeFields.GetOrAdd(
|
|
195
|
+
type,
|
|
196
|
+
inputType =>
|
|
197
|
+
{
|
|
198
|
+
return inputType
|
|
199
|
+
.GetFields(
|
|
200
|
+
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
201
|
+
)
|
|
202
|
+
.Where(field => field.FieldType == typeof(Attribute))
|
|
203
|
+
.ToDictionary(field => field.Name, StringComparer.Ordinal);
|
|
204
|
+
}
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Tags
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.Reflection;
|
|
6
|
+
using Core.Attributes;
|
|
7
|
+
using UnityEngine;
|
|
8
|
+
|
|
9
|
+
[RequireComponent(typeof(TagHandler))]
|
|
10
|
+
[RequireComponent(typeof(EffectHandler))]
|
|
11
|
+
public abstract class AttributesComponent : MonoBehaviour
|
|
12
|
+
{
|
|
13
|
+
public event Action<string, float, float> OnAttributeModified;
|
|
14
|
+
|
|
15
|
+
private readonly Dictionary<string, FieldInfo> _attributeFields;
|
|
16
|
+
private readonly HashSet<EffectHandle> _effectHandles;
|
|
17
|
+
|
|
18
|
+
[SiblingComponent]
|
|
19
|
+
protected TagHandler _tagHandler;
|
|
20
|
+
|
|
21
|
+
[SiblingComponent]
|
|
22
|
+
protected EffectHandler _effectHandler;
|
|
23
|
+
|
|
24
|
+
protected AttributesComponent()
|
|
25
|
+
{
|
|
26
|
+
_attributeFields = AttributeUtilities.GetAttributeFields(GetType());
|
|
27
|
+
_effectHandles = new HashSet<EffectHandle>();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
protected virtual void Awake()
|
|
31
|
+
{
|
|
32
|
+
this.AssignSiblingComponents();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public void ApplyAttributeModifications(
|
|
36
|
+
IEnumerable<AttributeModification> attributeModifications,
|
|
37
|
+
EffectHandle? handle
|
|
38
|
+
)
|
|
39
|
+
{
|
|
40
|
+
if (handle.HasValue)
|
|
41
|
+
{
|
|
42
|
+
ForceApplyAttributeModifications(handle.Value);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
InternalApplyAttributeModifications(attributeModifications);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public void ForceRemoveAttributeModifications(EffectHandle handle)
|
|
50
|
+
{
|
|
51
|
+
InternalRemoveAttributeModifications(handle);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private void InternalApplyAttributeModifications(
|
|
55
|
+
IEnumerable<AttributeModification> attributeModifications
|
|
56
|
+
)
|
|
57
|
+
{
|
|
58
|
+
foreach (AttributeModification modification in attributeModifications)
|
|
59
|
+
{
|
|
60
|
+
if (!TryGetAttribute(modification.attribute, out Attribute attribute))
|
|
61
|
+
{
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
float oldValue = attribute;
|
|
66
|
+
attribute.ApplyAttributeModification(modification);
|
|
67
|
+
float currentValue = attribute;
|
|
68
|
+
|
|
69
|
+
OnAttributeModified?.Invoke(modification.attribute, oldValue, currentValue);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public void ForceApplyAttributeModifications(EffectHandle handle)
|
|
74
|
+
{
|
|
75
|
+
AttributeEffect effect = handle.effect;
|
|
76
|
+
if (effect.modifications is not { Count: > 0 })
|
|
77
|
+
{
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
bool isNewEffect = false;
|
|
82
|
+
foreach (AttributeModification modification in effect.modifications)
|
|
83
|
+
{
|
|
84
|
+
if (!TryGetAttribute(modification.attribute, out Attribute attribute))
|
|
85
|
+
{
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
isNewEffect = isNewEffect || _effectHandles.Add(handle);
|
|
90
|
+
if (isNewEffect)
|
|
91
|
+
{
|
|
92
|
+
float oldValue = attribute;
|
|
93
|
+
attribute.ApplyAttributeModification(modification, handle);
|
|
94
|
+
float currentValue = attribute;
|
|
95
|
+
OnAttributeModified?.Invoke(modification.attribute, oldValue, currentValue);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public void ForceApplyAttributeModifications(AttributeEffect effect)
|
|
101
|
+
{
|
|
102
|
+
if (effect.modifications is not { Count: > 0 })
|
|
103
|
+
{
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
foreach (AttributeModification modification in effect.modifications)
|
|
108
|
+
{
|
|
109
|
+
if (!TryGetAttribute(modification.attribute, out Attribute attribute))
|
|
110
|
+
{
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
float oldValue = attribute;
|
|
115
|
+
attribute.ApplyAttributeModification(modification);
|
|
116
|
+
float currentValue = attribute;
|
|
117
|
+
OnAttributeModified?.Invoke(modification.attribute, oldValue, currentValue);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private void InternalRemoveAttributeModifications(EffectHandle handle)
|
|
122
|
+
{
|
|
123
|
+
AttributeEffect effect = handle.effect;
|
|
124
|
+
if (effect.modifications is not { Count: > 0 })
|
|
125
|
+
{
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
foreach (AttributeModification modification in effect.modifications)
|
|
130
|
+
{
|
|
131
|
+
if (!TryGetAttribute(modification.attribute, out Attribute attribute))
|
|
132
|
+
{
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
float oldValue = attribute;
|
|
137
|
+
_ = attribute.RemoveAttributeModification(handle);
|
|
138
|
+
float currentValue = attribute;
|
|
139
|
+
_ = _effectHandles.Remove(handle);
|
|
140
|
+
OnAttributeModified?.Invoke(modification.attribute, oldValue, currentValue);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private bool TryGetAttribute(string attributeName, out Attribute attribute)
|
|
145
|
+
{
|
|
146
|
+
if (!_attributeFields.TryGetValue(attributeName, out FieldInfo fieldInfo))
|
|
147
|
+
{
|
|
148
|
+
attribute = default;
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
object fieldValue = fieldInfo.GetValue(this);
|
|
153
|
+
if (fieldValue is Attribute fieldAttribute)
|
|
154
|
+
{
|
|
155
|
+
attribute = fieldAttribute;
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
attribute = default;
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Tags
|
|
2
|
+
{
|
|
3
|
+
using System.Collections.Generic;
|
|
4
|
+
using Core.Extension;
|
|
5
|
+
using UnityEngine;
|
|
6
|
+
|
|
7
|
+
[RequireComponent(typeof(CosmeticEffectData))]
|
|
8
|
+
public abstract class CosmeticEffectComponent : MonoBehaviour
|
|
9
|
+
{
|
|
10
|
+
public virtual bool RequiresInstance => false;
|
|
11
|
+
|
|
12
|
+
public virtual bool CleansUpSelf => false;
|
|
13
|
+
|
|
14
|
+
protected readonly List<GameObject> _appliedTargets = new();
|
|
15
|
+
|
|
16
|
+
protected virtual void OnDestroy()
|
|
17
|
+
{
|
|
18
|
+
if (_appliedTargets.Count <= 0)
|
|
19
|
+
{
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
foreach (GameObject appliedTarget in _appliedTargets.ToArray())
|
|
24
|
+
{
|
|
25
|
+
if (appliedTarget == null)
|
|
26
|
+
{
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
OnRemoveEffect(appliedTarget);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Executed when the associated effect is applied.
|
|
35
|
+
public virtual void OnApplyEffect(GameObject target)
|
|
36
|
+
{
|
|
37
|
+
_appliedTargets.Add(target);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Executed when the associated effect is non-instant and removed.
|
|
41
|
+
public virtual void OnRemoveEffect(GameObject target)
|
|
42
|
+
{
|
|
43
|
+
int appliedIndex = _appliedTargets.IndexOf(target);
|
|
44
|
+
if (0 <= appliedIndex)
|
|
45
|
+
{
|
|
46
|
+
_appliedTargets.RemoveAtSwapBack(appliedIndex);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Tags
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.Linq;
|
|
6
|
+
using Core.Helper;
|
|
7
|
+
using UnityEngine;
|
|
8
|
+
|
|
9
|
+
[DisallowMultipleComponent]
|
|
10
|
+
public sealed class CosmeticEffectData : MonoBehaviour, IEquatable<CosmeticEffectData>
|
|
11
|
+
{
|
|
12
|
+
// Is an instanced version of this gameObject created when applied.
|
|
13
|
+
public bool RequiresInstancing =>
|
|
14
|
+
_cosmetics.Value.Any(cosmeticEffect => cosmeticEffect.RequiresInstance);
|
|
15
|
+
|
|
16
|
+
[NonSerialized]
|
|
17
|
+
private readonly Lazy<CosmeticEffectComponent[]> _cosmetics;
|
|
18
|
+
|
|
19
|
+
[NonSerialized]
|
|
20
|
+
private readonly Lazy<HashSet<Type>> _cosmeticTypes;
|
|
21
|
+
|
|
22
|
+
public CosmeticEffectData()
|
|
23
|
+
{
|
|
24
|
+
_cosmetics = new Lazy<CosmeticEffectComponent[]>(
|
|
25
|
+
GetComponents<CosmeticEffectComponent>
|
|
26
|
+
);
|
|
27
|
+
_cosmeticTypes = new Lazy<HashSet<Type>>(
|
|
28
|
+
() => _cosmetics.Value.Select(cosmetic => cosmetic.GetType()).ToHashSet()
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public override bool Equals(object other)
|
|
33
|
+
{
|
|
34
|
+
return other is CosmeticEffectData cosmeticEffectData && Equals(cosmeticEffectData);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public bool Equals(CosmeticEffectData other)
|
|
38
|
+
{
|
|
39
|
+
if (ReferenceEquals(this, other))
|
|
40
|
+
{
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (other == null || GetHashCode() != other.GetHashCode())
|
|
45
|
+
{
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
bool componentTypeEquals = _cosmeticTypes.Value.SetEquals(other._cosmeticTypes.Value);
|
|
50
|
+
if (!componentTypeEquals)
|
|
51
|
+
{
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return Helpers.NameEquals(this, other);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public override int GetHashCode()
|
|
59
|
+
{
|
|
60
|
+
return _cosmeticTypes.Value.Count.GetHashCode();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Tags
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using Core.DataStructure.Adapters;
|
|
5
|
+
using Core.Extension;
|
|
6
|
+
|
|
7
|
+
[Serializable]
|
|
8
|
+
public readonly struct EffectHandle
|
|
9
|
+
: IEquatable<EffectHandle>,
|
|
10
|
+
IComparable<EffectHandle>,
|
|
11
|
+
IComparable
|
|
12
|
+
{
|
|
13
|
+
public readonly AttributeEffect effect;
|
|
14
|
+
|
|
15
|
+
public readonly KGuid id;
|
|
16
|
+
|
|
17
|
+
public static EffectHandle CreateInstance(AttributeEffect effect)
|
|
18
|
+
{
|
|
19
|
+
return new EffectHandle(Guid.NewGuid(), effect);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private EffectHandle(KGuid id, AttributeEffect effect)
|
|
23
|
+
{
|
|
24
|
+
this.id = id;
|
|
25
|
+
this.effect = effect;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public int CompareTo(EffectHandle other)
|
|
29
|
+
{
|
|
30
|
+
return id.CompareTo(other.id);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public int CompareTo(object obj)
|
|
34
|
+
{
|
|
35
|
+
if (obj is EffectHandle other)
|
|
36
|
+
{
|
|
37
|
+
return CompareTo(other);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return -1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public override bool Equals(object obj)
|
|
44
|
+
{
|
|
45
|
+
return obj is EffectHandle other && Equals(other);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public bool Equals(EffectHandle other)
|
|
49
|
+
{
|
|
50
|
+
return id == other.id;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public override int GetHashCode()
|
|
54
|
+
{
|
|
55
|
+
return id.GetHashCode();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public override string ToString()
|
|
59
|
+
{
|
|
60
|
+
return this.ToJson();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|