Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RacesOfValheimAzuEPICompatPatch v1.1.3
RacesOfValheimAzuEPICompat.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using RacesOfValheim; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RacesOfValheimAzuEPICompat")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.3.0")] [assembly: AssemblyInformationalVersion("1.1.3")] [assembly: AssemblyProduct("RacesOfValheimAzuEPICompat")] [assembly: AssemblyTitle("RacesOfValheimAzuEPICompat")] [assembly: AssemblyVersion("1.1.3.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RacesOfValheimAzuEPICompat { internal static class ArmorMaskMeshBuilder { private struct Vertex { internal Vector3 Position; internal Vector3 Normal; internal Vector4 Tangent; internal Vector2 Uv; internal Vector2 Uv2; internal Color Color; internal BoneWeight Weight; internal static Vertex Lerp(Vertex a, Vertex b, float t) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) Vertex result = new Vertex { Position = Vector3.Lerp(a.Position, b.Position, t) }; Vector3 val = Vector3.Lerp(a.Normal, b.Normal, t); result.Normal = ((Vector3)(ref val)).normalized; result.Tangent = Vector4.Lerp(a.Tangent, b.Tangent, t); result.Uv = Vector2.Lerp(a.Uv, b.Uv, t); result.Uv2 = Vector2.Lerp(a.Uv2, b.Uv2, t); result.Color = Color.Lerp(a.Color, b.Color, t); result.Weight = LerpWeight(a.Weight, b.Weight, t); return result; } internal Vertex Inverted() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Vertex result = this; result.Normal = -Normal; result.Tangent.w = 0f - result.Tangent.w; return result; } private static BoneWeight LerpWeight(BoneWeight a, BoneWeight b, float t) { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) float num = 1f - t; BoneWeightAccumulator boneWeightAccumulator = default(BoneWeightAccumulator); boneWeightAccumulator.Add(((BoneWeight)(ref a)).boneIndex0, ((BoneWeight)(ref a)).weight0 * num); boneWeightAccumulator.Add(((BoneWeight)(ref a)).boneIndex1, ((BoneWeight)(ref a)).weight1 * num); boneWeightAccumulator.Add(((BoneWeight)(ref a)).boneIndex2, ((BoneWeight)(ref a)).weight2 * num); boneWeightAccumulator.Add(((BoneWeight)(ref a)).boneIndex3, ((BoneWeight)(ref a)).weight3 * num); boneWeightAccumulator.Add(((BoneWeight)(ref b)).boneIndex0, ((BoneWeight)(ref b)).weight0 * t); boneWeightAccumulator.Add(((BoneWeight)(ref b)).boneIndex1, ((BoneWeight)(ref b)).weight1 * t); boneWeightAccumulator.Add(((BoneWeight)(ref b)).boneIndex2, ((BoneWeight)(ref b)).weight2 * t); boneWeightAccumulator.Add(((BoneWeight)(ref b)).boneIndex3, ((BoneWeight)(ref b)).weight3 * t); boneWeightAccumulator.TakeLargest(out var bone, out var weight); boneWeightAccumulator.TakeLargest(out var bone2, out var weight2); boneWeightAccumulator.TakeLargest(out var bone3, out var weight3); boneWeightAccumulator.TakeLargest(out var bone4, out var weight4); float num2 = weight + weight2 + weight3 + weight4; if (num2 <= 0f) { num2 = 1f; } BoneWeight result = default(BoneWeight); ((BoneWeight)(ref result)).boneIndex0 = bone; ((BoneWeight)(ref result)).weight0 = weight / num2; ((BoneWeight)(ref result)).boneIndex1 = bone2; ((BoneWeight)(ref result)).weight1 = weight2 / num2; ((BoneWeight)(ref result)).boneIndex2 = bone3; ((BoneWeight)(ref result)).weight2 = weight3 / num2; ((BoneWeight)(ref result)).boneIndex3 = bone4; ((BoneWeight)(ref result)).weight3 = weight4 / num2; return result; } } private struct BoneWeightAccumulator { private int _count; private int _bone0; private int _bone1; private int _bone2; private int _bone3; private int _bone4; private int _bone5; private int _bone6; private int _bone7; private float _weight0; private float _weight1; private float _weight2; private float _weight3; private float _weight4; private float _weight5; private float _weight6; private float _weight7; internal void Add(int bone, float weight) { if (weight <= 0f) { return; } for (int i = 0; i < _count; i++) { if (Bone(i) == bone) { SetWeight(i, Weight(i) + weight); return; } } if (_count < 8) { SetBone(_count, bone); SetWeight(_count, weight); _count++; } } internal void TakeLargest(out int bone, out float weight) { int num = -1; float num2 = 0f; for (int i = 0; i < _count; i++) { float num3 = Weight(i); if (!(num3 <= num2)) { num = i; num2 = num3; } } if (num < 0) { bone = 0; weight = 0f; } else { bone = Bone(num); weight = num2; SetWeight(num, 0f); } } private int Bone(int index) { return index switch { 0 => _bone0, 1 => _bone1, 2 => _bone2, 3 => _bone3, 4 => _bone4, 5 => _bone5, 6 => _bone6, _ => _bone7, }; } private float Weight(int index) { return index switch { 0 => _weight0, 1 => _weight1, 2 => _weight2, 3 => _weight3, 4 => _weight4, 5 => _weight5, 6 => _weight6, _ => _weight7, }; } private void SetBone(int index, int value) { switch (index) { case 0: _bone0 = value; break; case 1: _bone1 = value; break; case 2: _bone2 = value; break; case 3: _bone3 = value; break; case 4: _bone4 = value; break; case 5: _bone5 = value; break; case 6: _bone6 = value; break; default: _bone7 = value; break; } } private void SetWeight(int index, float value) { switch (index) { case 0: _weight0 = value; break; case 1: _weight1 = value; break; case 2: _weight2 = value; break; case 3: _weight3 = value; break; case 4: _weight4 = value; break; case 5: _weight5 = value; break; case 6: _weight6 = value; break; default: _weight7 = value; break; } } } private const int MaxSubdivisionDepth = 4; private static readonly Dictionary<string, Mesh> Cache = new Dictionary<string, Mesh>(); internal static Mesh GetOrBuild(Mesh source, Texture mask, SkeletonArmorPart part, float cutoff) { if ((Object)(object)source == (Object)null || (Object)(object)mask == (Object)null) { return null; } string key = ((Object)source).GetInstanceID() + ":" + ((Object)mask).GetInstanceID() + ":" + part.ToString() + ":" + cutoff; if (Cache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = MakeReadable(mask); if ((Object)(object)val == (Object)null) { return null; } try { Mesh val2 = Build(source, val, cutoff, part); if ((Object)(object)val2 != (Object)null) { Cache[key] = val2; } return val2; } finally { Object.Destroy((Object)(object)val); } } internal static void Clear() { foreach (Mesh value in Cache.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } Cache.Clear(); } private static Texture2D MakeReadable(Texture source) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown RenderTexture val = null; RenderTexture active = RenderTexture.active; try { val = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1); Graphics.Blit(source, val); RenderTexture.active = val; Texture2D val2 = new Texture2D(source.width, source.height, (TextureFormat)4, false, true); val2.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0, false); val2.Apply(false, false); ((Texture)val2).wrapMode = source.wrapMode; return val2; } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Could not read Skeleton armour alpha mask '" + ((Object)source).name + "': " + ex.Message)); } return null; } finally { RenderTexture.active = active; if ((Object)(object)val != (Object)null) { RenderTexture.ReleaseTemporary(val); } } } private static Mesh Build(Mesh source, Texture2D mask, float cutoff, SkeletonArmorPart part) { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) Vector3[] vertices = source.vertices; Vector3[] normals = source.normals; Vector4[] tangents = source.tangents; Vector2[] uv = source.uv; Vector2[] uv2 = source.uv2; Color[] colors = source.colors; BoneWeight[] boneWeights = source.boneWeights; int[] triangles = source.GetTriangles(0); if (vertices.Length == 0 || uv.Length != vertices.Length || triangles.Length == 0) { return null; } List<Vertex> list = new List<Vertex>(triangles.Length); List<int> list2 = new List<int>(triangles.Length); Color32[] pixels = mask.GetPixels32(); for (int i = 0; i < triangles.Length; i += 3) { Vertex a = ReadVertex(triangles[i], vertices, normals, tangents, uv, uv2, colors, boneWeights); Vertex b = ReadVertex(triangles[i + 1], vertices, normals, tangents, uv, uv2, colors, boneWeights); Vertex c = ReadVertex(triangles[i + 2], vertices, normals, tangents, uv, uv2, colors, boneWeights); ClipTriangle(a, b, c, 0, mask, pixels, cutoff, list, list2); } if (list2.Count == 0) { return null; } Mesh val = new Mesh { name = ((Object)source).name + "_SkeletonArmorMask_" + part, indexFormat = (IndexFormat)(list.Count > 65535), bindposes = source.bindposes }; List<Vector3> list3 = new List<Vector3>(list.Count); List<Vector3> list4 = new List<Vector3>(list.Count); List<Vector4> list5 = new List<Vector4>(list.Count); List<Vector2> list6 = new List<Vector2>(list.Count); List<Vector2> list7 = new List<Vector2>(list.Count); List<Color> list8 = new List<Color>(list.Count); BoneWeight[] array = (BoneWeight[])(object)new BoneWeight[list.Count]; for (int j = 0; j < list.Count; j++) { Vertex vertex = list[j]; list3.Add(vertex.Position); list4.Add(vertex.Normal); list5.Add(vertex.Tangent); list6.Add(vertex.Uv); list7.Add(vertex.Uv2); list8.Add(vertex.Color); array[j] = vertex.Weight; } val.SetVertices(list3); val.SetNormals(list4); val.SetTangents(list5); val.SetUVs(0, list6); val.SetUVs(1, list7); val.SetColors(list8); val.boneWeights = array; val.SetTriangles(list2, 0, true); val.bounds = source.bounds; return val; } private static void ClipTriangle(Vertex a, Vertex b, Vertex c, int depth, Texture2D mask, Color32[] pixels, float cutoff, List<Vertex> output, List<int> triangles) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) float num = Alpha(a.Uv, mask, pixels); float num2 = Alpha(b.Uv, mask, pixels); float num3 = Alpha(c.Uv, mask, pixels); Vector2 uv = (a.Uv + b.Uv) * 0.5f; Vector2 uv2 = (b.Uv + c.Uv) * 0.5f; Vector2 uv3 = (c.Uv + a.Uv) * 0.5f; float num4 = Alpha(uv, mask, pixels); float num5 = Alpha(uv2, mask, pixels); float num6 = Alpha(uv3, mask, pixels); float num7 = Alpha((a.Uv + b.Uv + c.Uv) / 3f, mask, pixels); if (!(num >= cutoff) && !(num2 >= cutoff) && !(num3 >= cutoff) && !(num4 >= cutoff) && !(num5 >= cutoff) && !(num6 >= cutoff) && !(num7 >= cutoff)) { return; } bool flag = num >= cutoff && num2 >= cutoff && num3 >= cutoff && num4 >= cutoff && num5 >= cutoff && num6 >= cutoff && num7 >= cutoff; if (flag || depth >= 4) { if (flag || num7 >= cutoff) { AddTriangle(a, b, c, output, triangles); } return; } Vertex vertex = Vertex.Lerp(a, b, 0.5f); Vertex vertex2 = Vertex.Lerp(b, c, 0.5f); Vertex vertex3 = Vertex.Lerp(c, a, 0.5f); ClipTriangle(a, vertex, vertex3, depth + 1, mask, pixels, cutoff, output, triangles); ClipTriangle(vertex, b, vertex2, depth + 1, mask, pixels, cutoff, output, triangles); ClipTriangle(vertex3, vertex2, c, depth + 1, mask, pixels, cutoff, output, triangles); ClipTriangle(vertex, vertex2, vertex3, depth + 1, mask, pixels, cutoff, output, triangles); } private static void AddTriangle(Vertex a, Vertex b, Vertex c, List<Vertex> output, List<int> triangles) { int count = output.Count; output.Add(a); output.Add(b); output.Add(c); triangles.Add(count); triangles.Add(count + 1); triangles.Add(count + 2); Vertex item = a.Inverted(); Vertex item2 = b.Inverted(); Vertex item3 = c.Inverted(); int count2 = output.Count; output.Add(item); output.Add(item2); output.Add(item3); triangles.Add(count2); triangles.Add(count2 + 2); triangles.Add(count2 + 1); } private static float Alpha(Vector2 uv, Texture2D texture, Color32[] pixels) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) float num = (((int)((Texture)texture).wrapMode == 0) ? (uv.x - Mathf.Floor(uv.x)) : Mathf.Clamp01(uv.x)); float num2 = (((int)((Texture)texture).wrapMode == 0) ? (uv.y - Mathf.Floor(uv.y)) : Mathf.Clamp01(uv.y)); int num3 = Mathf.Clamp(Mathf.RoundToInt(num * (float)(((Texture)texture).width - 1)), 0, ((Texture)texture).width - 1); int num4 = Mathf.Clamp(Mathf.RoundToInt(num2 * (float)(((Texture)texture).height - 1)), 0, ((Texture)texture).height - 1); return (float)(int)pixels[num4 * ((Texture)texture).width + num3].a / 255f; } private static Vertex ReadVertex(int index, Vector3[] positions, Vector3[] normals, Vector4[] tangents, Vector2[] uv, Vector2[] uv2, Color[] colors, BoneWeight[] weights) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) return new Vertex { Position = positions[index], Normal = ((normals.Length == positions.Length) ? normals[index] : Vector3.up), Tangent = (Vector4)((tangents.Length == positions.Length) ? tangents[index] : new Vector4(1f, 0f, 0f, 1f)), Uv = uv[index], Uv2 = ((uv2.Length == positions.Length) ? uv2[index] : Vector2.zero), Color = ((colors.Length == positions.Length) ? colors[index] : Color.white), Weight = (BoneWeight)((weights.Length == positions.Length) ? weights[index] : default(BoneWeight)) }; } } internal static class DoubleSidedEquipmentMeshes { private static readonly Dictionary<int, Mesh> Cache = new Dictionary<int, Mesh>(); private static readonly HashSet<int> GeneratedMeshes = new HashSet<int>(); internal static void Apply(GameObject instance) { if ((Object)(object)instance == (Object)null) { return; } SkinnedMeshRenderer[] componentsInChildren = instance.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null) { val.sharedMesh = GetOrBuild(val.sharedMesh); } } MeshFilter[] componentsInChildren2 = instance.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2.sharedMesh != (Object)null) { val2.sharedMesh = GetOrBuild(val2.sharedMesh); } } } private static Mesh GetOrBuild(Mesh source) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if (((Object)source).name.EndsWith("_RoVDoubleSided", StringComparison.Ordinal)) { return source; } int instanceID = ((Object)source).GetInstanceID(); if (GeneratedMeshes.Contains(instanceID)) { return source; } if (Cache.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null) { return value; } Mesh val = Object.Instantiate<Mesh>(source); ((Object)val).name = ((Object)source).name + "_RoVDoubleSided"; for (int i = 0; i < val.subMeshCount; i++) { if ((int)val.GetTopology(i) == 0) { int[] triangles = val.GetTriangles(i); int[] array = new int[triangles.Length * 2]; Array.Copy(triangles, array, triangles.Length); int num = triangles.Length; for (int j = 0; j < triangles.Length; j += 3) { array[num + j] = triangles[j]; array[num + j + 1] = triangles[j + 2]; array[num + j + 2] = triangles[j + 1]; } val.SetTriangles(array, i, false); } } val.bounds = source.bounds; Cache[instanceID] = val; GeneratedMeshes.Add(((Object)val).GetInstanceID()); return val; } internal static void Clear() { foreach (Mesh value in Cache.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } Cache.Clear(); GeneratedMeshes.Clear(); } } internal static class MainMenuProgressionSnapshot { private const string SnapshotKey = "RoVAzuEPI_LastProgressionState"; private static readonly string[] RaceStateZdoKeys = new string[5] { "RacesOfValheim_SkeletonState", "RacesOfValheim_AswidState", "RacesOfValheim_DvergarState", "RacesOfValheim_SvermState", "RacesOfValheim_TrentaState" }; private static readonly MethodInfo GetPreviewPlayerMethod = AccessTools.Method(typeof(FejdStartup), "GetPreviewPlayer", (Type[])null, (Type[])null); private static readonly MethodInfo UpdateVisualsMethod = AccessTools.Method(typeof(VisEquipment), "UpdateVisuals", (Type[])null, (Type[])null); private static readonly MethodInfo UpdateColorsMethod = AccessTools.Method(typeof(VisEquipment), "UpdateColors", (Type[])null, (Type[])null); private static int _previewProgression; internal static void Capture(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && player.m_customData != null && !((Object)(object)ZoneSystem.instance == (Object)null)) { int num = Mathf.Clamp(BossProgressionManager.GetCurrentProgressionState(), 1, 8); player.m_customData["RoVAzuEPI_LastProgressionState"] = num.ToString(); } } internal static void Refresh(FejdStartup startup) { if ((Object)(object)startup == (Object)null) { return; } try { object? obj = GetPreviewPlayerMethod?.Invoke(startup, null); Player val = (Player)((obj is Player) ? obj : null); if ((Object)(object)val == (Object)null || val.m_customData == null || !val.m_customData.TryGetValue("RoVAzuEPI_LastProgressionState", out var value) || !int.TryParse(value, out var result)) { return; } result = Mathf.Clamp(result, 1, 8); ZNetView component = ((Component)val).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { ZDO zDO = component.GetZDO(); if (val.m_customData.TryGetValue("Race", out var value2)) { zDO.Set("RacesOfValheim_Race", value2); } string[] raceStateZdoKeys = RaceStateZdoKeys; foreach (string text in raceStateZdoKeys) { zDO.Set(text, result); } zDO.Set("RoVAzuEPI_PassiveAuraEnabled", RaceOptions.IsEnabled(val)); zDO.Set("RoVAzuEPI_SkeletonModel", RaceOptions.SkeletonModel(val)); } VisEquipment component2 = ((Component)val).GetComponent<VisEquipment>(); if ((Object)(object)component2 == (Object)null) { return; } _previewProgression = result; RaceOptions.EnterVisualContext(val); try { UpdateColorsMethod?.Invoke(component2, null); UpdateVisualsMethod?.Invoke(component2, null); Plugin.ApplyPeriodicRaceVisuals(val); RaceOptions.ApplySkeletonPreviewFlame(val); } finally { RaceOptions.LeaveVisualContext(); _previewProgression = 0; } } catch (Exception ex) { _previewProgression = 0; RaceOptions.LeaveVisualContext(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Failed to apply saved progression to the main-menu preview: " + ex)); } } } internal static bool TryGetPreviewProgression(out int state) { state = _previewProgression; return state > 0; } } [HarmonyPatch(typeof(Player), "Save")] internal static class SaveMainMenuProgressionSnapshotPatch { private static void Prefix(Player __instance) { MainMenuProgressionSnapshot.Capture(__instance); } } [HarmonyPatch(typeof(BossProgressionManager), "GetCurrentProgressionState")] internal static class MainMenuProgressionOverridePatch { private static void Postfix(ref int __result) { if (MainMenuProgressionSnapshot.TryGetPreviewProgression(out var state)) { __result = state; } } } [HarmonyPatch(typeof(FejdStartup), "SetupCharacterPreview")] [HarmonyPriority(0)] internal static class MainMenuSetupPreviewProgressionPatch { private static void Postfix(FejdStartup __instance) { MainMenuProgressionSnapshot.Refresh(__instance); } } [HarmonyPatch(typeof(FejdStartup), "SetSelectedProfile")] [HarmonyPriority(0)] internal static class MainMenuSelectProfileProgressionPatch { private static void Postfix(FejdStartup __instance) { MainMenuProgressionSnapshot.Refresh(__instance); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class MainMenuModelReplacerLateRefreshPatch { [HarmonyPriority(0)] private static void Postfix() { if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(RefreshAfterPrefabReplacers()); } } private static IEnumerator RefreshAfterPrefabReplacers() { yield return null; yield return null; SkeletonModelReplacerCompat.CaptureEffectivePrefabs(); FejdStartup val = Object.FindObjectOfType<FejdStartup>(); if ((Object)(object)val != (Object)null && (Object)(object)ZoneSystem.instance == (Object)null) { MainMenuProgressionSnapshot.Refresh(val); } } } [BepInPlugin("danii.RacesOfValheimAzuEPICompat", "Races of Valheim - AzuEPI Compatibility", "1.1.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "danii.RacesOfValheimAzuEPICompat"; public const string PluginName = "Races of Valheim - AzuEPI Compatibility"; public const string PluginVersion = "1.1.3"; private const float ProgressionCheckInterval = 0.25f; internal static Plugin Instance; internal static ManualLogSource Log; private Harmony _harmony; private float _nextProgressionCheck; private string _displayedRace; private int _displayedProgression = -1; private static Type _panelType; private static FieldInfo _playerPreviewField; private static FieldInfo _playerPreviewCompField; private static FieldInfo _panelInstanceField; private static FieldInfo _cameraField; private static MethodInfo _progressionMethod; private static MethodInfo _updateColorsMethod; private static MethodInfo _updateVisualsMethod; private static Action<Player, bool> _dvergarApplyScale; private static Action<Player> _dvergarApplyEyes; private static Action<Player> _dvergarApplyHood; private static Action<Player, bool> _svermApplyScale; private static Action<Player> _svermApplyEyes; private static Action<Player> _svermApplyClaws; private static Action<Player> _svermApplySpines; private static Action<Player> _svermApplyCarapace; private static Action<Player> _trentaApplyCrown; private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; CacheReflection(); _harmony = new Harmony("danii.RacesOfValheimAzuEPICompat"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Races of Valheim - AzuEPI Compatibility 1.1.3 loaded"); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { if (Time.unscaledTime < _nextProgressionCheck) { return; } _nextProgressionCheck = Time.unscaledTime + 0.25f; if (IsPreviewVisible()) { string localRace = GetLocalRace(); int currentProgression = GetCurrentProgression(); if ((!(localRace == _displayedRace) || currentProgression != _displayedProgression) && ApplyRaceToPreview()) { _displayedRace = localRace; _displayedProgression = currentProgression; } } } internal void RefreshOnOpen() { ((MonoBehaviour)this).StopCoroutine("RefreshAfterOpen"); ((MonoBehaviour)this).StartCoroutine("RefreshAfterOpen"); } private IEnumerator RefreshAfterOpen() { RefreshAndRememberState(); yield return null; RefreshAndRememberState(); } private void RefreshAndRememberState() { if (ApplyRaceToPreview()) { _displayedRace = GetLocalRace(); _displayedProgression = GetCurrentProgression(); } } internal static bool ApplyRaceToPreview() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) try { if (!IsPreviewVisible()) { return false; } Player localPlayer = Player.m_localPlayer; Player previewPlayer = GetPreviewPlayer(); if ((Object)(object)localPlayer == (Object)null || (Object)(object)previewPlayer == (Object)null || (Object)(object)localPlayer == (Object)(object)previewPlayer) { return false; } previewPlayer.m_customData.Clear(); foreach (KeyValuePair<string, string> customDatum in localPlayer.m_customData) { previewPlayer.m_customData[customDatum.Key] = customDatum.Value; } ((Component)previewPlayer).transform.localScale = ((Component)localPlayer).transform.localScale; Transform val = ((Component)localPlayer).transform.Find("Visual"); Transform val2 = ((Component)previewPlayer).transform.Find("Visual"); if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { val2.localScale = val.localScale; } VisEquipment component = ((Component)previewPlayer).GetComponent<VisEquipment>(); if ((Object)(object)component == (Object)null) { return false; } component.m_isPlayer = true; _updateColorsMethod?.Invoke(component, null); _updateVisualsMethod?.Invoke(component, null); ApplyPeriodicRaceVisuals(previewPlayer); RaceOptions.ApplySkeletonPreviewFlame(previewPlayer, localPlayer); SetLayerRecursively(((Component)previewPlayer).gameObject, LayerMask.NameToLayer("UI")); Camera previewCamera = GetPreviewCamera(); if (previewCamera != null) { previewCamera.Render(); } return true; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("Failed to apply race to AzuEPI preview: " + ex)); } return false; } } private static string GetLocalRace() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && localPlayer.m_customData != null && localPlayer.m_customData.TryGetValue("Race", out var value)) { return value; } return "Human"; } private static int GetCurrentProgression() { if (!(_progressionMethod == null)) { return (int)_progressionMethod.Invoke(null, null); } return -1; } private static bool IsPreviewVisible() { object? obj = _playerPreviewField?.GetValue(null); GameObject val = (GameObject)((obj is GameObject) ? obj : null); Camera previewCamera = GetPreviewCamera(); if ((Object)(object)val != (Object)null && val.activeInHierarchy && (Object)(object)previewCamera != (Object)null) { return ((Behaviour)previewCamera).enabled; } return false; } private static Camera GetPreviewCamera() { object obj = _panelInstanceField?.GetValue(null); if (obj != null) { object? obj2 = _cameraField?.GetValue(obj); return (Camera)((obj2 is Camera) ? obj2 : null); } return null; } private static Player GetPreviewPlayer() { object? obj = _playerPreviewCompField?.GetValue(null); return (Player)((obj is Player) ? obj : null); } private static void CacheReflection() { _panelType = AccessTools.TypeByName("AzuEPI.Game.PlayerPreview.AzuEPICharacterPanel"); _playerPreviewField = AccessTools.Field(_panelType, "playerPreview"); _playerPreviewCompField = AccessTools.Field(_panelType, "playerPreviewComp"); _panelInstanceField = AccessTools.Field(_panelType, "instance"); _cameraField = AccessTools.Field(_panelType, "cam"); _progressionMethod = AccessTools.Method(AccessTools.TypeByName("RacesOfValheim.BossProgressionManager"), "GetCurrentProgressionState", (Type[])null, (Type[])null); _updateColorsMethod = AccessTools.Method(typeof(VisEquipment), "UpdateColors", (Type[])null, (Type[])null); _updateVisualsMethod = AccessTools.Method(typeof(VisEquipment), "UpdateVisuals", (Type[])null, (Type[])null); _dvergarApplyScale = CacheRaceVisual<Action<Player, bool>>("RacesOfValheim.DvergarVisuals", "ApplyScale"); _dvergarApplyEyes = CacheRaceVisual<Action<Player>>("RacesOfValheim.DvergarVisuals", "ApplyEyes"); _dvergarApplyHood = CacheRaceVisual<Action<Player>>("RacesOfValheim.DvergarVisuals", "ApplyHood"); _svermApplyScale = CacheRaceVisual<Action<Player, bool>>("RacesOfValheim.SvermVisuals", "ApplyScale"); _svermApplyEyes = CacheRaceVisual<Action<Player>>("RacesOfValheim.SvermVisuals", "ApplyEyes"); _svermApplyClaws = CacheRaceVisual<Action<Player>>("RacesOfValheim.SvermVisuals", "ApplyClaws"); _svermApplySpines = CacheRaceVisual<Action<Player>>("RacesOfValheim.SvermVisuals", "ApplySpines"); _svermApplyCarapace = CacheRaceVisual<Action<Player>>("RacesOfValheim.SvermVisuals", "ApplyCarapace"); _trentaApplyCrown = CacheRaceVisual<Action<Player>>("RacesOfValheim.TrentaVisuals", "ApplyCrown"); } private static T CacheRaceVisual<T>(string typeName, string methodName) where T : class { MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName(typeName), methodName, (Type[])null, (Type[])null); if (methodInfo == null) { return null; } try { return Delegate.CreateDelegate(typeof(T), methodInfo) as T; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Could not cache race visual " + typeName + "." + methodName + ": " + ex.Message)); } return null; } } internal static void ApplyPeriodicRaceVisuals(Player preview) { if (!preview.m_customData.TryGetValue("Race", out var value)) { value = "Human"; } switch (value) { case "Dvergar": _dvergarApplyScale?.Invoke(preview, arg2: true); _dvergarApplyEyes?.Invoke(preview); _dvergarApplyHood?.Invoke(preview); break; case "Sverm": _svermApplyScale?.Invoke(preview, arg2: true); _svermApplyEyes?.Invoke(preview); _svermApplyClaws?.Invoke(preview); _svermApplySpines?.Invoke(preview); _svermApplyCarapace?.Invoke(preview); break; case "Trenta": _trentaApplyCrown?.Invoke(preview); break; } } private static void SetLayerRecursively(GameObject root, int layer) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return; } root.layer = layer; foreach (Transform item in root.transform) { SetLayerRecursively(((Component)item).gameObject, layer); } } } [HarmonyPatch] internal static class AzuEPIShowPreviewPatch { private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("AzuEPI.Game.PlayerPreview.PlayerPreviewManager"), "ShowPlayerPreview", (Type[])null, (Type[])null); } private static void Postfix() { Plugin.Instance?.RefreshOnOpen(); } } internal static class RaceOptions { internal const string EnabledKey = "RoVAzuEPI_PassiveAuraEnabled"; internal const string SkeletonModelKey = "RoVAzuEPI_SkeletonModel"; private static Player _visualContext; internal static Player VisualContext => _visualContext; internal static string Race(Player player) { if (player?.m_customData != null && player.m_customData.TryGetValue("Race", out var value)) { return value; } return "Human"; } internal static bool SupportsToggle(string race) { switch (race) { default: return race == "Draugh"; case "Skeleton": case "Skadi": case "Aswid": case "Trenta": return true; } } internal static bool IsEnabled(Player player) { if (player?.m_customData != null && player.m_customData.TryGetValue("RoVAzuEPI_PassiveAuraEnabled", out var value) && bool.TryParse(value, out var result)) { return result; } return true; } internal static void SetEnabled(Player player, bool enabled) { if (player?.m_customData != null) { player.m_customData["RoVAzuEPI_PassiveAuraEnabled"] = enabled.ToString(); ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.IsOwner()) { component.GetZDO().Set("RoVAzuEPI_PassiveAuraEnabled", enabled); } if (Race(player) == "Aswid") { AswidRace.AuraEnabled = enabled; } } } internal static string SkeletonModel(Player player) { if (player?.m_customData != null && player.m_customData.TryGetValue("RoVAzuEPI_SkeletonModel", out var value)) { return value; } return "Auto"; } internal static void SetSkeletonModel(Player player, string model) { if (player?.m_customData != null) { player.m_customData["RoVAzuEPI_SkeletonModel"] = model ?? "Auto"; ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.IsOwner()) { component.GetZDO().Set("RoVAzuEPI_SkeletonModel", model ?? "Auto"); } } } internal static bool LocalEnabledFor(string race) { Player val = _visualContext ?? Player.m_localPlayer; if (!((Object)(object)val == (Object)null) && !(Race(val) != race)) { return IsEnabled(val); } return true; } internal static bool EnabledFor(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player == (Object)(object)Player.m_localPlayer) { return IsEnabled(player); } ZNetView component = ((Component)player).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { return component.GetZDO().GetBool("RoVAzuEPI_PassiveAuraEnabled", true); } return true; } internal static bool ShouldShowSkeletonHeadFlame(Player player) { if ((Object)(object)player == (Object)null || !SkeletonConfig.HeadFireVFXEnabled.Value || !EnabledFor(player) || Race(player) != "Skeleton") { return false; } ZNetView component = ((Component)player).GetComponent<ZNetView>(); return (((Object)(object)component != (Object)null && component.IsValid() && (Object)(object)player != (Object)(object)Player.m_localPlayer) ? component.GetZDO().GetInt("RacesOfValheim_SkeletonState", 0) : BossProgressionManager.GetCurrentProgressionState()) >= 5; } internal static Transform GetSkeletonEyeAnchor(Player player) { object obj; if (player == null) { obj = null; } else { VisEquipment component = ((Component)player).GetComponent<VisEquipment>(); if (component == null) { obj = null; } else { SkinnedMeshRenderer bodyModel = component.m_bodyModel; obj = ((bodyModel != null) ? bodyModel.bones : null); } } Transform[] array = (Transform[])obj; if (array == null) { return null; } Transform val = null; Transform result = null; Transform[] array2 = array; foreach (Transform val2 in array2) { if ((Object)(object)val2 == (Object)null) { continue; } bool flag = ((Object)val2).name.Equals("Head", StringComparison.OrdinalIgnoreCase); if (flag) { result = val2; } for (int j = 0; j < val2.childCount; j++) { Transform child = val2.GetChild(j); if (!((Object)child).name.StartsWith("SkeletonEyeFX_") || ((Object)child).name.Contains("_Removed") || !((Component)child).gameObject.activeInHierarchy) { continue; } string text = ((Object)val2).name.ToLowerInvariant(); if (text.Contains("eye_l") || text.Contains("eye_r") || text.Contains("lefteye") || text.Contains("righteye")) { if (!((Object)(object)val2.parent != (Object)null)) { return val2; } return val2.parent; } if (flag) { val = val2; } } } if (!((Object)(object)val != (Object)null)) { return result; } return val; } internal static void DisableDuplicatedHildirFire(Player player) { object obj; if (player == null) { obj = null; } else { VisEquipment component = ((Component)player).GetComponent<VisEquipment>(); if (component == null) { obj = null; } else { SkinnedMeshRenderer bodyModel = component.m_bodyModel; obj = ((bodyModel != null) ? bodyModel.bones : null); } } Transform[] array = (Transform[])obj; if (array == null) { return; } Transform[] array2 = array; foreach (Transform val in array2) { if ((Object)(object)val == (Object)null) { continue; } for (int j = 0; j < val.childCount; j++) { Transform child = val.GetChild(j); string text = ((Object)child).name.ToLowerInvariant(); if (text.StartsWith("skeletoneyefx_skeleton_hildir_") && (text.Contains("fx_torch_carried") || text.Contains("headlamp"))) { ((Component)child).gameObject.SetActive(false); } } } } internal static void ApplySkeletonPreviewFlame(Player preview, Player settingsSource = null) { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)preview == (Object)null) { return; } Transform val = ((Component)preview).transform.Find("RoVAzuEPI_SkeletonHeadFlamePreview"); GameObject val2 = (((Object)(object)val == (Object)null) ? null : ((Component)val).gameObject); if (Race(preview) != "Skeleton") { if ((Object)(object)val2 != (Object)null) { val2.SetActive(false); } return; } bool num = ShouldShowSkeletonHeadFlame(settingsSource ?? preview); DisableDuplicatedHildirFire(preview); if (!num) { if ((Object)(object)val2 != (Object)null) { val2.SetActive(false); } return; } Transform skeletonEyeAnchor = GetSkeletonEyeAnchor(preview); if ((Object)(object)skeletonEyeAnchor == (Object)null) { return; } if ((Object)(object)val2 == (Object)null) { MethodInfo methodInfo = AccessTools.Method(typeof(SkeletonVisuals), "ResolveFlameSource", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(SkeletonVisuals), "IsFire", (Type[])null, (Type[])null); object? obj = methodInfo?.Invoke(null, null); GameObject val3 = (GameObject)((obj is GameObject) ? obj : null); Type type = AccessTools.TypeByName("UnityEngine.ParticleSystem"); if ((Object)(object)val3 == (Object)null || type == null) { return; } val2 = new GameObject("RoVAzuEPI_SkeletonHeadFlamePreview"); val2.transform.SetParent(((Component)preview).transform, false); val2.transform.localScale = Vector3.one * 1.8f; int num2 = 0; Component[] componentsInChildren = val3.GetComponentsInChildren(type, true); foreach (Component val4 in componentsInChildren) { if (methodInfo2 == null || (bool)methodInfo2.Invoke(null, new object[1] { val4.gameObject })) { GameObject val5 = SkeletonVisuals.BorrowEffect(val4.gameObject, val2.transform, ((Object)val4.gameObject).name, false, "Skeleton preview"); if (!((Object)(object)val5 == (Object)null)) { val5.transform.localPosition = Vector3.zero; val5.transform.localRotation = Quaternion.identity; num2++; } } } if (num2 == 0) { Object.Destroy((Object)(object)val2); return; } } val2.SetActive(true); (val2.GetComponent<SkeletonPreviewFlameFollower>() ?? val2.AddComponent<SkeletonPreviewFlameFollower>()).Configure(skeletonEyeAnchor); } internal static void EnterVisualContext(Player player) { _visualContext = player; } internal static void LeaveVisualContext() { _visualContext = null; } internal static Player ReplaceVisualContext(Player player) { Player visualContext = _visualContext; _visualContext = player; return visualContext; } internal static void RestoreVisualContext(Player previous) { _visualContext = previous; } internal static void Publish(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } ZNetView component = ((Component)player).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner()) { bool flag = IsEnabled(player); component.GetZDO().Set("RoVAzuEPI_PassiveAuraEnabled", flag); component.GetZDO().Set("RoVAzuEPI_SkeletonModel", SkeletonModel(player)); if (Race(player) == "Aswid") { AswidRace.AuraEnabled = flag; } } } internal static string ContextSkeletonModel() { Player val = _visualContext ?? Player.m_localPlayer; if ((Object)(object)val == (Object)null) { return "Auto"; } if ((Object)(object)val == (Object)(object)Player.m_localPlayer || (val.m_customData != null && val.m_customData.ContainsKey("RoVAzuEPI_SkeletonModel"))) { return SkeletonModel(val); } ZNetView component = ((Component)val).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { return component.GetZDO().GetString("RoVAzuEPI_SkeletonModel", "Auto"); } return "Auto"; } } internal sealed class SkeletonPreviewFlameFollower : MonoBehaviour { private Transform _anchor; internal void Configure(Transform anchor) { _anchor = anchor; Follow(); } private void LateUpdate() { Follow(); } private void Follow() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_anchor == (Object)null)) { ((Component)this).transform.position = _anchor.position + _anchor.up * 0.18f; ((Component)this).transform.rotation = _anchor.rotation; } } } internal sealed class RaceOptionsUi : MonoBehaviour { private GameObject _root; private Button _toggle; private TMP_Text _toggleText; private TMP_Dropdown _models; private bool _updating; internal void Refresh() { //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; string text = RaceOptions.Race(localPlayer); int num = ((!((Object)(object)localPlayer == (Object)null)) ? BossProgressionManager.GetCurrentProgressionState() : 0); bool flag = (Object)(object)localPlayer != (Object)null && (RaceOptions.SupportsToggle(text) || text == "Skeleton"); if ((Object)(object)_root != (Object)null && ((Object)(object)_toggle == (Object)null || (Object)(object)_toggleText == (Object)null || (Object)(object)_models == (Object)null)) { Object.Destroy((Object)(object)_root); _root = null; } if ((Object)(object)_root == (Object)null) { Build(); } if ((Object)(object)_root == (Object)null || (Object)(object)_toggle == (Object)null || (Object)(object)_toggleText == (Object)null || (Object)(object)_models == (Object)null) { return; } _root.SetActive(flag); if (!flag) { return; } int num2; switch (text) { case "Skeleton": if (num < 5) { goto default; } goto case "Draugh"; default: if (!(text == "Skadi") || num < 7) { num2 = ((text == "Trenta" && num >= 7) ? 1 : 0); break; } goto case "Draugh"; case "Draugh": case "Aswid": num2 = 1; break; } bool active = (byte)num2 != 0; ((Component)_toggle).gameObject.SetActive(active); bool flag2 = RaceOptions.IsEnabled(localPlayer); _toggleText.text = "Aura"; ((Graphic)((Selectable)_toggle).image).color = (flag2 ? new Color(0.55f, 0.82f, 0.48f, 0.95f) : new Color(0.65f, 0.35f, 0.32f, 0.95f)); bool flag3 = text == "Skeleton"; ((Component)_models).gameObject.SetActive(flag3); if (flag3) { RefreshModels(localPlayer); } } private void Build() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { return; } Transform infoPanel = instance.m_infoPanel; RectTransform val = (RectTransform)(object)((infoPanel is RectTransform) ? infoPanel : null); if ((Object)(object)val == (Object)null) { return; } _root = new GameObject("RoV_RaceOptions", new Type[2] { typeof(RectTransform), typeof(HorizontalLayoutGroup) }); _root.transform.SetParent((Transform)(object)val, false); RectTransform val2 = (RectTransform)_root.transform; val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(10f, -8f); val2.sizeDelta = new Vector2(204f, 24f); _root.transform.SetAsLastSibling(); HorizontalLayoutGroup component = _root.GetComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component).spacing = 6f; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = false; _toggle = CreateButton(_root.transform, new Vector2(60f, 22f), out _toggleText); ((UnityEvent)_toggle.onClick).AddListener((UnityAction)delegate { Player localPlayer = Player.m_localPlayer; RaceOptions.SetEnabled(localPlayer, !RaceOptions.IsEnabled(localPlayer)); Refresh(); Plugin.Instance?.RefreshOnOpen(); }); _models = CreateDropdown(_root.transform); ((UnityEvent<int>)(object)_models.onValueChanged).AddListener((UnityAction<int>)delegate(int index) { if (!_updating && !((Object)(object)Player.m_localPlayer == (Object)null) && index >= 0 && index < _models.options.Count) { RaceOptions.SetSkeletonModel(Player.m_localPlayer, ModelId(_models.options[index].text)); Plugin.Instance?.RefreshOnOpen(); } }); } private void RefreshModels(Player player) { int currentProgressionState = BossProgressionManager.GetCurrentProgressionState(); List<string> list = new List<string> { "Automatic", "Skeleton" }; if (currentProgressionState >= 2) { list.Add("Poison skeleton"); } if (currentProgressionState >= 5) { list.Add("Fire skeleton"); } string text = RaceOptions.SkeletonModel(player); int value = 0; for (int i = 0; i < list.Count; i++) { if (ModelId(list[i]) == text) { value = i; } } _updating = true; _models.ClearOptions(); _models.AddOptions(list); _models.value = value; _models.RefreshShownValue(); _updating = false; } private static string ModelId(string label) { return label switch { "Skeleton" => "Skeleton", "Poison skeleton" => "Skeleton_Poison", "Fire skeleton" => "Skeleton_Hildir", _ => "Auto", }; } private static TMP_FontAsset UiFont() { InventoryGui instance = InventoryGui.instance; TMP_Text val = ((instance != null) ? ((Component)instance).GetComponentInChildren<TMP_Text>(true) : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.font; } private static Button CreateButton(Transform parent, Vector2 size, out TMP_Text label) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("AuraToggle", new Type[4] { typeof(RectTransform), typeof(Image), typeof(Button), typeof(LayoutElement) }); val.transform.SetParent(parent, false); ((RectTransform)val.transform).sizeDelta = size; LayoutElement component = val.GetComponent<LayoutElement>(); component.preferredWidth = size.x; component.preferredHeight = size.y; Button component2 = val.GetComponent<Button>(); ((Selectable)component2).targetGraphic = (Graphic)(object)val.GetComponent<Image>(); GameObject val2 = new GameObject("Label", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val2.transform.SetParent(val.transform, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; label = (TMP_Text)(object)val2.GetComponent<TextMeshProUGUI>(); label.font = UiFont(); label.fontSize = 13f; label.alignment = (TextAlignmentOptions)514; ((Graphic)label).color = Color.white; return component2; } private static TMP_Dropdown CreateDropdown(Transform parent) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Expected O, but got Unknown //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Expected O, but got Unknown GameObject val = new GameObject("SkeletonModelDropdown", new Type[4] { typeof(RectTransform), typeof(Image), typeof(TMP_Dropdown), typeof(LayoutElement) }); val.transform.SetParent(parent, false); ((RectTransform)val.transform).sizeDelta = new Vector2(132f, 22f); LayoutElement component = val.GetComponent<LayoutElement>(); component.preferredWidth = 132f; component.preferredHeight = 22f; ((Graphic)val.GetComponent<Image>()).color = new Color(0.18f, 0.18f, 0.18f, 0.95f); CreateText(val.transform, "Label", new Vector2(6f, 0f), new Vector2(-22f, 0f), out var text); GameObject val2 = new GameObject("Template", new Type[3] { typeof(RectTransform), typeof(Image), typeof(ScrollRect) }); val2.transform.SetParent(val.transform, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = new Vector2(0f, 0f); val3.anchorMax = new Vector2(1f, 0f); val3.pivot = new Vector2(0.5f, 1f); val3.anchoredPosition = Vector2.zero; val3.sizeDelta = new Vector2(0f, 112f); ((Graphic)val2.GetComponent<Image>()).color = new Color(0.12f, 0.12f, 0.12f, 0.98f); GameObject val4 = new GameObject("Viewport", new Type[3] { typeof(RectTransform), typeof(Mask), typeof(Image) }); val4.transform.SetParent(val2.transform, false); Stretch((RectTransform)val4.transform); val4.GetComponent<Mask>().showMaskGraphic = false; GameObject val5 = new GameObject("Content", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); val5.transform.SetParent(val4.transform, false); RectTransform val6 = (RectTransform)val5.transform; val6.anchorMin = new Vector2(0f, 1f); val6.anchorMax = new Vector2(1f, 1f); val6.pivot = new Vector2(0.5f, 1f); val6.sizeDelta = Vector2.zero; val5.GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2; GameObject val7 = new GameObject("Item", new Type[3] { typeof(RectTransform), typeof(Toggle), typeof(LayoutElement) }); val7.transform.SetParent(val5.transform, false); val7.GetComponent<LayoutElement>().preferredHeight = 28f; CreateText(val7.transform, "Item Label", new Vector2(6f, 0f), new Vector2(-4f, 0f), out var text2); ((Selectable)val7.GetComponent<Toggle>()).targetGraphic = (Graphic)(object)text2; ScrollRect component2 = val2.GetComponent<ScrollRect>(); component2.viewport = (RectTransform)val4.transform; component2.content = val6; component2.horizontal = false; TMP_Dropdown component3 = val.GetComponent<TMP_Dropdown>(); ((Selectable)component3).targetGraphic = (Graphic)(object)val.GetComponent<Image>(); component3.template = val3; component3.captionText = text; component3.itemText = text2; val2.SetActive(false); return component3; } private static void CreateText(Transform parent, string name, Vector2 leftBottom, Vector2 rightTop, out TMP_Text text) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = leftBottom; val2.offsetMax = rightTop; text = (TMP_Text)(object)val.GetComponent<TextMeshProUGUI>(); text.font = UiFont(); text.fontSize = 13f; text.alignment = (TextAlignmentOptions)4097; ((Graphic)text).color = Color.white; } private static void Stretch(RectTransform rt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.offsetMin = Vector2.zero; rt.offsetMax = Vector2.zero; } } [HarmonyPatch(typeof(InventoryGui), "Show")] internal static class RaceOptionsInventoryShowPatch { private static void Postfix(InventoryGui __instance) { (((Component)__instance).GetComponent<RaceOptionsUi>() ?? ((Component)__instance).gameObject.AddComponent<RaceOptionsUi>()).Refresh(); } } [HarmonyPatch] internal static class SkeletonAuraDamagePatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(SkeletonRace), "ApplyFireAura", (Type[])null, (Type[])null); } private static bool Prefix() { return RaceOptions.LocalEnabledFor("Skeleton"); } } [HarmonyPatch] internal static class SkeletonHeadFlameBuildEyeAnchorPatch { private static readonly MethodInfo ResolveSource = AccessTools.Method(typeof(SkeletonVisuals), "ResolveFlameSource", (Type[])null, (Type[])null); private static readonly MethodInfo IsFire = AccessTools.Method(typeof(SkeletonVisuals), "IsFire", (Type[])null, (Type[])null); private static MethodBase TargetMethod() { return AccessTools.Method(typeof(HeadFlame), "Build", (Type[])null, (Type[])null); } private static void Postfix(Player player, ref bool __result, ref GameObject ___m_instance, ref Transform ___m_headBone) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) if (__result || (Object)(object)player == (Object)null) { return; } Transform skeletonEyeAnchor = RaceOptions.GetSkeletonEyeAnchor(player); object? obj = ResolveSource?.Invoke(null, null); GameObject val = (GameObject)((obj is GameObject) ? obj : null); Type type = AccessTools.TypeByName("UnityEngine.ParticleSystem"); if ((Object)(object)skeletonEyeAnchor == (Object)null || (Object)(object)val == (Object)null || type == null) { return; } GameObject val2 = new GameObject("SkeletonHeadFlameVFX"); val2.transform.SetParent(((Component)player).transform, false); val2.transform.localScale = Vector3.one * 1.8f; int num = 0; Component[] componentsInChildren = val.GetComponentsInChildren(type, true); foreach (Component val3 in componentsInChildren) { if (IsFire == null || (bool)IsFire.Invoke(null, new object[1] { val3.gameObject })) { GameObject val4 = SkeletonVisuals.BorrowEffect(val3.gameObject, val2.transform, ((Object)val3.gameObject).name, false, "Skeleton"); if (!((Object)(object)val4 == (Object)null)) { val4.transform.localPosition = Vector3.zero; val4.transform.localRotation = Quaternion.identity; num++; } } } if (num == 0) { Object.Destroy((Object)(object)val2); return; } ___m_headBone = skeletonEyeAnchor; ___m_instance = val2; __result = true; } } [HarmonyPatch] internal static class SkeletonHeadFlameEyeAnchorPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(HeadFlame), "Apply", (Type[])null, (Type[])null); } private static void Prefix(Player player, ref bool enable) { enable = RaceOptions.ShouldShowSkeletonHeadFlame(player); } private static void Postfix(Player player, GameObject ___m_instance, ref Transform ___m_headBone) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) RaceOptions.DisableDuplicatedHildirFire(player); if (RaceOptions.ShouldShowSkeletonHeadFlame(player) && !((Object)(object)___m_instance == (Object)null)) { Transform skeletonEyeAnchor = RaceOptions.GetSkeletonEyeAnchor(player); if (!((Object)(object)skeletonEyeAnchor == (Object)null)) { ___m_headBone = skeletonEyeAnchor; ___m_instance.transform.position = skeletonEyeAnchor.position + skeletonEyeAnchor.up * 0.18f; ___m_instance.transform.rotation = skeletonEyeAnchor.rotation; } } } } [HarmonyPatch] internal static class SkadiAuraDamagePatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(SkadiRace), "ApplyColdAura", (Type[])null, (Type[])null); } private static bool Prefix() { return RaceOptions.LocalEnabledFor("Skadi"); } } [HarmonyPatch] internal static class SkadiAuraVisualPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(SkadiRace), "EnsureFrostAuraVFX", (Type[])null, (Type[])null); } private static void Prefix(ref bool enable) { if (!RaceOptions.LocalEnabledFor("Skadi")) { enable = false; } } } [HarmonyPatch] internal static class AswidAuraPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(AswidRace), "HandleVampiricAura", (Type[])null, (Type[])null); } private static bool Prefix() { return RaceOptions.LocalEnabledFor("Aswid"); } } [HarmonyPatch(typeof(TrentaAbilities), "TickHornetsNest")] internal static class TrentaAuraPatch { private static void Prefix(ref bool shouldExist) { if (!RaceOptions.LocalEnabledFor("Trenta")) { shouldExist = false; } } } [HarmonyPatch(typeof(DraughVisuals), "EnsureAura")] internal static class DraughStenchPatch { private static void Prefix(Player player, ref bool enable) { if (!RaceOptions.EnabledFor(player)) { enable = false; } } } [HarmonyPatch(typeof(VisEquipment), "UpdateVisuals")] internal static class SkeletonModelVisContextPatch { private static void Prefix(VisEquipment __instance, out Player __state) { __state = RaceOptions.ReplaceVisualContext(((Component)__instance).GetComponent<Player>()); } private static void Finalizer(Player __state) { RaceOptions.RestoreVisualContext(__state); } } [HarmonyPatch] internal static class SkeletonRemoteModelContextPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(RacesVisualController), "UpdateSkeletonVisuals", (Type[])null, (Type[])null); } private static void Prefix(RacesVisualController __instance, out Player __state) { __state = RaceOptions.ReplaceVisualContext(((Component)__instance).GetComponent<Player>()); } private static void Finalizer(Player __state) { RaceOptions.RestoreVisualContext(__state); } } [HarmonyPatch(typeof(Player), "Start")] internal static class RaceOptionsPublishPatch { private static void Postfix(Player __instance) { RaceOptions.Publish(__instance); } } [HarmonyPatch(typeof(SkeletonProgression), "GetRules")] internal static class SkeletonModelChoicePatch { private static void Postfix(int state, ref SkeletonRules __result) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) Player val = RaceOptions.VisualContext ?? Player.m_localPlayer; if (!((Object)(object)val == (Object)null) && !(RaceOptions.Race(val) != "Skeleton")) { string text = RaceOptions.ContextSkeletonModel(); if (!(text == "Auto") && (!(text == "Skeleton_Poison") || state >= 2) && (!(text == "Skeleton_Hildir") || state >= 5)) { __result.ModelPrefab = text; __result.ScaleMultiplier = ((text == "Skeleton_Hildir") ? SkeletonProgression.FireModelScale : Vector3.one); } } } } internal static class RagdollAppearance { private sealed class AppearanceSnapshot { internal int PlayerInstanceId; internal Vector3 Position; internal Vector3 Scale; internal Vector3 VisualScale; internal float ExpiresAt; internal readonly List<RendererSnapshot> Renderers = new List<RendererSnapshot>(); } private sealed class RendererSnapshot { private string _name; private string _parentName; private Vector3 _localPosition; private Quaternion _localRotation; private Vector3 _localScale; private Mesh _mesh; private Material[] _materials; private string[] _boneNames; private string _rootBoneName; private bool _skinned; private Bounds _localBounds; private bool _updateWhenOffscreen; internal static RendererSnapshot From(SkinnedMeshRenderer renderer, HashSet<Transform> sourceBones) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) RendererSnapshot rendererSnapshot = CreateCommon((Renderer)(object)renderer, sourceBones); rendererSnapshot._skinned = true; rendererSnapshot._localBounds = ((Renderer)renderer).localBounds; rendererSnapshot._updateWhenOffscreen = renderer.updateWhenOffscreen; rendererSnapshot._rootBoneName = (((Object)(object)renderer.rootBone == (Object)null) ? null : ((Object)renderer.rootBone).name); rendererSnapshot._boneNames = new string[renderer.bones.Length]; for (int i = 0; i < renderer.bones.Length; i++) { rendererSnapshot._boneNames[i] = (((Object)(object)renderer.bones[i] == (Object)null) ? null : ((Object)renderer.bones[i]).name); } return rendererSnapshot; } internal static RendererSnapshot From(MeshRenderer renderer, MeshFilter filter, HashSet<Transform> sourceBones) { RendererSnapshot rendererSnapshot = CreateCommon((Renderer)(object)renderer, sourceBones); rendererSnapshot._mesh = filter.sharedMesh; return rendererSnapshot; } private static RendererSnapshot CreateCommon(Renderer renderer, HashSet<Transform> sourceBones) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) RendererSnapshot obj = new RendererSnapshot { _name = ((Object)((Component)renderer).gameObject).name, _parentName = (((Object)(object)((Component)renderer).transform.parent == (Object)null) ? null : ((Object)((Component)renderer).transform.parent).name), _localPosition = ((Component)renderer).transform.localPosition, _localRotation = ((Component)renderer).transform.localRotation, _localScale = ((Component)renderer).transform.localScale }; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); obj._mesh = ((val != null) ? val.sharedMesh : null); obj._materials = renderer.sharedMaterials; RendererSnapshot rendererSnapshot = obj; Transform val2 = FindNearestBone(((Component)renderer).transform, sourceBones); if ((Object)(object)val2 != (Object)null) { rendererSnapshot._parentName = ((Object)val2).name; rendererSnapshot._localPosition = val2.InverseTransformPoint(((Component)renderer).transform.position); rendererSnapshot._localRotation = Quaternion.Inverse(val2.rotation) * ((Component)renderer).transform.rotation; rendererSnapshot._localScale = DivideScale(((Component)renderer).transform.lossyScale, val2.lossyScale); } return rendererSnapshot; } private static Transform FindNearestBone(Transform candidate, HashSet<Transform> sourceBones) { Transform parent = candidate.parent; while ((Object)(object)parent != (Object)null) { if (sourceBones.Contains(parent)) { return parent; } parent = parent.parent; } return null; } private static Vector3 DivideScale(Vector3 value, Vector3 divisor) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) return new Vector3((Mathf.Abs(divisor.x) < 0.0001f) ? value.x : (value.x / divisor.x), (Mathf.Abs(divisor.y) < 0.0001f) ? value.y : (value.y / divisor.y), (Mathf.Abs(divisor.z) < 0.0001f) ? value.z : (value.z / divisor.z)); } internal void Create(Transform fallbackParent, Dictionary<string, Transform> bones, int layer) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) Transform val = fallbackParent; if (_parentName != null && bones.TryGetValue(_parentName, out var value)) { val = value; } GameObject val2 = new GameObject("RoVRagdoll_" + _name); val2.layer = layer; val2.transform.SetParent(val, false); val2.transform.localPosition = _localPosition; val2.transform.localRotation = _localRotation; val2.transform.localScale = _localScale; if (_skinned) { SkinnedMeshRenderer val3 = val2.AddComponent<SkinnedMeshRenderer>(); val3.sharedMesh = _mesh; ((Renderer)val3).sharedMaterials = _materials; ((Renderer)val3).localBounds = _localBounds; val3.updateWhenOffscreen = _updateWhenOffscreen; val3.bones = ResolveBones(_boneNames, bones); if (_rootBoneName != null && bones.TryGetValue(_rootBoneName, out var value2)) { val3.rootBone = value2; } } else { val2.AddComponent<MeshFilter>().sharedMesh = _mesh; ((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterials = _materials; } } private static Transform[] ResolveBones(string[] names, Dictionary<string, Transform> bones) { if (names == null) { return Array.Empty<Transform>(); } Transform[] array = (Transform[])(object)new Transform[names.Length]; for (int i = 0; i < names.Length; i++) { if (names[i] != null) { bones.TryGetValue(names[i], out array[i]); } } return array; } } private sealed class AppliedRaceAppearance : MonoBehaviour { } private const float SnapshotLifetime = 15f; private const float MatchDistanceSquared = 16f; private static readonly List<AppearanceSnapshot> Pending = new List<AppearanceSnapshot>(); private static AppearanceSnapshot _activeDeath; internal static void Capture(Player player, bool markActiveDeath) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } string race = GetRace(player); if (race == "Human") { return; } int playerInstanceId = ((Object)player).GetInstanceID(); PruneExpired(); AppearanceSnapshot appearanceSnapshot = Pending.Find((AppearanceSnapshot snapshot) => snapshot.PlayerInstanceId == playerInstanceId); if (appearanceSnapshot != null) { if (markActiveDeath) { _activeDeath = appearanceSnapshot; } return; } Transform val = ((Component)player).transform.Find("Visual"); if ((Object)(object)val == (Object)null) { return; } Dictionary<Renderer, bool> hiddenRendererStates = GetHiddenRendererStates(val); bool transformed = hiddenRendererStates != null; List<Transform> excludedRendererRoots = GetExcludedRendererRoots(player, race); Mesh excludedBodyMesh = GetExcludedBodyMesh(player, race); HashSet<Transform> sourceBones = GetSourceBones(player); AppearanceSnapshot appearanceSnapshot2 = new AppearanceSnapshot { PlayerInstanceId = playerInstanceId, Position = ((Component)player).transform.position, Scale = GetBasePlayerScale(player, race, transformed), VisualScale = GetBaseVisualScale(player, race, val, transformed), ExpiresAt = Time.unscaledTime + 15f }; SkinnedMeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.sharedMesh == (Object)null) && WasVisibleBeforeTransformation((Renderer)(object)val2, hiddenRendererStates) && !IsUnderExcludedRoot(((Component)val2).transform, excludedRendererRoots) && (!((Object)(object)excludedBodyMesh != (Object)null) || !((Object)(object)val2.sharedMesh == (Object)(object)excludedBodyMesh) || IsSkeletonReplacement(((Component)val2).transform))) { RendererSnapshot item = RendererSnapshot.From(val2, sourceBones); appearanceSnapshot2.Renderers.Add(item); } } MeshRenderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val3 in componentsInChildren2) { MeshFilter component = ((Component)val3).GetComponent<MeshFilter>(); if (!((Object)(object)val3 == (Object)null) && WasVisibleBeforeTransformation((Renderer)(object)val3, hiddenRendererStates) && !((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null) && !IsUnderExcludedRoot(((Component)val3).transform, excludedRendererRoots)) { appearanceSnapshot2.Renderers.Add(RendererSnapshot.From(val3, component, sourceBones)); } } if (appearanceSnapshot2.Renderers.Count != 0) { Pending.Add(appearanceSnapshot2); if (markActiveDeath) { _activeDeath = appearanceSnapshot2; } } } internal static void FinishDeath() { _activeDeath = null; } internal static void HideTemporaryForm(Player player) { if ((Object)(object)player == (Object)null) { return; } Transform val = ((Component)player).transform.Find("Visual"); Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && (!((Object)(object)val != (Object)null) || !((Component)val2).transform.IsChildOf(val))) { val2.enabled = false; val2.forceRenderingOff = true; } } } internal static void Apply(Ragdoll ragdoll) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown if ((Object)(object)ragdoll == (Object)null || (Object)(object)((Component)ragdoll).GetComponent<AppliedRaceAppearance>() != (Object)null) { return; } PruneExpired(); AppearanceSnapshot appearanceSnapshot = FindSnapshot(((Component)ragdoll).transform.position); if (appearanceSnapshot == null) { return; } try { ((Component)ragdoll).gameObject.AddComponent<AppliedRaceAppearance>(); Renderer[] componentsInChildren = ((Component)ragdoll).GetComponentsInChildren<Renderer>(true); foreach (Renderer obj in componentsInChildren) { obj.enabled = false; obj.forceRenderingOff = true; } ((Component)ragdoll).transform.localScale = Vector3.Scale(appearanceSnapshot.Scale, appearanceSnapshot.VisualScale); Dictionary<string, Transform> bones = BuildTransformMap(((Component)ragdoll).transform); GameObject val = new GameObject("RacesOfValheimRagdollAppearance"); val.transform.SetParent(((Component)ragdoll).transform, false); val.layer = ((Component)ragdoll).gameObject.layer; foreach (RendererSnapshot renderer in appearanceSnapshot.Renderers) { renderer.Create(val.transform, bones, ((Component)ragdoll).gameObject.layer); } Pending.Remove(appearanceSnapshot); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)("Failed to apply race appearance to ragdoll: " + ex)); } } } private static AppearanceSnapshot FindSnapshot(Vector3 position) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) Vector3 val; if (_activeDeath != null) { val = _activeDeath.Position - position; if (((Vector3)(ref val)).sqrMagnitude <= 16f) { return _activeDeath; } } AppearanceSnapshot result = null; float num = 16f; foreach (AppearanceSnapshot item in Pending) { val = item.Position - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude <= num) { result = item; num = sqrMagnitude; } } return result; } private static void PruneExpired() { float now = Time.unscaledTime; Pending.RemoveAll((AppearanceSnapshot snapshot) => snapshot.ExpiresAt < now); } private static string GetRace(Player player) { ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { string text = component.GetZDO().GetString("RacesOfValheim_Race", "Human"); if (text != "Human") { return text; } } if (player.m_customData != null && player.m_customData.TryGetValue("Race", out var value)) { return value; } return "Human"; } private static List<Transform> GetExcludedRendererRoots(Player player, string race) { List<Transform> list = new List<Transform>(); if (race != "Skeleton" && race != "Dvergar") { return list; } VisEquipment component = ((Component)player).GetComponent<VisEquipment>(); if ((Object)(object)component == (Object)null) { return list; } if (race != "Skeleton" || !SkeletonArmorVisibility.IsEnabled(player, SkeletonArmorPart.Helmet)) { AddEquipmentInstanceRoot(component, "m_helmetItemInstance", list); } if (race == "Skeleton") { if ((Object)(object)component.m_bodyModel != (Object)null) { list.Add(((Component)component.m_bodyModel).transform); } AddEquipmentInstanceRoot(component, "m_hairItemInstance", list); AddEquipmentInstanceRoot(component, "m_beardItemInstance", list); } return list; } private static Dictionary<Renderer, bool> GetHiddenRendererStates(Transform visual) { Type type = AccessTools.TypeByName("RacesOfValheim.PlayerVisualHider"); Component val = ((type == null) ? null : ((Component)visual).GetComponent(type)); Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null); if (val2 == null || !val2.enabled) { return null; } if (!(AccessTools.Field(type, "m_hidden")?.GetValue(val) is IEnumerable enumerable)) { return null; } Dictionary<Renderer, bool> dictionary = new Dictionary<Renderer, bool>(); foreach (object item in enumerable) { if (item != null) { Type type2 = item.GetType(); object? obj = AccessTools.Field(type2, "Renderer")?.GetValue(item); Renderer val3 = (Renderer)((obj is Renderer) ? obj : null); object obj2 = AccessTools.Field(type2, "WasEnabled")?.GetValue(item); if ((Object)(object)val3 != (Object)null && obj2 is bool value) { dictionary[val3] = value; } } } return dictionary; } private static bool WasVisibleBeforeTransformation(Renderer renderer, Dictionary<Renderer, bool> hiddenRendererStates) { if (!((Component)renderer).gameObject.activeInHierarchy) { return false; } if (hiddenRendererStates != null && hiddenRendererStates.TryGetValue(renderer, out var value)) { return value; } if (renderer.enabled) { return !renderer.forceRenderingOff; } return false; } private static Vector3 GetBasePlayerScale(Player player, string race, bool transformed) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (!transformed || race != "Aswid") { return ((Component)player).transform.localScale; } int networkState = GetNetworkState(player, "RacesOfValheim_AswidState"); return Vector3.one * ((networkState >= 8) ? 1.1f : 1f); } private static Vector3 GetBaseVisualScale(Player player, string race, Transform visual, bool transformed) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) switch (race) { case "Dvergar": return Vector3.one * 0.78f; case "Furling": return Vector3.one * 0.81f; case "Trol": { int networkState = GetNetworkState(player, "RacesOfValheim_State"); float num = ((networkState >= 6) ? 1.3f : ((networkState >= 4) ? 1.25f : 1.2f)); return Vector3.one * num; } case "Sverm": { int networkState2 = GetNetworkState(player, "RacesOfValheim_SvermState"); return Vector3.one * ((networkState2 >= 7) ? 1.1f : 1f); } default: if (!transformed) { return visual.localScale; } return Vector3.one; } } private static int GetNetworkState(Player player, string key) { ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { return component.GetZDO().GetInt(key, 1); } return GetCurrentProgressionFallback(); } private static int GetCurrentProgressionFallback() { MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName("RacesOfValheim.BossProgressionManager"), "GetCurrentProgressionState", (Type[])null, (Type[])null); if (!(methodInfo == null)) { return (int)methodInfo.Invoke(null, null); } return 1; } private static void AddEquipmentInstanceRoot(VisEquipment equipment, string fieldName, List<Transform> roots) { object? obj = AccessTools.Field(typeof(VisEquipment), fieldName)?.GetValue(equipment); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if ((Object)(object)val != (Object)null) { roots.Add(val.transform); } } private static Mesh GetExcludedBodyMesh(Player player, string race) { if (race != "Skeleton") { return null; } VisEquipment component = ((Component)player).GetComponent<VisEquipment>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.m_bodyModel == (Object)null)) { return component.m_bodyModel.sharedMesh; } return null; } private static bool IsSkeletonReplacement(Transform candidate) { Transform val = candidate; while ((Object)(object)val != (Object)null) { if (((Object)val).name.StartsWith("SkeletonBody", StringComparison.Ordinal)) { return true; } val = val.parent; } return false; } private static bool IsUnderExcludedRoot(Transform candidate, List<Transform> excludedRoots) { foreach (Transform excludedRoot in excludedRoots) { if ((Object)(object)candidate == (Object)(object)excludedRoot || ca