using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; using ValheimCartographer.Compass; using ValheimCartographer.State; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("ValheimCartographer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Restrict map access to cartography table interactions")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("ValheimCartographer")] [assembly: AssemblyTitle("ValheimCartographer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 ValheimCartographer { [BepInPlugin("valheimcartographer.mapgate", "ValheimCartographer", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ValheimCartographerPlugin : BaseUnityPlugin { public const string ModGuid = "valheimcartographer.mapgate"; public const string ModName = "ValheimCartographer"; public const string ModVersion = "1.0.1"; internal static ManualLogSource Log; internal static ConfigEntry ModEnabled; internal static ConfigEntry HideMinimapWhenLocked; internal static ConfigEntry BlockBossStoneMapPing; internal static ConfigEntry DebugLogging; internal static ConfigEntry CompassEnabled; internal static ConfigEntry CompassIronCost; internal static ConfigEntry CompassWoodCost; internal static ConfigEntry CompassHudOffsetY; internal static ConfigEntry CompassRibbonUsableWidth; internal static ConfigEntry CompassHudTrackOffsetY; internal static ConfigEntry CompassHudScale; internal static ConfigEntry CompassHudSlidePixels; internal static ConfigEntry CompassHudSlideSmoothTime; internal static ConfigEntry CompassHudSortOffsetFromHud; private Harmony _harmony; internal static ValheimCartographerPlugin Instance { get; private set; } private void Awake() { //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Enable map gating."); HideMinimapWhenLocked = ((BaseUnityPlugin)this).Config.Bind("General", "HideMinimapWhenLocked", true, "Hide the small minimap when map access is not granted via a cartography table."); BlockBossStoneMapPing = ((BaseUnityPlugin)this).Config.Bind("General", "BlockBossStoneMapPing", true, "Prevent boss stones and similar from opening or pinging the map."); DebugLogging = ((BaseUnityPlugin)this).Config.Bind("General", "DebugLogging", false, "Verbose Harmony / state logging."); CompassEnabled = ((BaseUnityPlugin)this).Config.Bind("Compass", "Enabled", true, "Enable the craftable compass item and HUD."); CompassIronCost = ((BaseUnityPlugin)this).Config.Bind("Compass", "IronCost", 1, "Iron ingots required to craft the compass at a forge."); CompassWoodCost = ((BaseUnityPlugin)this).Config.Bind("Compass", "WoodCost", 5, "Fine wood (Finewood) required to craft the compass at a forge."); CompassHudOffsetY = ((BaseUnityPlugin)this).Config.Bind("Compass", "HudTopInsetY", 10f, "Distance from the top of the screen to the compass (pixels at 1080p reference). Lower = closer to the top edge."); CompassRibbonUsableWidth = ((BaseUnityPlugin)this).Config.Bind("Compass", "RibbonUsableWidth", 873f, "Width of the clipped ribbon viewport over Ribbon_backing (pixels at 1080p reference)."); CompassHudTrackOffsetY = ((BaseUnityPlugin)this).Config.Bind("Compass", "HudTrackOffsetY", 0f, "Additional vertical offset of the ribbon mask within the backing; positive moves the mask down (pixels at 1080p reference)."); CompassHudScale = ((BaseUnityPlugin)this).Config.Bind("Compass", "HudStripScale", 0.28f, "Uniform scale for the whole compass HUD (backing + ribbon). 1 = native pixel size at 1080p reference; lower = smaller on screen."); CompassHudSlidePixels = ((BaseUnityPlugin)this).Config.Bind("Compass", "HudSlidePixels", 220f, "When hiding for UI (inventory, map, etc.), how far to slide the compass on the Y axis (reference pixels). Positive = off toward the top of the screen; flip sign if it moves the wrong way."); CompassHudSlideSmoothTime = ((BaseUnityPlugin)this).Config.Bind("Compass", "HudSlideSmoothTime", 0.12f, "Seconds for the compass slide when opening/closing other UI."); CompassHudSortOffsetFromHud = ((BaseUnityPlugin)this).Config.Bind("Compass", "HudCanvasSortOffset", -1, "Added to vanilla Hud canvas sortingOrder (read at runtime from the same canvas as the teleport/sleep black screen). Negative draws the compass under that overlay so portal fades cover it; adjust if layering looks wrong."); CompassItemSetup.Register(); new GameObject("ValheimCartographer_CompassHud").AddComponent(); _harmony = new Harmony("valheimcartographer.mapgate"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)"ValheimCartographer 1.0.1 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchAll("valheimcartographer.mapgate"); } ((BaseUnityPlugin)this).Config.Save(); } internal static void LogDebug(string message) { if (DebugLogging.Value) { Log.LogDebug((object)message); } } } } namespace ValheimCartographer.State { public static class MapAccessState { public static bool IsCartographyAccessActive { get; private set; } public static MapTable? ActiveTable { get; private set; } public static void BeginCartographyAccess(MapTable table) { IsCartographyAccessActive = true; ActiveTable = table; } public static void EndCartographyAccess() { IsCartographyAccessActive = false; ActiveTable = null; } } } namespace ValheimCartographer.Patches { [HarmonyPatch] public static class CartographyTablePatches { [HarmonyPrefix] [HarmonyPatch(typeof(MapTable), "OnRead", new Type[] { typeof(Switch), typeof(Humanoid), typeof(ItemData) })] [HarmonyPatch(typeof(MapTable), "OnRead", new Type[] { typeof(Switch), typeof(Humanoid), typeof(ItemData), typeof(bool) })] private static void OnReadPrefix(MapTable __instance, ItemData? item) { if (ValheimCartographerPlugin.ModEnabled.Value && !((Object)(object)Player.m_localPlayer == (Object)null) && item == null) { MapAccessState.BeginCartographyAccess(__instance); ValheimCartographerPlugin.LogDebug("Cartography access begin (MapTable.OnRead prefix)"); } } [HarmonyPostfix] [HarmonyPatch(typeof(MapTable), "OnRead", new Type[] { typeof(Switch), typeof(Humanoid), typeof(ItemData) })] [HarmonyPatch(typeof(MapTable), "OnRead", new Type[] { typeof(Switch), typeof(Humanoid), typeof(ItemData), typeof(bool) })] private static void OnReadPostfix(ItemData? item) { if (ValheimCartographerPlugin.ModEnabled.Value && !((Object)(object)Player.m_localPlayer == (Object)null) && item == null) { Minimap.instance.SetMapMode((MapMode)2); ValheimCartographerPlugin.LogDebug("Map opened from MapTable.OnRead postfix"); } } } [HarmonyPatch(typeof(Minimap))] public static class MinimapPatches { [HarmonyPrefix] [HarmonyPatch("SetMapMode")] private static bool SetMapMode_Prefix(MapMode mode) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if (!ValheimCartographerPlugin.ModEnabled.Value) { return true; } if ((int)mode == 2 && !MapAccessState.IsCartographyAccessActive) { ValheimCartographerPlugin.LogDebug("Blocked SetMapMode(Large) — not at cartography table"); return false; } return true; } [HarmonyPostfix] [HarmonyPatch("SetMapMode")] private static void SetMapMode_Postfix(MapMode mode) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (ValheimCartographerPlugin.ModEnabled.Value && (int)mode <= 1) { MapAccessState.EndCartographyAccess(); ValheimCartographerPlugin.LogDebug($"Map closed or minimized ({mode}); cartography access cleared"); } } [HarmonyPostfix] [HarmonyPatch("Update")] private static void Update_Postfix(Minimap __instance) { if (ValheimCartographerPlugin.ModEnabled.Value && ValheimCartographerPlugin.HideMinimapWhenLocked.Value && (Object)(object)__instance.m_smallRoot != (Object)null && !MapAccessState.IsCartographyAccessActive) { __instance.m_smallRoot.SetActive(false); } } [HarmonyPrefix] [HarmonyPatch("ShowPointOnMap")] private static bool ShowPointOnMap_Prefix() { if (!ValheimCartographerPlugin.ModEnabled.Value || !ValheimCartographerPlugin.BlockBossStoneMapPing.Value) { return true; } if (!MapAccessState.IsCartographyAccessActive) { ValheimCartographerPlugin.LogDebug("Blocked ShowPointOnMap"); return false; } return true; } } [HarmonyPatch(typeof(Player))] public static class PlayerPatches { [HarmonyPostfix] [HarmonyPatch("UpdateStations")] private static void CloseMapWhenTooFarFromTable(Player __instance) { //IL_0046: 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) if (!ValheimCartographerPlugin.ModEnabled.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !MapAccessState.IsCartographyAccessActive || (Object)(object)MapAccessState.ActiveTable == (Object)null) { return; } MapTable activeTable = MapAccessState.ActiveTable; if (!((Object)(object)activeTable == (Object)null)) { float num = Vector3.Distance(((Component)__instance).transform.position, ((Component)activeTable).transform.position); float num2 = __instance.m_maxInteractDistance + 1.75f; if (num > num2) { ValheimCartographerPlugin.LogDebug("Closing map — player left cartography table range"); Minimap.instance.SetMapMode((MapMode)1); } } } } [HarmonyPatch(typeof(Player), "UpdateWishbone")] public static class PlayerWishboneGuard { private static bool Prepare() { return AccessTools.Method(typeof(Player), "UpdateWishbone", (Type[])null, (Type[])null) != null; } private static bool Prefix(Player __instance) { if (!ValheimCartographerPlugin.ModEnabled.Value) { return true; } if (CompassItemSetup.IsCompassEquipped(__instance)) { return false; } return true; } } } namespace ValheimCartographer.Compass { public static class CompassConstants { public const string PrefabName = "VC_CartographerCompass"; public const string NameToken = "$vc_cartographer_compass"; public const string DescToken = "$vc_cartographer_compass_desc"; } internal static class CompassCustomModelLoader { private static class SimpleObjLoader { private readonly struct Corner { public readonly Vector3 Pos; public readonly Vector2 Uv; public readonly Vector3 Normal; public Corner(Vector3 pos, Vector2 uv, Vector3 normal) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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_0009: 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_0010: Unknown result type (might be due to invalid IL or missing references) Pos = pos; Uv = uv; Normal = normal; } } public static bool TryLoad(string path, out Mesh? mesh) { //IL_0088: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) mesh = null; List list = new List(); List list2 = new List(); List list3 = new List(); string[] array; try { array = File.ReadAllLines(path, Encoding.UTF8); } catch { return false; } string[] array2 = array; for (int i = 0; i < array2.Length; i++) { string text = array2[i].Trim(); if (text.Length == 0 || text[0] == '#') { continue; } if (text.StartsWith("v ", StringComparison.Ordinal)) { float[] array3 = SplitFloats(text, 3); if (array3 != null) { list.Add(new Vector3(array3[0], array3[1], array3[2])); } } else if (text.StartsWith("vt ", StringComparison.Ordinal)) { float[] array4 = SplitFloats(text, 2); if (array4 != null) { list2.Add(new Vector2(array4[0], array4[1])); } } else if (text.StartsWith("vn ", StringComparison.Ordinal)) { float[] array5 = SplitFloats(text, 3); if (array5 != null) { list3.Add(new Vector3(array5[0], array5[1], array5[2])); } } } List<(string, List)> list4 = CollectFaceGroups(array); if (list4.Count == 0) { return false; } var (arg, list5) = ChooseLargestFaceGroup(list4); if (list5 == null || list5.Count == 0) { return false; } if (ValheimCartographerPlugin.DebugLogging.Value && list4.Count > 1) { ValheimCartographerPlugin.Log.LogInfo((object)$"Compass OBJ: {list4.Count} object/group(s); using \"{arg}\" ({list5.Count} face line(s))."); } List list6 = new List(); List list7 = new List(); List list8 = new List(); List list9 = new List(); foreach (string item in list5) { List list10 = ParseFaceCorners(item, list, list2, list3); if (list10.Count < 3) { continue; } int count = list6.Count; foreach (Corner item2 in list10) { list6.Add(item2.Pos); list7.Add(item2.Uv); list8.Add(item2.Normal); } for (int j = 1; j < list10.Count - 1; j++) { list9.Add(count); list9.Add(count + j); list9.Add(count + j + 1); } } if (list6.Count == 0 || list9.Count < 3) { return false; } mesh = new Mesh { name = "CompassObjMesh" }; mesh.indexFormat = (IndexFormat)(list6.Count > 65535); mesh.SetVertices(list6); mesh.SetUVs(0, list7); bool flag = false; foreach (Vector3 item3 in list8) { Vector3 current2 = item3; if (((Vector3)(ref current2)).sqrMagnitude > 1E-08f) { flag = true; break; } } if (flag) { mesh.SetNormals(list8); } else { mesh.RecalculateNormals(); } mesh.SetTriangles(list9, 0); mesh.RecalculateBounds(); return true; } private static List<(string name, List faces)> CollectFaceGroups(string[] lines) { List<(string, List)> list = new List<(string, List)>(); List list2 = null; string item = "default"; for (int i = 0; i < lines.Length; i++) { string text = lines[i].Trim(); if (text.Length == 0 || text[0] == '#') { continue; } if (text.StartsWith("o ", StringComparison.Ordinal) || text.StartsWith("g ", StringComparison.Ordinal)) { string text2 = text.Substring(2).Trim(); if (string.IsNullOrEmpty(text2)) { text2 = "unnamed"; } item = text2; list2 = new List(); list.Add((item, list2)); } else if (text.StartsWith("f ", StringComparison.Ordinal)) { if (list2 == null) { list2 = new List(); list.Add((item, list2)); } list2.Add(text); } } return list; } private static int EstimateTriangleFanCount(string fLine) { int num = fLine.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).Length - 1; if (num < 3) { return 0; } return num - 2; } private static (string name, List? faces) ChooseLargestFaceGroup(List<(string name, List faces)> groups) { List list = null; string text = ""; int num = -1; foreach (var (text2, list2) in groups) { if (list2.Count == 0) { continue; } int num2 = 0; foreach (string item in list2) { num2 += EstimateTriangleFanCount(item); } if (num2 > 0) { if (num2 > num) { num = num2; list = list2; text = text2; } else if (num2 == num && list != null && LooksLikeReferencePlane(text) && !LooksLikeReferencePlane(text2)) { list = list2; text = text2; } } } return (text, list); } private static bool LooksLikeReferencePlane(string name) { if (string.IsNullOrEmpty(name)) { return false; } string text = name.Trim().ToLowerInvariant(); if (!(text == "plane")) { return text.StartsWith("plane.", StringComparison.Ordinal); } return true; } private static List ParseFaceCorners(string line, List vIn, List vtIn, List vnIn) { //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) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0157: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) string[] array = line.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); List list = new List(); for (int i = 1; i < array.Length; i++) { string obj = array[i]; int result = 0; int result2 = 0; int result3 = 0; string[] array2 = obj.Split(new char[1] { '/' }); if (array2.Length != 0 && array2[0].Length > 0) { int.TryParse(array2[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out result); } if (array2.Length > 1 && array2[1].Length > 0) { int.TryParse(array2[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out result2); } if (array2.Length > 2 && array2[2].Length > 0) { int.TryParse(array2[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out result3); } int num = ResolveIndex(result, vIn.Count); if (num < 0 || num >= vIn.Count) { continue; } Vector3 pos = vIn[num]; Vector2 uv = Vector2.zero; if (result2 != 0 && vtIn.Count > 0) { int num2 = ResolveIndex(result2, vtIn.Count); if (num2 >= 0 && num2 < vtIn.Count) { uv = vtIn[num2]; } } Vector3 normal = Vector3.zero; if (result3 != 0 && vnIn.Count > 0) { int num3 = ResolveIndex(result3, vnIn.Count); if (num3 >= 0 && num3 < vnIn.Count) { normal = vnIn[num3]; } } list.Add(new Corner(pos, uv, normal)); } return list; } private static float[]? SplitFloats(string line, int count) { string[] array = line.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length < count + 1) { return null; } float[] array2 = new float[count]; for (int i = 0; i < count; i++) { if (!float.TryParse(array[i + 1], NumberStyles.Float, CultureInfo.InvariantCulture, out array2[i])) { return null; } } return array2; } private static int ResolveIndex(int idx, int count) { if (count <= 0) { return -1; } if (idx > 0) { return idx - 1; } if (idx < 0) { return count + idx; } return -1; } } private const string BundleFileNoExt = "valheimcartographer_compass"; private const string BundleFileAlt = "valheimcartographer_compass.bundle"; private static readonly string[] s_objCandidates = new string[2] { "CompassModel.obj", "compass_model.obj" }; private static readonly string[] s_textureFallbacks = new string[1] { "DarkTexture.png" }; public static bool TryApply(GameObject compassPrefab) { if ((Object)(object)compassPrefab == (Object)null) { return false; } string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrEmpty(directoryName)) { return false; } if (TryApplyFromAssetBundle(compassPrefab, directoryName)) { return true; } if (TryApplyFromObjAndTexture(compassPrefab, directoryName)) { return true; } return false; } private static bool TryApplyFromAssetBundle(GameObject compassPrefab, string dir) { string[] array = new string[2] { "valheimcartographer_compass", "valheimcartographer_compass.bundle" }; foreach (string text in array) { string text2 = Path.Combine(dir, text); if (!File.Exists(text2)) { continue; } AssetBundle val = null; try { val = AssetBundle.LoadFromFile(text2); if ((Object)(object)val == (Object)null) { continue; } string[] array2 = new string[4] { "CompassWorld", "CompassPrefab", "compass_model", "CompassMesh" }; foreach (string text3 in array2) { GameObject val2 = val.LoadAsset(text3); if ((Object)(object)val2 != (Object)null && CompassPickupVisual.TryCopyMeshesFromSource(compassPrefab, val2)) { ValheimCartographerPlugin.Log.LogInfo((object)("Compass world model loaded from AssetBundle \"" + text + "\" asset \"" + text3 + "\".")); return true; } } GameObject[] array3 = val.LoadAllAssets(); foreach (GameObject val3 in array3) { if ((Object)(object)val3 != (Object)null && CompassPickupVisual.TryCopyMeshesFromSource(compassPrefab, val3)) { ValheimCartographerPlugin.Log.LogInfo((object)("Compass world model loaded from AssetBundle \"" + text + "\" asset \"" + ((Object)val3).name + "\".")); return true; } } } finally { if (val != null) { val.Unload(false); } } } return false; } private static bool TryApplyFromObjAndTexture(GameObject compassPrefab, string dir) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown if (!TryResolveObjPath(dir, out string objPath, out string label)) { return false; } if (!SimpleObjLoader.TryLoad(objPath, out Mesh mesh) || (Object)(object)mesh == (Object)null) { ValheimCartographerPlugin.Log.LogWarning((object)("Failed to parse " + label + ". Export OBJ from Blender (File → Export → Wavefront OBJ). Raw FBX is not loaded at runtime.")); return false; } Texture2D val = LoadDiffuseTexture(dir, objPath); MeshFilter[] componentsInChildren = compassPrefab.GetComponentsInChildren(true); if (componentsInChildren.Length == 0) { Object.Destroy((Object)(object)mesh); return false; } MeshRenderer component = ((Component)componentsInChildren[0]).GetComponent(); Material val2 = (((Object)(object)component != (Object)null) ? ((Renderer)component).sharedMaterial : null); if ((Object)(object)val2 == (Object)null) { ObjectDB instance = ObjectDB.instance; GameObject val3 = ((instance != null) ? instance.GetItemPrefab("AmberPearl") : null); if ((Object)(object)val3 != (Object)null) { MeshRenderer componentInChildren = val3.GetComponentInChildren(true); val2 = (((Object)(object)componentInChildren != (Object)null) ? ((Renderer)componentInChildren).sharedMaterial : null); } } componentsInChildren[0].sharedMesh = mesh; if ((Object)(object)component != (Object)null && (Object)(object)val2 != (Object)null) { Material val4 = new Material(val2); if ((Object)(object)val != (Object)null) { if (val4.HasProperty("_MainTex")) { val4.SetTexture("_MainTex", (Texture)(object)val); } else if (val4.HasProperty("_Diffuse")) { val4.SetTexture("_Diffuse", (Texture)(object)val); } } ((Renderer)component).sharedMaterial = val4; } string text = (((Object)(object)val != (Object)null) ? (" with texture \"" + ((Object)val).name + "\".") : "."); ValheimCartographerPlugin.Log.LogInfo((object)("Compass world model loaded from " + label + text)); return true; } private static bool TryResolveObjPath(string dir, out string objPath, out string label) { string[] array = s_objCandidates; foreach (string text in array) { string text2 = Path.Combine(dir, text); if (File.Exists(text2)) { objPath = text2; label = text; return true; } } objPath = ""; label = ""; return false; } private static Texture2D? LoadDiffuseTexture(string pluginDir, string objPath) { string text = Path.GetDirectoryName(objPath); if (string.IsNullOrEmpty(text)) { text = pluginDir; } string text2 = ReadMtllibNameFromObj(objPath); string[] array = new string[2] { text2, Path.GetFileNameWithoutExtension(objPath) + ".mtl" }; foreach (string text3 in array) { if (string.IsNullOrEmpty(text3)) { continue; } string text4 = Path.Combine(text, text3); if (!File.Exists(text4)) { continue; } string text5 = TryParseMapKdFromMtl(text4); if (!string.IsNullOrEmpty(text5)) { string path = text5.Replace('/', Path.DirectorySeparatorChar); Texture2D val = TryLoadTextureFile(Path.GetFullPath(Path.Combine(text, path))); if ((Object)(object)val != (Object)null) { return val; } } } array = s_textureFallbacks; foreach (string path2 in array) { Texture2D val2 = TryLoadTextureFile(Path.Combine(pluginDir, path2)); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } private static string? ReadMtllibNameFromObj(string objPath) { try { foreach (string item in File.ReadLines(objPath, Encoding.UTF8)) { string text = item.Trim(); if (text.Length != 0 && text[0] != '#' && text.StartsWith("mtllib ", StringComparison.Ordinal)) { string text2 = text.Substring(7).Trim(); return string.IsNullOrEmpty(text2) ? null : text2; } } } catch { } return null; } private static string? TryParseMapKdFromMtl(string mtlPath) { try { foreach (string item in File.ReadLines(mtlPath, Encoding.UTF8)) { string text = item.Trim(); if (text.Length == 0 || text[0] == '#' || !text.StartsWith("map_Kd", StringComparison.OrdinalIgnoreCase)) { continue; } string[] array = text.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length < 2) { continue; } int num = 1; while (num < array.Length && array[num].StartsWith("-", StringComparison.Ordinal)) { switch (array[num].ToLowerInvariant()) { case "-o": case "-s": case "-t": num += 4; break; case "-bm": case "-mm": case "-clamp": num += 2; break; case "-cc": case "-blendu": case "-blendv": case "-imfchan": num += 2; break; default: num++; break; } } if (num < array.Length) { string text2 = string.Join(" ", array, num, array.Length - num).Trim('"', ' ', '\t'); return string.IsNullOrEmpty(text2) ? null : text2; } } } catch { } return null; } private static Texture2D? TryLoadTextureFile(string path) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (!File.Exists(path)) { return null; } try { byte[] bytes = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!CompassIconLoader.TryLoadImageBytes(val, bytes)) { Object.Destroy((Object)(object)val); return null; } ((Object)val).name = Path.GetFileNameWithoutExtension(path); ((Texture)val).wrapMode = (TextureWrapMode)0; return val; } catch { return null; } } } internal static class CompassEquipment { private static MethodInfo? s_getEquippedInSlot; private static object? s_utilitySlotEnum; private static bool s_resolved; private static void EnsureResolved() { if (s_resolved) { return; } s_resolved = true; MethodInfo[] methods = typeof(Inventory).GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "GetEquippedItemInSlot") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length != 1) { continue; } Type parameterType = parameters[0].ParameterType; if (parameterType.IsEnum) { try { s_utilitySlotEnum = Enum.Parse(parameterType, "Utility"); s_getEquippedInSlot = methodInfo; break; } catch { } } } } public static ItemData? GetUtilityItem(Player? player) { if ((Object)(object)player == (Object)null) { return null; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return null; } EnsureResolved(); if (s_getEquippedInSlot != null && s_utilitySlotEnum != null) { object? obj = s_getEquippedInSlot.Invoke(inventory, new object[1] { s_utilitySlotEnum }); ItemData val = (ItemData)((obj is ItemData) ? obj : null); if (val != null && val.m_shared?.m_name == "$vc_cartographer_compass") { return val; } return null; } foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem.m_equipped && !(allItem.m_shared?.m_name != "$vc_cartographer_compass")) { return allItem; } } return null; } } public sealed class CompassHud : MonoBehaviour { private Canvas? _canvas; private RectTransform? _compassRootRt; private RectTransform? _ribbon0; private RectTransform? _ribbon1; private float _ribbonWidth; private float _halfViewport; private float _pixelsPerDegree; private bool _assetsReady; private float _currentRootY; private float _smoothVel; private bool _hadEquipped; private bool _canvasSortSynced; private void Awake() { Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); BuildUi(); } private void BuildUi() { //IL_0049: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Expected O, but got Unknown //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: 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) _canvas = ((Component)this).gameObject.AddComponent(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 400; CanvasScaler obj = ((Component)this).gameObject.AddComponent(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); ((Component)this).gameObject.AddComponent(); if (!CompassUiTextureLoader.TryLoadSprite("Ribbon_backing.png", new Vector2(0.5f, 0.5f), out Sprite sprite) || !CompassUiTextureLoader.TryLoadSprite("Ribbon.png", new Vector2(0f, 0.5f), out Sprite ribbonSprite)) { ValheimCartographerPlugin.Log.LogWarning((object)"Compass HUD: Ribbon.png and/or Ribbon_backing.png missing next to the DLL; compass ribbon will not show."); _assetsReady = false; ((Behaviour)_canvas).enabled = false; return; } Texture2D texture = sprite.texture; Texture2D ribbonTex = ribbonSprite.texture; _ribbonWidth = ((Texture)ribbonTex).width; _pixelsPerDegree = _ribbonWidth / 360f; float value = ValheimCartographerPlugin.CompassRibbonUsableWidth.Value; float value2 = ValheimCartographerPlugin.CompassHudTrackOffsetY.Value; _halfViewport = value * 0.5f; GameObject val = new GameObject("CompassRoot"); val.transform.SetParent(((Component)this).transform, false); RectTransform val2 = (_compassRootRt = val.AddComponent()); val2.anchorMin = new Vector2(0.5f, 1f); val2.anchorMax = new Vector2(0.5f, 1f); val2.pivot = new Vector2(0.5f, 1f); float value3 = ValheimCartographerPlugin.CompassHudOffsetY.Value; _currentRootY = 0f - value3; val2.anchoredPosition = new Vector2(0f, _currentRootY); val2.sizeDelta = new Vector2((float)((Texture)texture).width, (float)((Texture)texture).height); float num = Mathf.Clamp(ValheimCartographerPlugin.CompassHudScale.Value, 0.08f, 1.5f); ((Transform)val2).localScale = new Vector3(num, num, 1f); GameObject val3 = new GameObject("RibbonBacking"); val3.transform.SetParent(val.transform, false); RectTransform obj2 = val3.AddComponent(); obj2.anchorMin = Vector2.zero; obj2.anchorMax = Vector2.one; obj2.offsetMin = Vector2.zero; obj2.offsetMax = Vector2.zero; Image obj3 = val3.AddComponent(); obj3.sprite = sprite; obj3.preserveAspect = false; ((Graphic)obj3).raycastTarget = false; GameObject maskGo = new GameObject("RibbonScrollMask"); maskGo.transform.SetParent(val.transform, false); RectTransform obj4 = maskGo.AddComponent(); obj4.anchorMin = new Vector2(0.5f, 1f); obj4.anchorMax = new Vector2(0.5f, 1f); obj4.pivot = new Vector2(0.5f, 0.5f); float num2 = (float)(-((Texture)texture).height) * 0.5f - value2; obj4.anchoredPosition = new Vector2(0f, num2); obj4.sizeDelta = new Vector2(value, (float)((Texture)ribbonTex).height); maskGo.AddComponent(); AddRibbon("Ribbon0", out _ribbon0); AddRibbon("Ribbon1", out _ribbon1); _assetsReady = true; ((Behaviour)_canvas).enabled = false; void AddRibbon(string name, out RectTransform rt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0032: 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_005e: 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_008e: Unknown result type (might be due to invalid IL or missing references) GameObject val4 = new GameObject(name); val4.transform.SetParent(maskGo.transform, false); rt = val4.AddComponent(); rt.anchorMin = new Vector2(0f, 0.5f); rt.anchorMax = new Vector2(0f, 0.5f); rt.pivot = new Vector2(0f, 0.5f); rt.anchoredPosition = Vector2.zero; rt.sizeDelta = new Vector2((float)((Texture)ribbonTex).width, (float)((Texture)ribbonTex).height); Image obj5 = val4.AddComponent(); obj5.sprite = ribbonSprite; obj5.type = (Type)0; obj5.preserveAspect = false; ((Graphic)obj5).raycastTarget = false; } } private void TrySyncCanvasSortingBehindHud() { if (!_canvasSortSynced && !((Object)(object)_canvas == (Object)null) && !((Object)(object)Hud.instance == (Object)null)) { Canvas val = null; if ((Object)(object)Hud.instance.m_loadingScreen != (Object)null) { val = ((Component)Hud.instance.m_loadingScreen).GetComponentInParent(); } if ((Object)(object)val == (Object)null && (Object)(object)Hud.instance.m_rootObject != (Object)null) { val = Hud.instance.m_rootObject.GetComponent(); } if (!((Object)(object)val == (Object)null)) { _canvas.sortingOrder = val.sortingOrder + ValheimCartographerPlugin.CompassHudSortOffsetFromHud.Value; _canvasSortSynced = true; } } } private static float NormalizeYawDegrees(float eulerY) { float num = eulerY % 360f; if (num < 0f) { num += 360f; } return num; } private void Update() { //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) if (!_assetsReady || (Object)(object)_canvas == (Object)null || (Object)(object)_compassRootRt == (Object)null || (Object)(object)_ribbon0 == (Object)null || (Object)(object)_ribbon1 == (Object)null) { return; } TrySyncCanvasSortingBehindHud(); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !CompassItemSetup.IsCompassEquipped(localPlayer)) { ((Behaviour)_canvas).enabled = false; _hadEquipped = false; return; } float num = 0f - ValheimCartographerPlugin.CompassHudOffsetY.Value; float num2 = num + ValheimCartographerPlugin.CompassHudSlidePixels.Value; Camera main = Camera.main; if ((Object)(object)main == (Object)null) { ((Behaviour)_canvas).enabled = false; return; } ((Behaviour)_canvas).enabled = true; if (!_hadEquipped) { _hadEquipped = true; bool flag = CompassHudVisibility.ShouldHideAnimated(); _currentRootY = (flag ? num2 : num); _smoothVel = 0f; _compassRootRt.anchoredPosition = new Vector2(0f, _currentRootY); } float num3 = (CompassHudVisibility.ShouldHideAnimated() ? num2 : num); float num4 = Mathf.Max(0.01f, ValheimCartographerPlugin.CompassHudSlideSmoothTime.Value); _currentRootY = Mathf.SmoothDamp(_currentRootY, num3, ref _smoothVel, num4, float.PositiveInfinity, Time.unscaledDeltaTime); _compassRootRt.anchoredPosition = new Vector2(0f, _currentRootY); float num5 = NormalizeYawDegrees(((Component)main).transform.eulerAngles.y); float num6 = Mathf.Repeat(_halfViewport - (num5 + 360f) * _pixelsPerDegree, _ribbonWidth); if (num6 > 0.0001f) { num6 -= _ribbonWidth; } _ribbon0.anchoredPosition = new Vector2(num6, 0f); _ribbon1.anchoredPosition = new Vector2(num6 + _ribbonWidth, 0f); } } internal static class CompassHudVisibility { internal static bool ShouldHideAnimated() { if ((Object)(object)ZNetScene.instance == (Object)null) { return true; } if (Game.IsPaused()) { return true; } if (Time.timeScale <= 0f) { return true; } if (InventoryGui.IsVisible()) { return true; } if (TextInput.IsVisible()) { return true; } if (Minimap.IsOpen()) { return true; } if (Menu.IsVisible()) { return true; } if (StoreGui.IsVisible()) { return true; } if (Console.IsVisible()) { return true; } return false; } } internal static class CompassIconLoader { private static readonly MethodInfo? s_imageConversionLoadImage = ResolveImageConversionLoadImage(); private static MethodInfo? ResolveImageConversionLoadImage() { return Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(Texture2D), typeof(byte[]) }, null); } internal static bool TryLoadImageBytes(Texture2D tex, byte[] bytes) { if (s_imageConversionLoadImage == null) { return false; } object obj = s_imageConversionLoadImage.Invoke(null, new object[2] { tex, bytes }); if (obj is bool) { return (bool)obj; } return false; } public static Sprite? TryLoadSprite() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrEmpty(directoryName)) { return null; } string text = null; string[] array = new string[3] { "icon.png", "Icon.png", "CompassSprite.png" }; foreach (string path in array) { string text2 = Path.Combine(directoryName, path); if (File.Exists(text2)) { text = text2; break; } } if (text == null) { ValheimCartographerPlugin.Log.LogWarning((object)"No icon.png, Icon.png, or CompassSprite.png next to the plugin DLL; compass will use the wishbone icon."); return null; } byte[] bytes; try { bytes = File.ReadAllBytes(text); } catch (IOException ex) { ValheimCartographerPlugin.Log.LogWarning((object)("Could not read " + text + ": " + ex.Message)); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!TryLoadImageBytes(val, bytes)) { ValheimCartographerPlugin.Log.LogWarning((object)((s_imageConversionLoadImage == null) ? "UnityEngine.ImageConversion.LoadImage is not available; compass will use the wishbone icon." : ("Could not decode image: " + text))); return null; } Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = "VC_CartographerIcon"; return obj; } } internal static class CompassItemPostprocess { private static readonly FieldInfo[] s_statusEffectFields = ResolveStatusEffectFields(); private static FieldInfo[] ResolveStatusEffectFields() { Type nestedType = typeof(ItemData).GetNestedType("SharedData", BindingFlags.Public | BindingFlags.NonPublic); if (nestedType == null) { return Array.Empty(); } string[] obj = new string[4] { "m_equipStatusEffect", "m_setStatusEffect", "m_holdStatusEffect", "m_consumeStatusEffect" }; List list = new List(); string[] array = obj; foreach (string name in array) { FieldInfo field = nestedType.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && typeof(StatusEffect).IsAssignableFrom(field.FieldType)) { list.Add(field); } } return list.ToArray(); } public static void StripWishboneStatusEffects(ItemDrop itemDrop) { SharedData val = itemDrop.m_itemData?.m_shared; if (val == null) { return; } FieldInfo[] array = s_statusEffectFields; foreach (FieldInfo fieldInfo in array) { try { fieldInfo.SetValue(val, null); } catch { } } } } public static class CompassItemSetup { private static bool _registered; public static void Register() { if (!_registered) { PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable; } } private static void OnVanillaPrefabsAvailable() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0051: 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_0064: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; int value = ValheimCartographerPlugin.CompassIronCost.Value; int value2 = ValheimCartographerPlugin.CompassWoodCost.Value; ItemConfig val = new ItemConfig { Name = "$vc_cartographer_compass", Description = "$vc_cartographer_compass_desc", CraftingStation = CraftingStations.Forge, MinStationLevel = 1 }; val.AddRequirement("Iron", value, 1); val.AddRequirement("FineWood", value2, 1); Sprite val2 = CompassIconLoader.TryLoadSprite(); if ((Object)(object)val2 != (Object)null) { val.Icon = val2; } CustomItem val3 = new CustomItem("VC_CartographerCompass", "Wishbone", val); ItemManager.Instance.AddItem(val3); CompassItemPostprocess.StripWishboneStatusEffects(val3.ItemDrop); CompassPickupVisual.ApplyToPrefab(val3.ItemPrefab); CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; string text2 = "$vc_cartographer_compass"; localization.AddTranslation(ref text, ref text2, "Cartographer's Compass"); text = "English"; text2 = "$vc_cartographer_compass_desc"; localization.AddTranslation(ref text, ref text2, "A simple compass for reading the land. Equip in the utility slot to see a heading strip at the top of the screen."); _registered = true; ValheimCartographerPlugin.Log.LogInfo((object)"Compass item registered."); } public static bool IsCompassEquipped(Player? player) { if ((Object)(object)player == (Object)null || !ValheimCartographerPlugin.CompassEnabled.Value) { return false; } ItemData utilityItem = CompassEquipment.GetUtilityItem(player); if (utilityItem != null) { return utilityItem.m_shared?.m_name == "$vc_cartographer_compass"; } return false; } } internal static class CompassPickupVisual { private static readonly string[] s_sourcePrefabNames = new string[3] { "AmberPearl", "Ruby", "Coins" }; public static void ApplyToPrefab(GameObject compassPrefab) { if ((Object)(object)compassPrefab == (Object)null || CompassCustomModelLoader.TryApply(compassPrefab)) { return; } string[] array = s_sourcePrefabNames; foreach (string text in array) { GameObject val = ResolveItemPrefab(text); if (!((Object)(object)val == (Object)null) && TryCopyMeshes(compassPrefab, val)) { ValheimCartographerPlugin.Log.LogInfo((object)("Compass world model meshes copied from vanilla prefab \"" + text + "\".")); return; } } ValheimCartographerPlugin.Log.LogWarning((object)"Could not replace compass world meshes; dropped item may still look like a wishbone."); } private static GameObject? ResolveItemPrefab(string name) { if ((Object)(object)ObjectDB.instance != (Object)null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(name); if ((Object)(object)itemPrefab != (Object)null) { return itemPrefab; } } PrefabManager instance = PrefabManager.Instance; if (instance == null) { return null; } return instance.GetPrefab(name); } internal static bool TryCopyMeshesFromSource(GameObject compassPrefab, GameObject sourcePrefab) { return TryCopyMeshes(compassPrefab, sourcePrefab); } private static bool TryCopyMeshes(GameObject compassPrefab, GameObject sourcePrefab) { MeshFilter[] componentsInChildren = sourcePrefab.GetComponentsInChildren(true); MeshFilter[] componentsInChildren2 = compassPrefab.GetComponentsInChildren(true); if (componentsInChildren.Length != 0 && componentsInChildren2.Length != 0) { int num = Mathf.Min(componentsInChildren.Length, componentsInChildren2.Length); for (int i = 0; i < num; i++) { componentsInChildren2[i].sharedMesh = componentsInChildren[i].sharedMesh; MeshRenderer component = ((Component)componentsInChildren2[i]).GetComponent(); MeshRenderer component2 = ((Component)componentsInChildren[i]).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { ((Renderer)component).sharedMaterials = ((Renderer)component2).sharedMaterials; } } return true; } SkinnedMeshRenderer[] componentsInChildren3 = sourcePrefab.GetComponentsInChildren(true); SkinnedMeshRenderer[] componentsInChildren4 = compassPrefab.GetComponentsInChildren(true); if (componentsInChildren3.Length != 0 && componentsInChildren4.Length != 0) { int num2 = Mathf.Min(componentsInChildren3.Length, componentsInChildren4.Length); for (int j = 0; j < num2; j++) { componentsInChildren4[j].sharedMesh = componentsInChildren3[j].sharedMesh; ((Renderer)componentsInChildren4[j]).sharedMaterials = ((Renderer)componentsInChildren3[j]).sharedMaterials; } return true; } return false; } } internal static class CompassUiTextureLoader { internal static bool TryLoadSprite(string fileName, Vector2 pivot, out Sprite sprite) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) sprite = null; string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrEmpty(directoryName)) { return false; } string path = Path.Combine(directoryName, fileName); if (!File.Exists(path)) { return false; } byte[] bytes; try { bytes = File.ReadAllBytes(path); } catch (IOException) { return false; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!CompassIconLoader.TryLoadImageBytes(val, bytes)) { return false; } ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), pivot, 100f); ((Object)sprite).name = "VC_" + fileName; return true; } } }