//#define ENABLE_ASSERTS using System.Numerics; using System.Globalization; using System.Runtime.CompilerServices; #if ENABLE_ASSERTS using System.Diagnostics; #endif using SharpPluginLoader.Core; using SharpPluginLoader.Core.Memory; namespace WorldTuningTool { internal static class Utility { internal const float defaultParamWidth = 0.21f; internal const float fadeAlphaFactor = 0.7f; internal const float disableAlphaFactor = 0.6f; private static bool loggedAssertFailed = false; internal static void Assert(bool condition = false, [CallerLineNumber] int line = 0) { if (!condition && !loggedAssertFailed) { Log.Error($"Assert failed on line {line}, further asserts won't be logged."); loggedAssertFailed = true; } #if ENABLE_ASSERTS Trace.Assert(condition); #endif } internal static byte ByteFlag(bool f) { return f ? (byte)0x1 : (byte)0x0; } internal static T Get(nint addr, nint offset = 0x0) where T : unmanaged { return MemoryUtil.Read(addr + offset); } internal static T Get(long addr, nint offset = 0x0) where T : unmanaged { return MemoryUtil.Read((nint)addr + offset); } internal static unsafe T *GetPtrInline(nint addr, nint offset = 0x0) where T : unmanaged { return (T *)(addr + offset); } internal static ref T GetRef(nint addr, nint offset = 0x0) where T : unmanaged { return ref MemoryUtil.GetRef(addr + offset); } internal static int BitIndex(int mask) { return BitOperations.Log2((uint)(mask & (-mask))); } internal static Vector4 ColorVectorFromInt(int c) { return new Vector4( ((c ) & 0xFF) / 255.0f, ((c >> 8 ) & 0xFF) / 255.0f, ((c >> 16) & 0xFF) / 255.0f, ((c >> 24) & 0xFF) / 255.0f); } internal static int ColorVectorToInt(Vector4 v) { return ((int)MathF.Round(v.X * 255.0f) | ((int)MathF.Round(v.Y * 255.0f) << 8) | ((int)MathF.Round(v.Z * 255.0f) << 16) | ((int)MathF.Round(v.W * 255.0f) << 24)); } internal static float StringToSingle(string s) { return Convert.ToSingle(s, CultureInfo.InvariantCulture); } internal static bool StringToBoolean(string s) { return Convert.ToBoolean(s, CultureInfo.InvariantCulture); } internal static int StringToInt32(string s, int fromBase = 10) { if (fromBase == 10) return Convert.ToInt32(s, CultureInfo.InvariantCulture); return Convert.ToInt32(s, fromBase); } internal static string SingleToString(float f, string? format = null) { return f.ToString(format, CultureInfo.InvariantCulture); } internal static string BooleanToString(bool b) { return b.ToString(CultureInfo.InvariantCulture); } internal static string Int32ToString(int i, string? format = null) { return i.ToString(format, CultureInfo.InvariantCulture); } internal static Vector2 StringToVector2(string s, char delim = ',') { if (String.IsNullOrEmpty(s)) throw new FormatException(); string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); if (sp.Length != 2) throw new FormatException(); return new(StringToSingle(sp[0]), StringToSingle(sp[1])); } internal static Vector3 StringToVector3(string s, char delim = ',') { if (String.IsNullOrEmpty(s)) throw new FormatException(); string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); if (sp.Length != 3) throw new FormatException(); return new(StringToSingle(sp[0]), StringToSingle(sp[1]), StringToSingle(sp[2])); } internal static Vector4 StringToVector4(string s, char delim = ',') { if (String.IsNullOrEmpty(s)) throw new FormatException(); string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); if (sp.Length != 4) throw new FormatException(); return new(StringToSingle(sp[0]), StringToSingle(sp[1]), StringToSingle(sp[2]), StringToSingle(sp[3])); } internal static string Vector2ToString(Vector2 v) { return string.Format(CultureInfo.InvariantCulture, "{0},{1}", v.X, v.Y); } internal static string Vector3ToString(Vector3 v) { return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", v.X, v.Y, v.Z); } internal static string Vector4ToString(Vector4 v) { return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", v.X, v.Y, v.Z, v.W); } } }