com.wallstop-studios.unity-helpers 2.0.2 → 2.0.4

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.
@@ -2,6 +2,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
2
2
  {
3
3
  using System;
4
4
  using System.Collections.Concurrent;
5
+ using System.Threading.Tasks;
5
6
  using UnityEngine;
6
7
  using Utils;
7
8
  #if UNITY_EDITOR
@@ -104,7 +105,8 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
104
105
  /// </summary>
105
106
  public System.Threading.Tasks.Task RunAsync(Action action)
106
107
  {
107
- var tcs = new System.Threading.Tasks.TaskCompletionSource<bool>();
108
+ TaskCompletionSource<bool> tcs =
109
+ new System.Threading.Tasks.TaskCompletionSource<bool>();
108
110
  RunOnMainThread(() =>
109
111
  {
110
112
  try
@@ -125,7 +127,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
125
127
  /// </summary>
126
128
  public System.Threading.Tasks.Task<T> Post<T>(Func<T> func)
127
129
  {
128
- var tcs = new System.Threading.Tasks.TaskCompletionSource<T>();
130
+ TaskCompletionSource<T> tcs = new System.Threading.Tasks.TaskCompletionSource<T>();
129
131
  RunOnMainThread(() =>
130
132
  {
131
133
  try
@@ -9,6 +9,7 @@ namespace WallstopStudios.UnityHelpers.Tags
9
9
  using Core.Extension;
10
10
  using Core.Helper;
11
11
  using UnityEngine;
12
+ using WallstopStudios.UnityHelpers.Utils;
12
13
  #if ODIN_INSPECTOR
13
14
  using Sirenix.OdinInspector;
14
15
  #endif
@@ -52,6 +53,7 @@ namespace WallstopStudios.UnityHelpers.Tags
52
53
  /// </para>
53
54
  /// </remarks>
54
55
  [Serializable]
56
+ [CreateAssetMenu(menuName = "Wallstop Studios/Unity Helpers/Attribute Effect")]
55
57
  public sealed class AttributeEffect :
56
58
  #if ODIN_INSPECTOR
57
59
  SerializedScriptableObject
@@ -72,7 +74,7 @@ namespace WallstopStudios.UnityHelpers.Tags
72
74
  /// The list of attribute modifications to apply when this effect is activated.
73
75
  /// Each modification specifies an attribute name, action type, and value.
74
76
  /// </summary>
75
- public readonly List<AttributeModification> modifications = new();
77
+ public List<AttributeModification> modifications = new();
76
78
 
77
79
  /// <summary>
78
80
  /// Specifies how long this effect should persist (Instant, Duration, or Infinite).
@@ -110,12 +112,172 @@ namespace WallstopStudios.UnityHelpers.Tags
110
112
  /// </example>
111
113
  public List<string> effectTags = new();
112
114
 
115
+ /// <summary>
116
+ /// Determines whether this effect applies the specified tag.
117
+ /// </summary>
118
+ /// <param name="effectTag">The tag to check.</param>
119
+ /// <returns><c>true</c> if the tag is present; otherwise, <c>false</c>.</returns>
120
+ public bool HasTag(string effectTag)
121
+ {
122
+ if (effectTags == null || string.IsNullOrEmpty(effectTag))
123
+ {
124
+ return false;
125
+ }
126
+
127
+ for (int i = 0; i < effectTags.Count; ++i)
128
+ {
129
+ if (string.Equals(effectTags[i], effectTag, StringComparison.Ordinal))
130
+ {
131
+ return true;
132
+ }
133
+ }
134
+
135
+ return false;
136
+ }
137
+
138
+ /// <summary>
139
+ /// Determines whether this effect applies any of the specified tags.
140
+ /// </summary>
141
+ /// <param name="effectTagsToCheck">The tags to inspect.</param>
142
+ /// <returns><c>true</c> if at least one tag is applied; otherwise, <c>false</c>.</returns>
143
+ public bool HasAnyTag(IEnumerable<string> effectTagsToCheck)
144
+ {
145
+ if (effectTags == null || effectTagsToCheck == null)
146
+ {
147
+ return false;
148
+ }
149
+
150
+ switch (effectTagsToCheck)
151
+ {
152
+ case IReadOnlyList<string> list:
153
+ {
154
+ return HasAnyTag(list);
155
+ }
156
+ case HashSet<string> hashSet:
157
+ {
158
+ foreach (string candidate in hashSet)
159
+ {
160
+ if (string.IsNullOrEmpty(candidate))
161
+ {
162
+ continue;
163
+ }
164
+
165
+ if (HasTag(candidate))
166
+ {
167
+ return true;
168
+ }
169
+ }
170
+
171
+ return false;
172
+ }
173
+ }
174
+
175
+ foreach (string candidate in effectTagsToCheck)
176
+ {
177
+ if (string.IsNullOrEmpty(candidate))
178
+ {
179
+ continue;
180
+ }
181
+
182
+ if (HasTag(candidate))
183
+ {
184
+ return true;
185
+ }
186
+ }
187
+
188
+ return false;
189
+ }
190
+
191
+ /// <summary>
192
+ /// Determines whether this effect applies any of the specified tags.
193
+ /// Optimized for indexed collections.
194
+ /// </summary>
195
+ /// <param name="effectTagsToCheck">The tags to inspect.</param>
196
+ /// <returns><c>true</c> if at least one tag is applied; otherwise, <c>false</c>.</returns>
197
+ public bool HasAnyTag(IReadOnlyList<string> effectTagsToCheck)
198
+ {
199
+ if (effectTags == null || effectTagsToCheck == null)
200
+ {
201
+ return false;
202
+ }
203
+
204
+ for (int i = 0; i < effectTagsToCheck.Count; ++i)
205
+ {
206
+ string candidate = effectTagsToCheck[i];
207
+ if (string.IsNullOrEmpty(candidate))
208
+ {
209
+ continue;
210
+ }
211
+
212
+ if (HasTag(candidate))
213
+ {
214
+ return true;
215
+ }
216
+ }
217
+
218
+ return false;
219
+ }
220
+
221
+ /// <summary>
222
+ /// Determines whether this effect contains modifications for the specified attribute.
223
+ /// </summary>
224
+ /// <param name="attributeName">The attribute name to inspect.</param>
225
+ /// <returns><c>true</c> if the effect modifies <paramref name="attributeName"/>; otherwise, <c>false</c>.</returns>
226
+ public bool ModifiesAttribute(string attributeName)
227
+ {
228
+ if (modifications == null || string.IsNullOrEmpty(attributeName))
229
+ {
230
+ return false;
231
+ }
232
+
233
+ for (int i = 0; i < modifications.Count; ++i)
234
+ {
235
+ AttributeModification modification = modifications[i];
236
+ if (string.Equals(modification.attribute, attributeName, StringComparison.Ordinal))
237
+ {
238
+ return true;
239
+ }
240
+ }
241
+
242
+ return false;
243
+ }
244
+
245
+ /// <summary>
246
+ /// Copies all modifications that affect the specified attribute into the provided buffer.
247
+ /// </summary>
248
+ /// <param name="attributeName">The attribute to filter by.</param>
249
+ /// <param name="buffer">The destination buffer. Existing entries are preserved.</param>
250
+ /// <returns>The number of modifications added to <paramref name="buffer"/>.</returns>
251
+ public List<AttributeModification> GetModifications(
252
+ string attributeName,
253
+ List<AttributeModification> buffer = null
254
+ )
255
+ {
256
+ buffer ??= new List<AttributeModification>();
257
+ buffer.Clear();
258
+ if (modifications == null || string.IsNullOrEmpty(attributeName))
259
+ {
260
+ return buffer;
261
+ }
262
+
263
+ for (int i = 0; i < modifications.Count; ++i)
264
+ {
265
+ AttributeModification modification = modifications[i];
266
+ if (string.Equals(modification.attribute, attributeName, StringComparison.Ordinal))
267
+ {
268
+ buffer.Add(modification);
269
+ }
270
+ }
271
+
272
+ return buffer;
273
+ }
274
+
113
275
  /// <summary>
114
276
  /// A list of cosmetic effect data that defines visual and audio feedback for this effect.
115
277
  /// These are applied when the effect becomes active and removed when it expires.
116
278
  /// </summary>
117
279
  [JsonIgnore]
118
- public readonly List<CosmeticEffectData> cosmeticEffects = new();
280
+ public List<CosmeticEffectData> cosmeticEffects = new();
119
281
 
120
282
  private List<string> CosmeticEffectsForJson =>
121
283
  cosmeticEffects?.Select(cosmeticEffectData => cosmeticEffectData.name).ToList()
@@ -145,7 +307,9 @@ namespace WallstopStudios.UnityHelpers.Tags
145
307
  return nameof(AttributeEffect);
146
308
  }
147
309
 
148
- StringBuilder descriptionBuilder = new();
310
+ using PooledResource<StringBuilder> stringBuilderBuffer = Buffers.StringBuilder.Get(
311
+ out StringBuilder descriptionBuilder
312
+ );
149
313
  for (int i = 0; i < modifications.Count; ++i)
150
314
  {
151
315
  AttributeModification modification = modifications[i];