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 BoringCompass v0.5.0
BoringCompass.dll
Decompiled 8 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JG224.BoringCompass.Core; using JG224.BoringCompass.UI; using JG224.ModCore.API; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [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("BoringCompass")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.5.0.0")] [assembly: AssemblyInformationalVersion("0.5.0")] [assembly: AssemblyProduct("BoringCompass")] [assembly: AssemblyTitle("BoringCompass")] [assembly: AssemblyVersion("0.5.0.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 JG224.BoringCompass { internal sealed class BoringCompassConfig { private readonly ConfigFile _file; private readonly List<ConfigEntryBase> _entries = new List<ConfigEntryBase>(); internal ConfigEntry<bool> Enabled { get; } internal ConfigEntry<bool> AutoWidth { get; } internal ConfigEntry<bool> ShowWhenHudHidden { get; } internal ConfigEntry<bool> ShowDeathMarker { get; } internal ConfigEntry<bool> ShowMapMarkers { get; } internal ConfigEntry<float> MarkerDistance { get; } internal ConfigEntry<CompassHeadingSource> HeadingSource { get; } internal ConfigEntry<float> Scale { get; } internal ConfigEntry<float> OffsetX { get; } internal ConfigEntry<float> OffsetY { get; } internal ConfigEntry<string> Color { get; } internal ConfigEntry<float> Opacity { get; } private BoringCompassConfig(ConfigFile file) { _file = file; Enabled = Bind("Enabled", value: true, "Show the scrolling compass at the top centre of the screen."); AutoWidth = Bind("AutoWidth", value: true, "Fit the compass and its offsets inside the current screen; Scale remains the maximum size."); ShowWhenHudHidden = Bind("ShowWhenHudHidden", value: false, "Keep the compass visible when the HUD is hidden."); ShowDeathMarker = Bind("ShowDeathMarker", value: true, "Show your latest death map pin at any distance. Checked or removed death pins stay hidden."); ShowMapMarkers = Bind("ShowMapMarkers", value: false, "Show nearby unchecked saved map pins, including pins available through map sharing. Excludes other death pins and live player/event pins."); MarkerDistance = BindRange("MarkerDistance", 100f, 1f, 10000f, "Maximum horizontal distance in metres for non-death map markers. Does not limit your latest death marker."); HeadingSource = Bind("HeadingSource", CompassHeadingSource.Camera, "Camera, PlayerFacing, or Movement. Movement falls back to player facing while stationary."); Scale = BindRange("Scale", 1.3f, 0.5f, 2f, "Compass display scale."); OffsetX = BindRange("OffsetX", 0f, -1000f, 1000f, "Horizontal compass offset in screen pixels."); OffsetY = BindRange("OffsetY", 8f, -500f, 500f, "Distance down from the top edge in screen pixels."); Color = Bind("Color", "#F2E6C9", "Compass HTML color, for example #F2E6C9."); Opacity = BindRange("Opacity", 0.95f, 0f, 1f, "Compass opacity."); } internal static BoringCompassConfig Load(BaseUnityPlugin plugin, string configDirectory, ManualLogSource log) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown if (!Directory.Exists(configDirectory)) { Directory.CreateDirectory(configDirectory); } string text = LegacyCompassConfigRules.FindImportSource(Directory.GetFiles(configDirectory, "*.cfg", SearchOption.TopDirectoryOnly)); string text2 = Path.Combine(configDirectory, "jg224.BoringCompass.cfg"); BoringCompassConfig boringCompassConfig = new BoringCompassConfig(PluginConfigFiles.Attach(plugin, new ConfigFile(text2, true, plugin.Info.Metadata))); if (text != null) { boringCompassConfig.ImportLegacyGeneralTweaks(text, log); } return boringCompassConfig; } internal IEnumerable<IDisposable> RegisterMetadata(ICoreServices services, ModuleId owner) { //IL_0016: 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) foreach (ConfigEntryBase entry in _entries) { yield return services.Configuration.Register(new ConfigSettingDescriptor(owner, entry.Definition.Section, entry.Definition.Key, (ConfigScope)1, (Func<string>)(() => Convert.ToString(entry.BoxedValue, CultureInfo.InvariantCulture)), 1)); } } internal static Color ParseColor(string value, float opacity) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (!ColorUtility.TryParseHtmlString(value ?? string.Empty, ref result)) { ((Color)(ref result))..ctor(0.95f, 0.9f, 0.79f); } result.a = Mathf.Clamp01(opacity); return result; } private void ImportLegacyGeneralTweaks(string path, ManualLogSource log) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown try { ConfigFile val = new ConfigFile(path, false); Enabled.Value = val.Bind<bool>("Compass", "Enabled", Enabled.Value, (ConfigDescription)null).Value; HeadingSource.Value = val.Bind<CompassHeadingSource>("Compass", "HeadingSource", HeadingSource.Value, (ConfigDescription)null).Value; Scale.Value = val.Bind<float>("Compass", "Scale", Scale.Value, (ConfigDescription)null).Value; OffsetX.Value = val.Bind<float>("Compass", "OffsetX", OffsetX.Value, (ConfigDescription)null).Value; OffsetY.Value = val.Bind<float>("Compass", "OffsetY", OffsetY.Value, (ConfigDescription)null).Value; Color.Value = val.Bind<string>("Compass", "Color", Color.Value, (ConfigDescription)null).Value; Opacity.Value = val.Bind<float>("Compass", "Opacity", Opacity.Value, (ConfigDescription)null).Value; _file.Save(); if (log != null) { log.LogInfo((object)("Imported compass settings from " + Path.GetFileName(path) + " into jg224.BoringCompass.cfg.")); } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("Could not import GeneralTweaks compass settings; using BoringCompass defaults. " + ex.Message)); } } } private ConfigEntry<T> Bind<T>(string key, T value, string description) { ConfigEntry<T> val = _file.Bind<T>("Compass", key, value, description); _entries.Add((ConfigEntryBase)(object)val); return val; } private ConfigEntry<float> BindRange(string key, float value, float min, float max, string description) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown ConfigEntry<float> val = _file.Bind<float>("Compass", key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>())); _entries.Add((ConfigEntryBase)(object)val); return val; } } [BepInPlugin("jg224.BoringCompass", "BoringCompass", "0.5.0")] [BepInProcess("valheim.exe")] [BepInDependency("com.jg224.modcore", "0.5.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "jg224.BoringCompass"; public const string PluginName = "BoringCompass"; public const string PluginVersion = "0.5.0"; public const string ModCoreGuid = "com.jg224.modcore"; public const string GeneralTweaksGuid = "JG224.GeneralTweaks"; public const int ProtocolVersion = 1; public static readonly ModuleId ModuleId = new ModuleId("boringcompass"); private readonly List<IDisposable> _registrations = new List<IDisposable>(); private Harmony _harmony; private bool _shutDown; internal static ManualLogSource Log { get; private set; } internal static BoringCompassConfig Settings { get; private set; } internal static ICoreServices Core { get; private set; } private void Awake() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Settings = BoringCompassConfig.Load((BaseUnityPlugin)(object)this, Paths.ConfigPath, ((BaseUnityPlugin)this).Logger); try { if (!ModCoreApi.IsAvailable) { throw new InvalidOperationException("ModCore did not initialize before BoringCompass."); } Core = ModCoreApi.Services; RegisterWithCore(); if (TryGetLegacyCompassOwner(out var version)) { string text = "GeneralTweaks " + version?.ToString() + " still contains the compass; BoringCompass is paused to prevent duplicate overlays."; Core.Modules.SetState(ModuleId, (ModuleRuntimeState)3, text); ((BaseUnityPlugin)this).Logger.LogWarning((object)(text + " Update GeneralTweaks to 1.0.0 or newer.")); } else { _harmony = new Harmony("jg224.BoringCompass"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); Core.Modules.SetState(ModuleId, (ModuleRuntimeState)2, "Client-local late-camera compass overlay ready."); Game.isModded = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("BoringCompass 0.5.0 loaded; protocol " + 1 + ".")); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("BoringCompass failed to initialize safely: " + ex)); if (Core != null) { Core.Modules.SetState(ModuleId, (ModuleRuntimeState)5, ex.Message); } Shutdown(); throw; } } private void OnDestroy() { Shutdown(); } private void RegisterWithCore() { //IL_0029: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0059: 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_00cd: 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_00e5: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) SemanticVersion val = default(SemanticVersion); if (!SemanticVersion.TryParse("0.5.0", ref val)) { throw new InvalidOperationException("Invalid plugin version."); } _registrations.Add(Core.Modules.Register(new ModuleDescriptor(ModuleId, "jg224.BoringCompass", "BoringCompass", val, 1, (ModuleSide)1, (ModuleRequirement)1, 0uL, 1, 1))); foreach (IDisposable item in Settings.RegisterMetadata(Core, ModuleId)) { _registrations.Add(item); } _registrations.Add(Core.Namespaces.Register(ModuleId, (NamespaceKind)8, "jg224.boringcompass.", 1, Array.Empty<string>())); _registrations.Add(Core.Ui.Reserve(new UiReservation(ModuleId, (UiSurface)6, "top-center.compass", 20, false))); _registrations.Add(Core.Lifecycle.Subscribe(ModuleId, (LifecycleEventKind)9, (Action<LifecycleEvent>)delegate { CompassOverlay.Destroy(); }, 0)); _registrations.Add(Core.Lifecycle.Subscribe(ModuleId, (LifecycleEventKind)3, (Action<LifecycleEvent>)delegate { CompassOverlay.Destroy(); }, 0)); } private static bool TryGetLegacyCompassOwner(out Version version) { version = null; if (!Chainloader.PluginInfos.TryGetValue("JG224.GeneralTweaks", out var value)) { return false; } version = value.Metadata.Version; if (version != null) { return version.CompareTo(new Version(1, 0, 0)) < 0; } return false; } private void Shutdown() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (_shutDown) { return; } _shutDown = true; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; CompassOverlay.Destroy(); for (int num = _registrations.Count - 1; num >= 0; num--) { try { _registrations[num].Dispose(); } catch (Exception ex) { ManualLogSource logger = ((BaseUnityPlugin)this).Logger; if (logger != null) { logger.LogWarning((object)("Registration cleanup failed: " + ex.Message)); } } } _registrations.Clear(); if (Core != null) { Core.Metrics.RemoveOwner(ModuleId); } Core = null; Settings = null; Log = null; } } } namespace JG224.BoringCompass.UI { internal sealed class CompassMarkers { private static readonly FieldRef<Minimap, List<PinData>> Pins = AccessTools.FieldRefAccess<Minimap, List<PinData>>("m_pins"); private readonly Transform _parent; private readonly List<PinData> _candidates = new List<PinData>(); private readonly List<Image> _images = new List<Image>(); private Minimap _map; private PinData _latestDeath; private float _refreshAt; private bool _showDeath; private bool _showOthers; private float _range; internal CompassMarkers(Transform parent) { _parent = parent; } internal void Update(Player player, float heading, Color color, BoringCompassConfig config) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0161: 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) //IL_0186: Unknown result type (might be due to invalid IL or missing references) Minimap instance = Minimap.instance; float num = CompassMarkerRules.DistanceLimit(config.MarkerDistance.Value); Vector3 position = ((Component)player).transform.position; if ((Object)(object)instance != (Object)(object)_map || Time.unscaledTime >= _refreshAt || config.ShowDeathMarker.Value != _showDeath || config.ShowMapMarkers.Value != _showOthers || num != _range) { _map = instance; _showDeath = config.ShowDeathMarker.Value; _showOthers = config.ShowMapMarkers.Value; _range = num; Refresh(position); _refreshAt = Time.unscaledTime + 0.25f; } int num2 = 0; if (Object.op_Implicit((Object)(object)instance)) { foreach (PinData candidate in _candidates) { Vector3 val = candidate.m_pos - position; if (ShouldShow(candidate, val) && Object.op_Implicit((Object)(object)candidate.m_icon)) { float relativeDegrees = CompassMarkerRules.RelativeBearing(val.x, val.z, heading); float num3 = CompassLayoutRules.EdgeOpacity(relativeDegrees); if (!(num3 <= 0f)) { Image image = GetImage(num2++); image.sprite = candidate.m_icon; ((Graphic)image).color = new Color(1f, 1f, 1f, color.a * num3); ((Graphic)image).rectTransform.anchoredPosition = new Vector2(CompassLayoutRules.HorizontalOffset(relativeDegrees), -68f); ((Component)image).gameObject.SetActive(true); } } } } for (int i = num2; i < _images.Count; i++) { ((Component)_images[i]).gameObject.SetActive(false); } } private void Refresh(Vector3 position) { //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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Invalid comparison between Unknown and I4 //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) _candidates.Clear(); _latestDeath = null; if (!Object.op_Implicit((Object)(object)_map) || (!_showDeath && !_showOthers)) { return; } PlayerProfile val = (Object.op_Implicit((Object)(object)Game.instance) ? Game.instance.GetPlayerProfile() : null); List<PinData> list = Pins.Invoke(_map); if (_showDeath && val != null && val.HaveDeathPoint()) { Vector3 deathPoint = val.GetDeathPoint(); foreach (PinData item in list) { Vector3 val2 = item.m_pos - deathPoint; if (CompassMarkerRules.MatchesLatestDeath((int)item.m_type == 4, item.m_ownerID, val2.x, val2.y, val2.z)) { _latestDeath = item; } } } foreach (PinData item2 in list) { if (item2 != _latestDeath && ShouldShow(item2, item2.m_pos - position)) { _candidates.Add(item2); } } if (_latestDeath != null && ShouldShow(_latestDeath, _latestDeath.m_pos - position)) { _candidates.Add(_latestDeath); } } private bool ShouldShow(PinData pin, Vector3 delta) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0032: 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) if (!pin.m_shouldDelete) { return CompassMarkerRules.ShouldShow((int)pin.m_type == 4, pin == _latestDeath, pin.m_save, pin.m_checked, _showDeath, _showOthers, delta.x, delta.z, _range); } return false; } private Image GetImage(int index) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if (index < _images.Count) { return _images[index]; } GameObject val = new GameObject("MapMarker" + index, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(_parent, false); Image val2 = val.AddComponent<Image>(); ((Graphic)val2).raycastTarget = false; val2.preserveAspect = true; RectTransform rectTransform = ((Graphic)val2).rectTransform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 1f); rectTransform.anchorMax = val3; rectTransform.anchorMin = val3; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.sizeDelta = new Vector2(24f, 24f); _images.Add(val2); return val2; } } internal static class CompassOverlay { private const int TickCount = 25; private const float TickDegrees = 5f; private const float CompassOutlineWidth = 3f / 14f; private const float CompassFaceDilate = 0.2f; private const float PointerOutlineWidth = 5f / 52f; private const float PointerFaceDilate = 0.05f; private static readonly List<TextMeshProUGUI> CompassTicks = new List<TextMeshProUGUI>(); private static readonly List<Material> FontMaterials = new List<Material>(); private static GameObject _root; private static RectTransform _compass; private static Image _compassRail; private static TextMeshProUGUI _pointer; private static TMP_FontAsset _compassFont; private static CompassMarkers _markers; private static int _renderedCompassCentre = int.MinValue; private static float _lastHeading = float.NaN; private static float _retryAt; private static bool _reportedFailure; internal static void TickAfterCamera() { //IL_010e: 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) if (Application.isBatchMode || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)ZNet.instance)) { if (Object.op_Implicit((Object)(object)_root)) { _root.SetActive(false); } } else { if (Time.realtimeSinceStartup < _retryAt) { return; } try { EnsureCreated(); if (!Object.op_Implicit((Object)(object)_root)) { return; } _root.SetActive(true); UpdateCompass(Player.m_localPlayer); if (_reportedFailure) { _reportedFailure = false; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Compass overlay recovered after its HUD initialization failure."); } ICoreServices core = Plugin.Core; if (core != null) { core.Modules.SetState(Plugin.ModuleId, (ModuleRuntimeState)2, "Client-local late-camera compass overlay ready."); } } } catch (Exception ex) { ReleaseObjects(); _retryAt = Time.realtimeSinceStartup + 5f; if (!_reportedFailure) { _reportedFailure = true; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogError((object)("Compass overlay failed; retrying in five seconds: " + ex)); } ICoreServices core2 = Plugin.Core; if (core2 != null) { core2.Modules.SetState(Plugin.ModuleId, (ModuleRuntimeState)3, "Compass overlay initialization/update failed; waiting to retry."); } } } } } internal static void Destroy() { ReleaseObjects(); _retryAt = 0f; } private static void ReleaseObjects() { if (Object.op_Implicit((Object)(object)_root)) { _root.SetActive(false); Object.Destroy((Object)(object)_root); } foreach (Material fontMaterial in FontMaterials) { if (Object.op_Implicit((Object)(object)fontMaterial)) { Object.Destroy((Object)(object)fontMaterial); } } FontMaterials.Clear(); _root = null; _compass = null; _compassRail = null; _pointer = null; _compassFont = null; _markers = null; _renderedCompassCentre = int.MinValue; _lastHeading = float.NaN; CompassTicks.Clear(); } private static void EnsureCreated() { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_023e: 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_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_root)) { return; } ReleaseObjects(); if (Object.op_Implicit((Object)(object)Hud.instance) && Object.op_Implicit((Object)(object)Hud.instance.m_healthText)) { _compassFont = Hud.instance.m_healthText.font; } if (!Object.op_Implicit((Object)(object)_compassFont) && Object.op_Implicit((Object)(object)MessageHud.instance) && Object.op_Implicit((Object)(object)MessageHud.instance.m_messageText)) { _compassFont = MessageHud.instance.m_messageText.font; } if (!Object.op_Implicit((Object)(object)_compassFont)) { _compassFont = TMP_Settings.defaultFontAsset; } if (!Object.op_Implicit((Object)(object)_compassFont) || !Object.op_Implicit((Object)(object)((TMP_Asset)_compassFont).material) || !Object.op_Implicit((Object)(object)_compassFont.atlasTexture)) { return; } _root = new GameObject("JG224.BoringCompass.Overlay"); _root.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_root); Canvas obj = _root.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 200; obj.pixelPerfect = false; _root.AddComponent<CanvasScaler>().uiScaleMode = (ScaleMode)0; ((Behaviour)_root.AddComponent<GraphicRaycaster>()).enabled = false; GameObject val = new GameObject("Compass", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(_root.transform, false); _compass = val.GetComponent<RectTransform>(); _compass.anchorMin = new Vector2(0.5f, 1f); _compass.anchorMax = new Vector2(0.5f, 1f); _compass.pivot = new Vector2(0.5f, 1f); _compass.sizeDelta = new Vector2(900f, 96f); val.AddComponent<RectMask2D>(); _compassRail = CreateRule("TopRail", (Transform)(object)_compass, new Vector2(896f, 2f), new Vector2(0f, -5f)); Vector2 val3 = default(Vector2); for (int i = 0; i < 25; i++) { TextMeshProUGUI val2 = CreateCompassText("Tick" + i, (Transform)(object)_compass); RectTransform rectTransform = ((TMP_Text)val2).rectTransform; ((Vector2)(ref val3))..ctor(0.5f, 1f); rectTransform.anchorMax = val3; rectTransform.anchorMin = val3; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.sizeDelta = new Vector2(58f, 58f); CompassTicks.Add(val2); } _pointer = CreateCompassPointer((Transform)(object)_compass); _markers = new CompassMarkers((Transform)(object)_compass); _root.SetActive(true); foreach (TextMeshProUGUI compassTick in CompassTicks) { ApplyMaterialStyle(compassTick, 3f / 14f, 0.2f); } ApplyMaterialStyle(_pointer, 5f / 52f, 0.05f); } private static TextMeshProUGUI CreateCompassText(string name, Transform parent) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); if (Object.op_Implicit((Object)(object)_compassFont)) { ((TMP_Text)val2).font = _compassFont; } ((TMP_Text)val2).fontSize = 14f; ((TMP_Text)val2).fontStyle = (FontStyles)1; ((TMP_Text)val2).fontWeight = (FontWeight)900; ((TMP_Text)val2).alignment = (TextAlignmentOptions)258; ((TMP_Text)val2).richText = true; ((TMP_Text)val2).enableAutoSizing = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((Graphic)val2).raycastTarget = false; return val2; } private static void ApplyMaterialStyle(TextMeshProUGUI text, float outlineWidth, float faceDilate) { //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) if (!((Behaviour)text).isActiveAndEnabled || !Object.op_Implicit((Object)(object)((TMP_Text)text).fontSharedMaterial)) { throw new InvalidOperationException("Compass text has no active font material."); } Material fontMaterial = ((TMP_Text)text).fontMaterial; if (!Object.op_Implicit((Object)(object)fontMaterial)) { throw new InvalidOperationException("Compass font material could not be initialized."); } FontMaterials.Add(fontMaterial); ((TMP_Text)text).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)text).outlineWidth = outlineWidth; if (fontMaterial.HasProperty(ShaderUtilities.ID_FaceDilate)) { fontMaterial.SetFloat(ShaderUtilities.ID_FaceDilate, faceDilate); } ((TMP_Text)text).UpdateMeshPadding(); } private static TextMeshProUGUI CreateCompassPointer(Transform parent) { //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_005c: 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_0085: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI obj = CreateCompassText("Pointer", parent); ((TMP_Text)obj).text = "<size=13>▼</size>"; ((TMP_Text)obj).fontWeight = (FontWeight)700; ((TMP_Text)obj).alignment = (TextAlignmentOptions)258; RectTransform rectTransform = ((TMP_Text)obj).rectTransform; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 1f); rectTransform.anchorMax = val; rectTransform.anchorMin = val; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(0f, -1f); rectTransform.sizeDelta = new Vector2(22f, 17f); return obj; } private static Image CreateRule(string name, Transform parent, Vector2 size, Vector2 position) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); Image obj = val.AddComponent<Image>(); ((Graphic)obj).raycastTarget = false; RectTransform rectTransform = ((Graphic)obj).rectTransform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 1f); rectTransform.anchorMax = val2; rectTransform.anchorMin = val2; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = position; rectTransform.sizeDelta = size; return obj; } private static void UpdateCompass(Player player) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0132: 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) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) BoringCompassConfig settings = Plugin.Settings; bool flag = settings != null && settings.Enabled.Value && (settings.ShowWhenHudHidden.Value || (Object.op_Implicit((Object)(object)Hud.instance) && !Hud.IsUserHidden() && Object.op_Implicit((Object)(object)Hud.instance.m_rootObject) && Hud.instance.m_rootObject.activeInHierarchy)); ((Component)_compass).gameObject.SetActive(flag); if (!flag) { return; } float num = CompassFitRules.Scale(settings.Scale.Value, Screen.width, Screen.height, settings.AutoWidth.Value); ((Transform)_compass).localScale = Vector3.one * num; float num2 = (settings.AutoWidth.Value ? CompassFitRules.OffsetX(settings.OffsetX.Value, Screen.width, num) : settings.OffsetX.Value); float num3 = (settings.AutoWidth.Value ? Mathf.Clamp(settings.OffsetY.Value, 0f, Mathf.Max(0f, (float)Screen.height - 96f * num)) : settings.OffsetY.Value); _compass.anchoredPosition = new Vector2(num2, 0f - num3); Color val = BoringCompassConfig.ParseColor(settings.Color.Value, settings.Opacity.Value); ((Graphic)_pointer).color = val; Color color = val; color.a *= 0.75f; ((Graphic)_compassRail).color = color; float num4 = Heading(player, settings.HeadingSource.Value); int num5 = Mathf.RoundToInt(num4 / 5f) * 5; bool flag2 = CompassLayoutRules.ShouldRefreshText(_renderedCompassCentre, num5); int num6 = 12; for (int i = 0; i < 25; i++) { int num7 = num5 + (i - num6) * 5; float num8 = HeadingRules.Normalize(num7); float relativeDegrees = Mathf.DeltaAngle(num4, num8); TextMeshProUGUI val2 = CompassTicks[i]; CompassTickKind compassTickKind = HeadingRules.TickKindFor(num7); if (flag2) { string bearingText = HeadingRules.BearingText(num7); string text = CompassLayoutRules.TickMarkFor(compassTickKind); string text2 = CompassLayoutRules.BearingNumberFor(compassTickKind, bearingText); switch (compassTickKind) { case CompassTickKind.Cardinal: ((TMP_Text)val2).text = "<size=16>" + text + "</size>\n<size=24>" + HeadingRules.LabelFor(num8) + "</size>"; break; case CompassTickKind.Ordinal: ((TMP_Text)val2).text = "<size=16>" + text + "</size>\n<size=18>" + HeadingRules.LabelFor(num8) + "</size>"; break; default: ((TMP_Text)val2).text = "<size=16>" + text + "</size>\n<size=14>" + text2 + "</size>"; break; } } Color color2 = val; color2.a *= CompassLayoutRules.EdgeOpacity(relativeDegrees); ((Graphic)val2).color = color2; ((TMP_Text)val2).rectTransform.anchoredPosition = new Vector2(CompassLayoutRules.HorizontalOffset(relativeDegrees), CompassLayoutRules.VerticalOffset(compassTickKind)); } if (flag2) { _renderedCompassCentre = num5; } _markers.Update(player, num4, val, settings); } private static float Heading(Player player, CompassHeadingSource source) { //IL_0010: 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_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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_005e: 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_0063: Unknown result type (might be due to invalid IL or missing references) Vector3 val; switch (source) { case CompassHeadingSource.PlayerFacing: val = ((Component)player).transform.forward; break; case CompassHeadingSource.Movement: val = ((Character)player).GetMoveDir(); if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = ((Component)player).transform.forward; } break; default: val = (Object.op_Implicit((Object)(object)GameCamera.instance) ? ((Component)GameCamera.instance).transform.forward : ((Component)player).transform.forward); break; } Vector3 forward = ((Component)player).transform.forward; _lastHeading = CompassFitRules.Heading(val.x, val.z, forward.x, forward.z, _lastHeading); return _lastHeading; } } } namespace JG224.BoringCompass.Patches { [HarmonyPatch(typeof(GameCamera), "LateUpdate")] internal static class CompassCameraLateUpdatePatch { private static void Postfix() { CompassOverlay.TickAfterCamera(); } } } namespace JG224.BoringCompass.Core { internal static class CompassFitRules { internal static float Heading(float x, float z, float facingX, float facingZ, float previous) { if (Finite(x) && Finite(z) && x * x + z * z >= 0.0001f) { return HeadingRules.Normalize((float)(Math.Atan2(x, z) * 180.0 / Math.PI)); } if (Finite(previous)) { return HeadingRules.Normalize(previous); } if (Finite(facingX) && Finite(facingZ) && facingX * facingX + facingZ * facingZ >= 0.0001f) { return HeadingRules.Normalize((float)(Math.Atan2(facingX, facingZ) * 180.0 / Math.PI)); } return 0f; } internal static float Scale(float requested, int width, int height, bool autoWidth) { requested = (Finite(requested) ? Math.Max(0.5f, Math.Min(2f, requested)) : 1f); if (!autoWidth) { return requested; } return Math.Min(requested, Math.Max(0.01f, Math.Min((float)Math.Max(1, width - 16) / 900f, (float)Math.Max(1, height) / 96f))); } internal static float OffsetX(float requested, int width, float scale) { float num = Math.Max(0f, ((float)width - 900f * scale) / 2f); if (!Finite(requested)) { return 0f; } return Math.Max(0f - num, Math.Min(num, requested)); } private static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } public enum CompassHeadingSource { Camera, PlayerFacing, Movement } internal enum CompassTickKind { Minor, Ordinal, Cardinal } internal static class HeadingRules { private static readonly string[] Labels = new string[8] { "N", "NE", "E", "SE", "S", "SW", "W", "NW" }; internal static float Normalize(float degrees) { degrees %= 360f; if (!(degrees < 0f)) { return degrees; } return degrees + 360f; } internal static string LabelFor(float degrees) { int num = (int)Math.Floor((Normalize(degrees) + 22.5f) / 45f) % Labels.Length; return Labels[num]; } internal static bool IsNamedBearing(int degrees) { return (degrees % 45 + 45) % 45 == 0; } internal static bool IsCardinalBearing(int degrees) { return (degrees % 90 + 90) % 90 == 0; } internal static CompassTickKind TickKindFor(int degrees) { if (IsCardinalBearing(degrees)) { return CompassTickKind.Cardinal; } if (!IsNamedBearing(degrees)) { return CompassTickKind.Minor; } return CompassTickKind.Ordinal; } internal static string BearingText(int degrees) { return ((degrees % 360 + 360) % 360).ToString("000", CultureInfo.InvariantCulture); } } internal static class CompassLayoutRules { internal const float ViewportHeight = 96f; internal const float TickTextHeight = 58f; private const float PixelsPerDegree = 10.625f; private const float OpaqueHalfDegrees = 34f; private const float VisibleHalfDegrees = 42f; internal static string TickMarkFor(CompassTickKind kind) { return "|"; } internal static string BearingNumberFor(CompassTickKind kind, string bearingText) { if (kind != CompassTickKind.Minor) { return string.Empty; } return bearingText; } internal static float HorizontalOffset(float relativeDegrees) { return relativeDegrees * 10.625f; } internal static float VerticalOffset(CompassTickKind kind) { return -6f; } internal static bool ShouldRefreshText(int renderedCentre, int currentCentre) { return renderedCentre != currentCentre; } internal static float EdgeOpacity(float relativeDegrees) { if (float.IsNaN(relativeDegrees) || float.IsInfinity(relativeDegrees)) { return 0f; } float num = Math.Abs(relativeDegrees); if (num <= 34f) { return 1f; } if (num >= 42f) { return 0f; } return (42f - num) / 8f; } } internal static class CompassMarkerRules { internal const float DefaultDistance = 100f; internal static bool MatchesLatestDeath(bool isDeath, long ownerId, float deltaX, float deltaY, float deltaZ) { if (isDeath && ownerId == 0L && deltaX == 0f && deltaY == 0f) { return deltaZ == 0f; } return false; } internal static float DistanceLimit(float configured) { if (!Finite(configured)) { return 100f; } return Math.Max(1f, Math.Min(10000f, configured)); } internal static bool ShouldShow(bool isDeath, bool isLatestDeath, bool saved, bool isChecked, bool showDeath, bool showOthers, float deltaX, float deltaZ, float range) { if (isChecked || !Finite(deltaX) || !Finite(deltaZ)) { return false; } if (isDeath) { return showDeath && isLatestDeath; } double num = DistanceLimit(range); if (showOthers && saved) { return (double)deltaX * (double)deltaX + (double)deltaZ * (double)deltaZ <= num * num; } return false; } internal static float RelativeBearing(float deltaX, float deltaZ, float heading) { if (deltaX == 0f && deltaZ == 0f) { return 0f; } return HeadingRules.Normalize((float)(Math.Atan2(deltaX, deltaZ) * 180.0 / Math.PI) - heading + 180f) - 180f; } private static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } internal static class LegacyCompassConfigRules { internal const string CurrentFileName = "jg224.BoringCompass.cfg"; internal const string GeneralTweaksFileName = "jg224.GeneralTweaks.cfg"; internal const string LegacyGeneralTweaksFileName = "JG224.GeneralTweaks.cfg"; internal static string FindImportSource(IEnumerable<string> candidatePaths) { string[] paths = ((candidatePaths == null) ? Array.Empty<string>() : candidatePaths.ToArray()); if (FindExact(paths, "jg224.BoringCompass.cfg") != null) { return null; } return FindExact(paths, "jg224.GeneralTweaks.cfg") ?? FindExact(paths, "JG224.GeneralTweaks.cfg"); } private static string FindExact(IEnumerable<string> paths, string fileName) { return paths.FirstOrDefault((string path) => string.Equals(Path.GetFileName(path), fileName, StringComparison.Ordinal)); } } }