diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..add57be
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+bin/
+obj/
+/packages/
+riderModule.iml
+/_ReSharper.Caches/
\ No newline at end of file
diff --git a/.idea/.idea.GameDevLibrary/.idea/workspace.xml b/.idea/.idea.GameDevLibrary/.idea/workspace.xml
new file mode 100644
index 0000000..5dfabfa
--- /dev/null
+++ b/.idea/.idea.GameDevLibrary/.idea/workspace.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1713617089947
+
+
+ 1713617089947
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.OmegaLeo.HelperLib/.idea/.gitignore b/.idea/.idea.OmegaLeo.HelperLib/.idea/.gitignore
new file mode 100644
index 0000000..fce483a
--- /dev/null
+++ b/.idea/.idea.OmegaLeo.HelperLib/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/contentModel.xml
+/modules.xml
+/.idea.GameDevLibrary.iml
+/projectSettingsUpdater.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.idea.OmegaLeo.HelperLib/.idea/.name b/.idea/.idea.OmegaLeo.HelperLib/.idea/.name
new file mode 100644
index 0000000..afe219f
--- /dev/null
+++ b/.idea/.idea.OmegaLeo.HelperLib/.idea/.name
@@ -0,0 +1 @@
+OmegaLeo.HelperLib
\ No newline at end of file
diff --git a/.idea/.idea.OmegaLeo.HelperLib/.idea/encodings.xml b/.idea/.idea.OmegaLeo.HelperLib/.idea/encodings.xml
new file mode 100644
index 0000000..df87cf9
--- /dev/null
+++ b/.idea/.idea.OmegaLeo.HelperLib/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.OmegaLeo.HelperLib/.idea/indexLayout.xml b/.idea/.idea.OmegaLeo.HelperLib/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/.idea/.idea.OmegaLeo.HelperLib/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.OmegaLeo.HelperLib/.idea/vcs.xml b/.idea/.idea.OmegaLeo.HelperLib/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/.idea.OmegaLeo.HelperLib/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OmegaLeo.HelperLib.sln b/OmegaLeo.HelperLib.sln
new file mode 100644
index 0000000..9e6e5fc
--- /dev/null
+++ b/OmegaLeo.HelperLib.sln
@@ -0,0 +1,16 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib", "OmegaLeo.HelperLib\OmegaLeo.HelperLib.csproj", "{A7256931-5D66-46FA-BA50-22B2FA4CD9E9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A7256931-5D66-46FA-BA50-22B2FA4CD9E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A7256931-5D66-46FA-BA50-22B2FA4CD9E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A7256931-5D66-46FA-BA50-22B2FA4CD9E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A7256931-5D66-46FA-BA50-22B2FA4CD9E9}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/OmegaLeo.HelperLib/Extensions/ArrayExtensions.cs b/OmegaLeo.HelperLib/Extensions/ArrayExtensions.cs
new file mode 100644
index 0000000..00ad8a4
--- /dev/null
+++ b/OmegaLeo.HelperLib/Extensions/ArrayExtensions.cs
@@ -0,0 +1,19 @@
+using UnityFlow.DocumentationHelper.Library.Attributes;
+
+namespace GameDevLibrary.Extensions
+{
+ [Documentation("Array Extensions", "Set of extension methods to help with Arrays.")]
+ public static class ArrayExtensions
+ {
+ // Idea obtained from TaroDev's video on things to do in Unity - https://youtu.be/Ic5ux-tpkCE?t=302
+ [Documentation("Next", @"Method to obtain the next object in the array by passing the current index.
+Note: Idea obtained from TaroDev's video on things to do in Unity - https://youtu.be/Ic5ux-tpkCE?t=302", new []
+ {
+ "CurrentIndex - The index we're currently on inside the array passed as reference so we can automatically assign to it the next index"
+ })]
+ public static T Next(this T[] array, ref int currentIndex)
+ {
+ return array[currentIndex++ % array.Length];
+ }
+ }
+}
\ No newline at end of file
diff --git a/OmegaLeo.HelperLib/Extensions/FloatExtensions.cs b/OmegaLeo.HelperLib/Extensions/FloatExtensions.cs
new file mode 100644
index 0000000..5b59758
--- /dev/null
+++ b/OmegaLeo.HelperLib/Extensions/FloatExtensions.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace GameDevLibrary.Extensions
+{
+ public static class FloatExtensions
+ {
+ public static float Round(this float value, int digits = 2)
+ {
+ return MathF.Round(value, digits);
+ }
+
+ public static int RoundToInt(this float value)
+ {
+ return (int)value.Round(0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OmegaLeo.HelperLib/Extensions/IListExtensions.cs b/OmegaLeo.HelperLib/Extensions/IListExtensions.cs
new file mode 100644
index 0000000..1d22ed4
--- /dev/null
+++ b/OmegaLeo.HelperLib/Extensions/IListExtensions.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace GameDevLibrary.Extensions
+{
+ public static class IListExtensions
+ {
+ ///
+ /// Swaps the position of 2 elements inside of a List
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// List with swapped elements
+ public static IList Swap(this IList list, int indexA, int indexB)
+ {
+ (list[indexA], list[indexB]) = (list[indexB], list[indexA]);
+ return list;
+ }
+
+ ///
+ /// Swaps the position of 2 elements inside of a List
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// List with swapped elements
+ public static IList Swap(this IList list, T itemA, T itemB)
+ {
+ return list.Swap(list.IndexOf(itemA), list.IndexOf(itemB));
+ }
+
+ ///
+ /// Replace an element inside a list with a different element
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static IList Replace(this IList list, T originalValue, T valueToReplace)
+ {
+ var index = list.IndexOf(originalValue);
+
+ if (index != -1)
+ {
+ list[index] = valueToReplace;
+ }
+
+ return list;
+ }
+
+ ///
+ /// Method to obtain a random element from inside a list
+ ///
+ ///
+ ///
+ ///
+ public static T Random(this IList list)
+ {
+ if (list.Count == 0) return default;
+
+ // Updated based on Robin King's tip about random items https://twitter.com/quoxel/status/1729137730607841755/photo/1
+ int seed = (int)DateTime.Now.Ticks;
+
+ var r = new Random(seed);
+
+ var randomIndex = r.Next(0, list.Count);
+
+ var returnValue = list[randomIndex];
+
+ return returnValue ?? list[0];
+
+ }
+
+ ///
+ /// Method to obtain elements from inside a list
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static List Random(this IList list, int count = 1)
+ {
+ if (count <= 0) throw new ArgumentOutOfRangeException(nameof(count));
+
+ List values = new List();
+
+ for (int i = 0; i < count; i++)
+ {
+ values.Add(list.Where(x => !values.Contains(x)).ToList().Random());
+ }
+
+ return values;
+ }
+
+ public static IEnumerable DistinctBy
+ (this IEnumerable source, Func keySelector)
+ {
+ HashSet seenKeys = new HashSet();
+ foreach (TSource element in source)
+ {
+ if (seenKeys.Add(keySelector(element)))
+ {
+ yield return element;
+ }
+ }
+ }
+
+
+ // Idea obtained from TaroDev's video on things to do in Unity - https://youtu.be/Ic5ux-tpkCE?t=302
+ public static T Next(this List array, ref int currentIndex)
+ {
+ return array[currentIndex++ % array.Count];
+ }
+ }
+}
\ No newline at end of file
diff --git a/OmegaLeo.HelperLib/Extensions/MathExtensions.cs b/OmegaLeo.HelperLib/Extensions/MathExtensions.cs
new file mode 100644
index 0000000..fbbf63e
--- /dev/null
+++ b/OmegaLeo.HelperLib/Extensions/MathExtensions.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace GameDevLibrary.Extensions
+{
+ public static class MathExtensions
+ {
+ ///
+ /// Calculate the average value based on a list of values
+ ///
+ ///
+ ///
+ public static int AverageWithNullValidation(this IEnumerable list)
+ {
+ return list.Any() ? (int)list.Average() : 0;
+ }
+
+ ///
+ /// Calculate the average value based on a list of values
+ ///
+ ///
+ ///
+ public static double AverageWithNullValidation(this IEnumerable list)
+ {
+ return list.Any() ? list.Average() : 0.0;
+ }
+
+ ///
+ /// Calculate the average value based on a list of values
+ ///
+ ///
+ ///
+ public static float AverageWithNullValidation(this IEnumerable list)
+ {
+ return list.Any() ? list.Average() : 0.0f;
+ }
+ }
+}
\ No newline at end of file
diff --git a/OmegaLeo.HelperLib/Extensions/StringExtensions.cs b/OmegaLeo.HelperLib/Extensions/StringExtensions.cs
new file mode 100644
index 0000000..932f338
--- /dev/null
+++ b/OmegaLeo.HelperLib/Extensions/StringExtensions.cs
@@ -0,0 +1,69 @@
+using System;
+
+namespace GameDevLibrary.Extensions
+{
+ public static class StringExtensions
+ {
+ ///
+ /// Cut off a string once it reaches a amount of characters and add '...' to the end of the string
+ ///
+ ///
+ ///
+ ///
+ public static string Truncate(this string value, int maxChars)
+ {
+ return value.Length <= maxChars ? value : value.Substring(0, maxChars) + "...";
+ }
+
+ ///
+ /// Identify if a string is null or empty
+ ///
+ ///
+ ///
+ public static bool IsNullOrEmpty(this string str)
+ {
+ return String.IsNullOrEmpty(str);
+ }
+
+ ///
+ /// Identify if a string is not null or empty
+ ///
+ ///
+ ///
+ public static bool IsNotNullOrEmpty(this string str)
+ {
+ return !str.IsNullOrEmpty();
+ }
+
+ ///
+ /// Check if the string matches any of the search parameters
+ ///
+ ///
+ ///
+ ///
+ public static bool AnyMatch(this string str, params string[] search)
+ {
+ foreach (string s in search)
+ {
+ if (s.Equals(str, StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// Reverses a given string
+ ///
+ ///
+ ///
+ public static string Reverse(this string str)
+ {
+ char[] charArray = str.ToCharArray();
+ Array.Reverse(charArray);
+ return new string(charArray);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OmegaLeo.HelperLib/Models/NeoDictionary.cs b/OmegaLeo.HelperLib/Models/NeoDictionary.cs
new file mode 100644
index 0000000..af3ba14
--- /dev/null
+++ b/OmegaLeo.HelperLib/Models/NeoDictionary.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+
+namespace GameDevLibrary.Models
+{
+ // Inspiration: https://www.youtube.com/watch?v=x-ejym1WdjE
+ [Serializable]
+ public class NeoDictionary
+ {
+ public List> Items = new List>();
+
+ public Dictionary ToDictionary() => (Items.Any())
+ ? Items.ToDictionary(x => x.Key, x => x.Value)
+ : new Dictionary();
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
+ var item = Items.FirstOrDefault(x => x.Key.Equals(key));
+
+ if (item != null)
+ {
+ value = item.Value;
+ return true;
+ }
+
+ value = default;
+
+ return false;
+ }
+
+ public bool TryGetValueFromIndex(int index, out TValue value)
+ {
+ if (index < Items.Count)
+ {
+ var item = Items[index];
+
+ if (item != null)
+ {
+ value = item.Value;
+ return true;
+ }
+ }
+
+ value = default;
+
+ return false;
+ }
+
+ public void Add(TKey key, TValue value)
+ {
+ Items.Add(new NeoDictionaryItem(key, value));
+ }
+
+ public void AddRange(NeoDictionary values)
+ {
+ Items.AddRange(values.Items);
+ }
+
+ public void AddRange(IEnumerable> values)
+ {
+ Items.AddRange(values);
+ }
+
+ public bool Any() => Items.Any();
+
+ public bool Any(Func, bool> predicate) => Items.Any(predicate);
+ }
+
+ [Serializable]
+ public class NeoDictionaryItem
+ {
+ public TKey Key;
+ public TValue Value;
+
+ public NeoDictionaryItem(TKey key, TValue value)
+ {
+ Key = key;
+ Value = value;
+ }
+ }
+}
\ No newline at end of file
diff --git a/OmegaLeo.HelperLib/OmegaLeo.HelperLib.csproj b/OmegaLeo.HelperLib/OmegaLeo.HelperLib.csproj
new file mode 100644
index 0000000..1e91962
--- /dev/null
+++ b/OmegaLeo.HelperLib/OmegaLeo.HelperLib.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netstandard2.1
+ enable
+ GameDevLibrary
+ 0.0.2
+ Omega Leo's Helper Library
+ Nuno "Omega Leo" Diogo
+
+
+
+
+
+
+